summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorne (Richard Coles) <torne@google.com>2014-11-06 11:12:39 +0000
committerTorne (Richard Coles) <torne@google.com>2014-11-06 11:12:39 +0000
commit77155b05052120107f7496d7c424ee24e6420550 (patch)
tree5013368c038081fc9d542ad65efe3ec381540eb2
parent401138990c86cc095df3bac0acaf3951b393e32e (diff)
parentb44eb8f9b54e77b4ac5c426ea947f72a6ad74aad (diff)
downloadwebrtc-77155b05052120107f7496d7c424ee24e6420550.tar.gz
Merge from Chromium at DEPS revision db3f05efe0f9
This commit was generated by merge_to_master.py. Change-Id: Ibb07e7633f0f96e925c9bd5cdcb91747ad656b6e
-rw-r--r--BUILD.gn4
-rw-r--r--base/BUILD.gn48
-rw-r--r--base/base.gyp67
-rw-r--r--base/rtc_base.target.darwin-arm.mk10
-rw-r--r--base/rtc_base.target.darwin-arm64.mk12
-rw-r--r--base/rtc_base.target.darwin-mips.mk10
-rw-r--r--base/rtc_base.target.darwin-mips64.mk336
-rw-r--r--base/rtc_base.target.darwin-x86.mk10
-rw-r--r--base/rtc_base.target.darwin-x86_64.mk10
-rw-r--r--base/rtc_base.target.linux-arm.mk10
-rw-r--r--base/rtc_base.target.linux-arm64.mk12
-rw-r--r--base/rtc_base.target.linux-mips.mk10
-rw-r--r--base/rtc_base.target.linux-mips64.mk336
-rw-r--r--base/rtc_base.target.linux-x86.mk10
-rw-r--r--base/rtc_base.target.linux-x86_64.mk10
-rw-r--r--base/rtc_base_approved.target.darwin-arm.mk10
-rw-r--r--base/rtc_base_approved.target.darwin-arm64.mk12
-rw-r--r--base/rtc_base_approved.target.darwin-mips.mk10
-rw-r--r--base/rtc_base_approved.target.darwin-mips64.mk263
-rw-r--r--base/rtc_base_approved.target.darwin-x86.mk10
-rw-r--r--base/rtc_base_approved.target.darwin-x86_64.mk10
-rw-r--r--base/rtc_base_approved.target.linux-arm.mk10
-rw-r--r--base/rtc_base_approved.target.linux-arm64.mk12
-rw-r--r--base/rtc_base_approved.target.linux-mips.mk10
-rw-r--r--base/rtc_base_approved.target.linux-mips64.mk263
-rw-r--r--base/rtc_base_approved.target.linux-x86.mk10
-rw-r--r--base/rtc_base_approved.target.linux-x86_64.mk10
-rw-r--r--base/webrtc_base.target.darwin-mips64.mk47
-rw-r--r--base/webrtc_base.target.linux-mips64.mk47
-rw-r--r--build/common.gypi9
-rw-r--r--build/isolate.gypi12
-rw-r--r--build/merge_libs.gyp2
-rw-r--r--build/tsan_suppressions_webrtc.cc1
-rw-r--r--common_audio/BUILD.gn8
-rw-r--r--common_audio/audio_converter.cc110
-rw-r--r--common_audio/audio_converter.h55
-rw-r--r--common_audio/audio_converter_unittest.cc155
-rw-r--r--common_audio/audio_util.cc22
-rw-r--r--common_audio/audio_util_unittest.cc48
-rw-r--r--common_audio/common_audio.gyp14
-rw-r--r--common_audio/common_audio.target.darwin-arm.mk14
-rw-r--r--common_audio/common_audio.target.darwin-arm64.mk16
-rw-r--r--common_audio/common_audio.target.darwin-mips.mk14
-rw-r--r--common_audio/common_audio.target.darwin-mips64.mk316
-rw-r--r--common_audio/common_audio.target.darwin-x86.mk14
-rw-r--r--common_audio/common_audio.target.darwin-x86_64.mk14
-rw-r--r--common_audio/common_audio.target.linux-arm.mk14
-rw-r--r--common_audio/common_audio.target.linux-arm64.mk16
-rw-r--r--common_audio/common_audio.target.linux-mips.mk14
-rw-r--r--common_audio/common_audio.target.linux-mips64.mk316
-rw-r--r--common_audio/common_audio.target.linux-x86.mk14
-rw-r--r--common_audio/common_audio.target.linux-x86_64.mk14
-rw-r--r--common_audio/common_audio_neon.target.darwin-arm.mk10
-rw-r--r--common_audio/common_audio_neon.target.linux-arm.mk10
-rw-r--r--common_audio/common_audio_sse2.target.darwin-x86.mk10
-rw-r--r--common_audio/common_audio_sse2.target.darwin-x86_64.mk10
-rw-r--r--common_audio/common_audio_sse2.target.linux-x86.mk10
-rw-r--r--common_audio/common_audio_sse2.target.linux-x86_64.mk10
-rw-r--r--common_audio/common_audio_unittests.isolate7
-rw-r--r--common_audio/include/audio_util.h54
-rw-r--r--common_audio/resampler/push_sinc_resampler.cc2
-rw-r--r--common_audio/resampler/push_sinc_resampler_unittest.cc9
-rw-r--r--common_audio/signal_processing/complex_fft.c69
-rw-r--r--common_audio/signal_processing/division_operations.c15
-rw-r--r--common_audio/signal_processing/include/signal_processing_library.h3
-rw-r--r--common_audio/signal_processing/levinson_durbin.c58
-rw-r--r--common_audio/signal_processing/lpc_to_refl_coef.c4
-rw-r--r--common_audio/signal_processing/min_max_operations_neon.S2
-rw-r--r--common_audio/signal_processing/signal_processing_unittest.cc2
-rw-r--r--common_audio/signal_processing/spl_sqrt.c22
-rw-r--r--common_audio/signal_processing/splitting_filter.c10
-rw-r--r--common_audio/vad/include/vad.h45
-rw-r--r--common_audio/vad/mock/mock_vad.h34
-rw-r--r--common_audio/vad/vad.cc43
-rw-r--r--common_audio/wav_file.cc166
-rw-r--r--common_audio/wav_file.h98
-rw-r--r--common_audio/wav_file_unittest.cc (renamed from common_audio/wav_writer_unittest.cc)34
-rw-r--r--common_audio/wav_header.cc130
-rw-r--r--common_audio/wav_header.h14
-rw-r--r--common_audio/wav_header_unittest.cc90
-rw-r--r--common_audio/wav_writer.cc115
-rw-r--r--common_audio/wav_writer.h72
-rw-r--r--common_types.h82
-rw-r--r--common_video/common_video.target.darwin-arm.mk10
-rw-r--r--common_video/common_video.target.darwin-arm64.mk12
-rw-r--r--common_video/common_video.target.darwin-mips.mk10
-rw-r--r--common_video/common_video.target.darwin-mips64.mk273
-rw-r--r--common_video/common_video.target.darwin-x86.mk10
-rw-r--r--common_video/common_video.target.darwin-x86_64.mk10
-rw-r--r--common_video/common_video.target.linux-arm.mk10
-rw-r--r--common_video/common_video.target.linux-arm64.mk12
-rw-r--r--common_video/common_video.target.linux-mips.mk10
-rw-r--r--common_video/common_video.target.linux-mips64.mk273
-rw-r--r--common_video/common_video.target.linux-x86.mk10
-rw-r--r--common_video/common_video.target.linux-x86_64.mk10
-rw-r--r--common_video/common_video_unittests.gyp1
-rw-r--r--common_video/common_video_unittests.isolate7
-rw-r--r--config.cc36
-rw-r--r--config.h25
-rw-r--r--engine_configurations.h7
-rw-r--r--examples/android/media_demo/build.xml77
-rw-r--r--examples/android/media_demo/project.properties2
-rw-r--r--examples/android/opensl_loopback/project.properties2
-rw-r--r--libjingle/xmllite/rtc_xmllite.target.darwin-arm.mk10
-rw-r--r--libjingle/xmllite/rtc_xmllite.target.darwin-arm64.mk12
-rw-r--r--libjingle/xmllite/rtc_xmllite.target.darwin-mips.mk10
-rw-r--r--libjingle/xmllite/rtc_xmllite.target.darwin-mips64.mk275
-rw-r--r--libjingle/xmllite/rtc_xmllite.target.darwin-x86.mk10
-rw-r--r--libjingle/xmllite/rtc_xmllite.target.darwin-x86_64.mk10
-rw-r--r--libjingle/xmllite/rtc_xmllite.target.linux-arm.mk10
-rw-r--r--libjingle/xmllite/rtc_xmllite.target.linux-arm64.mk12
-rw-r--r--libjingle/xmllite/rtc_xmllite.target.linux-mips.mk10
-rw-r--r--libjingle/xmllite/rtc_xmllite.target.linux-mips64.mk275
-rw-r--r--libjingle/xmllite/rtc_xmllite.target.linux-x86.mk10
-rw-r--r--libjingle/xmllite/rtc_xmllite.target.linux-x86_64.mk10
-rw-r--r--libjingle/xmpp/OWNERS13
-rw-r--r--libjingle/xmpp/asyncsocket.h72
-rw-r--r--libjingle/xmpp/chatroommodule.h253
-rw-r--r--libjingle/xmpp/chatroommodule_unittest.cc280
-rw-r--r--libjingle/xmpp/chatroommoduleimpl.cc735
-rw-r--r--libjingle/xmpp/constants.cc614
-rw-r--r--libjingle/xmpp/constants.h551
-rw-r--r--libjingle/xmpp/discoitemsquerytask.cc62
-rw-r--r--libjingle/xmpp/discoitemsquerytask.h65
-rw-r--r--libjingle/xmpp/fakexmppclient.h106
-rw-r--r--libjingle/xmpp/hangoutpubsubclient.cc400
-rw-r--r--libjingle/xmpp/hangoutpubsubclient.h178
-rw-r--r--libjingle/xmpp/hangoutpubsubclient_unittest.cc753
-rw-r--r--libjingle/xmpp/iqtask.cc69
-rw-r--r--libjingle/xmpp/iqtask.h48
-rw-r--r--libjingle/xmpp/jid.cc379
-rw-r--r--libjingle/xmpp/jid.h81
-rw-r--r--libjingle/xmpp/jid_unittest.cc122
-rw-r--r--libjingle/xmpp/jingleinfotask.cc121
-rw-r--r--libjingle/xmpp/jingleinfotask.h44
-rw-r--r--libjingle/xmpp/module.h35
-rw-r--r--libjingle/xmpp/moduleimpl.cc48
-rw-r--r--libjingle/xmpp/moduleimpl.h76
-rw-r--r--libjingle/xmpp/mucroomconfigtask.cc74
-rw-r--r--libjingle/xmpp/mucroomconfigtask.h47
-rw-r--r--libjingle/xmpp/mucroomconfigtask_unittest.cc127
-rw-r--r--libjingle/xmpp/mucroomdiscoverytask.cc66
-rw-r--r--libjingle/xmpp/mucroomdiscoverytask.h41
-rw-r--r--libjingle/xmpp/mucroomdiscoverytask_unittest.cc145
-rw-r--r--libjingle/xmpp/mucroomlookuptask.cc159
-rw-r--r--libjingle/xmpp/mucroomlookuptask.h76
-rw-r--r--libjingle/xmpp/mucroomlookuptask_unittest.cc187
-rw-r--r--libjingle/xmpp/mucroomuniquehangoutidtask.cc51
-rw-r--r--libjingle/xmpp/mucroomuniquehangoutidtask.h38
-rw-r--r--libjingle/xmpp/mucroomuniquehangoutidtask_unittest.cc99
-rw-r--r--libjingle/xmpp/pingtask.cc92
-rw-r--r--libjingle/xmpp/pingtask.h54
-rw-r--r--libjingle/xmpp/pingtask_unittest.cc101
-rw-r--r--libjingle/xmpp/plainsaslhandler.h64
-rw-r--r--libjingle/xmpp/presenceouttask.cc140
-rw-r--r--libjingle/xmpp/presenceouttask.h37
-rw-r--r--libjingle/xmpp/presencereceivetask.cc141
-rw-r--r--libjingle/xmpp/presencereceivetask.h56
-rw-r--r--libjingle/xmpp/presencestatus.cc45
-rw-r--r--libjingle/xmpp/presencestatus.h188
-rw-r--r--libjingle/xmpp/prexmppauth.h71
-rw-r--r--libjingle/xmpp/pubsub_task.cc200
-rw-r--r--libjingle/xmpp/pubsub_task.h58
-rw-r--r--libjingle/xmpp/pubsubclient.cc129
-rw-r--r--libjingle/xmpp/pubsubclient.h111
-rw-r--r--libjingle/xmpp/pubsubclient_unittest.cc278
-rw-r--r--libjingle/xmpp/pubsubstateclient.cc25
-rw-r--r--libjingle/xmpp/pubsubstateclient.h270
-rw-r--r--libjingle/xmpp/pubsubtasks.cc204
-rw-r--r--libjingle/xmpp/pubsubtasks.h114
-rw-r--r--libjingle/xmpp/pubsubtasks_unittest.cc280
-rw-r--r--libjingle/xmpp/receivetask.cc34
-rw-r--r--libjingle/xmpp/receivetask.h41
-rw-r--r--libjingle/xmpp/rostermodule.h331
-rw-r--r--libjingle/xmpp/rostermodule_unittest.cc832
-rw-r--r--libjingle/xmpp/rostermoduleimpl.cc1064
-rw-r--r--libjingle/xmpp/rostermoduleimpl.h285
-rw-r--r--libjingle/xmpp/saslcookiemechanism.h69
-rw-r--r--libjingle/xmpp/saslhandler.h42
-rw-r--r--libjingle/xmpp/saslmechanism.cc55
-rw-r--r--libjingle/xmpp/saslmechanism.h57
-rw-r--r--libjingle/xmpp/saslplainmechanism.h48
-rw-r--r--libjingle/xmpp/util_unittest.cc109
-rw-r--r--libjingle/xmpp/util_unittest.h58
-rw-r--r--libjingle/xmpp/xmpp.gyp141
-rw-r--r--libjingle/xmpp/xmpp_tests.gypi37
-rw-r--r--libjingle/xmpp/xmppauth.cc88
-rw-r--r--libjingle/xmpp/xmppauth.h61
-rw-r--r--libjingle/xmpp/xmppclient.cc424
-rw-r--r--libjingle/xmpp/xmppclient.h148
-rw-r--r--libjingle/xmpp/xmppclientsettings.h111
-rw-r--r--libjingle/xmpp/xmppengine.h332
-rw-r--r--libjingle/xmpp/xmppengine_unittest.cc325
-rw-r--r--libjingle/xmpp/xmppengineimpl.cc446
-rw-r--r--libjingle/xmpp/xmppengineimpl.h265
-rw-r--r--libjingle/xmpp/xmppengineimpl_iq.cc260
-rw-r--r--libjingle/xmpp/xmpplogintask.cc380
-rw-r--r--libjingle/xmpp/xmpplogintask.h87
-rw-r--r--libjingle/xmpp/xmpplogintask_unittest.cc621
-rw-r--r--libjingle/xmpp/xmpppump.cc67
-rw-r--r--libjingle/xmpp/xmpppump.h62
-rw-r--r--libjingle/xmpp/xmppsocket.cc245
-rw-r--r--libjingle/xmpp/xmppsocket.h72
-rw-r--r--libjingle/xmpp/xmppstanzaparser.cc89
-rw-r--r--libjingle/xmpp/xmppstanzaparser.h80
-rw-r--r--libjingle/xmpp/xmppstanzaparser_unittest.cc175
-rw-r--r--libjingle/xmpp/xmpptask.cc158
-rw-r--r--libjingle/xmpp/xmpptask.h172
-rw-r--r--libjingle/xmpp/xmppthread.cc69
-rw-r--r--libjingle/xmpp/xmppthread.h45
-rw-r--r--modules/CNG.target.darwin-arm.mk10
-rw-r--r--modules/CNG.target.darwin-arm64.mk12
-rw-r--r--modules/CNG.target.darwin-mips.mk10
-rw-r--r--modules/CNG.target.darwin-mips64.mk275
-rw-r--r--modules/CNG.target.darwin-x86.mk10
-rw-r--r--modules/CNG.target.darwin-x86_64.mk10
-rw-r--r--modules/CNG.target.linux-arm.mk10
-rw-r--r--modules/CNG.target.linux-arm64.mk12
-rw-r--r--modules/CNG.target.linux-mips.mk10
-rw-r--r--modules/CNG.target.linux-mips64.mk275
-rw-r--r--modules/CNG.target.linux-x86.mk10
-rw-r--r--modules/CNG.target.linux-x86_64.mk10
-rw-r--r--modules/G711.target.darwin-arm.mk14
-rw-r--r--modules/G711.target.darwin-arm64.mk16
-rw-r--r--modules/G711.target.darwin-mips.mk14
-rw-r--r--modules/G711.target.darwin-mips64.mk271
-rw-r--r--modules/G711.target.darwin-x86.mk14
-rw-r--r--modules/G711.target.darwin-x86_64.mk14
-rw-r--r--modules/G711.target.linux-arm.mk14
-rw-r--r--modules/G711.target.linux-arm64.mk16
-rw-r--r--modules/G711.target.linux-mips.mk14
-rw-r--r--modules/G711.target.linux-mips64.mk271
-rw-r--r--modules/G711.target.linux-x86.mk14
-rw-r--r--modules/G711.target.linux-x86_64.mk14
-rw-r--r--modules/G722.target.darwin-arm.mk10
-rw-r--r--modules/G722.target.darwin-arm64.mk12
-rw-r--r--modules/G722.target.darwin-mips.mk10
-rw-r--r--modules/G722.target.darwin-mips64.mk270
-rw-r--r--modules/G722.target.darwin-x86.mk10
-rw-r--r--modules/G722.target.darwin-x86_64.mk10
-rw-r--r--modules/G722.target.linux-arm.mk10
-rw-r--r--modules/G722.target.linux-arm64.mk12
-rw-r--r--modules/G722.target.linux-mips.mk10
-rw-r--r--modules/G722.target.linux-mips64.mk270
-rw-r--r--modules/G722.target.linux-x86.mk10
-rw-r--r--modules/G722.target.linux-x86_64.mk10
-rw-r--r--modules/PCM16B.target.darwin-arm.mk10
-rw-r--r--modules/PCM16B.target.darwin-arm64.mk12
-rw-r--r--modules/PCM16B.target.darwin-mips.mk10
-rw-r--r--modules/PCM16B.target.darwin-mips64.mk268
-rw-r--r--modules/PCM16B.target.darwin-x86.mk10
-rw-r--r--modules/PCM16B.target.darwin-x86_64.mk10
-rw-r--r--modules/PCM16B.target.linux-arm.mk10
-rw-r--r--modules/PCM16B.target.linux-arm64.mk12
-rw-r--r--modules/PCM16B.target.linux-mips.mk10
-rw-r--r--modules/PCM16B.target.linux-mips64.mk268
-rw-r--r--modules/PCM16B.target.linux-x86.mk10
-rw-r--r--modules/PCM16B.target.linux-x86_64.mk10
-rw-r--r--modules/audio_coding/BUILD.gn4
-rw-r--r--modules/audio_coding/codecs/audio_encoder.h64
-rw-r--r--modules/audio_coding/codecs/g711/audio_encoder_pcm.cc98
-rw-r--r--modules/audio_coding/codecs/g711/g711.gypi2
-rw-r--r--modules/audio_coding/codecs/g711/g711_interface.c28
-rw-r--r--modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h79
-rw-r--r--modules/audio_coding/codecs/g711/include/g711_interface.h25
-rw-r--r--modules/audio_coding/codecs/g711/test/testG711.cc9
-rw-r--r--modules/audio_coding/codecs/ilbc/cb_construct.c2
-rw-r--r--modules/audio_coding/codecs/ilbc/cb_mem_energy.c4
-rw-r--r--modules/audio_coding/codecs/ilbc/cb_mem_energy_augmentation.c2
-rw-r--r--modules/audio_coding/codecs/ilbc/cb_mem_energy_calc.c4
-rw-r--r--modules/audio_coding/codecs/ilbc/cb_search_core.c2
-rw-r--r--modules/audio_coding/codecs/ilbc/cb_update_best_index.c3
-rw-r--r--modules/audio_coding/codecs/ilbc/chebyshev.c10
-rw-r--r--modules/audio_coding/codecs/ilbc/do_plc.c10
-rw-r--r--modules/audio_coding/codecs/ilbc/get_lsp_poly.c4
-rw-r--r--modules/audio_coding/codecs/ilbc/hp_input.c2
-rw-r--r--modules/audio_coding/codecs/ilbc/hp_output.c2
-rw-r--r--modules/audio_coding/codecs/ilbc/interpolate.c4
-rw-r--r--modules/audio_coding/codecs/ilbc/lsf_to_lsp.c2
-rw-r--r--modules/audio_coding/codecs/ilbc/lsf_to_poly.c4
-rw-r--r--modules/audio_coding/codecs/ilbc/poly_to_lsp.c6
-rw-r--r--modules/audio_coding/codecs/ilbc/refiner.c2
-rw-r--r--modules/audio_coding/codecs/ilbc/smooth.c14
-rw-r--r--modules/audio_coding/codecs/ilbc/smooth_out_data.c3
-rw-r--r--modules/audio_coding/codecs/ilbc/sort_sq.c2
-rw-r--r--modules/audio_coding/codecs/ilbc/window32_w32.c8
-rw-r--r--modules/audio_coding/codecs/ilbc/xcorr_coef.c4
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/arith_routines.c12
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/arith_routines_hist.c9
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/arith_routines_logist.c12
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.c78
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/decode.c8
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/decode_plc.c17
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/encode.c3
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/entropy_coding.c121
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/filterbanks.c10
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/filters.c9
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/isacfix.c170
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/isacfix.gypi2
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/lattice.c12
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/lattice_c.c6
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.c117
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/pitch_estimator.c20
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/pitch_estimator_c.c6
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/pitch_estimator_mips.c6
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/pitch_filter.c19
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/pitch_filter_c.c5
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/transform.c35
-rw-r--r--modules/audio_coding/codecs/isac/main/source/entropy_coding.c21
-rw-r--r--modules/audio_coding/codecs/isac/main/test/ReleaseTest-API/ReleaseTest-API.cc2
-rw-r--r--modules/audio_coding/codecs/isac/main/test/simpleKenny.c4
-rw-r--r--modules/audio_coding/codecs/opus/audio_encoder_opus.cc104
-rw-r--r--modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h55
-rw-r--r--modules/audio_coding/codecs/opus/opus.gypi2
-rw-r--r--modules/audio_coding/codecs/pcm16b/include/pcm16b.h3
-rw-r--r--modules/audio_coding/codecs/pcm16b/pcm16b.c6
-rw-r--r--modules/audio_coding/codecs/tools/audio_codec_speed_tests.gypi1
-rw-r--r--modules/audio_coding/codecs/tools/audio_codec_speed_tests.isolate9
-rw-r--r--modules/audio_coding/main/acm2/acm_isac.cc3
-rw-r--r--modules/audio_coding/main/acm2/acm_pcma.cc2
-rw-r--r--modules/audio_coding/main/acm2/acm_pcmu.cc2
-rw-r--r--modules/audio_coding/main/acm2/acm_receiver.cc109
-rw-r--r--modules/audio_coding/main/acm2/acm_receiver.h4
-rw-r--r--modules/audio_coding/main/acm2/audio_coding_module.gypi4
-rw-r--r--modules/audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc4
-rw-r--r--modules/audio_coding/main/test/APITest.cc2
-rw-r--r--modules/audio_coding/neteq/audio_decoder.cc22
-rw-r--r--modules/audio_coding/neteq/audio_decoder_impl.cc84
-rw-r--r--modules/audio_coding/neteq/audio_decoder_impl.h32
-rw-r--r--modules/audio_coding/neteq/audio_decoder_unittest.cc375
-rw-r--r--modules/audio_coding/neteq/audio_decoder_unittests.isolate9
-rw-r--r--modules/audio_coding/neteq/decision_logic_normal.cc10
-rw-r--r--modules/audio_coding/neteq/decoder_database_unittest.cc4
-rw-r--r--modules/audio_coding/neteq/expand.cc2
-rw-r--r--modules/audio_coding/neteq/interface/audio_decoder.h10
-rw-r--r--modules/audio_coding/neteq/interface/neteq.h2
-rw-r--r--modules/audio_coding/neteq/mock/mock_audio_decoder.h2
-rw-r--r--modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h12
-rw-r--r--modules/audio_coding/neteq/mock/mock_packet_buffer.h4
-rw-r--r--modules/audio_coding/neteq/neteq.gypi6
-rw-r--r--modules/audio_coding/neteq/neteq_external_decoder_unittest.cc17
-rw-r--r--modules/audio_coding/neteq/neteq_impl.cc10
-rw-r--r--modules/audio_coding/neteq/neteq_impl.h2
-rw-r--r--modules/audio_coding/neteq/neteq_impl_unittest.cc98
-rw-r--r--modules/audio_coding/neteq/neteq_tests.gypi2
-rw-r--r--modules/audio_coding/neteq/packet_buffer.cc12
-rw-r--r--modules/audio_coding/neteq/packet_buffer.h28
-rw-r--r--modules/audio_coding/neteq/packet_buffer_unittest.cc59
-rw-r--r--modules/audio_coding/neteq/test/RTPencode.cc7
-rw-r--r--modules/audio_coding/neteq/tools/neteq_rtpplay.cc37
-rw-r--r--modules/audio_coding/neteq/tools/resample_input_audio_file.cc42
-rw-r--r--modules/audio_coding/neteq/tools/resample_input_audio_file.h40
-rw-r--r--modules/audio_coding_module.target.darwin-arm.mk10
-rw-r--r--modules/audio_coding_module.target.darwin-arm64.mk12
-rw-r--r--modules/audio_coding_module.target.darwin-mips.mk10
-rw-r--r--modules/audio_coding_module.target.darwin-mips64.mk328
-rw-r--r--modules/audio_coding_module.target.darwin-x86.mk10
-rw-r--r--modules/audio_coding_module.target.darwin-x86_64.mk10
-rw-r--r--modules/audio_coding_module.target.linux-arm.mk10
-rw-r--r--modules/audio_coding_module.target.linux-arm64.mk12
-rw-r--r--modules/audio_coding_module.target.linux-mips.mk10
-rw-r--r--modules/audio_coding_module.target.linux-mips64.mk328
-rw-r--r--modules/audio_coding_module.target.linux-x86.mk10
-rw-r--r--modules/audio_coding_module.target.linux-x86_64.mk10
-rw-r--r--modules/audio_conference_mixer.target.darwin-arm.mk10
-rw-r--r--modules/audio_conference_mixer.target.darwin-arm64.mk12
-rw-r--r--modules/audio_conference_mixer.target.darwin-mips.mk10
-rw-r--r--modules/audio_conference_mixer.target.darwin-mips64.mk274
-rw-r--r--modules/audio_conference_mixer.target.darwin-x86.mk10
-rw-r--r--modules/audio_conference_mixer.target.darwin-x86_64.mk10
-rw-r--r--modules/audio_conference_mixer.target.linux-arm.mk10
-rw-r--r--modules/audio_conference_mixer.target.linux-arm64.mk12
-rw-r--r--modules/audio_conference_mixer.target.linux-mips.mk10
-rw-r--r--modules/audio_conference_mixer.target.linux-mips64.mk274
-rw-r--r--modules/audio_conference_mixer.target.linux-x86.mk10
-rw-r--r--modules/audio_conference_mixer.target.linux-x86_64.mk10
-rw-r--r--modules/audio_device.target.darwin-arm.mk10
-rw-r--r--modules/audio_device.target.darwin-arm64.mk12
-rw-r--r--modules/audio_device.target.darwin-mips.mk10
-rw-r--r--modules/audio_device.target.darwin-mips64.mk291
-rw-r--r--modules/audio_device.target.darwin-x86.mk10
-rw-r--r--modules/audio_device.target.darwin-x86_64.mk10
-rw-r--r--modules/audio_device.target.linux-arm.mk10
-rw-r--r--modules/audio_device.target.linux-arm64.mk12
-rw-r--r--modules/audio_device.target.linux-mips.mk10
-rw-r--r--modules/audio_device.target.linux-mips64.mk291
-rw-r--r--modules/audio_device.target.linux-x86.mk10
-rw-r--r--modules/audio_device.target.linux-x86_64.mk10
-rw-r--r--modules/audio_device/audio_device.gypi1
-rw-r--r--modules/audio_device/audio_device_tests.isolate7
-rw-r--r--modules/audio_device/audio_device_utility.cc4
-rw-r--r--modules/audio_device/win/audio_device_core_win.cc11
-rw-r--r--modules/audio_processing.target.darwin-arm.mk10
-rw-r--r--modules/audio_processing.target.darwin-arm64.mk12
-rw-r--r--modules/audio_processing.target.darwin-mips.mk10
-rw-r--r--modules/audio_processing.target.darwin-mips64.mk316
-rw-r--r--modules/audio_processing.target.darwin-x86.mk10
-rw-r--r--modules/audio_processing.target.darwin-x86_64.mk10
-rw-r--r--modules/audio_processing.target.linux-arm.mk10
-rw-r--r--modules/audio_processing.target.linux-arm64.mk12
-rw-r--r--modules/audio_processing.target.linux-mips.mk10
-rw-r--r--modules/audio_processing.target.linux-mips64.mk316
-rw-r--r--modules/audio_processing.target.linux-x86.mk10
-rw-r--r--modules/audio_processing.target.linux-x86_64.mk10
-rw-r--r--modules/audio_processing/aec/aec_core.c2
-rw-r--r--modules/audio_processing/aec/aec_core_internal.h10
-rw-r--r--modules/audio_processing/audio_buffer.cc41
-rw-r--r--modules/audio_processing/audio_processing.gypi4
-rw-r--r--modules/audio_processing/gen_aecm_core_neon_offsets_h.target.darwin-arm.mk10
-rw-r--r--modules/audio_processing/gen_aecm_core_neon_offsets_h.target.linux-arm.mk10
-rw-r--r--modules/audio_processing/gen_nsx_core_neon_offsets_h.target.darwin-arm.mk10
-rw-r--r--modules/audio_processing/gen_nsx_core_neon_offsets_h.target.linux-arm.mk10
-rw-r--r--modules/audio_processing/lib_core_neon_offsets.target.darwin-arm.mk10
-rw-r--r--modules/audio_processing/lib_core_neon_offsets.target.linux-arm.mk10
-rw-r--r--modules/audio_processing/ns/ns_core.c1760
-rw-r--r--modules/audio_processing/ns/ns_core.h108
-rw-r--r--modules/audio_processing/ns/nsx_core_neon.c280
-rw-r--r--modules/audio_processing/test/audio_processing_unittest.cc62
-rw-r--r--modules/audio_processing/test/process_test.cc20
-rw-r--r--modules/audio_processing/test/test_utils.h29
-rw-r--r--modules/audio_processing/test/unpack.cc24
-rw-r--r--modules/audio_processing_neon.target.darwin-arm.mk10
-rw-r--r--modules/audio_processing_neon.target.linux-arm.mk10
-rw-r--r--modules/audio_processing_sse2.target.darwin-x86.mk10
-rw-r--r--modules/audio_processing_sse2.target.darwin-x86_64.mk10
-rw-r--r--modules/audio_processing_sse2.target.linux-x86.mk10
-rw-r--r--modules/audio_processing_sse2.target.linux-x86_64.mk10
-rw-r--r--modules/audioproc_debug_proto.target.darwin-arm.mk10
-rw-r--r--modules/audioproc_debug_proto.target.darwin-arm64.mk12
-rw-r--r--modules/audioproc_debug_proto.target.darwin-mips.mk10
-rw-r--r--modules/audioproc_debug_proto.target.darwin-mips64.mk301
-rw-r--r--modules/audioproc_debug_proto.target.darwin-x86.mk10
-rw-r--r--modules/audioproc_debug_proto.target.darwin-x86_64.mk10
-rw-r--r--modules/audioproc_debug_proto.target.linux-arm.mk10
-rw-r--r--modules/audioproc_debug_proto.target.linux-arm64.mk12
-rw-r--r--modules/audioproc_debug_proto.target.linux-mips.mk10
-rw-r--r--modules/audioproc_debug_proto.target.linux-mips64.mk301
-rw-r--r--modules/audioproc_debug_proto.target.linux-x86.mk10
-rw-r--r--modules/audioproc_debug_proto.target.linux-x86_64.mk10
-rw-r--r--modules/bitrate_controller.target.darwin-arm.mk10
-rw-r--r--modules/bitrate_controller.target.darwin-arm64.mk12
-rw-r--r--modules/bitrate_controller.target.darwin-mips.mk10
-rw-r--r--modules/bitrate_controller.target.darwin-mips64.mk268
-rw-r--r--modules/bitrate_controller.target.darwin-x86.mk10
-rw-r--r--modules/bitrate_controller.target.darwin-x86_64.mk10
-rw-r--r--modules/bitrate_controller.target.linux-arm.mk10
-rw-r--r--modules/bitrate_controller.target.linux-arm64.mk12
-rw-r--r--modules/bitrate_controller.target.linux-mips.mk10
-rw-r--r--modules/bitrate_controller.target.linux-mips64.mk268
-rw-r--r--modules/bitrate_controller.target.linux-x86.mk10
-rw-r--r--modules/bitrate_controller.target.linux-x86_64.mk10
-rw-r--r--modules/bitrate_controller/bitrate_controller_unittest.cc175
-rw-r--r--modules/bitrate_controller/send_side_bandwidth_estimation.cc60
-rw-r--r--modules/bitrate_controller/send_side_bandwidth_estimation.h9
-rw-r--r--modules/iLBC.target.darwin-arm.mk10
-rw-r--r--modules/iLBC.target.darwin-arm64.mk12
-rw-r--r--modules/iLBC.target.darwin-mips.mk10
-rw-r--r--modules/iLBC.target.darwin-mips64.mk342
-rw-r--r--modules/iLBC.target.darwin-x86.mk10
-rw-r--r--modules/iLBC.target.darwin-x86_64.mk10
-rw-r--r--modules/iLBC.target.linux-arm.mk10
-rw-r--r--modules/iLBC.target.linux-arm64.mk12
-rw-r--r--modules/iLBC.target.linux-mips.mk10
-rw-r--r--modules/iLBC.target.linux-mips64.mk342
-rw-r--r--modules/iLBC.target.linux-x86.mk10
-rw-r--r--modules/iLBC.target.linux-x86_64.mk10
-rw-r--r--modules/iSAC.target.darwin-arm.mk10
-rw-r--r--modules/iSAC.target.darwin-arm64.mk12
-rw-r--r--modules/iSAC.target.darwin-mips.mk10
-rw-r--r--modules/iSAC.target.darwin-mips64.mk301
-rw-r--r--modules/iSAC.target.darwin-x86.mk10
-rw-r--r--modules/iSAC.target.darwin-x86_64.mk10
-rw-r--r--modules/iSAC.target.linux-arm.mk10
-rw-r--r--modules/iSAC.target.linux-arm64.mk12
-rw-r--r--modules/iSAC.target.linux-mips.mk10
-rw-r--r--modules/iSAC.target.linux-mips64.mk301
-rw-r--r--modules/iSAC.target.linux-x86.mk10
-rw-r--r--modules/iSAC.target.linux-x86_64.mk10
-rw-r--r--modules/iSACFix.target.darwin-arm.mk10
-rw-r--r--modules/iSACFix.target.darwin-arm64.mk12
-rw-r--r--modules/iSACFix.target.darwin-mips.mk10
-rw-r--r--modules/iSACFix.target.darwin-mips64.mk303
-rw-r--r--modules/iSACFix.target.darwin-x86.mk10
-rw-r--r--modules/iSACFix.target.darwin-x86_64.mk10
-rw-r--r--modules/iSACFix.target.linux-arm.mk10
-rw-r--r--modules/iSACFix.target.linux-arm64.mk12
-rw-r--r--modules/iSACFix.target.linux-mips.mk10
-rw-r--r--modules/iSACFix.target.linux-mips64.mk303
-rw-r--r--modules/iSACFix.target.linux-x86.mk10
-rw-r--r--modules/iSACFix.target.linux-x86_64.mk10
-rw-r--r--modules/isac_neon.target.darwin-arm.mk10
-rw-r--r--modules/isac_neon.target.linux-arm.mk10
-rw-r--r--modules/media_file.target.darwin-arm.mk10
-rw-r--r--modules/media_file.target.darwin-arm64.mk12
-rw-r--r--modules/media_file.target.darwin-mips.mk10
-rw-r--r--modules/media_file.target.darwin-mips64.mk273
-rw-r--r--modules/media_file.target.darwin-x86.mk10
-rw-r--r--modules/media_file.target.darwin-x86_64.mk10
-rw-r--r--modules/media_file.target.linux-arm.mk10
-rw-r--r--modules/media_file.target.linux-arm64.mk12
-rw-r--r--modules/media_file.target.linux-mips.mk10
-rw-r--r--modules/media_file.target.linux-mips64.mk273
-rw-r--r--modules/media_file.target.linux-x86.mk10
-rw-r--r--modules/media_file.target.linux-x86_64.mk10
-rw-r--r--modules/modules.gyp11
-rw-r--r--modules/modules_tests.isolate7
-rw-r--r--modules/modules_unittests.isolate13
-rw-r--r--modules/neteq.target.darwin-arm.mk10
-rw-r--r--modules/neteq.target.darwin-arm64.mk12
-rw-r--r--modules/neteq.target.darwin-mips.mk10
-rw-r--r--modules/neteq.target.darwin-mips64.mk329
-rw-r--r--modules/neteq.target.darwin-x86.mk10
-rw-r--r--modules/neteq.target.darwin-x86_64.mk10
-rw-r--r--modules/neteq.target.linux-arm.mk10
-rw-r--r--modules/neteq.target.linux-arm64.mk12
-rw-r--r--modules/neteq.target.linux-mips.mk10
-rw-r--r--modules/neteq.target.linux-mips64.mk329
-rw-r--r--modules/neteq.target.linux-x86.mk10
-rw-r--r--modules/neteq.target.linux-x86_64.mk10
-rw-r--r--modules/paced_sender.target.darwin-arm.mk11
-rw-r--r--modules/paced_sender.target.darwin-arm64.mk13
-rw-r--r--modules/paced_sender.target.darwin-mips.mk11
-rw-r--r--modules/paced_sender.target.darwin-mips64.mk268
-rw-r--r--modules/paced_sender.target.darwin-x86.mk11
-rw-r--r--modules/paced_sender.target.darwin-x86_64.mk11
-rw-r--r--modules/paced_sender.target.linux-arm.mk11
-rw-r--r--modules/paced_sender.target.linux-arm64.mk13
-rw-r--r--modules/paced_sender.target.linux-mips.mk11
-rw-r--r--modules/paced_sender.target.linux-mips64.mk268
-rw-r--r--modules/paced_sender.target.linux-x86.mk11
-rw-r--r--modules/paced_sender.target.linux-x86_64.mk11
-rw-r--r--modules/pacing/BUILD.gn2
-rw-r--r--modules/pacing/bitrate_prober.cc120
-rw-r--r--modules/pacing/bitrate_prober.h57
-rw-r--r--modules/pacing/bitrate_prober_unittest.cc57
-rw-r--r--modules/pacing/include/mock/mock_paced_sender.h2
-rw-r--r--modules/pacing/include/paced_sender.h70
-rw-r--r--modules/pacing/paced_sender.cc370
-rw-r--r--modules/pacing/paced_sender_unittest.cc488
-rw-r--r--modules/pacing/pacing.gypi2
-rw-r--r--modules/remote_bitrate_estimator.target.darwin-arm.mk10
-rw-r--r--modules/remote_bitrate_estimator.target.darwin-arm64.mk12
-rw-r--r--modules/remote_bitrate_estimator.target.darwin-mips.mk10
-rw-r--r--modules/remote_bitrate_estimator.target.darwin-mips64.mk267
-rw-r--r--modules/remote_bitrate_estimator.target.darwin-x86.mk10
-rw-r--r--modules/remote_bitrate_estimator.target.darwin-x86_64.mk10
-rw-r--r--modules/remote_bitrate_estimator.target.linux-arm.mk10
-rw-r--r--modules/remote_bitrate_estimator.target.linux-arm64.mk12
-rw-r--r--modules/remote_bitrate_estimator.target.linux-mips.mk10
-rw-r--r--modules/remote_bitrate_estimator.target.linux-mips64.mk267
-rw-r--r--modules/remote_bitrate_estimator.target.linux-x86.mk10
-rw-r--r--modules/remote_bitrate_estimator.target.linux-x86_64.mk10
-rw-r--r--modules/remote_bitrate_estimator/bwe_simulations.cc27
-rw-r--r--modules/remote_bitrate_estimator/rbe_components.target.darwin-arm.mk10
-rw-r--r--modules/remote_bitrate_estimator/rbe_components.target.darwin-arm64.mk12
-rw-r--r--modules/remote_bitrate_estimator/rbe_components.target.darwin-mips.mk10
-rw-r--r--modules/remote_bitrate_estimator/rbe_components.target.darwin-mips64.mk259
-rw-r--r--modules/remote_bitrate_estimator/rbe_components.target.darwin-x86.mk10
-rw-r--r--modules/remote_bitrate_estimator/rbe_components.target.darwin-x86_64.mk10
-rw-r--r--modules/remote_bitrate_estimator/rbe_components.target.linux-arm.mk10
-rw-r--r--modules/remote_bitrate_estimator/rbe_components.target.linux-arm64.mk12
-rw-r--r--modules/remote_bitrate_estimator/rbe_components.target.linux-mips.mk10
-rw-r--r--modules/remote_bitrate_estimator/rbe_components.target.linux-mips64.mk259
-rw-r--r--modules/remote_bitrate_estimator/rbe_components.target.linux-x86.mk10
-rw-r--r--modules/remote_bitrate_estimator/rbe_components.target.linux-x86_64.mk10
-rw-r--r--modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi4
-rw-r--r--modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc16
-rw-r--r--modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.cc28
-rw-r--r--modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h3
-rw-r--r--modules/remote_bitrate_estimator/test/bwe_test_framework.cc133
-rw-r--r--modules/remote_bitrate_estimator/test/bwe_test_framework.h54
-rw-r--r--modules/rtp_rtcp.target.darwin-arm.mk10
-rw-r--r--modules/rtp_rtcp.target.darwin-arm64.mk12
-rw-r--r--modules/rtp_rtcp.target.darwin-mips.mk10
-rw-r--r--modules/rtp_rtcp.target.darwin-mips64.mk299
-rw-r--r--modules/rtp_rtcp.target.darwin-x86.mk10
-rw-r--r--modules/rtp_rtcp.target.darwin-x86_64.mk10
-rw-r--r--modules/rtp_rtcp.target.linux-arm.mk10
-rw-r--r--modules/rtp_rtcp.target.linux-arm64.mk12
-rw-r--r--modules/rtp_rtcp.target.linux-mips.mk10
-rw-r--r--modules/rtp_rtcp.target.linux-mips64.mk299
-rw-r--r--modules/rtp_rtcp.target.linux-x86.mk10
-rw-r--r--modules/rtp_rtcp.target.linux-x86_64.mk10
-rw-r--r--modules/rtp_rtcp/source/rtcp_receiver.cc4
-rw-r--r--modules/rtp_rtcp/source/rtcp_receiver.h2
-rw-r--r--modules/rtp_rtcp/source/rtcp_receiver_unittest.cc7
-rw-r--r--modules/rtp_rtcp/source/rtcp_sender.cc17
-rw-r--r--modules/rtp_rtcp/source/rtcp_sender.h2
-rw-r--r--modules/rtp_rtcp/source/rtcp_utility.cc17
-rw-r--r--modules/rtp_rtcp/source/rtcp_utility.h23
-rw-r--r--modules/rtp_rtcp/source/rtcp_utility_unittest.cc72
-rw-r--r--modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc50
-rw-r--r--modules/rtp_rtcp/source/rtp_sender.cc37
-rw-r--r--modules/rtp_rtcp/source/rtp_sender.h2
-rw-r--r--modules/video_capture/android/java/src/org/webrtc/videoengine/VideoCaptureAndroid.java44
-rw-r--r--modules/video_capture/android/java/src/org/webrtc/videoengine/VideoCaptureDeviceInfoAndroid.java30
-rw-r--r--modules/video_capture/video_capture.gypi17
-rw-r--r--modules/video_capture/video_capture_tests.isolate7
-rw-r--r--modules/video_capture_module.target.darwin-arm.mk10
-rw-r--r--modules/video_capture_module.target.darwin-arm64.mk12
-rw-r--r--modules/video_capture_module.target.darwin-mips.mk10
-rw-r--r--modules/video_capture_module.target.darwin-mips64.mk273
-rw-r--r--modules/video_capture_module.target.darwin-x86.mk10
-rw-r--r--modules/video_capture_module.target.darwin-x86_64.mk10
-rw-r--r--modules/video_capture_module.target.linux-arm.mk10
-rw-r--r--modules/video_capture_module.target.linux-arm64.mk12
-rw-r--r--modules/video_capture_module.target.linux-mips.mk10
-rw-r--r--modules/video_capture_module.target.linux-mips64.mk273
-rw-r--r--modules/video_capture_module.target.linux-x86.mk10
-rw-r--r--modules/video_capture_module.target.linux-x86_64.mk10
-rw-r--r--modules/video_capture_module_impl.target.darwin-arm.mk10
-rw-r--r--modules/video_capture_module_impl.target.darwin-arm64.mk12
-rw-r--r--modules/video_capture_module_impl.target.darwin-mips.mk10
-rw-r--r--modules/video_capture_module_impl.target.darwin-mips64.mk266
-rw-r--r--modules/video_capture_module_impl.target.darwin-x86.mk10
-rw-r--r--modules/video_capture_module_impl.target.darwin-x86_64.mk10
-rw-r--r--modules/video_capture_module_impl.target.linux-arm.mk10
-rw-r--r--modules/video_capture_module_impl.target.linux-arm64.mk12
-rw-r--r--modules/video_capture_module_impl.target.linux-mips.mk10
-rw-r--r--modules/video_capture_module_impl.target.linux-mips64.mk266
-rw-r--r--modules/video_capture_module_impl.target.linux-x86.mk10
-rw-r--r--modules/video_capture_module_impl.target.linux-x86_64.mk10
-rw-r--r--modules/video_coding/BUILD.gn33
-rw-r--r--modules/video_coding/codecs/interface/video_codec_interface.h105
-rw-r--r--modules/video_coding/codecs/test/videoprocessor_integrationtest.cc230
-rw-r--r--modules/video_coding/codecs/tools/video_codecs_tools.gypi2
-rw-r--r--modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc6
-rw-r--r--modules/video_coding/codecs/vp8/vp8_impl.h94
-rw-r--r--modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-arm.mk10
-rw-r--r--modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-arm64.mk12
-rw-r--r--modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-mips.mk10
-rw-r--r--modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-mips64.mk269
-rw-r--r--modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-x86.mk10
-rw-r--r--modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-x86_64.mk10
-rw-r--r--modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-arm.mk10
-rw-r--r--modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-arm64.mk12
-rw-r--r--modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-mips.mk10
-rw-r--r--modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-mips64.mk269
-rw-r--r--modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-x86.mk10
-rw-r--r--modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-x86_64.mk10
-rw-r--r--modules/video_coding/codecs/vp9/include/vp9.h35
-rw-r--r--modules/video_coding/codecs/vp9/vp9.gyp36
-rw-r--r--modules/video_coding/codecs/vp9/vp9_impl.cc487
-rw-r--r--modules/video_coding/codecs/vp9/vp9_impl.h115
-rw-r--r--modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-arm.mk287
-rw-r--r--modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-arm64.mk259
-rw-r--r--modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-mips.mk271
-rw-r--r--modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-mips64.mk265
-rw-r--r--modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-x86.mk269
-rw-r--r--modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-x86_64.mk267
-rw-r--r--modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-arm.mk287
-rw-r--r--modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-arm64.mk259
-rw-r--r--modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-mips.mk271
-rw-r--r--modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-mips64.mk265
-rw-r--r--modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-x86.mk269
-rw-r--r--modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-x86_64.mk267
-rw-r--r--modules/video_coding/main/interface/video_coding_defines.h3
-rw-r--r--modules/video_coding/main/source/codec_database.cc54
-rw-r--r--modules/video_coding/main/source/internal_defines.h9
-rw-r--r--modules/video_coding/main/source/jitter_buffer.cc29
-rw-r--r--modules/video_coding/main/source/jitter_buffer.h12
-rw-r--r--modules/video_coding/main/source/jitter_buffer_unittest.cc8
-rw-r--r--modules/video_coding/main/source/video_coding.gypi1
-rw-r--r--modules/video_coding/main/source/video_coding_impl.h5
-rw-r--r--modules/video_coding/main/source/video_coding_test.gypi2
-rw-r--r--modules/video_coding/main/source/video_receiver.cc8
-rw-r--r--modules/video_coding/main/test/normal_test.cc3
-rw-r--r--modules/video_coding/main/test/test_callbacks.cc3
-rw-r--r--modules/video_coding/main/test/test_util.cc3
-rw-r--r--modules/video_coding/main/test/tester_main.cc2
-rw-r--r--modules/video_coding/utility/video_coding_utility.target.darwin-arm.mk10
-rw-r--r--modules/video_coding/utility/video_coding_utility.target.darwin-arm64.mk12
-rw-r--r--modules/video_coding/utility/video_coding_utility.target.darwin-mips.mk10
-rw-r--r--modules/video_coding/utility/video_coding_utility.target.darwin-mips64.mk260
-rw-r--r--modules/video_coding/utility/video_coding_utility.target.darwin-x86.mk10
-rw-r--r--modules/video_coding/utility/video_coding_utility.target.darwin-x86_64.mk10
-rw-r--r--modules/video_coding/utility/video_coding_utility.target.linux-arm.mk10
-rw-r--r--modules/video_coding/utility/video_coding_utility.target.linux-arm64.mk12
-rw-r--r--modules/video_coding/utility/video_coding_utility.target.linux-mips.mk10
-rw-r--r--modules/video_coding/utility/video_coding_utility.target.linux-mips64.mk260
-rw-r--r--modules/video_coding/utility/video_coding_utility.target.linux-x86.mk10
-rw-r--r--modules/video_coding/utility/video_coding_utility.target.linux-x86_64.mk10
-rw-r--r--modules/video_processing.target.darwin-arm.mk10
-rw-r--r--modules/video_processing.target.darwin-arm64.mk12
-rw-r--r--modules/video_processing.target.darwin-mips.mk10
-rw-r--r--modules/video_processing.target.darwin-mips64.mk285
-rw-r--r--modules/video_processing.target.darwin-x86.mk10
-rw-r--r--modules/video_processing.target.darwin-x86_64.mk10
-rw-r--r--modules/video_processing.target.linux-arm.mk10
-rw-r--r--modules/video_processing.target.linux-arm64.mk12
-rw-r--r--modules/video_processing.target.linux-mips.mk10
-rw-r--r--modules/video_processing.target.linux-mips64.mk285
-rw-r--r--modules/video_processing.target.linux-x86.mk10
-rw-r--r--modules/video_processing.target.linux-x86_64.mk10
-rw-r--r--modules/video_processing_sse2.target.darwin-x86.mk10
-rw-r--r--modules/video_processing_sse2.target.darwin-x86_64.mk10
-rw-r--r--modules/video_processing_sse2.target.linux-x86.mk10
-rw-r--r--modules/video_processing_sse2.target.linux-x86_64.mk10
-rw-r--r--modules/video_render/incoming_video_stream.cc4
-rw-r--r--modules/video_render/video_render.gypi1
-rw-r--r--modules/video_render/video_render_tests.isolate7
-rw-r--r--modules/video_render_module.target.darwin-arm.mk10
-rw-r--r--modules/video_render_module.target.darwin-arm64.mk12
-rw-r--r--modules/video_render_module.target.darwin-mips.mk10
-rw-r--r--modules/video_render_module.target.darwin-mips64.mk273
-rw-r--r--modules/video_render_module.target.darwin-x86.mk10
-rw-r--r--modules/video_render_module.target.darwin-x86_64.mk10
-rw-r--r--modules/video_render_module.target.linux-arm.mk10
-rw-r--r--modules/video_render_module.target.linux-arm64.mk12
-rw-r--r--modules/video_render_module.target.linux-mips.mk10
-rw-r--r--modules/video_render_module.target.linux-mips64.mk273
-rw-r--r--modules/video_render_module.target.linux-x86.mk10
-rw-r--r--modules/video_render_module.target.linux-x86_64.mk10
-rw-r--r--modules/video_render_module_impl.target.darwin-arm.mk10
-rw-r--r--modules/video_render_module_impl.target.darwin-arm64.mk12
-rw-r--r--modules/video_render_module_impl.target.darwin-mips.mk10
-rw-r--r--modules/video_render_module_impl.target.darwin-mips64.mk265
-rw-r--r--modules/video_render_module_impl.target.darwin-x86.mk10
-rw-r--r--modules/video_render_module_impl.target.darwin-x86_64.mk10
-rw-r--r--modules/video_render_module_impl.target.linux-arm.mk10
-rw-r--r--modules/video_render_module_impl.target.linux-arm64.mk12
-rw-r--r--modules/video_render_module_impl.target.linux-mips.mk10
-rw-r--r--modules/video_render_module_impl.target.linux-mips64.mk265
-rw-r--r--modules/video_render_module_impl.target.linux-x86.mk10
-rw-r--r--modules/video_render_module_impl.target.linux-x86_64.mk10
-rw-r--r--modules/webrtc_i420.target.darwin-arm.mk10
-rw-r--r--modules/webrtc_i420.target.darwin-arm64.mk12
-rw-r--r--modules/webrtc_i420.target.darwin-mips.mk10
-rw-r--r--modules/webrtc_i420.target.darwin-mips64.mk267
-rw-r--r--modules/webrtc_i420.target.darwin-x86.mk10
-rw-r--r--modules/webrtc_i420.target.darwin-x86_64.mk10
-rw-r--r--modules/webrtc_i420.target.linux-arm.mk10
-rw-r--r--modules/webrtc_i420.target.linux-arm64.mk12
-rw-r--r--modules/webrtc_i420.target.linux-mips.mk10
-rw-r--r--modules/webrtc_i420.target.linux-mips64.mk267
-rw-r--r--modules/webrtc_i420.target.linux-x86.mk10
-rw-r--r--modules/webrtc_i420.target.linux-x86_64.mk10
-rw-r--r--modules/webrtc_opus.target.darwin-arm.mk12
-rw-r--r--modules/webrtc_opus.target.darwin-arm64.mk14
-rw-r--r--modules/webrtc_opus.target.darwin-mips.mk12
-rw-r--r--modules/webrtc_opus.target.darwin-mips64.mk270
-rw-r--r--modules/webrtc_opus.target.darwin-x86.mk12
-rw-r--r--modules/webrtc_opus.target.darwin-x86_64.mk12
-rw-r--r--modules/webrtc_opus.target.linux-arm.mk12
-rw-r--r--modules/webrtc_opus.target.linux-arm64.mk14
-rw-r--r--modules/webrtc_opus.target.linux-mips.mk12
-rw-r--r--modules/webrtc_opus.target.linux-mips64.mk270
-rw-r--r--modules/webrtc_opus.target.linux-x86.mk12
-rw-r--r--modules/webrtc_opus.target.linux-x86_64.mk12
-rw-r--r--modules/webrtc_utility.target.darwin-arm.mk10
-rw-r--r--modules/webrtc_utility.target.darwin-arm64.mk12
-rw-r--r--modules/webrtc_utility.target.darwin-mips.mk10
-rw-r--r--modules/webrtc_utility.target.darwin-mips64.mk290
-rw-r--r--modules/webrtc_utility.target.darwin-x86.mk10
-rw-r--r--modules/webrtc_utility.target.darwin-x86_64.mk10
-rw-r--r--modules/webrtc_utility.target.linux-arm.mk10
-rw-r--r--modules/webrtc_utility.target.linux-arm64.mk12
-rw-r--r--modules/webrtc_utility.target.linux-mips.mk10
-rw-r--r--modules/webrtc_utility.target.linux-mips64.mk290
-rw-r--r--modules/webrtc_utility.target.linux-x86.mk10
-rw-r--r--modules/webrtc_utility.target.linux-x86_64.mk10
-rw-r--r--modules/webrtc_video_coding.target.darwin-arm.mk10
-rw-r--r--modules/webrtc_video_coding.target.darwin-arm64.mk12
-rw-r--r--modules/webrtc_video_coding.target.darwin-mips.mk10
-rw-r--r--modules/webrtc_video_coding.target.darwin-mips64.mk293
-rw-r--r--modules/webrtc_video_coding.target.darwin-x86.mk10
-rw-r--r--modules/webrtc_video_coding.target.darwin-x86_64.mk10
-rw-r--r--modules/webrtc_video_coding.target.linux-arm.mk10
-rw-r--r--modules/webrtc_video_coding.target.linux-arm64.mk12
-rw-r--r--modules/webrtc_video_coding.target.linux-mips.mk10
-rw-r--r--modules/webrtc_video_coding.target.linux-mips64.mk293
-rw-r--r--modules/webrtc_video_coding.target.linux-x86.mk10
-rw-r--r--modules/webrtc_video_coding.target.linux-x86_64.mk10
-rw-r--r--p2p/OWNERS13
-rw-r--r--p2p/base/asyncstuntcpsocket.cc153
-rw-r--r--p2p/base/asyncstuntcpsocket.h50
-rw-r--r--p2p/base/asyncstuntcpsocket_unittest.cc263
-rw-r--r--p2p/base/basicpacketsocketfactory.cc204
-rw-r--r--p2p/base/basicpacketsocketfactory.h51
-rw-r--r--p2p/base/candidate.h212
-rw-r--r--p2p/base/common.h20
-rw-r--r--p2p/base/constants.cc257
-rw-r--r--p2p/base/constants.h259
-rw-r--r--p2p/base/dtlstransport.h240
-rw-r--r--p2p/base/dtlstransportchannel.cc623
-rw-r--r--p2p/base/dtlstransportchannel.h246
-rw-r--r--p2p/base/dtlstransportchannel_unittest.cc823
-rw-r--r--p2p/base/fakesession.h492
-rw-r--r--p2p/base/p2ptransport.cc246
-rw-r--r--p2p/base/p2ptransport.h86
-rw-r--r--p2p/base/p2ptransportchannel.cc1274
-rw-r--r--p2p/base/p2ptransportchannel.h242
-rw-r--r--p2p/base/p2ptransportchannel_unittest.cc1702
-rw-r--r--p2p/base/packetsocketfactory.h52
-rw-r--r--p2p/base/parsing.cc141
-rw-r--r--p2p/base/parsing.h140
-rw-r--r--p2p/base/port.cc1430
-rw-r--r--p2p/base/port.h602
-rw-r--r--p2p/base/port_unittest.cc2494
-rw-r--r--p2p/base/portallocator.cc92
-rw-r--r--p2p/base/portallocator.h192
-rw-r--r--p2p/base/portallocatorsessionproxy.cc222
-rw-r--r--p2p/base/portallocatorsessionproxy.h106
-rw-r--r--p2p/base/portallocatorsessionproxy_unittest.cc146
-rw-r--r--p2p/base/portinterface.h126
-rw-r--r--p2p/base/portproxy.cc163
-rw-r--r--p2p/base/portproxy.h87
-rw-r--r--p2p/base/pseudotcp.cc1274
-rw-r--r--p2p/base/pseudotcp.h241
-rw-r--r--p2p/base/pseudotcp_unittest.cc841
-rw-r--r--p2p/base/rawtransport.cc115
-rw-r--r--p2p/base/rawtransport.h64
-rw-r--r--p2p/base/rawtransportchannel.cc260
-rw-r--r--p2p/base/rawtransportchannel.h189
-rw-r--r--p2p/base/relayport.cc818
-rw-r--r--p2p/base/relayport.h101
-rw-r--r--p2p/base/relayport_unittest.cc272
-rw-r--r--p2p/base/relayserver.cc746
-rw-r--r--p2p/base/relayserver.h235
-rw-r--r--p2p/base/relayserver_unittest.cc519
-rw-r--r--p2p/base/session.cc1760
-rw-r--r--p2p/base/session.h730
-rw-r--r--p2p/base/session_unittest.cc2430
-rw-r--r--p2p/base/sessionclient.h78
-rw-r--r--p2p/base/sessiondescription.cc222
-rw-r--r--p2p/base/sessiondescription.h185
-rw-r--r--p2p/base/sessionid.h20
-rw-r--r--p2p/base/sessionmanager.cc309
-rw-r--r--p2p/base/sessionmanager.h194
-rw-r--r--p2p/base/sessionmessages.cc1132
-rw-r--r--p2p/base/sessionmessages.h226
-rw-r--r--p2p/base/stun.cc915
-rw-r--r--p2p/base/stun.h632
-rw-r--r--p2p/base/stun_unittest.cc1402
-rw-r--r--p2p/base/stunport.cc451
-rw-r--r--p2p/base/stunport.h238
-rw-r--r--p2p/base/stunport_unittest.cc283
-rw-r--r--p2p/base/stunrequest.cc193
-rw-r--r--p2p/base/stunrequest.h116
-rw-r--r--p2p/base/stunrequest_unittest.cc203
-rw-r--r--p2p/base/stunserver.cc99
-rw-r--r--p2p/base/stunserver.h66
-rw-r--r--p2p/base/stunserver_unittest.cc109
-rw-r--r--p2p/base/tcpport.cc321
-rw-r--r--p2p/base/tcpport.h136
-rw-r--r--p2p/base/testrelayserver.h101
-rw-r--r--p2p/base/teststunserver.h58
-rw-r--r--p2p/base/testturnserver.h103
-rw-r--r--p2p/base/transport.cc960
-rw-r--r--p2p/base/transport.h513
-rw-r--r--p2p/base/transport_unittest.cc438
-rw-r--r--p2p/base/transportchannel.cc43
-rw-r--r--p2p/base/transportchannel.h143
-rw-r--r--p2p/base/transportchannelimpl.h111
-rw-r--r--p2p/base/transportchannelproxy.cc249
-rw-r--r--p2p/base/transportchannelproxy.h95
-rw-r--r--p2p/base/transportdescription.cc55
-rw-r--r--p2p/base/transportdescription.h171
-rw-r--r--p2p/base/transportdescriptionfactory.cc160
-rw-r--r--p2p/base/transportdescriptionfactory.h66
-rw-r--r--p2p/base/transportdescriptionfactory_unittest.cc365
-rw-r--r--p2p/base/transportinfo.h43
-rw-r--r--p2p/base/turnport.cc1196
-rw-r--r--p2p/base/turnport.h237
-rw-r--r--p2p/base/turnport_unittest.cc668
-rw-r--r--p2p/base/turnserver.cc1011
-rw-r--r--p2p/base/turnserver.h190
-rw-r--r--p2p/base/udpport.h17
-rw-r--r--p2p/client/autoportallocator.h52
-rw-r--r--p2p/client/basicportallocator.cc1190
-rw-r--r--p2p/client/basicportallocator.h241
-rw-r--r--p2p/client/connectivitychecker.cc573
-rw-r--r--p2p/client/connectivitychecker.h281
-rw-r--r--p2p/client/connectivitychecker_unittest.cc375
-rw-r--r--p2p/client/fakeportallocator.h121
-rw-r--r--p2p/client/httpportallocator.cc326
-rw-r--r--p2p/client/httpportallocator.h173
-rw-r--r--p2p/client/portallocator_unittest.cc1066
-rw-r--r--p2p/client/sessionmanagertask.h76
-rw-r--r--p2p/client/sessionsendtask.h128
-rw-r--r--p2p/client/socketmonitor.cc97
-rw-r--r--p2p/client/socketmonitor.h54
-rw-r--r--p2p/p2p.gyp130
-rw-r--r--p2p/p2p_tests.gypi44
-rw-r--r--rtc_unittests.isolate5
-rw-r--r--system_wrappers/BUILD.gn37
-rw-r--r--system_wrappers/interface/metrics.h130
-rw-r--r--system_wrappers/interface/scoped_ptr.h165
-rw-r--r--system_wrappers/interface/scoped_vector.h7
-rw-r--r--system_wrappers/interface/timestamp_extrapolator.h4
-rw-r--r--system_wrappers/source/cpu_features_android.target.darwin-arm.mk10
-rw-r--r--system_wrappers/source/cpu_features_android.target.darwin-arm64.mk12
-rw-r--r--system_wrappers/source/cpu_features_android.target.darwin-mips.mk10
-rw-r--r--system_wrappers/source/cpu_features_android.target.darwin-mips64.mk262
-rw-r--r--system_wrappers/source/cpu_features_android.target.darwin-x86.mk10
-rw-r--r--system_wrappers/source/cpu_features_android.target.darwin-x86_64.mk10
-rw-r--r--system_wrappers/source/cpu_features_android.target.linux-arm.mk10
-rw-r--r--system_wrappers/source/cpu_features_android.target.linux-arm64.mk12
-rw-r--r--system_wrappers/source/cpu_features_android.target.linux-mips.mk10
-rw-r--r--system_wrappers/source/cpu_features_android.target.linux-mips64.mk262
-rw-r--r--system_wrappers/source/cpu_features_android.target.linux-x86.mk10
-rw-r--r--system_wrappers/source/cpu_features_android.target.linux-x86_64.mk10
-rw-r--r--system_wrappers/source/logging.cc2
-rw-r--r--system_wrappers/source/metrics_default.cc29
-rw-r--r--system_wrappers/source/move.h21
-rw-r--r--system_wrappers/source/system_wrappers.gyp17
-rw-r--r--system_wrappers/source/system_wrappers.target.darwin-arm.mk10
-rw-r--r--system_wrappers/source/system_wrappers.target.darwin-arm64.mk12
-rw-r--r--system_wrappers/source/system_wrappers.target.darwin-mips.mk10
-rw-r--r--system_wrappers/source/system_wrappers.target.darwin-mips64.mk293
-rw-r--r--system_wrappers/source/system_wrappers.target.darwin-x86.mk10
-rw-r--r--system_wrappers/source/system_wrappers.target.darwin-x86_64.mk10
-rw-r--r--system_wrappers/source/system_wrappers.target.linux-arm.mk10
-rw-r--r--system_wrappers/source/system_wrappers.target.linux-arm64.mk12
-rw-r--r--system_wrappers/source/system_wrappers.target.linux-mips.mk10
-rw-r--r--system_wrappers/source/system_wrappers.target.linux-mips64.mk293
-rw-r--r--system_wrappers/source/system_wrappers.target.linux-x86.mk10
-rw-r--r--system_wrappers/source/system_wrappers.target.linux-x86_64.mk10
-rw-r--r--system_wrappers/source/system_wrappers_tests.gyp1
-rw-r--r--system_wrappers/source/system_wrappers_unittests.isolate7
-rw-r--r--system_wrappers/source/timestamp_extrapolator.cc30
-rw-r--r--system_wrappers/source/trace_impl.h2
-rw-r--r--test/BUILD.gn1
-rw-r--r--test/call_test.cc23
-rw-r--r--test/call_test.h2
-rw-r--r--test/encoder_settings.cc34
-rw-r--r--test/encoder_settings.h3
-rw-r--r--test/run_loop.cc2
-rw-r--r--test/test.gyp7
-rw-r--r--test/test_support_unittests.isolate7
-rw-r--r--test/webrtc_test_common.gyp5
-rw-r--r--tools/rtcbot/README14
-rw-r--r--tools/rtcbot/bot/api.js2
-rw-r--r--tools/rtcbot/bot/browser/bot.js19
-rw-r--r--tools/rtcbot/botmanager.js19
-rw-r--r--tools/rtcbot/rtcBotReportVisualizer/index.html14
-rw-r--r--tools/rtcbot/rtcBotReportVisualizer/main.js191
-rw-r--r--tools/rtcbot/test/oneWayVideoStreamingWithDownloadingFile.js122
-rw-r--r--tools/rtcbot/test/three_bots_video_conference.js135
-rw-r--r--tools/rtcbot/test/two_way_video_streaming.js112
-rw-r--r--tools/rtcbot/test/webrtc_video_streaming.js2
-rw-r--r--tools/tools.gyp5
-rw-r--r--tools/tools_unittests.isolate7
-rw-r--r--video/bitrate_estimator_tests.cc11
-rw-r--r--video/call.cc12
-rw-r--r--video/call_perf_tests.cc92
-rw-r--r--video/end_to_end_tests.cc131
-rw-r--r--video/full_stack.cc4
-rw-r--r--video/loopback.cc34
-rw-r--r--video/rampup_tests.cc4
-rw-r--r--video/replay.cc8
-rw-r--r--video/video_receive_stream.cc65
-rw-r--r--video/video_receive_stream.h2
-rw-r--r--video/video_send_stream.cc42
-rw-r--r--video/video_send_stream.h5
-rw-r--r--video/video_send_stream_tests.cc48
-rw-r--r--video_decoder.h74
-rw-r--r--video_encoder.h58
-rw-r--r--video_engine/include/vie_base.h2
-rw-r--r--video_engine/overuse_frame_detector.cc130
-rw-r--r--video_engine/overuse_frame_detector.h3
-rw-r--r--video_engine/overuse_frame_detector_unittest.cc93
-rw-r--r--video_engine/test/auto_test/source/vie_autotest.cc3
-rw-r--r--video_engine/test/auto_test/source/vie_autotest_loopback.cc6
-rw-r--r--video_engine/test/auto_test/source/vie_autotest_main.cc4
-rw-r--r--video_engine/test/auto_test/source/vie_autotest_network.cc4
-rw-r--r--video_engine/test/auto_test/source/vie_autotest_record.cc6
-rw-r--r--video_engine/test/auto_test/vie_auto_test.gypi3
-rw-r--r--video_engine/test/auto_test/vie_auto_test.isolate9
-rw-r--r--video_engine/video_engine_core.gypi3
-rw-r--r--video_engine/video_engine_core.target.darwin-arm.mk10
-rw-r--r--video_engine/video_engine_core.target.darwin-arm64.mk12
-rw-r--r--video_engine/video_engine_core.target.darwin-mips.mk10
-rw-r--r--video_engine/video_engine_core.target.darwin-mips64.mk292
-rw-r--r--video_engine/video_engine_core.target.darwin-x86.mk10
-rw-r--r--video_engine/video_engine_core.target.darwin-x86_64.mk10
-rw-r--r--video_engine/video_engine_core.target.linux-arm.mk10
-rw-r--r--video_engine/video_engine_core.target.linux-arm64.mk12
-rw-r--r--video_engine/video_engine_core.target.linux-mips.mk10
-rw-r--r--video_engine/video_engine_core.target.linux-mips64.mk292
-rw-r--r--video_engine/video_engine_core.target.linux-x86.mk10
-rw-r--r--video_engine/video_engine_core.target.linux-x86_64.mk10
-rw-r--r--video_engine/video_engine_core_unittests.isolate7
-rw-r--r--video_engine/vie_channel.cc54
-rw-r--r--video_engine/vie_channel.h3
-rw-r--r--video_engine/vie_channel_group.cc2
-rw-r--r--video_engine/vie_codec_impl.cc2
-rw-r--r--video_engine/vie_encoder.cc78
-rw-r--r--video_engine/vie_encoder.h5
-rw-r--r--video_engine_tests.isolate7
-rw-r--r--video_receive_stream.h68
-rw-r--r--video_send_stream.h10
-rw-r--r--voice_engine/utility.cc3
-rw-r--r--voice_engine/voe_auto_test.isolate7
-rw-r--r--voice_engine/voice_engine.gyp6
-rw-r--r--voice_engine/voice_engine.target.darwin-arm.mk10
-rw-r--r--voice_engine/voice_engine.target.darwin-arm64.mk12
-rw-r--r--voice_engine/voice_engine.target.darwin-mips.mk10
-rw-r--r--voice_engine/voice_engine.target.darwin-mips64.mk301
-rw-r--r--voice_engine/voice_engine.target.darwin-x86.mk10
-rw-r--r--voice_engine/voice_engine.target.darwin-x86_64.mk10
-rw-r--r--voice_engine/voice_engine.target.linux-arm.mk10
-rw-r--r--voice_engine/voice_engine.target.linux-arm64.mk12
-rw-r--r--voice_engine/voice_engine.target.linux-mips.mk10
-rw-r--r--voice_engine/voice_engine.target.linux-mips64.mk301
-rw-r--r--voice_engine/voice_engine.target.linux-x86.mk10
-rw-r--r--voice_engine/voice_engine.target.linux-x86_64.mk10
-rw-r--r--voice_engine/voice_engine_unittests.isolate7
-rw-r--r--webrtc.gyp5
-rw-r--r--webrtc.target.darwin-arm.mk10
-rw-r--r--webrtc.target.darwin-arm64.mk12
-rw-r--r--webrtc.target.darwin-mips.mk10
-rw-r--r--webrtc.target.darwin-mips64.mk263
-rw-r--r--webrtc.target.darwin-x86.mk10
-rw-r--r--webrtc.target.darwin-x86_64.mk10
-rw-r--r--webrtc.target.linux-arm.mk10
-rw-r--r--webrtc.target.linux-arm64.mk12
-rw-r--r--webrtc.target.linux-mips.mk10
-rw-r--r--webrtc.target.linux-mips64.mk263
-rw-r--r--webrtc.target.linux-x86.mk10
-rw-r--r--webrtc.target.linux-x86_64.mk10
-rw-r--r--webrtc_common.target.darwin-arm.mk10
-rw-r--r--webrtc_common.target.darwin-arm64.mk12
-rw-r--r--webrtc_common.target.darwin-mips.mk10
-rw-r--r--webrtc_common.target.darwin-mips64.mk257
-rw-r--r--webrtc_common.target.darwin-x86.mk10
-rw-r--r--webrtc_common.target.darwin-x86_64.mk10
-rw-r--r--webrtc_common.target.linux-arm.mk10
-rw-r--r--webrtc_common.target.linux-arm64.mk12
-rw-r--r--webrtc_common.target.linux-mips.mk10
-rw-r--r--webrtc_common.target.linux-mips64.mk257
-rw-r--r--webrtc_common.target.linux-x86.mk10
-rw-r--r--webrtc_common.target.linux-x86_64.mk10
-rw-r--r--webrtc_examples.gyp2
-rw-r--r--webrtc_perf_tests.isolate7
-rw-r--r--webrtc_tests.gypi16
1036 files changed, 98972 insertions, 4878 deletions
diff --git a/BUILD.gn b/BUILD.gn
index 9d2fa6a0..157be6f9 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -120,6 +120,10 @@ config("common_config") {
}
}
+ if (cpu_arch == "arm64") {
+ defines += [ "WEBRTC_ARCH_ARM" ]
+ }
+
if (cpu_arch == "arm") {
defines += [ "WEBRTC_ARCH_ARM" ]
if (arm_version == 7) {
diff --git a/base/BUILD.gn b/base/BUILD.gn
index be53e40f..1c2527af 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -40,7 +40,7 @@ config("openssl_config") {
]
}
-config("no_openssl_config") {
+config("nss_config") {
defines = [
"SSL_USE_NSS",
"HAVE_NSS_SSL_H",
@@ -465,24 +465,30 @@ static_library("webrtc_base") {
"opensslstreamadapter.h",
]
} else {
- public_configs += [ ":no_openssl_config" ]
+ public_configs += [ ":nss_config" ]
+ if (rtc_build_ssl) {
+ if (build_with_chromium) {
+ deps += [ "//crypto:platform" ]
+ } else {
+ deps += [ "//net/third_party/nss/ssl:libssl" ]
+ if (is_linux) {
+ deps += [ ":linux_system_ssl" ]
+ } else {
+ deps += [
+ "//third_party/nss:nspr",
+ "//third_party/nss:nss",
+ ]
+ }
+ }
+ } else {
+ configs += [ "external_ssl_library" ]
+ }
sources += [
"nssidentity.cc",
"nssidentity.h",
"nssstreamadapter.cc",
"nssstreamadapter.h",
]
- if (is_mac || is_ios || is_win) {
- if (rtc_build_ssl) {
- deps += [
- "//net/third_party/nss/ssl:libssl",
- "//third_party/nss:nspr",
- "//third_party/nss:nss",
- ]
- } else {
- configs += [ "external_ssl_library" ]
- }
- }
}
if (is_android) {
@@ -518,13 +524,9 @@ static_library("webrtc_base") {
if (is_linux) {
libs += [
- "crypto",
"dl",
"rt",
]
- if (rtc_build_ssl) {
- configs += [ "//third_party/nss:system_nss_no_ssl_config" ]
- }
}
if (is_mac) {
@@ -595,16 +597,4 @@ static_library("webrtc_base") {
"linux.h",
]
}
-
- if (is_posix && !is_mac && !is_ios && !is_android) {
- if (build_with_chromium) {
- deps += [ "//crypto:platform" ]
- } else {
- if (rtc_build_ssl) {
- deps += [ ":linux_system_ssl" ]
- } else {
- configs += [ "external_ssl_library" ]
- }
- }
- }
}
diff --git a/base/base.gyp b/base/base.gyp
index 569db740..2fd64ba5 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -539,32 +539,31 @@
],
},
}],
- ['OS=="mac" or OS=="ios" or OS=="win"', {
+ ['build_ssl==1', {
'conditions': [
- ['build_ssl==1', {
+ # On some platforms, the rest of NSS is bundled. On others,
+ # it's pulled from the system.
+ ['OS == "mac" or OS == "ios" or OS == "win"', {
'dependencies': [
'<(DEPTH)/net/third_party/nss/ssl.gyp:libssl',
'<(DEPTH)/third_party/nss/nss.gyp:nspr',
'<(DEPTH)/third_party/nss/nss.gyp:nss',
],
- }, {
- 'include_dirs': [
- '<(ssl_root)',
+ }],
+ ['os_posix == 1 and OS != "mac" and OS != "ios" and OS != "android"', {
+ 'dependencies': [
+ '<(DEPTH)/build/linux/system.gyp:ssl',
],
}],
],
+ }, {
+ 'include_dirs': [
+ '<(ssl_root)',
+ ],
}],
],
}],
['OS == "android"', {
- 'defines': [
- 'HAVE_OPENSSL_SSL_H'
- ],
- 'direct_dependent_settings': {
- 'defines': [
- 'HAVE_OPENSSL_SSL_H'
- ],
- },
'link_settings': {
'libraries': [
'-llog',
@@ -572,20 +571,6 @@
],
},
}, {
- 'conditions': [
- ['use_legacy_ssl_defaults!=1', {
- 'defines': [
- 'HAVE_NSS_SSL_H',
- 'SSL_USE_NSS_RNG',
- ],
- 'direct_dependent_settings': {
- 'defines': [
- 'HAVE_NSS_SSL_H',
- 'SSL_USE_NSS_RNG',
- ],
- },
- }],
- ],
'sources!': [
'ifaddrs-android.cc',
'ifaddrs-android.h',
@@ -627,21 +612,6 @@
'-lrt',
],
},
- 'conditions': [
- ['build_ssl==1', {
- 'link_settings': {
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l nss | sed -e "s/-lssl3//")',
- ],
- },
- 'cflags': [
- '<!@(<(pkg-config) --cflags nss)',
- ],
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other nss)',
- ],
- }],
- ],
}, {
'sources!': [
'dbus.cc',
@@ -757,19 +727,6 @@
'linux.h',
],
}],
- ['os_posix == 1 and OS != "mac" and OS != "ios" and OS != "android"', {
- 'conditions': [
- ['build_ssl==1', {
- 'dependencies': [
- '<(DEPTH)/build/linux/system.gyp:ssl',
- ],
- }, {
- 'include_dirs': [
- '<(ssl_root)',
- ],
- }],
- ],
- }],
],
},
],
diff --git a/base/rtc_base.target.darwin-arm.mk b/base/rtc_base.target.darwin-arm.mk
index c352b2b7..5c7018c1 100644
--- a/base/rtc_base.target.darwin-arm.mk
+++ b/base/rtc_base.target.darwin-arm.mk
@@ -145,11 +145,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -171,6 +173,7 @@ MY_DEFS_Debug := \
'-DNO_MAIN_THREAD_WRAPPING' \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -265,11 +268,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -291,6 +296,7 @@ MY_DEFS_Release := \
'-DNO_MAIN_THREAD_WRAPPING' \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/base/rtc_base.target.darwin-arm64.mk b/base/rtc_base.target.darwin-arm64.mk
index f9dd5035..6633e54b 100644
--- a/base/rtc_base.target.darwin-arm64.mk
+++ b/base/rtc_base.target.darwin-arm64.mk
@@ -134,11 +134,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -147,6 +149,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
@@ -157,6 +160,7 @@ MY_DEFS_Debug := \
'-DNO_MAIN_THREAD_WRAPPING' \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -239,11 +243,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -252,6 +258,7 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
@@ -262,6 +269,7 @@ MY_DEFS_Release := \
'-DNO_MAIN_THREAD_WRAPPING' \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/base/rtc_base.target.darwin-mips.mk b/base/rtc_base.target.darwin-mips.mk
index 5b11cbf9..049b1efc 100644
--- a/base/rtc_base.target.darwin-mips.mk
+++ b/base/rtc_base.target.darwin-mips.mk
@@ -138,11 +138,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -163,6 +165,7 @@ MY_DEFS_Debug := \
'-DNO_MAIN_THREAD_WRAPPING' \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -250,11 +253,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -275,6 +280,7 @@ MY_DEFS_Release := \
'-DNO_MAIN_THREAD_WRAPPING' \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/base/rtc_base.target.darwin-mips64.mk b/base/rtc_base.target.darwin-mips64.mk
new file mode 100644
index 00000000..b83453d0
--- /dev/null
+++ b/base/rtc_base.target.darwin-mips64.mk
@@ -0,0 +1,336 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_base_rtc_base_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/base/asyncfile.cc \
+ third_party/webrtc/base/asynchttprequest.cc \
+ third_party/webrtc/base/asyncsocket.cc \
+ third_party/webrtc/base/asynctcpsocket.cc \
+ third_party/webrtc/base/asyncudpsocket.cc \
+ third_party/webrtc/base/autodetectproxy.cc \
+ third_party/webrtc/base/base64.cc \
+ third_party/webrtc/base/bytebuffer.cc \
+ third_party/webrtc/base/common.cc \
+ third_party/webrtc/base/cpumonitor.cc \
+ third_party/webrtc/base/crc32.cc \
+ third_party/webrtc/base/diskcache.cc \
+ third_party/webrtc/base/event.cc \
+ third_party/webrtc/base/fileutils.cc \
+ third_party/webrtc/base/firewallsocketserver.cc \
+ third_party/webrtc/base/flags.cc \
+ third_party/webrtc/base/helpers.cc \
+ third_party/webrtc/base/httpbase.cc \
+ third_party/webrtc/base/httpclient.cc \
+ third_party/webrtc/base/httpcommon.cc \
+ third_party/webrtc/base/httprequest.cc \
+ third_party/webrtc/base/ifaddrs-android.cc \
+ third_party/webrtc/base/ipaddress.cc \
+ third_party/webrtc/base/linux.cc \
+ third_party/webrtc/base/messagedigest.cc \
+ third_party/webrtc/base/messagehandler.cc \
+ third_party/webrtc/base/messagequeue.cc \
+ third_party/webrtc/base/nethelpers.cc \
+ third_party/webrtc/base/network.cc \
+ third_party/webrtc/base/pathutils.cc \
+ third_party/webrtc/base/physicalsocketserver.cc \
+ third_party/webrtc/base/proxydetect.cc \
+ third_party/webrtc/base/proxyinfo.cc \
+ third_party/webrtc/base/ratelimiter.cc \
+ third_party/webrtc/base/ratetracker.cc \
+ third_party/webrtc/base/sha1.cc \
+ third_party/webrtc/base/signalthread.cc \
+ third_party/webrtc/base/socketadapters.cc \
+ third_party/webrtc/base/socketaddress.cc \
+ third_party/webrtc/base/socketaddresspair.cc \
+ third_party/webrtc/base/socketpool.cc \
+ third_party/webrtc/base/socketstream.cc \
+ third_party/webrtc/base/ssladapter.cc \
+ third_party/webrtc/base/sslfingerprint.cc \
+ third_party/webrtc/base/sslidentity.cc \
+ third_party/webrtc/base/sslsocketfactory.cc \
+ third_party/webrtc/base/sslstreamadapter.cc \
+ third_party/webrtc/base/sslstreamadapterhelper.cc \
+ third_party/webrtc/base/stream.cc \
+ third_party/webrtc/base/systeminfo.cc \
+ third_party/webrtc/base/task.cc \
+ third_party/webrtc/base/taskparent.cc \
+ third_party/webrtc/base/taskrunner.cc \
+ third_party/webrtc/base/thread.cc \
+ third_party/webrtc/base/thread_checker_impl.cc \
+ third_party/webrtc/base/timing.cc \
+ third_party/webrtc/base/unixfilesystem.cc \
+ third_party/webrtc/base/urlencode.cc \
+ third_party/webrtc/base/worker.cc \
+ third_party/webrtc/overrides/webrtc/base/logging.cc \
+ third_party/webrtc/base/openssladapter.cc \
+ third_party/webrtc/base/openssldigest.cc \
+ third_party/webrtc/base/opensslidentity.cc \
+ third_party/webrtc/base/opensslstreamadapter.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DFEATURE_ENABLE_SSL' \
+ '-DLOGGING=1' \
+ '-DUSE_WEBRTC_DEV_BRANCH' \
+ '-DNO_MAIN_THREAD_WRAPPING' \
+ '-DSSL_USE_OPENSSL' \
+ '-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/third_party/jsoncpp/overrides/include \
+ $(LOCAL_PATH)/third_party/third_party/jsoncpp/source/include \
+ $(LOCAL_PATH)/third_party/boringssl/src/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DFEATURE_ENABLE_SSL' \
+ '-DLOGGING=1' \
+ '-DUSE_WEBRTC_DEV_BRANCH' \
+ '-DNO_MAIN_THREAD_WRAPPING' \
+ '-DSSL_USE_OPENSSL' \
+ '-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/third_party/jsoncpp/overrides/include \
+ $(LOCAL_PATH)/third_party/third_party/jsoncpp/source/include \
+ $(LOCAL_PATH)/third_party/boringssl/src/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_base_rtc_base_gyp
+
+# Alias gyp target name.
+.PHONY: rtc_base
+rtc_base: third_party_webrtc_base_rtc_base_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/base/rtc_base.target.darwin-x86.mk b/base/rtc_base.target.darwin-x86.mk
index fff4716f..50f5234d 100644
--- a/base/rtc_base.target.darwin-x86.mk
+++ b/base/rtc_base.target.darwin-x86.mk
@@ -140,11 +140,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -163,6 +165,7 @@ MY_DEFS_Debug := \
'-DNO_MAIN_THREAD_WRAPPING' \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -251,11 +254,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -274,6 +279,7 @@ MY_DEFS_Release := \
'-DNO_MAIN_THREAD_WRAPPING' \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/base/rtc_base.target.darwin-x86_64.mk b/base/rtc_base.target.darwin-x86_64.mk
index e6932f47..fbb7d546 100644
--- a/base/rtc_base.target.darwin-x86_64.mk
+++ b/base/rtc_base.target.darwin-x86_64.mk
@@ -139,11 +139,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -162,6 +164,7 @@ MY_DEFS_Debug := \
'-DNO_MAIN_THREAD_WRAPPING' \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -249,11 +252,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -272,6 +277,7 @@ MY_DEFS_Release := \
'-DNO_MAIN_THREAD_WRAPPING' \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/base/rtc_base.target.linux-arm.mk b/base/rtc_base.target.linux-arm.mk
index c352b2b7..5c7018c1 100644
--- a/base/rtc_base.target.linux-arm.mk
+++ b/base/rtc_base.target.linux-arm.mk
@@ -145,11 +145,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -171,6 +173,7 @@ MY_DEFS_Debug := \
'-DNO_MAIN_THREAD_WRAPPING' \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -265,11 +268,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -291,6 +296,7 @@ MY_DEFS_Release := \
'-DNO_MAIN_THREAD_WRAPPING' \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/base/rtc_base.target.linux-arm64.mk b/base/rtc_base.target.linux-arm64.mk
index f9dd5035..6633e54b 100644
--- a/base/rtc_base.target.linux-arm64.mk
+++ b/base/rtc_base.target.linux-arm64.mk
@@ -134,11 +134,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -147,6 +149,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
@@ -157,6 +160,7 @@ MY_DEFS_Debug := \
'-DNO_MAIN_THREAD_WRAPPING' \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -239,11 +243,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -252,6 +258,7 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
@@ -262,6 +269,7 @@ MY_DEFS_Release := \
'-DNO_MAIN_THREAD_WRAPPING' \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/base/rtc_base.target.linux-mips.mk b/base/rtc_base.target.linux-mips.mk
index 5b11cbf9..049b1efc 100644
--- a/base/rtc_base.target.linux-mips.mk
+++ b/base/rtc_base.target.linux-mips.mk
@@ -138,11 +138,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -163,6 +165,7 @@ MY_DEFS_Debug := \
'-DNO_MAIN_THREAD_WRAPPING' \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -250,11 +253,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -275,6 +280,7 @@ MY_DEFS_Release := \
'-DNO_MAIN_THREAD_WRAPPING' \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/base/rtc_base.target.linux-mips64.mk b/base/rtc_base.target.linux-mips64.mk
new file mode 100644
index 00000000..b83453d0
--- /dev/null
+++ b/base/rtc_base.target.linux-mips64.mk
@@ -0,0 +1,336 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_base_rtc_base_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/base/asyncfile.cc \
+ third_party/webrtc/base/asynchttprequest.cc \
+ third_party/webrtc/base/asyncsocket.cc \
+ third_party/webrtc/base/asynctcpsocket.cc \
+ third_party/webrtc/base/asyncudpsocket.cc \
+ third_party/webrtc/base/autodetectproxy.cc \
+ third_party/webrtc/base/base64.cc \
+ third_party/webrtc/base/bytebuffer.cc \
+ third_party/webrtc/base/common.cc \
+ third_party/webrtc/base/cpumonitor.cc \
+ third_party/webrtc/base/crc32.cc \
+ third_party/webrtc/base/diskcache.cc \
+ third_party/webrtc/base/event.cc \
+ third_party/webrtc/base/fileutils.cc \
+ third_party/webrtc/base/firewallsocketserver.cc \
+ third_party/webrtc/base/flags.cc \
+ third_party/webrtc/base/helpers.cc \
+ third_party/webrtc/base/httpbase.cc \
+ third_party/webrtc/base/httpclient.cc \
+ third_party/webrtc/base/httpcommon.cc \
+ third_party/webrtc/base/httprequest.cc \
+ third_party/webrtc/base/ifaddrs-android.cc \
+ third_party/webrtc/base/ipaddress.cc \
+ third_party/webrtc/base/linux.cc \
+ third_party/webrtc/base/messagedigest.cc \
+ third_party/webrtc/base/messagehandler.cc \
+ third_party/webrtc/base/messagequeue.cc \
+ third_party/webrtc/base/nethelpers.cc \
+ third_party/webrtc/base/network.cc \
+ third_party/webrtc/base/pathutils.cc \
+ third_party/webrtc/base/physicalsocketserver.cc \
+ third_party/webrtc/base/proxydetect.cc \
+ third_party/webrtc/base/proxyinfo.cc \
+ third_party/webrtc/base/ratelimiter.cc \
+ third_party/webrtc/base/ratetracker.cc \
+ third_party/webrtc/base/sha1.cc \
+ third_party/webrtc/base/signalthread.cc \
+ third_party/webrtc/base/socketadapters.cc \
+ third_party/webrtc/base/socketaddress.cc \
+ third_party/webrtc/base/socketaddresspair.cc \
+ third_party/webrtc/base/socketpool.cc \
+ third_party/webrtc/base/socketstream.cc \
+ third_party/webrtc/base/ssladapter.cc \
+ third_party/webrtc/base/sslfingerprint.cc \
+ third_party/webrtc/base/sslidentity.cc \
+ third_party/webrtc/base/sslsocketfactory.cc \
+ third_party/webrtc/base/sslstreamadapter.cc \
+ third_party/webrtc/base/sslstreamadapterhelper.cc \
+ third_party/webrtc/base/stream.cc \
+ third_party/webrtc/base/systeminfo.cc \
+ third_party/webrtc/base/task.cc \
+ third_party/webrtc/base/taskparent.cc \
+ third_party/webrtc/base/taskrunner.cc \
+ third_party/webrtc/base/thread.cc \
+ third_party/webrtc/base/thread_checker_impl.cc \
+ third_party/webrtc/base/timing.cc \
+ third_party/webrtc/base/unixfilesystem.cc \
+ third_party/webrtc/base/urlencode.cc \
+ third_party/webrtc/base/worker.cc \
+ third_party/webrtc/overrides/webrtc/base/logging.cc \
+ third_party/webrtc/base/openssladapter.cc \
+ third_party/webrtc/base/openssldigest.cc \
+ third_party/webrtc/base/opensslidentity.cc \
+ third_party/webrtc/base/opensslstreamadapter.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DFEATURE_ENABLE_SSL' \
+ '-DLOGGING=1' \
+ '-DUSE_WEBRTC_DEV_BRANCH' \
+ '-DNO_MAIN_THREAD_WRAPPING' \
+ '-DSSL_USE_OPENSSL' \
+ '-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/third_party/jsoncpp/overrides/include \
+ $(LOCAL_PATH)/third_party/third_party/jsoncpp/source/include \
+ $(LOCAL_PATH)/third_party/boringssl/src/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DFEATURE_ENABLE_SSL' \
+ '-DLOGGING=1' \
+ '-DUSE_WEBRTC_DEV_BRANCH' \
+ '-DNO_MAIN_THREAD_WRAPPING' \
+ '-DSSL_USE_OPENSSL' \
+ '-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/third_party/jsoncpp/overrides/include \
+ $(LOCAL_PATH)/third_party/third_party/jsoncpp/source/include \
+ $(LOCAL_PATH)/third_party/boringssl/src/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_base_rtc_base_gyp
+
+# Alias gyp target name.
+.PHONY: rtc_base
+rtc_base: third_party_webrtc_base_rtc_base_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/base/rtc_base.target.linux-x86.mk b/base/rtc_base.target.linux-x86.mk
index fff4716f..50f5234d 100644
--- a/base/rtc_base.target.linux-x86.mk
+++ b/base/rtc_base.target.linux-x86.mk
@@ -140,11 +140,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -163,6 +165,7 @@ MY_DEFS_Debug := \
'-DNO_MAIN_THREAD_WRAPPING' \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -251,11 +254,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -274,6 +279,7 @@ MY_DEFS_Release := \
'-DNO_MAIN_THREAD_WRAPPING' \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/base/rtc_base.target.linux-x86_64.mk b/base/rtc_base.target.linux-x86_64.mk
index e6932f47..fbb7d546 100644
--- a/base/rtc_base.target.linux-x86_64.mk
+++ b/base/rtc_base.target.linux-x86_64.mk
@@ -139,11 +139,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -162,6 +164,7 @@ MY_DEFS_Debug := \
'-DNO_MAIN_THREAD_WRAPPING' \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -249,11 +252,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -272,6 +277,7 @@ MY_DEFS_Release := \
'-DNO_MAIN_THREAD_WRAPPING' \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/base/rtc_base_approved.target.darwin-arm.mk b/base/rtc_base_approved.target.darwin-arm.mk
index a8b08feb..3ea72cf7 100644
--- a/base/rtc_base_approved.target.darwin-arm.mk
+++ b/base/rtc_base_approved.target.darwin-arm.mk
@@ -89,11 +89,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -109,6 +111,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -201,11 +204,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -221,6 +226,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/base/rtc_base_approved.target.darwin-arm64.mk b/base/rtc_base_approved.target.darwin-arm64.mk
index f836ae01..3bd58bfe 100644
--- a/base/rtc_base_approved.target.darwin-arm64.mk
+++ b/base/rtc_base_approved.target.darwin-arm64.mk
@@ -78,11 +78,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -91,10 +93,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -175,11 +179,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -188,10 +194,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/base/rtc_base_approved.target.darwin-mips.mk b/base/rtc_base_approved.target.darwin-mips.mk
index bf55d2ef..cf2a6c07 100644
--- a/base/rtc_base_approved.target.darwin-mips.mk
+++ b/base/rtc_base_approved.target.darwin-mips.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -186,11 +189,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -205,6 +210,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/base/rtc_base_approved.target.darwin-mips64.mk b/base/rtc_base_approved.target.darwin-mips64.mk
new file mode 100644
index 00000000..060a2265
--- /dev/null
+++ b/base/rtc_base_approved.target.darwin-mips64.mk
@@ -0,0 +1,263 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_base_rtc_base_approved_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/base/checks.cc \
+ third_party/webrtc/base/exp_filter.cc \
+ third_party/webrtc/base/md5.cc \
+ third_party/webrtc/base/platform_file.cc \
+ third_party/webrtc/base/stringencode.cc \
+ third_party/webrtc/base/stringutils.cc \
+ third_party/webrtc/base/timeutils.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_base_rtc_base_approved_gyp
+
+# Alias gyp target name.
+.PHONY: rtc_base_approved
+rtc_base_approved: third_party_webrtc_base_rtc_base_approved_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/base/rtc_base_approved.target.darwin-x86.mk b/base/rtc_base_approved.target.darwin-x86.mk
index ef5db5dd..e71ccfb4 100644
--- a/base/rtc_base_approved.target.darwin-x86.mk
+++ b/base/rtc_base_approved.target.darwin-x86.mk
@@ -84,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -187,11 +190,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -204,6 +209,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/base/rtc_base_approved.target.darwin-x86_64.mk b/base/rtc_base_approved.target.darwin-x86_64.mk
index 1b39de15..44ac3b00 100644
--- a/base/rtc_base_approved.target.darwin-x86_64.mk
+++ b/base/rtc_base_approved.target.darwin-x86_64.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -185,11 +188,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -202,6 +207,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/base/rtc_base_approved.target.linux-arm.mk b/base/rtc_base_approved.target.linux-arm.mk
index a8b08feb..3ea72cf7 100644
--- a/base/rtc_base_approved.target.linux-arm.mk
+++ b/base/rtc_base_approved.target.linux-arm.mk
@@ -89,11 +89,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -109,6 +111,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -201,11 +204,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -221,6 +226,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/base/rtc_base_approved.target.linux-arm64.mk b/base/rtc_base_approved.target.linux-arm64.mk
index f836ae01..3bd58bfe 100644
--- a/base/rtc_base_approved.target.linux-arm64.mk
+++ b/base/rtc_base_approved.target.linux-arm64.mk
@@ -78,11 +78,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -91,10 +93,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -175,11 +179,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -188,10 +194,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/base/rtc_base_approved.target.linux-mips.mk b/base/rtc_base_approved.target.linux-mips.mk
index bf55d2ef..cf2a6c07 100644
--- a/base/rtc_base_approved.target.linux-mips.mk
+++ b/base/rtc_base_approved.target.linux-mips.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -186,11 +189,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -205,6 +210,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/base/rtc_base_approved.target.linux-mips64.mk b/base/rtc_base_approved.target.linux-mips64.mk
new file mode 100644
index 00000000..060a2265
--- /dev/null
+++ b/base/rtc_base_approved.target.linux-mips64.mk
@@ -0,0 +1,263 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_base_rtc_base_approved_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/base/checks.cc \
+ third_party/webrtc/base/exp_filter.cc \
+ third_party/webrtc/base/md5.cc \
+ third_party/webrtc/base/platform_file.cc \
+ third_party/webrtc/base/stringencode.cc \
+ third_party/webrtc/base/stringutils.cc \
+ third_party/webrtc/base/timeutils.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_base_rtc_base_approved_gyp
+
+# Alias gyp target name.
+.PHONY: rtc_base_approved
+rtc_base_approved: third_party_webrtc_base_rtc_base_approved_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/base/rtc_base_approved.target.linux-x86.mk b/base/rtc_base_approved.target.linux-x86.mk
index ef5db5dd..e71ccfb4 100644
--- a/base/rtc_base_approved.target.linux-x86.mk
+++ b/base/rtc_base_approved.target.linux-x86.mk
@@ -84,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -187,11 +190,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -204,6 +209,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/base/rtc_base_approved.target.linux-x86_64.mk b/base/rtc_base_approved.target.linux-x86_64.mk
index 1b39de15..44ac3b00 100644
--- a/base/rtc_base_approved.target.linux-x86_64.mk
+++ b/base/rtc_base_approved.target.linux-x86_64.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -185,11 +188,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -202,6 +207,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/base/webrtc_base.target.darwin-mips64.mk b/base/webrtc_base.target.darwin-mips64.mk
new file mode 100644
index 00000000..3ec755ad
--- /dev/null
+++ b/base/webrtc_base.target.darwin-mips64.mk
@@ -0,0 +1,47 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := third_party_webrtc_base_webrtc_base_gyp
+LOCAL_MODULE_STEM := webrtc_base
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_base_rtc_base_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_base_rtc_base_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_base_webrtc_base_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_base
+webrtc_base: third_party_webrtc_base_webrtc_base_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+LOCAL_2ND_ARCH_VAR_PREFIX := $(GYP_VAR_PREFIX)
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
+
+LOCAL_2ND_ARCH_VAR_PREFIX :=
diff --git a/base/webrtc_base.target.linux-mips64.mk b/base/webrtc_base.target.linux-mips64.mk
new file mode 100644
index 00000000..3ec755ad
--- /dev/null
+++ b/base/webrtc_base.target.linux-mips64.mk
@@ -0,0 +1,47 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := GYP
+LOCAL_MODULE := third_party_webrtc_base_webrtc_base_gyp
+LOCAL_MODULE_STEM := webrtc_base
+LOCAL_MODULE_SUFFIX := .stamp
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_base_rtc_base_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_base_rtc_base_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_base_webrtc_base_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_base
+webrtc_base: third_party_webrtc_base_webrtc_base_gyp
+
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
+LOCAL_UNINSTALLABLE_MODULE := true
+LOCAL_2ND_ARCH_VAR_PREFIX := $(GYP_VAR_PREFIX)
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
+ $(hide) echo "Gyp timestamp: $@"
+ $(hide) mkdir -p $(dir $@)
+ $(hide) touch $@
+
+LOCAL_2ND_ARCH_VAR_PREFIX :=
diff --git a/build/common.gypi b/build/common.gypi
index 18b33830..366e7e9f 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -42,6 +42,7 @@
'modules_java_gyp_path%': '<(modules_java_gyp_path)',
'gen_core_neon_offsets_gyp%': '<(gen_core_neon_offsets_gyp)',
'webrtc_vp8_dir%': '<(webrtc_root)/modules/video_coding/codecs/vp8',
+ 'webrtc_vp9_dir%': '<(webrtc_root)/modules/video_coding/codecs/vp9',
'rbe_components_path%': '<(webrtc_root)/modules/remote_bitrate_estimator',
'include_opus%': 1,
},
@@ -52,6 +53,7 @@
'modules_java_gyp_path%': '<(modules_java_gyp_path)',
'gen_core_neon_offsets_gyp%': '<(gen_core_neon_offsets_gyp)',
'webrtc_vp8_dir%': '<(webrtc_vp8_dir)',
+ 'webrtc_vp9_dir%': '<(webrtc_vp9_dir)',
'include_opus%': '<(include_opus)',
'rtc_relative_path%': 1,
'rbe_components_path%': '<(rbe_components_path)',
@@ -250,6 +252,11 @@
}],
],
}],
+ ['target_arch=="arm64"', {
+ 'defines': [
+ 'WEBRTC_ARCH_ARM',
+ ],
+ }],
['target_arch=="arm" or target_arch=="armv7"', {
'defines': [
'WEBRTC_ARCH_ARM',
@@ -267,7 +274,7 @@
}],
],
}],
- ['target_arch=="mipsel"', {
+ ['target_arch=="mipsel" and mips_arch_variant!="r6"', {
'defines': [
'MIPS32_LE',
],
diff --git a/build/isolate.gypi b/build/isolate.gypi
index 2e86020e..86169fd0 100644
--- a/build/isolate.gypi
+++ b/build/isolate.gypi
@@ -62,18 +62,6 @@
# Files that are known to be involved in this step.
'<(DEPTH)/tools/swarming_client/isolate.py',
'<(DEPTH)/tools/swarming_client/run_isolated.py',
-
- # Disable file tracking by the build driver for now. This means the
- # project must have the proper build-time dependency for their runtime
- # dependency. This improves the runtime of the build driver since it
- # doesn't have to stat() all these files.
- #
- # More importantly, it means that even if a isolate_dependency_tracked
- # file is missing, for example if a file was deleted and the .isolate
- # file was not updated, that won't break the build, especially in the
- # case where foo_tests_run is not built! This should be reenabled once
- # the switch-over to running tests on Swarm is completed.
- #'<@(isolate_dependency_tracked)',
],
'outputs': [
'<(PRODUCT_DIR)/<(RULE_INPUT_ROOT).isolated',
diff --git a/build/merge_libs.gyp b/build/merge_libs.gyp
index d6610029..d28d71ba 100644
--- a/build/merge_libs.gyp
+++ b/build/merge_libs.gyp
@@ -21,6 +21,8 @@
'../webrtc.gyp:webrtc',
'../sound/sound.gyp:rtc_sound',
'../libjingle/xmllite/xmllite.gyp:rtc_xmllite',
+ '../libjingle/xmpp/xmpp.gyp:rtc_xmpp',
+ '../p2p/p2p.gyp:rtc_p2p',
],
'sources': ['no_op.cc',],
},
diff --git a/build/tsan_suppressions_webrtc.cc b/build/tsan_suppressions_webrtc.cc
index 723e62a2..01658ed2 100644
--- a/build/tsan_suppressions_webrtc.cc
+++ b/build/tsan_suppressions_webrtc.cc
@@ -27,6 +27,7 @@ char kTSanDefaultSuppressions[] =
"race:rtc::MessageQueue::Quit\n"
"race:FileVideoCapturerTest::VideoCapturerListener::OnFrameCaptured\n"
"race:vp8cx_remove_encoder_threads\n"
+"race:third_party/libvpx/source/libvpx/vp9/common/vp9_scan.h\n"
// Usage of trace callback and trace level is racy in libjingle_media_unittests.
// https://code.google.com/p/webrtc/issues/detail?id=3372
diff --git a/common_audio/BUILD.gn b/common_audio/BUILD.gn
index 455e5279..ba1d1795 100644
--- a/common_audio/BUILD.gn
+++ b/common_audio/BUILD.gn
@@ -19,6 +19,8 @@ config("common_audio_config") {
source_set("common_audio") {
sources = [
+ "audio_converter.cc",
+ "audio_converter.h",
"audio_util.cc",
"blocker.cc",
"blocker.h",
@@ -69,7 +71,9 @@ source_set("common_audio") {
"signal_processing/splitting_filter.c",
"signal_processing/sqrt_of_one_minus_x_squared.c",
"signal_processing/vector_scaling_operations.c",
+ "vad/include/vad.h",
"vad/include/webrtc_vad.h",
+ "vad/vad.cc",
"vad/webrtc_vad.c",
"vad/vad_core.c",
"vad/vad_core.h",
@@ -81,8 +85,8 @@ source_set("common_audio") {
"vad/vad_sp.h",
"wav_header.cc",
"wav_header.h",
- "wav_writer.cc",
- "wav_writer.h",
+ "wav_file.cc",
+ "wav_file.h",
"window_generator.cc",
"window_generator.h",
]
diff --git a/common_audio/audio_converter.cc b/common_audio/audio_converter.cc
new file mode 100644
index 00000000..f085ff13
--- /dev/null
+++ b/common_audio/audio_converter.cc
@@ -0,0 +1,110 @@
+/*
+ * 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 "webrtc/base/checks.h"
+#include "webrtc/common_audio/audio_converter.h"
+#include "webrtc/common_audio/resampler/push_sinc_resampler.h"
+
+namespace webrtc {
+namespace {
+
+void DownmixToMono(const float* const* src,
+ int src_channels,
+ int frames,
+ float* dst) {
+ DCHECK_GT(src_channels, 0);
+ for (int i = 0; i < frames; ++i) {
+ float sum = 0;
+ for (int j = 0; j < src_channels; ++j)
+ sum += src[j][i];
+ dst[i] = sum / src_channels;
+ }
+}
+
+void UpmixFromMono(const float* src,
+ int dst_channels,
+ int frames,
+ float* const* dst) {
+ DCHECK_GT(dst_channels, 0);
+ for (int i = 0; i < frames; ++i) {
+ float value = src[i];
+ for (int j = 0; j < dst_channels; ++j)
+ dst[j][i] = value;
+ }
+}
+
+} // namespace
+
+AudioConverter::AudioConverter(int src_channels, int src_frames,
+ int dst_channels, int dst_frames)
+ : src_channels_(src_channels),
+ src_frames_(src_frames),
+ dst_channels_(dst_channels),
+ dst_frames_(dst_frames) {
+ CHECK(dst_channels == src_channels || dst_channels == 1 || src_channels == 1);
+ const int resample_channels = std::min(src_channels, dst_channels);
+
+ // Prepare buffers as needed for intermediate stages.
+ if (dst_channels < src_channels)
+ downmix_buffer_.reset(new ChannelBuffer<float>(src_frames,
+ resample_channels));
+
+ if (src_frames != dst_frames) {
+ resamplers_.reserve(resample_channels);
+ for (int i = 0; i < resample_channels; ++i)
+ resamplers_.push_back(new PushSincResampler(src_frames, dst_frames));
+ }
+}
+
+void AudioConverter::Convert(const float* const* src,
+ int src_channels,
+ int src_frames,
+ int dst_channels,
+ int dst_frames,
+ float* const* dst) {
+ DCHECK_EQ(src_channels_, src_channels);
+ DCHECK_EQ(src_frames_, src_frames);
+ DCHECK_EQ(dst_channels_, dst_channels);
+ DCHECK_EQ(dst_frames_, dst_frames);;
+
+ if (src_channels == dst_channels && src_frames == dst_frames) {
+ // Shortcut copy.
+ if (src != dst) {
+ for (int i = 0; i < src_channels; ++i)
+ memcpy(dst[i], src[i], dst_frames * sizeof(*dst[i]));
+ }
+ return;
+ }
+
+ const float* const* src_ptr = src;
+ if (dst_channels < src_channels) {
+ float* const* dst_ptr = dst;
+ if (src_frames != dst_frames) {
+ // Downmix to a buffer for subsequent resampling.
+ DCHECK_EQ(downmix_buffer_->num_channels(), dst_channels);
+ DCHECK_EQ(downmix_buffer_->samples_per_channel(), src_frames);
+ dst_ptr = downmix_buffer_->channels();
+ }
+
+ DownmixToMono(src, src_channels, src_frames, dst_ptr[0]);
+ src_ptr = dst_ptr;
+ }
+
+ if (src_frames != dst_frames) {
+ for (size_t i = 0; i < resamplers_.size(); ++i)
+ resamplers_[i]->Resample(src_ptr[i], src_frames, dst[i], dst_frames);
+ src_ptr = dst;
+ }
+
+ if (dst_channels > src_channels)
+ UpmixFromMono(src_ptr[0], dst_channels, dst_frames, dst);
+}
+
+} // namespace webrtc
diff --git a/common_audio/audio_converter.h b/common_audio/audio_converter.h
new file mode 100644
index 00000000..6365f587
--- /dev/null
+++ b/common_audio/audio_converter.h
@@ -0,0 +1,55 @@
+/*
+ * 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 WEBRTC_COMMON_AUDIO_AUDIO_CONVERTER_H_
+#define WEBRTC_COMMON_AUDIO_AUDIO_CONVERTER_H_
+
+// TODO(ajm): Move channel buffer to common_audio.
+#include "webrtc/base/constructormagic.h"
+#include "webrtc/modules/audio_processing/common.h"
+#include "webrtc/system_wrappers/interface/scoped_ptr.h"
+#include "webrtc/system_wrappers/interface/scoped_vector.h"
+
+namespace webrtc {
+
+class PushSincResampler;
+
+// Format conversion (remixing and resampling) for audio. Only simple remixing
+// conversions are supported: downmix to mono (i.e. |dst_channels| == 1) or
+// upmix from mono (i.e. |src_channels == 1|).
+//
+// The source and destination chunks have the same duration in time; specifying
+// the number of frames is equivalent to specifying the sample rates.
+class AudioConverter {
+ public:
+ AudioConverter(int src_channels, int src_frames,
+ int dst_channels, int dst_frames);
+
+ void Convert(const float* const* src,
+ int src_channels,
+ int src_frames,
+ int dst_channels,
+ int dst_frames,
+ float* const* dest);
+
+ private:
+ const int src_channels_;
+ const int src_frames_;
+ const int dst_channels_;
+ const int dst_frames_;
+ scoped_ptr<ChannelBuffer<float>> downmix_buffer_;
+ ScopedVector<PushSincResampler> resamplers_;
+
+ DISALLOW_COPY_AND_ASSIGN(AudioConverter);
+};
+
+} // namespace webrtc
+
+#endif // WEBRTC_COMMON_AUDIO_AUDIO_CONVERTER_H_
diff --git a/common_audio/audio_converter_unittest.cc b/common_audio/audio_converter_unittest.cc
new file mode 100644
index 00000000..91836f9c
--- /dev/null
+++ b/common_audio/audio_converter_unittest.cc
@@ -0,0 +1,155 @@
+/*
+ * 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 <math.h>
+#include <algorithm>
+#include <vector>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/common_audio/audio_converter.h"
+#include "webrtc/common_audio/resampler/push_sinc_resampler.h"
+#include "webrtc/modules/audio_processing/common.h"
+#include "webrtc/system_wrappers/interface/scoped_ptr.h"
+
+namespace webrtc {
+
+typedef scoped_ptr<ChannelBuffer<float>> ScopedBuffer;
+
+// Sets the signal value to increase by |data| with every sample.
+ScopedBuffer CreateBuffer(const std::vector<float>& data, int frames) {
+ const int num_channels = static_cast<int>(data.size());
+ ScopedBuffer sb(new ChannelBuffer<float>(frames, num_channels));
+ for (int i = 0; i < num_channels; ++i)
+ for (int j = 0; j < frames; ++j)
+ sb->channel(i)[j] = data[i] * j;
+ return sb;
+}
+
+void VerifyParams(const ChannelBuffer<float>& ref,
+ const ChannelBuffer<float>& test) {
+ EXPECT_EQ(ref.num_channels(), test.num_channels());
+ EXPECT_EQ(ref.samples_per_channel(), test.samples_per_channel());
+}
+
+// Computes the best SNR based on the error between |ref_frame| and
+// |test_frame|. It searches around |expected_delay| in samples between the
+// signals to compensate for the resampling delay.
+float ComputeSNR(const ChannelBuffer<float>& ref,
+ const ChannelBuffer<float>& test,
+ int expected_delay) {
+ VerifyParams(ref, test);
+ float best_snr = 0;
+ int best_delay = 0;
+
+ // Search within one sample of the expected delay.
+ for (int delay = std::max(expected_delay - 1, 0);
+ delay <= std::min(expected_delay + 1, ref.samples_per_channel());
+ ++delay) {
+ float mse = 0;
+ float variance = 0;
+ float mean = 0;
+ for (int i = 0; i < ref.num_channels(); ++i) {
+ for (int j = 0; j < ref.samples_per_channel() - delay; ++j) {
+ float error = ref.channel(i)[j] - test.channel(i)[j + delay];
+ mse += error * error;
+ variance += ref.channel(i)[j] * ref.channel(i)[j];
+ mean += ref.channel(i)[j];
+ }
+ }
+ const int length = ref.num_channels() * (ref.samples_per_channel() - delay);
+ mse /= length;
+ variance /= length;
+ mean /= length;
+ variance -= mean * mean;
+ float snr = 100; // We assign 100 dB to the zero-error case.
+ if (mse > 0)
+ snr = 10 * log10(variance / mse);
+ if (snr > best_snr) {
+ best_snr = snr;
+ best_delay = delay;
+ }
+ }
+ printf("SNR=%.1f dB at delay=%d\n", best_snr, best_delay);
+ return best_snr;
+}
+
+// Sets the source to a linearly increasing signal for which we can easily
+// generate a reference. Runs the AudioConverter and ensures the output has
+// sufficiently high SNR relative to the reference.
+void RunAudioConverterTest(int src_channels,
+ int src_sample_rate_hz,
+ int dst_channels,
+ int dst_sample_rate_hz) {
+ const float kSrcLeft = 0.0002f;
+ const float kSrcRight = 0.0001f;
+ const float resampling_factor = (1.f * src_sample_rate_hz) /
+ dst_sample_rate_hz;
+ const float dst_left = resampling_factor * kSrcLeft;
+ const float dst_right = resampling_factor * kSrcRight;
+ const float dst_mono = (dst_left + dst_right) / 2;
+ const int src_frames = src_sample_rate_hz / 100;
+ const int dst_frames = dst_sample_rate_hz / 100;
+
+ std::vector<float> src_data(1, kSrcLeft);
+ if (src_channels == 2)
+ src_data.push_back(kSrcRight);
+ ScopedBuffer src_buffer = CreateBuffer(src_data, src_frames);
+
+ std::vector<float> dst_data(1, 0);
+ std::vector<float> ref_data;
+ if (dst_channels == 1) {
+ if (src_channels == 1)
+ ref_data.push_back(dst_left);
+ else
+ ref_data.push_back(dst_mono);
+ } else {
+ dst_data.push_back(0);
+ ref_data.push_back(dst_left);
+ if (src_channels == 1)
+ ref_data.push_back(dst_left);
+ else
+ ref_data.push_back(dst_right);
+ }
+ ScopedBuffer dst_buffer = CreateBuffer(dst_data, dst_frames);
+ ScopedBuffer ref_buffer = CreateBuffer(ref_data, dst_frames);
+
+ // The sinc resampler has a known delay, which we compute here.
+ const int delay_frames = src_sample_rate_hz == dst_sample_rate_hz ? 0 :
+ PushSincResampler::AlgorithmicDelaySeconds(src_sample_rate_hz) *
+ dst_sample_rate_hz;
+ printf("(%d, %d Hz) -> (%d, %d Hz) ", // SNR reported on the same line later.
+ src_channels, src_sample_rate_hz, dst_channels, dst_sample_rate_hz);
+
+ AudioConverter converter(src_channels, src_frames, dst_channels, dst_frames);
+ converter.Convert(src_buffer->channels(), src_channels, src_frames,
+ dst_channels, dst_frames, dst_buffer->channels());
+
+ EXPECT_LT(43.f,
+ ComputeSNR(*ref_buffer.get(), *dst_buffer.get(), delay_frames));
+}
+
+TEST(AudioConverterTest, ConversionsPassSNRThreshold) {
+ const int kSampleRates[] = {8000, 16000, 32000, 44100, 48000};
+ const int kSampleRatesSize = sizeof(kSampleRates) / sizeof(*kSampleRates);
+ const int kChannels[] = {1, 2};
+ const int kChannelsSize = sizeof(kChannels) / sizeof(*kChannels);
+ for (int src_rate = 0; src_rate < kSampleRatesSize; ++src_rate) {
+ for (int dst_rate = 0; dst_rate < kSampleRatesSize; ++dst_rate) {
+ for (int src_channel = 0; src_channel < kChannelsSize; ++src_channel) {
+ for (int dst_channel = 0; dst_channel < kChannelsSize; ++dst_channel) {
+ RunAudioConverterTest(kChannels[src_channel], kSampleRates[src_rate],
+ kChannels[dst_channel], kSampleRates[dst_rate]);
+ }
+ }
+ }
+ }
+}
+
+} // namespace webrtc
diff --git a/common_audio/audio_util.cc b/common_audio/audio_util.cc
index f2936b07..2047295c 100644
--- a/common_audio/audio_util.cc
+++ b/common_audio/audio_util.cc
@@ -14,19 +14,29 @@
namespace webrtc {
-void RoundToInt16(const float* src, size_t size, int16_t* dest) {
+void FloatToS16(const float* src, size_t size, int16_t* dest) {
for (size_t i = 0; i < size; ++i)
- dest[i] = RoundToInt16(src[i]);
+ dest[i] = FloatToS16(src[i]);
}
-void ScaleAndRoundToInt16(const float* src, size_t size, int16_t* dest) {
+void S16ToFloat(const int16_t* src, size_t size, float* dest) {
for (size_t i = 0; i < size; ++i)
- dest[i] = ScaleAndRoundToInt16(src[i]);
+ dest[i] = S16ToFloat(src[i]);
}
-void ScaleToFloat(const int16_t* src, size_t size, float* dest) {
+void FloatS16ToS16(const float* src, size_t size, int16_t* dest) {
for (size_t i = 0; i < size; ++i)
- dest[i] = ScaleToFloat(src[i]);
+ dest[i] = FloatS16ToS16(src[i]);
+}
+
+void FloatToFloatS16(const float* src, size_t size, float* dest) {
+ for (size_t i = 0; i < size; ++i)
+ dest[i] = FloatToFloatS16(src[i]);
+}
+
+void FloatS16ToFloat(const float* src, size_t size, float* dest) {
+ for (size_t i = 0; i < size; ++i)
+ dest[i] = FloatS16ToFloat(src[i]);
}
} // namespace webrtc
diff --git a/common_audio/audio_util_unittest.cc b/common_audio/audio_util_unittest.cc
index bf9ad812..2cdf5381 100644
--- a/common_audio/audio_util_unittest.cc
+++ b/common_audio/audio_util_unittest.cc
@@ -26,35 +26,59 @@ void ExpectArraysEq(const float* ref, const float* test, int length) {
}
}
-TEST(AudioUtilTest, RoundToInt16) {
+TEST(AudioUtilTest, FloatToS16) {
+ const int kSize = 9;
+ const float kInput[kSize] = {
+ 0.f, 0.4f / 32767.f, 0.6f / 32767.f, -0.4f / 32768.f, -0.6f / 32768.f,
+ 1.f, -1.f, 1.1f, -1.1f};
+ const int16_t kReference[kSize] = {
+ 0, 0, 1, 0, -1, 32767, -32768, 32767, -32768};
+ int16_t output[kSize];
+ FloatToS16(kInput, kSize, output);
+ ExpectArraysEq(kReference, output, kSize);
+}
+
+TEST(AudioUtilTest, S16ToFloat) {
+ const int kSize = 7;
+ const int16_t kInput[kSize] = {0, 1, -1, 16384, -16384, 32767, -32768};
+ const float kReference[kSize] = {
+ 0.f, 1.f / 32767.f, -1.f / 32768.f, 16384.f / 32767.f, -0.5f, 1.f, -1.f};
+ float output[kSize];
+ S16ToFloat(kInput, kSize, output);
+ ExpectArraysEq(kReference, output, kSize);
+}
+
+TEST(AudioUtilTest, FloatS16ToS16) {
const int kSize = 7;
const float kInput[kSize] = {
0.f, 0.4f, 0.5f, -0.4f, -0.5f, 32768.f, -32769.f};
const int16_t kReference[kSize] = {0, 0, 1, 0, -1, 32767, -32768};
int16_t output[kSize];
- RoundToInt16(kInput, kSize, output);
+ FloatS16ToS16(kInput, kSize, output);
ExpectArraysEq(kReference, output, kSize);
}
-TEST(AudioUtilTest, ScaleAndRoundToInt16) {
+TEST(AudioUtilTest, FloatToFloatS16) {
const int kSize = 9;
const float kInput[kSize] = {
0.f, 0.4f / 32767.f, 0.6f / 32767.f, -0.4f / 32768.f, -0.6f / 32768.f,
1.f, -1.f, 1.1f, -1.1f};
- const int16_t kReference[kSize] = {
- 0, 0, 1, 0, -1, 32767, -32768, 32767, -32768};
- int16_t output[kSize];
- ScaleAndRoundToInt16(kInput, kSize, output);
+ const float kReference[kSize] = {
+ 0.f, 0.4f, 0.6f, -0.4f, -0.6f, 32767.f, -32768.f, 36043.7f, -36044.8f};
+ float output[kSize];
+ FloatToFloatS16(kInput, kSize, output);
ExpectArraysEq(kReference, output, kSize);
}
-TEST(AudioUtilTest, ScaleToFloat) {
- const int kSize = 7;
- const int16_t kInput[kSize] = {0, 1, -1, 16384, -16384, 32767, -32768};
+TEST(AudioUtilTest, FloatS16ToFloat) {
+ const int kSize = 9;
+ const float kInput[kSize] = {
+ 0.f, 0.4f, 0.6f, -0.4f, -0.6f, 32767.f, -32768.f, 36043.7f, -36044.8f};
const float kReference[kSize] = {
- 0.f, 1.f / 32767.f, -1.f / 32768.f, 16384.f / 32767.f, -0.5f, 1.f, -1.f};
+ 0.f, 0.4f / 32767.f, 0.6f / 32767.f, -0.4f / 32768.f, -0.6f / 32768.f,
+ 1.f, -1.f, 1.1f, -1.1f};
float output[kSize];
- ScaleToFloat(kInput, kSize, output);
+ FloatS16ToFloat(kInput, kSize, output);
ExpectArraysEq(kReference, output, kSize);
}
diff --git a/common_audio/common_audio.gyp b/common_audio/common_audio.gyp
index 66ab7779..8f96674f 100644
--- a/common_audio/common_audio.gyp
+++ b/common_audio/common_audio.gyp
@@ -29,6 +29,8 @@
],
},
'sources': [
+ 'audio_converter.cc',
+ 'audio_converter.h',
'audio_util.cc',
'blocker.cc',
'blocker.h',
@@ -83,7 +85,9 @@
'signal_processing/splitting_filter.c',
'signal_processing/sqrt_of_one_minus_x_squared.c',
'signal_processing/vector_scaling_operations.c',
+ 'vad/include/vad.h',
'vad/include/webrtc_vad.h',
+ 'vad/vad.cc',
'vad/webrtc_vad.c',
'vad/vad_core.c',
'vad/vad_core.h',
@@ -95,8 +99,8 @@
'vad/vad_sp.h',
'wav_header.cc',
'wav_header.h',
- 'wav_writer.cc',
- 'wav_writer.h',
+ 'wav_file.cc',
+ 'wav_file.h',
'window_generator.cc',
'window_generator.h',
],
@@ -136,7 +140,7 @@
}],
], # conditions
}],
- ['target_arch=="mipsel"', {
+ ['target_arch=="mipsel" and mips_arch_variant!="r6"', {
'sources': [
'signal_processing/include/spl_inl_mips.h',
'signal_processing/complex_bit_reverse_mips.c',
@@ -222,6 +226,7 @@
'<(DEPTH)/testing/gtest.gyp:gtest',
],
'sources': [
+ 'audio_converter_unittest.cc',
'audio_util_unittest.cc',
'blocker_unittest.cc',
'fir_filter_unittest.cc',
@@ -240,7 +245,7 @@
'vad/vad_unittest.cc',
'vad/vad_unittest.h',
'wav_header_unittest.cc',
- 'wav_writer_unittest.cc',
+ 'wav_file_unittest.cc',
'window_generator_unittest.cc',
],
'conditions': [
@@ -280,7 +285,6 @@
],
'includes': [
'../build/isolate.gypi',
- 'common_audio_unittests.isolate',
],
'sources': [
'common_audio_unittests.isolate',
diff --git a/common_audio/common_audio.target.darwin-arm.mk b/common_audio/common_audio.target.darwin-arm.mk
index 4d28e2eb..1ee1df1d 100644
--- a/common_audio/common_audio.target.darwin-arm.mk
+++ b/common_audio/common_audio.target.darwin-arm.mk
@@ -24,6 +24,7 @@ LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/common_audio/audio_converter.cc \
third_party/webrtc/common_audio/audio_util.cc \
third_party/webrtc/common_audio/blocker.cc \
third_party/webrtc/common_audio/fir_filter.cc \
@@ -61,13 +62,14 @@ LOCAL_SRC_FILES := \
third_party/webrtc/common_audio/signal_processing/splitting_filter.c \
third_party/webrtc/common_audio/signal_processing/sqrt_of_one_minus_x_squared.c \
third_party/webrtc/common_audio/signal_processing/vector_scaling_operations.c \
+ third_party/webrtc/common_audio/vad/vad.cc \
third_party/webrtc/common_audio/vad/webrtc_vad.c \
third_party/webrtc/common_audio/vad/vad_core.c \
third_party/webrtc/common_audio/vad/vad_filterbank.c \
third_party/webrtc/common_audio/vad/vad_gmm.c \
third_party/webrtc/common_audio/vad/vad_sp.c \
third_party/webrtc/common_audio/wav_header.cc \
- third_party/webrtc/common_audio/wav_writer.cc \
+ third_party/webrtc/common_audio/wav_file.cc \
third_party/webrtc/common_audio/window_generator.cc \
third_party/webrtc/common_audio/lapped_transform.cc \
third_party/webrtc/common_audio/real_fourier.cc \
@@ -132,11 +134,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -153,6 +157,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DDL_ARM_NEON_OPTIONAL' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -249,11 +254,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -270,6 +277,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DDL_ARM_NEON_OPTIONAL' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_audio/common_audio.target.darwin-arm64.mk b/common_audio/common_audio.target.darwin-arm64.mk
index fabeaf16..27d0e13e 100644
--- a/common_audio/common_audio.target.darwin-arm64.mk
+++ b/common_audio/common_audio.target.darwin-arm64.mk
@@ -24,6 +24,7 @@ LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/common_audio/audio_converter.cc \
third_party/webrtc/common_audio/audio_util.cc \
third_party/webrtc/common_audio/blocker.cc \
third_party/webrtc/common_audio/fir_filter.cc \
@@ -64,13 +65,14 @@ LOCAL_SRC_FILES := \
third_party/webrtc/common_audio/signal_processing/splitting_filter.c \
third_party/webrtc/common_audio/signal_processing/sqrt_of_one_minus_x_squared.c \
third_party/webrtc/common_audio/signal_processing/vector_scaling_operations.c \
+ third_party/webrtc/common_audio/vad/vad.cc \
third_party/webrtc/common_audio/vad/webrtc_vad.c \
third_party/webrtc/common_audio/vad/vad_core.c \
third_party/webrtc/common_audio/vad/vad_filterbank.c \
third_party/webrtc/common_audio/vad/vad_gmm.c \
third_party/webrtc/common_audio/vad/vad_sp.c \
third_party/webrtc/common_audio/wav_header.cc \
- third_party/webrtc/common_audio/wav_writer.cc \
+ third_party/webrtc/common_audio/wav_file.cc \
third_party/webrtc/common_audio/window_generator.cc \
third_party/webrtc/common_audio/lapped_transform.cc \
third_party/webrtc/common_audio/real_fourier.cc
@@ -121,11 +123,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -134,11 +138,13 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DDL_ARM_NEON' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -223,11 +229,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -236,11 +244,13 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DDL_ARM_NEON' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_audio/common_audio.target.darwin-mips.mk b/common_audio/common_audio.target.darwin-mips.mk
index fe76cba3..c1396e43 100644
--- a/common_audio/common_audio.target.darwin-mips.mk
+++ b/common_audio/common_audio.target.darwin-mips.mk
@@ -24,6 +24,7 @@ LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/common_audio/audio_converter.cc \
third_party/webrtc/common_audio/audio_util.cc \
third_party/webrtc/common_audio/blocker.cc \
third_party/webrtc/common_audio/fir_filter.cc \
@@ -60,13 +61,14 @@ LOCAL_SRC_FILES := \
third_party/webrtc/common_audio/signal_processing/splitting_filter.c \
third_party/webrtc/common_audio/signal_processing/sqrt_of_one_minus_x_squared.c \
third_party/webrtc/common_audio/signal_processing/vector_scaling_operations.c \
+ third_party/webrtc/common_audio/vad/vad.cc \
third_party/webrtc/common_audio/vad/webrtc_vad.c \
third_party/webrtc/common_audio/vad/vad_core.c \
third_party/webrtc/common_audio/vad/vad_filterbank.c \
third_party/webrtc/common_audio/vad/vad_gmm.c \
third_party/webrtc/common_audio/vad/vad_sp.c \
third_party/webrtc/common_audio/wav_header.cc \
- third_party/webrtc/common_audio/wav_writer.cc \
+ third_party/webrtc/common_audio/wav_file.cc \
third_party/webrtc/common_audio/window_generator.cc \
third_party/webrtc/common_audio/lapped_transform.cc \
third_party/webrtc/common_audio/real_fourier.cc \
@@ -129,11 +131,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -148,6 +152,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -237,11 +242,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -256,6 +263,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_audio/common_audio.target.darwin-mips64.mk b/common_audio/common_audio.target.darwin-mips64.mk
new file mode 100644
index 00000000..2893a038
--- /dev/null
+++ b/common_audio/common_audio.target.darwin-mips64.mk
@@ -0,0 +1,316 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_common_audio_common_audio_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/common_audio/audio_converter.cc \
+ third_party/webrtc/common_audio/audio_util.cc \
+ third_party/webrtc/common_audio/blocker.cc \
+ third_party/webrtc/common_audio/fir_filter.cc \
+ third_party/webrtc/common_audio/resampler/push_resampler.cc \
+ third_party/webrtc/common_audio/resampler/push_sinc_resampler.cc \
+ third_party/webrtc/common_audio/resampler/resampler.cc \
+ third_party/webrtc/common_audio/resampler/sinc_resampler.cc \
+ third_party/webrtc/common_audio/signal_processing/auto_corr_to_refl_coef.c \
+ third_party/webrtc/common_audio/signal_processing/auto_correlation.c \
+ third_party/webrtc/common_audio/signal_processing/complex_fft.c \
+ third_party/webrtc/common_audio/signal_processing/complex_bit_reverse.c \
+ third_party/webrtc/common_audio/signal_processing/copy_set_operations.c \
+ third_party/webrtc/common_audio/signal_processing/cross_correlation.c \
+ third_party/webrtc/common_audio/signal_processing/division_operations.c \
+ third_party/webrtc/common_audio/signal_processing/dot_product_with_scale.c \
+ third_party/webrtc/common_audio/signal_processing/downsample_fast.c \
+ third_party/webrtc/common_audio/signal_processing/energy.c \
+ third_party/webrtc/common_audio/signal_processing/filter_ar.c \
+ third_party/webrtc/common_audio/signal_processing/filter_ar_fast_q12.c \
+ third_party/webrtc/common_audio/signal_processing/filter_ma_fast_q12.c \
+ third_party/webrtc/common_audio/signal_processing/get_hanning_window.c \
+ third_party/webrtc/common_audio/signal_processing/get_scaling_square.c \
+ third_party/webrtc/common_audio/signal_processing/ilbc_specific_functions.c \
+ third_party/webrtc/common_audio/signal_processing/levinson_durbin.c \
+ third_party/webrtc/common_audio/signal_processing/lpc_to_refl_coef.c \
+ third_party/webrtc/common_audio/signal_processing/min_max_operations.c \
+ third_party/webrtc/common_audio/signal_processing/randomization_functions.c \
+ third_party/webrtc/common_audio/signal_processing/refl_coef_to_lpc.c \
+ third_party/webrtc/common_audio/signal_processing/real_fft.c \
+ third_party/webrtc/common_audio/signal_processing/resample.c \
+ third_party/webrtc/common_audio/signal_processing/resample_48khz.c \
+ third_party/webrtc/common_audio/signal_processing/resample_by_2.c \
+ third_party/webrtc/common_audio/signal_processing/resample_by_2_internal.c \
+ third_party/webrtc/common_audio/signal_processing/resample_fractional.c \
+ third_party/webrtc/common_audio/signal_processing/spl_init.c \
+ third_party/webrtc/common_audio/signal_processing/spl_sqrt.c \
+ third_party/webrtc/common_audio/signal_processing/spl_sqrt_floor.c \
+ third_party/webrtc/common_audio/signal_processing/splitting_filter.c \
+ third_party/webrtc/common_audio/signal_processing/sqrt_of_one_minus_x_squared.c \
+ third_party/webrtc/common_audio/signal_processing/vector_scaling_operations.c \
+ third_party/webrtc/common_audio/vad/vad.cc \
+ third_party/webrtc/common_audio/vad/webrtc_vad.c \
+ third_party/webrtc/common_audio/vad/vad_core.c \
+ third_party/webrtc/common_audio/vad/vad_filterbank.c \
+ third_party/webrtc/common_audio/vad/vad_gmm.c \
+ third_party/webrtc/common_audio/vad/vad_sp.c \
+ third_party/webrtc/common_audio/wav_header.cc \
+ third_party/webrtc/common_audio/wav_file.cc \
+ third_party/webrtc/common_audio/window_generator.cc \
+ third_party/webrtc/common_audio/lapped_transform.cc \
+ third_party/webrtc/common_audio/real_fourier.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/openmax_dl
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/openmax_dl
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_common_audio_common_audio_gyp
+
+# Alias gyp target name.
+.PHONY: common_audio
+common_audio: third_party_webrtc_common_audio_common_audio_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/common_audio/common_audio.target.darwin-x86.mk b/common_audio/common_audio.target.darwin-x86.mk
index 5358eb35..afd55299 100644
--- a/common_audio/common_audio.target.darwin-x86.mk
+++ b/common_audio/common_audio.target.darwin-x86.mk
@@ -24,6 +24,7 @@ LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/common_audio/audio_converter.cc \
third_party/webrtc/common_audio/audio_util.cc \
third_party/webrtc/common_audio/blocker.cc \
third_party/webrtc/common_audio/fir_filter.cc \
@@ -64,13 +65,14 @@ LOCAL_SRC_FILES := \
third_party/webrtc/common_audio/signal_processing/splitting_filter.c \
third_party/webrtc/common_audio/signal_processing/sqrt_of_one_minus_x_squared.c \
third_party/webrtc/common_audio/signal_processing/vector_scaling_operations.c \
+ third_party/webrtc/common_audio/vad/vad.cc \
third_party/webrtc/common_audio/vad/webrtc_vad.c \
third_party/webrtc/common_audio/vad/vad_core.c \
third_party/webrtc/common_audio/vad/vad_filterbank.c \
third_party/webrtc/common_audio/vad/vad_gmm.c \
third_party/webrtc/common_audio/vad/vad_sp.c \
third_party/webrtc/common_audio/wav_header.cc \
- third_party/webrtc/common_audio/wav_writer.cc \
+ third_party/webrtc/common_audio/wav_file.cc \
third_party/webrtc/common_audio/window_generator.cc \
third_party/webrtc/common_audio/lapped_transform.cc \
third_party/webrtc/common_audio/real_fourier.cc
@@ -127,11 +129,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -144,6 +148,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -234,11 +239,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -251,6 +258,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_audio/common_audio.target.darwin-x86_64.mk b/common_audio/common_audio.target.darwin-x86_64.mk
index 1a99a3af..90b4dd05 100644
--- a/common_audio/common_audio.target.darwin-x86_64.mk
+++ b/common_audio/common_audio.target.darwin-x86_64.mk
@@ -24,6 +24,7 @@ LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/common_audio/audio_converter.cc \
third_party/webrtc/common_audio/audio_util.cc \
third_party/webrtc/common_audio/blocker.cc \
third_party/webrtc/common_audio/fir_filter.cc \
@@ -64,13 +65,14 @@ LOCAL_SRC_FILES := \
third_party/webrtc/common_audio/signal_processing/splitting_filter.c \
third_party/webrtc/common_audio/signal_processing/sqrt_of_one_minus_x_squared.c \
third_party/webrtc/common_audio/signal_processing/vector_scaling_operations.c \
+ third_party/webrtc/common_audio/vad/vad.cc \
third_party/webrtc/common_audio/vad/webrtc_vad.c \
third_party/webrtc/common_audio/vad/vad_core.c \
third_party/webrtc/common_audio/vad/vad_filterbank.c \
third_party/webrtc/common_audio/vad/vad_gmm.c \
third_party/webrtc/common_audio/vad/vad_sp.c \
third_party/webrtc/common_audio/wav_header.cc \
- third_party/webrtc/common_audio/wav_writer.cc \
+ third_party/webrtc/common_audio/wav_file.cc \
third_party/webrtc/common_audio/window_generator.cc \
third_party/webrtc/common_audio/lapped_transform.cc \
third_party/webrtc/common_audio/real_fourier.cc
@@ -126,11 +128,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -143,6 +147,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -232,11 +237,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -249,6 +256,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_audio/common_audio.target.linux-arm.mk b/common_audio/common_audio.target.linux-arm.mk
index 4d28e2eb..1ee1df1d 100644
--- a/common_audio/common_audio.target.linux-arm.mk
+++ b/common_audio/common_audio.target.linux-arm.mk
@@ -24,6 +24,7 @@ LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/common_audio/audio_converter.cc \
third_party/webrtc/common_audio/audio_util.cc \
third_party/webrtc/common_audio/blocker.cc \
third_party/webrtc/common_audio/fir_filter.cc \
@@ -61,13 +62,14 @@ LOCAL_SRC_FILES := \
third_party/webrtc/common_audio/signal_processing/splitting_filter.c \
third_party/webrtc/common_audio/signal_processing/sqrt_of_one_minus_x_squared.c \
third_party/webrtc/common_audio/signal_processing/vector_scaling_operations.c \
+ third_party/webrtc/common_audio/vad/vad.cc \
third_party/webrtc/common_audio/vad/webrtc_vad.c \
third_party/webrtc/common_audio/vad/vad_core.c \
third_party/webrtc/common_audio/vad/vad_filterbank.c \
third_party/webrtc/common_audio/vad/vad_gmm.c \
third_party/webrtc/common_audio/vad/vad_sp.c \
third_party/webrtc/common_audio/wav_header.cc \
- third_party/webrtc/common_audio/wav_writer.cc \
+ third_party/webrtc/common_audio/wav_file.cc \
third_party/webrtc/common_audio/window_generator.cc \
third_party/webrtc/common_audio/lapped_transform.cc \
third_party/webrtc/common_audio/real_fourier.cc \
@@ -132,11 +134,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -153,6 +157,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DDL_ARM_NEON_OPTIONAL' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -249,11 +254,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -270,6 +277,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DDL_ARM_NEON_OPTIONAL' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_audio/common_audio.target.linux-arm64.mk b/common_audio/common_audio.target.linux-arm64.mk
index fabeaf16..27d0e13e 100644
--- a/common_audio/common_audio.target.linux-arm64.mk
+++ b/common_audio/common_audio.target.linux-arm64.mk
@@ -24,6 +24,7 @@ LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/common_audio/audio_converter.cc \
third_party/webrtc/common_audio/audio_util.cc \
third_party/webrtc/common_audio/blocker.cc \
third_party/webrtc/common_audio/fir_filter.cc \
@@ -64,13 +65,14 @@ LOCAL_SRC_FILES := \
third_party/webrtc/common_audio/signal_processing/splitting_filter.c \
third_party/webrtc/common_audio/signal_processing/sqrt_of_one_minus_x_squared.c \
third_party/webrtc/common_audio/signal_processing/vector_scaling_operations.c \
+ third_party/webrtc/common_audio/vad/vad.cc \
third_party/webrtc/common_audio/vad/webrtc_vad.c \
third_party/webrtc/common_audio/vad/vad_core.c \
third_party/webrtc/common_audio/vad/vad_filterbank.c \
third_party/webrtc/common_audio/vad/vad_gmm.c \
third_party/webrtc/common_audio/vad/vad_sp.c \
third_party/webrtc/common_audio/wav_header.cc \
- third_party/webrtc/common_audio/wav_writer.cc \
+ third_party/webrtc/common_audio/wav_file.cc \
third_party/webrtc/common_audio/window_generator.cc \
third_party/webrtc/common_audio/lapped_transform.cc \
third_party/webrtc/common_audio/real_fourier.cc
@@ -121,11 +123,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -134,11 +138,13 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DDL_ARM_NEON' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -223,11 +229,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -236,11 +244,13 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DDL_ARM_NEON' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_audio/common_audio.target.linux-mips.mk b/common_audio/common_audio.target.linux-mips.mk
index fe76cba3..c1396e43 100644
--- a/common_audio/common_audio.target.linux-mips.mk
+++ b/common_audio/common_audio.target.linux-mips.mk
@@ -24,6 +24,7 @@ LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/common_audio/audio_converter.cc \
third_party/webrtc/common_audio/audio_util.cc \
third_party/webrtc/common_audio/blocker.cc \
third_party/webrtc/common_audio/fir_filter.cc \
@@ -60,13 +61,14 @@ LOCAL_SRC_FILES := \
third_party/webrtc/common_audio/signal_processing/splitting_filter.c \
third_party/webrtc/common_audio/signal_processing/sqrt_of_one_minus_x_squared.c \
third_party/webrtc/common_audio/signal_processing/vector_scaling_operations.c \
+ third_party/webrtc/common_audio/vad/vad.cc \
third_party/webrtc/common_audio/vad/webrtc_vad.c \
third_party/webrtc/common_audio/vad/vad_core.c \
third_party/webrtc/common_audio/vad/vad_filterbank.c \
third_party/webrtc/common_audio/vad/vad_gmm.c \
third_party/webrtc/common_audio/vad/vad_sp.c \
third_party/webrtc/common_audio/wav_header.cc \
- third_party/webrtc/common_audio/wav_writer.cc \
+ third_party/webrtc/common_audio/wav_file.cc \
third_party/webrtc/common_audio/window_generator.cc \
third_party/webrtc/common_audio/lapped_transform.cc \
third_party/webrtc/common_audio/real_fourier.cc \
@@ -129,11 +131,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -148,6 +152,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -237,11 +242,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -256,6 +263,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_audio/common_audio.target.linux-mips64.mk b/common_audio/common_audio.target.linux-mips64.mk
new file mode 100644
index 00000000..2893a038
--- /dev/null
+++ b/common_audio/common_audio.target.linux-mips64.mk
@@ -0,0 +1,316 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_common_audio_common_audio_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/common_audio/audio_converter.cc \
+ third_party/webrtc/common_audio/audio_util.cc \
+ third_party/webrtc/common_audio/blocker.cc \
+ third_party/webrtc/common_audio/fir_filter.cc \
+ third_party/webrtc/common_audio/resampler/push_resampler.cc \
+ third_party/webrtc/common_audio/resampler/push_sinc_resampler.cc \
+ third_party/webrtc/common_audio/resampler/resampler.cc \
+ third_party/webrtc/common_audio/resampler/sinc_resampler.cc \
+ third_party/webrtc/common_audio/signal_processing/auto_corr_to_refl_coef.c \
+ third_party/webrtc/common_audio/signal_processing/auto_correlation.c \
+ third_party/webrtc/common_audio/signal_processing/complex_fft.c \
+ third_party/webrtc/common_audio/signal_processing/complex_bit_reverse.c \
+ third_party/webrtc/common_audio/signal_processing/copy_set_operations.c \
+ third_party/webrtc/common_audio/signal_processing/cross_correlation.c \
+ third_party/webrtc/common_audio/signal_processing/division_operations.c \
+ third_party/webrtc/common_audio/signal_processing/dot_product_with_scale.c \
+ third_party/webrtc/common_audio/signal_processing/downsample_fast.c \
+ third_party/webrtc/common_audio/signal_processing/energy.c \
+ third_party/webrtc/common_audio/signal_processing/filter_ar.c \
+ third_party/webrtc/common_audio/signal_processing/filter_ar_fast_q12.c \
+ third_party/webrtc/common_audio/signal_processing/filter_ma_fast_q12.c \
+ third_party/webrtc/common_audio/signal_processing/get_hanning_window.c \
+ third_party/webrtc/common_audio/signal_processing/get_scaling_square.c \
+ third_party/webrtc/common_audio/signal_processing/ilbc_specific_functions.c \
+ third_party/webrtc/common_audio/signal_processing/levinson_durbin.c \
+ third_party/webrtc/common_audio/signal_processing/lpc_to_refl_coef.c \
+ third_party/webrtc/common_audio/signal_processing/min_max_operations.c \
+ third_party/webrtc/common_audio/signal_processing/randomization_functions.c \
+ third_party/webrtc/common_audio/signal_processing/refl_coef_to_lpc.c \
+ third_party/webrtc/common_audio/signal_processing/real_fft.c \
+ third_party/webrtc/common_audio/signal_processing/resample.c \
+ third_party/webrtc/common_audio/signal_processing/resample_48khz.c \
+ third_party/webrtc/common_audio/signal_processing/resample_by_2.c \
+ third_party/webrtc/common_audio/signal_processing/resample_by_2_internal.c \
+ third_party/webrtc/common_audio/signal_processing/resample_fractional.c \
+ third_party/webrtc/common_audio/signal_processing/spl_init.c \
+ third_party/webrtc/common_audio/signal_processing/spl_sqrt.c \
+ third_party/webrtc/common_audio/signal_processing/spl_sqrt_floor.c \
+ third_party/webrtc/common_audio/signal_processing/splitting_filter.c \
+ third_party/webrtc/common_audio/signal_processing/sqrt_of_one_minus_x_squared.c \
+ third_party/webrtc/common_audio/signal_processing/vector_scaling_operations.c \
+ third_party/webrtc/common_audio/vad/vad.cc \
+ third_party/webrtc/common_audio/vad/webrtc_vad.c \
+ third_party/webrtc/common_audio/vad/vad_core.c \
+ third_party/webrtc/common_audio/vad/vad_filterbank.c \
+ third_party/webrtc/common_audio/vad/vad_gmm.c \
+ third_party/webrtc/common_audio/vad/vad_sp.c \
+ third_party/webrtc/common_audio/wav_header.cc \
+ third_party/webrtc/common_audio/wav_file.cc \
+ third_party/webrtc/common_audio/window_generator.cc \
+ third_party/webrtc/common_audio/lapped_transform.cc \
+ third_party/webrtc/common_audio/real_fourier.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/openmax_dl
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/openmax_dl
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_common_audio_common_audio_gyp
+
+# Alias gyp target name.
+.PHONY: common_audio
+common_audio: third_party_webrtc_common_audio_common_audio_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/common_audio/common_audio.target.linux-x86.mk b/common_audio/common_audio.target.linux-x86.mk
index 5358eb35..afd55299 100644
--- a/common_audio/common_audio.target.linux-x86.mk
+++ b/common_audio/common_audio.target.linux-x86.mk
@@ -24,6 +24,7 @@ LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/common_audio/audio_converter.cc \
third_party/webrtc/common_audio/audio_util.cc \
third_party/webrtc/common_audio/blocker.cc \
third_party/webrtc/common_audio/fir_filter.cc \
@@ -64,13 +65,14 @@ LOCAL_SRC_FILES := \
third_party/webrtc/common_audio/signal_processing/splitting_filter.c \
third_party/webrtc/common_audio/signal_processing/sqrt_of_one_minus_x_squared.c \
third_party/webrtc/common_audio/signal_processing/vector_scaling_operations.c \
+ third_party/webrtc/common_audio/vad/vad.cc \
third_party/webrtc/common_audio/vad/webrtc_vad.c \
third_party/webrtc/common_audio/vad/vad_core.c \
third_party/webrtc/common_audio/vad/vad_filterbank.c \
third_party/webrtc/common_audio/vad/vad_gmm.c \
third_party/webrtc/common_audio/vad/vad_sp.c \
third_party/webrtc/common_audio/wav_header.cc \
- third_party/webrtc/common_audio/wav_writer.cc \
+ third_party/webrtc/common_audio/wav_file.cc \
third_party/webrtc/common_audio/window_generator.cc \
third_party/webrtc/common_audio/lapped_transform.cc \
third_party/webrtc/common_audio/real_fourier.cc
@@ -127,11 +129,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -144,6 +148,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -234,11 +239,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -251,6 +258,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_audio/common_audio.target.linux-x86_64.mk b/common_audio/common_audio.target.linux-x86_64.mk
index 1a99a3af..90b4dd05 100644
--- a/common_audio/common_audio.target.linux-x86_64.mk
+++ b/common_audio/common_audio.target.linux-x86_64.mk
@@ -24,6 +24,7 @@ LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/common_audio/audio_converter.cc \
third_party/webrtc/common_audio/audio_util.cc \
third_party/webrtc/common_audio/blocker.cc \
third_party/webrtc/common_audio/fir_filter.cc \
@@ -64,13 +65,14 @@ LOCAL_SRC_FILES := \
third_party/webrtc/common_audio/signal_processing/splitting_filter.c \
third_party/webrtc/common_audio/signal_processing/sqrt_of_one_minus_x_squared.c \
third_party/webrtc/common_audio/signal_processing/vector_scaling_operations.c \
+ third_party/webrtc/common_audio/vad/vad.cc \
third_party/webrtc/common_audio/vad/webrtc_vad.c \
third_party/webrtc/common_audio/vad/vad_core.c \
third_party/webrtc/common_audio/vad/vad_filterbank.c \
third_party/webrtc/common_audio/vad/vad_gmm.c \
third_party/webrtc/common_audio/vad/vad_sp.c \
third_party/webrtc/common_audio/wav_header.cc \
- third_party/webrtc/common_audio/wav_writer.cc \
+ third_party/webrtc/common_audio/wav_file.cc \
third_party/webrtc/common_audio/window_generator.cc \
third_party/webrtc/common_audio/lapped_transform.cc \
third_party/webrtc/common_audio/real_fourier.cc
@@ -126,11 +128,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -143,6 +147,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -232,11 +237,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -249,6 +256,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_audio/common_audio_neon.target.darwin-arm.mk b/common_audio/common_audio_neon.target.darwin-arm.mk
index f8ab09f8..f00da325 100644
--- a/common_audio/common_audio_neon.target.darwin-arm.mk
+++ b/common_audio/common_audio_neon.target.darwin-arm.mk
@@ -90,11 +90,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -110,6 +112,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -204,11 +207,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -224,6 +229,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_audio/common_audio_neon.target.linux-arm.mk b/common_audio/common_audio_neon.target.linux-arm.mk
index f8ab09f8..f00da325 100644
--- a/common_audio/common_audio_neon.target.linux-arm.mk
+++ b/common_audio/common_audio_neon.target.linux-arm.mk
@@ -90,11 +90,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -110,6 +112,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -204,11 +207,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -224,6 +229,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_audio/common_audio_sse2.target.darwin-x86.mk b/common_audio/common_audio_sse2.target.darwin-x86.mk
index 6c6158c3..70af2b19 100644
--- a/common_audio/common_audio_sse2.target.darwin-x86.mk
+++ b/common_audio/common_audio_sse2.target.darwin-x86.mk
@@ -80,11 +80,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -97,6 +99,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -184,11 +187,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -201,6 +206,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_audio/common_audio_sse2.target.darwin-x86_64.mk b/common_audio/common_audio_sse2.target.darwin-x86_64.mk
index 552a99fc..7f82d7ec 100644
--- a/common_audio/common_audio_sse2.target.darwin-x86_64.mk
+++ b/common_audio/common_audio_sse2.target.darwin-x86_64.mk
@@ -79,11 +79,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -96,6 +98,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -182,11 +185,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -199,6 +204,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_audio/common_audio_sse2.target.linux-x86.mk b/common_audio/common_audio_sse2.target.linux-x86.mk
index 6c6158c3..70af2b19 100644
--- a/common_audio/common_audio_sse2.target.linux-x86.mk
+++ b/common_audio/common_audio_sse2.target.linux-x86.mk
@@ -80,11 +80,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -97,6 +99,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -184,11 +187,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -201,6 +206,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_audio/common_audio_sse2.target.linux-x86_64.mk b/common_audio/common_audio_sse2.target.linux-x86_64.mk
index 552a99fc..7f82d7ec 100644
--- a/common_audio/common_audio_sse2.target.linux-x86_64.mk
+++ b/common_audio/common_audio_sse2.target.linux-x86_64.mk
@@ -79,11 +79,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -96,6 +98,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -182,11 +185,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -199,6 +204,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_audio/common_audio_unittests.isolate b/common_audio/common_audio_unittests.isolate
index cc5e6ab4..80eb0fc4 100644
--- a/common_audio/common_audio_unittests.isolate
+++ b/common_audio/common_audio_unittests.isolate
@@ -9,7 +9,7 @@
'conditions': [
['OS=="android"', {
'variables': {
- 'isolate_dependency_untracked': [
+ 'files': [
'<(DEPTH)/data/',
'<(DEPTH)/resources/',
],
@@ -21,13 +21,10 @@
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/common_audio_unittests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/common_audio_unittests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_untracked': [
- '<(DEPTH)/tools/swarming_client/',
- ],
},
}],
],
diff --git a/common_audio/include/audio_util.h b/common_audio/include/audio_util.h
index 0ce034be..767b21c5 100644
--- a/common_audio/include/audio_util.h
+++ b/common_audio/include/audio_util.h
@@ -20,18 +20,11 @@ namespace webrtc {
typedef std::numeric_limits<int16_t> limits_int16;
-static inline int16_t RoundToInt16(float v) {
- const float kMaxRound = limits_int16::max() - 0.5f;
- const float kMinRound = limits_int16::min() + 0.5f;
- if (v > 0)
- return v >= kMaxRound ? limits_int16::max() :
- static_cast<int16_t>(v + 0.5f);
- return v <= kMinRound ? limits_int16::min() :
- static_cast<int16_t>(v - 0.5f);
-}
-
-// Scale (from [-1, 1]) and round to full-range int16 with clamping.
-static inline int16_t ScaleAndRoundToInt16(float v) {
+// The conversion functions use the following naming convention:
+// S16: int16_t [-32768, 32767]
+// Float: float [-1.0, 1.0]
+// FloatS16: float [-32768.0, 32767.0]
+static inline int16_t FloatToS16(float v) {
if (v > 0)
return v >= 1 ? limits_int16::max() :
static_cast<int16_t>(v * limits_int16::max() + 0.5f);
@@ -39,22 +32,37 @@ static inline int16_t ScaleAndRoundToInt16(float v) {
static_cast<int16_t>(-v * limits_int16::min() - 0.5f);
}
-// Scale to float [-1, 1].
-static inline float ScaleToFloat(int16_t v) {
- const float kMaxInt16Inverse = 1.f / limits_int16::max();
- const float kMinInt16Inverse = 1.f / limits_int16::min();
+static inline float S16ToFloat(int16_t v) {
+ static const float kMaxInt16Inverse = 1.f / limits_int16::max();
+ static const float kMinInt16Inverse = 1.f / limits_int16::min();
return v * (v > 0 ? kMaxInt16Inverse : -kMinInt16Inverse);
}
-// Round |size| elements of |src| to int16 with clamping and write to |dest|.
-void RoundToInt16(const float* src, size_t size, int16_t* dest);
+static inline int16_t FloatS16ToS16(float v) {
+ static const float kMaxRound = limits_int16::max() - 0.5f;
+ static const float kMinRound = limits_int16::min() + 0.5f;
+ if (v > 0)
+ return v >= kMaxRound ? limits_int16::max() :
+ static_cast<int16_t>(v + 0.5f);
+ return v <= kMinRound ? limits_int16::min() :
+ static_cast<int16_t>(v - 0.5f);
+}
-// Scale (from [-1, 1]) and round |size| elements of |src| to full-range int16
-// with clamping and write to |dest|.
-void ScaleAndRoundToInt16(const float* src, size_t size, int16_t* dest);
+static inline float FloatToFloatS16(float v) {
+ return v * (v > 0 ? limits_int16::max() : -limits_int16::min());
+}
+
+static inline float FloatS16ToFloat(float v) {
+ static const float kMaxInt16Inverse = 1.f / limits_int16::max();
+ static const float kMinInt16Inverse = 1.f / limits_int16::min();
+ return v * (v > 0 ? kMaxInt16Inverse : -kMinInt16Inverse);
+}
-// Scale |size| elements of |src| to float [-1, 1] and write to |dest|.
-void ScaleToFloat(const int16_t* src, size_t size, float* dest);
+void FloatToS16(const float* src, size_t size, int16_t* dest);
+void S16ToFloat(const int16_t* src, size_t size, float* dest);
+void FloatS16ToS16(const float* src, size_t size, int16_t* dest);
+void FloatToFloatS16(const float* src, size_t size, float* dest);
+void FloatS16ToFloat(const float* src, size_t size, float* dest);
// Deinterleave audio from |interleaved| to the channel buffers pointed to
// by |deinterleaved|. There must be sufficient space allocated in the
diff --git a/common_audio/resampler/push_sinc_resampler.cc b/common_audio/resampler/push_sinc_resampler.cc
index 02755590..49e2e12e 100644
--- a/common_audio/resampler/push_sinc_resampler.cc
+++ b/common_audio/resampler/push_sinc_resampler.cc
@@ -40,7 +40,7 @@ int PushSincResampler::Resample(const int16_t* source,
source_ptr_int_ = source;
// Pass NULL as the float source to have Run() read from the int16 source.
Resample(NULL, source_length, float_buffer_.get(), destination_frames_);
- RoundToInt16(float_buffer_.get(), destination_frames_, destination);
+ FloatS16ToS16(float_buffer_.get(), destination_frames_, destination);
source_ptr_int_ = NULL;
return destination_frames_;
}
diff --git a/common_audio/resampler/push_sinc_resampler_unittest.cc b/common_audio/resampler/push_sinc_resampler_unittest.cc
index 1ca4fdf9..90ac0cf0 100644
--- a/common_audio/resampler/push_sinc_resampler_unittest.cc
+++ b/common_audio/resampler/push_sinc_resampler_unittest.cc
@@ -160,16 +160,15 @@ void PushSincResamplerTest::ResampleTest(bool int_format) {
resampler_source.Run(input_samples, source.get());
if (int_format) {
for (int i = 0; i < kNumBlocks; ++i) {
- ScaleAndRoundToInt16(
- &source[i * input_block_size], input_block_size, source_int.get());
+ FloatToS16(&source[i * input_block_size], input_block_size,
+ source_int.get());
EXPECT_EQ(output_block_size,
resampler.Resample(source_int.get(),
input_block_size,
destination_int.get(),
output_block_size));
- ScaleToFloat(destination_int.get(),
- output_block_size,
- &resampled_destination[i * output_block_size]);
+ S16ToFloat(destination_int.get(), output_block_size,
+ &resampled_destination[i * output_block_size]);
}
} else {
for (int i = 0; i < kNumBlocks; ++i) {
diff --git a/common_audio/signal_processing/complex_fft.c b/common_audio/signal_processing/complex_fft.c
index c8230647..74b4258a 100644
--- a/common_audio/signal_processing/complex_fft.c
+++ b/common_audio/signal_processing/complex_fft.c
@@ -65,18 +65,16 @@ int WebRtcSpl_ComplexFFT(int16_t frfi[], int stages, int mode)
{
j = i + l;
- tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j])
- - WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1])), 15);
+ tr32 = (wr * frfi[2 * j] - wi * frfi[2 * j + 1]) >> 15;
- ti32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1])
- + WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j])), 15);
+ ti32 = (wr * frfi[2 * j + 1] + wi * frfi[2 * j]) >> 15;
qr32 = (int32_t)frfi[2 * i];
qi32 = (int32_t)frfi[2 * i + 1];
- frfi[2 * j] = (int16_t)WEBRTC_SPL_RSHIFT_W32(qr32 - tr32, 1);
- frfi[2 * j + 1] = (int16_t)WEBRTC_SPL_RSHIFT_W32(qi32 - ti32, 1);
- frfi[2 * i] = (int16_t)WEBRTC_SPL_RSHIFT_W32(qr32 + tr32, 1);
- frfi[2 * i + 1] = (int16_t)WEBRTC_SPL_RSHIFT_W32(qi32 + ti32, 1);
+ frfi[2 * j] = (int16_t)((qr32 - tr32) >> 1);
+ frfi[2 * j + 1] = (int16_t)((qi32 - ti32) >> 1);
+ frfi[2 * i] = (int16_t)((qr32 + tr32) >> 1);
+ frfi[2 * i + 1] = (int16_t)((qi32 + ti32) >> 1);
}
}
@@ -135,20 +133,20 @@ int WebRtcSpl_ComplexFFT(int16_t frfi[], int stages, int mode)
+ WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j]) + CFFTRND;
#endif
- tr32 = WEBRTC_SPL_RSHIFT_W32(tr32, 15 - CFFTSFT);
- ti32 = WEBRTC_SPL_RSHIFT_W32(ti32, 15 - CFFTSFT);
+ tr32 >>= 15 - CFFTSFT;
+ ti32 >>= 15 - CFFTSFT;
qr32 = ((int32_t)frfi[2 * i]) << CFFTSFT;
qi32 = ((int32_t)frfi[2 * i + 1]) << CFFTSFT;
- frfi[2 * j] = (int16_t)WEBRTC_SPL_RSHIFT_W32(
- (qr32 - tr32 + CFFTRND2), 1 + CFFTSFT);
- frfi[2 * j + 1] = (int16_t)WEBRTC_SPL_RSHIFT_W32(
- (qi32 - ti32 + CFFTRND2), 1 + CFFTSFT);
- frfi[2 * i] = (int16_t)WEBRTC_SPL_RSHIFT_W32(
- (qr32 + tr32 + CFFTRND2), 1 + CFFTSFT);
- frfi[2 * i + 1] = (int16_t)WEBRTC_SPL_RSHIFT_W32(
- (qi32 + ti32 + CFFTRND2), 1 + CFFTSFT);
+ frfi[2 * j] = (int16_t)(
+ (qr32 - tr32 + CFFTRND2) >> (1 + CFFTSFT));
+ frfi[2 * j + 1] = (int16_t)(
+ (qi32 - ti32 + CFFTRND2) >> (1 + CFFTSFT));
+ frfi[2 * i] = (int16_t)(
+ (qr32 + tr32 + CFFTRND2) >> (1 + CFFTSFT));
+ frfi[2 * i + 1] = (int16_t)(
+ (qi32 + ti32 + CFFTRND2) >> (1 + CFFTSFT));
}
}
@@ -219,19 +217,16 @@ int WebRtcSpl_ComplexIFFT(int16_t frfi[], int stages, int mode)
{
j = i + l;
- tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j], 0)
- - WEBRTC_SPL_MUL_16_16_RSFT(wi, frfi[2 * j + 1], 0)), 15);
+ tr32 = (wr * frfi[2 * j] - wi * frfi[2 * j + 1]) >> 15;
- ti32 = WEBRTC_SPL_RSHIFT_W32(
- (WEBRTC_SPL_MUL_16_16_RSFT(wr, frfi[2 * j + 1], 0)
- + WEBRTC_SPL_MUL_16_16_RSFT(wi,frfi[2*j],0)), 15);
+ ti32 = (wr * frfi[2 * j + 1] + wi * frfi[2 * j]) >> 15;
qr32 = (int32_t)frfi[2 * i];
qi32 = (int32_t)frfi[2 * i + 1];
- frfi[2 * j] = (int16_t)WEBRTC_SPL_RSHIFT_W32(qr32 - tr32, shift);
- frfi[2 * j + 1] = (int16_t)WEBRTC_SPL_RSHIFT_W32(qi32 - ti32, shift);
- frfi[2 * i] = (int16_t)WEBRTC_SPL_RSHIFT_W32(qr32 + tr32, shift);
- frfi[2 * i + 1] = (int16_t)WEBRTC_SPL_RSHIFT_W32(qi32 + ti32, shift);
+ frfi[2 * j] = (int16_t)((qr32 - tr32) >> shift);
+ frfi[2 * j + 1] = (int16_t)((qi32 - ti32) >> shift);
+ frfi[2 * i] = (int16_t)((qr32 + tr32) >> shift);
+ frfi[2 * i + 1] = (int16_t)((qi32 + ti32) >> shift);
}
}
} else
@@ -281,20 +276,20 @@ int WebRtcSpl_ComplexIFFT(int16_t frfi[], int stages, int mode)
ti32 = WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1])
+ WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j]) + CIFFTRND;
#endif
- tr32 = WEBRTC_SPL_RSHIFT_W32(tr32, 15 - CIFFTSFT);
- ti32 = WEBRTC_SPL_RSHIFT_W32(ti32, 15 - CIFFTSFT);
+ tr32 >>= 15 - CIFFTSFT;
+ ti32 >>= 15 - CIFFTSFT;
qr32 = ((int32_t)frfi[2 * i]) << CIFFTSFT;
qi32 = ((int32_t)frfi[2 * i + 1]) << CIFFTSFT;
- frfi[2 * j] = (int16_t)WEBRTC_SPL_RSHIFT_W32((qr32 - tr32+round2),
- shift+CIFFTSFT);
- frfi[2 * j + 1] = (int16_t)WEBRTC_SPL_RSHIFT_W32(
- (qi32 - ti32 + round2), shift + CIFFTSFT);
- frfi[2 * i] = (int16_t)WEBRTC_SPL_RSHIFT_W32((qr32 + tr32 + round2),
- shift + CIFFTSFT);
- frfi[2 * i + 1] = (int16_t)WEBRTC_SPL_RSHIFT_W32(
- (qi32 + ti32 + round2), shift + CIFFTSFT);
+ frfi[2 * j] = (int16_t)(
+ (qr32 - tr32 + round2) >> (shift + CIFFTSFT));
+ frfi[2 * j + 1] = (int16_t)(
+ (qi32 - ti32 + round2) >> (shift + CIFFTSFT));
+ frfi[2 * i] = (int16_t)(
+ (qr32 + tr32 + round2) >> (shift + CIFFTSFT));
+ frfi[2 * i + 1] = (int16_t)(
+ (qi32 + ti32 + round2) >> (shift + CIFFTSFT));
}
}
diff --git a/common_audio/signal_processing/division_operations.c b/common_audio/signal_processing/division_operations.c
index e9554f44..6aeb0fb2 100644
--- a/common_audio/signal_processing/division_operations.c
+++ b/common_audio/signal_processing/division_operations.c
@@ -113,23 +113,20 @@ int32_t WebRtcSpl_DivW32HiLow(int32_t num, int16_t den_hi, int16_t den_low)
tmpW32 = (int32_t)0x7fffffffL - tmpW32; // result in Q30 (tmpW32 = 2.0-(den*approx))
// Store tmpW32 in hi and low format
- tmp_hi = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16);
- tmp_low = (int16_t)WEBRTC_SPL_RSHIFT_W32((tmpW32
- - WEBRTC_SPL_LSHIFT_W32((int32_t)tmp_hi, 16)), 1);
+ tmp_hi = (int16_t)(tmpW32 >> 16);
+ tmp_low = (int16_t)((tmpW32 - ((int32_t)tmp_hi << 16)) >> 1);
// tmpW32 = 1/den in Q29
tmpW32 = ((WEBRTC_SPL_MUL_16_16(tmp_hi, approx) + (WEBRTC_SPL_MUL_16_16(tmp_low, approx)
>> 15)) << 1);
// 1/den in hi and low format
- tmp_hi = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmpW32, 16);
- tmp_low = (int16_t)WEBRTC_SPL_RSHIFT_W32((tmpW32
- - WEBRTC_SPL_LSHIFT_W32((int32_t)tmp_hi, 16)), 1);
+ tmp_hi = (int16_t)(tmpW32 >> 16);
+ tmp_low = (int16_t)((tmpW32 - ((int32_t)tmp_hi << 16)) >> 1);
// Store num in hi and low format
- num_hi = (int16_t)WEBRTC_SPL_RSHIFT_W32(num, 16);
- num_low = (int16_t)WEBRTC_SPL_RSHIFT_W32((num
- - WEBRTC_SPL_LSHIFT_W32((int32_t)num_hi, 16)), 1);
+ num_hi = (int16_t)(num >> 16);
+ num_low = (int16_t)((num - ((int32_t)num_hi << 16)) >> 1);
// num * (1/den) by 32 bit multiplication (result in Q28)
diff --git a/common_audio/signal_processing/include/signal_processing_library.h b/common_audio/signal_processing/include/signal_processing_library.h
index e3a29ae5..2bdfc23c 100644
--- a/common_audio/signal_processing/include/signal_processing_library.h
+++ b/common_audio/signal_processing/include/signal_processing_library.h
@@ -40,8 +40,6 @@
((int32_t) ((int32_t)(a) * (int32_t)(b)))
#define WEBRTC_SPL_UMUL(a, b) \
((uint32_t) ((uint32_t)(a) * (uint32_t)(b)))
-#define WEBRTC_SPL_UMUL_16_16(a, b) \
- ((uint32_t) (uint16_t)(a) * (uint16_t)(b))
#define WEBRTC_SPL_UMUL_32_16(a, b) \
((uint32_t) ((uint32_t)(a) * (uint16_t)(b)))
#define WEBRTC_SPL_MUL_16_U16(a, b) \
@@ -89,7 +87,6 @@
// Shifting with negative numbers not allowed
// We cannot do casting here due to signed/unsigned problem
-#define WEBRTC_SPL_RSHIFT_W32(x, c) ((x) >> (c))
#define WEBRTC_SPL_LSHIFT_W32(x, c) ((x) << (c))
#define WEBRTC_SPL_RSHIFT_U32(x, c) ((uint32_t)(x) >> (c))
diff --git a/common_audio/signal_processing/levinson_durbin.c b/common_audio/signal_processing/levinson_durbin.c
index 5c5d2246..29f2398d 100644
--- a/common_audio/signal_processing/levinson_durbin.c
+++ b/common_audio/signal_processing/levinson_durbin.c
@@ -45,9 +45,8 @@ int16_t WebRtcSpl_LevinsonDurbin(int32_t *R, int16_t *A, int16_t *K,
{
temp1W32 = WEBRTC_SPL_LSHIFT_W32(R[i], norm);
// Put R in hi and low format
- R_hi[i] = (int16_t)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
- R_low[i] = (int16_t)WEBRTC_SPL_RSHIFT_W32((temp1W32
- - WEBRTC_SPL_LSHIFT_W32((int32_t)R_hi[i], 16)), 1);
+ R_hi[i] = (int16_t)(temp1W32 >> 16);
+ R_low[i] = (int16_t)((temp1W32 - ((int32_t)R_hi[i] << 16)) >> 1);
}
// K = A[1] = -R[1] / R[0]
@@ -63,19 +62,17 @@ int16_t WebRtcSpl_LevinsonDurbin(int32_t *R, int16_t *A, int16_t *K,
}
// Put K in hi and low format
- K_hi = (int16_t)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
- K_low = (int16_t)WEBRTC_SPL_RSHIFT_W32((temp1W32
- - WEBRTC_SPL_LSHIFT_W32((int32_t)K_hi, 16)), 1);
+ K_hi = (int16_t)(temp1W32 >> 16);
+ K_low = (int16_t)((temp1W32 - ((int32_t)K_hi << 16)) >> 1);
// Store first reflection coefficient
K[0] = K_hi;
- temp1W32 = WEBRTC_SPL_RSHIFT_W32(temp1W32, 4); // A[1] in Q27
+ temp1W32 >>= 4; // A[1] in Q27.
// Put A[1] in hi and low format
- A_hi[1] = (int16_t)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
- A_low[1] = (int16_t)WEBRTC_SPL_RSHIFT_W32((temp1W32
- - WEBRTC_SPL_LSHIFT_W32((int32_t)A_hi[1], 16)), 1);
+ A_hi[1] = (int16_t)(temp1W32 >> 16);
+ A_low[1] = (int16_t)((temp1W32 - ((int32_t)A_hi[1] << 16)) >> 1);
// Alpha = R[0] * (1-K^2)
@@ -86,9 +83,8 @@ int16_t WebRtcSpl_LevinsonDurbin(int32_t *R, int16_t *A, int16_t *K,
temp1W32 = (int32_t)0x7fffffffL - temp1W32; // temp1W32 = (1 - K[0]*K[0]) in Q31
// Store temp1W32 = 1 - K[0]*K[0] on hi and low format
- tmp_hi = (int16_t)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
- tmp_low = (int16_t)WEBRTC_SPL_RSHIFT_W32((temp1W32
- - WEBRTC_SPL_LSHIFT_W32((int32_t)tmp_hi, 16)), 1);
+ tmp_hi = (int16_t)(temp1W32 >> 16);
+ tmp_low = (int16_t)((temp1W32 - ((int32_t)tmp_hi << 16)) >> 1);
// Calculate Alpha in Q31
temp1W32 = ((WEBRTC_SPL_MUL_16_16(R_hi[0], tmp_hi)
@@ -99,9 +95,8 @@ int16_t WebRtcSpl_LevinsonDurbin(int32_t *R, int16_t *A, int16_t *K,
Alpha_exp = WebRtcSpl_NormW32(temp1W32);
temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, Alpha_exp);
- Alpha_hi = (int16_t)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
- Alpha_low = (int16_t)WEBRTC_SPL_RSHIFT_W32((temp1W32
- - WEBRTC_SPL_LSHIFT_W32((int32_t)Alpha_hi, 16)), 1);
+ Alpha_hi = (int16_t)(temp1W32 >> 16);
+ Alpha_low = (int16_t)((temp1W32 - ((int32_t)Alpha_hi << 16)) >> 1);
// Perform the iterative calculations in the Levinson-Durbin algorithm
@@ -155,9 +150,8 @@ int16_t WebRtcSpl_LevinsonDurbin(int32_t *R, int16_t *A, int16_t *K,
}
// Put K on hi and low format
- K_hi = (int16_t)WEBRTC_SPL_RSHIFT_W32(temp3W32, 16);
- K_low = (int16_t)WEBRTC_SPL_RSHIFT_W32((temp3W32
- - WEBRTC_SPL_LSHIFT_W32((int32_t)K_hi, 16)), 1);
+ K_hi = (int16_t)(temp3W32 >> 16);
+ K_low = (int16_t)((temp3W32 - ((int32_t)K_hi << 16)) >> 1);
// Store Reflection coefficient in Q15
K[i - 1] = K_hi;
@@ -188,18 +182,18 @@ int16_t WebRtcSpl_LevinsonDurbin(int32_t *R, int16_t *A, int16_t *K,
+ (WEBRTC_SPL_MUL_16_16(K_low, A_hi[i-j]) >> 15)) << 1);
// Put Anew in hi and low format
- A_upd_hi[j] = (int16_t)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
- A_upd_low[j] = (int16_t)WEBRTC_SPL_RSHIFT_W32((temp1W32
- - WEBRTC_SPL_LSHIFT_W32((int32_t)A_upd_hi[j], 16)), 1);
+ A_upd_hi[j] = (int16_t)(temp1W32 >> 16);
+ A_upd_low[j] = (int16_t)(
+ (temp1W32 - ((int32_t)A_upd_hi[j] << 16)) >> 1);
}
// temp3W32 = K in Q27 (Convert from Q31 to Q27)
- temp3W32 = WEBRTC_SPL_RSHIFT_W32(temp3W32, 4);
+ temp3W32 >>= 4;
// Store Anew in hi and low format
- A_upd_hi[i] = (int16_t)WEBRTC_SPL_RSHIFT_W32(temp3W32, 16);
- A_upd_low[i] = (int16_t)WEBRTC_SPL_RSHIFT_W32((temp3W32
- - WEBRTC_SPL_LSHIFT_W32((int32_t)A_upd_hi[i], 16)), 1);
+ A_upd_hi[i] = (int16_t)(temp3W32 >> 16);
+ A_upd_low[i] = (int16_t)(
+ (temp3W32 - ((int32_t)A_upd_hi[i] << 16)) >> 1);
// Alpha = Alpha * (1-K^2)
@@ -210,9 +204,8 @@ int16_t WebRtcSpl_LevinsonDurbin(int32_t *R, int16_t *A, int16_t *K,
temp1W32 = (int32_t)0x7fffffffL - temp1W32; // 1 - K*K in Q31
// Convert 1- K^2 in hi and low format
- tmp_hi = (int16_t)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
- tmp_low = (int16_t)WEBRTC_SPL_RSHIFT_W32((temp1W32
- - WEBRTC_SPL_LSHIFT_W32((int32_t)tmp_hi, 16)), 1);
+ tmp_hi = (int16_t)(temp1W32 >> 16);
+ tmp_low = (int16_t)((temp1W32 - ((int32_t)tmp_hi << 16)) >> 1);
// Calculate Alpha = Alpha * (1-K^2) in Q31
temp1W32 = ((WEBRTC_SPL_MUL_16_16(Alpha_hi, tmp_hi)
@@ -224,9 +217,8 @@ int16_t WebRtcSpl_LevinsonDurbin(int32_t *R, int16_t *A, int16_t *K,
norm = WebRtcSpl_NormW32(temp1W32);
temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, norm);
- Alpha_hi = (int16_t)WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
- Alpha_low = (int16_t)WEBRTC_SPL_RSHIFT_W32((temp1W32
- - WEBRTC_SPL_LSHIFT_W32((int32_t)Alpha_hi, 16)), 1);
+ Alpha_hi = (int16_t)(temp1W32 >> 16);
+ Alpha_low = (int16_t)((temp1W32 - ((int32_t)Alpha_hi << 16)) >> 1);
// Update the total normalization of Alpha
Alpha_exp = Alpha_exp + norm;
@@ -253,7 +245,7 @@ int16_t WebRtcSpl_LevinsonDurbin(int32_t *R, int16_t *A, int16_t *K,
temp1W32 = WEBRTC_SPL_LSHIFT_W32((int32_t)A_hi[i], 16)
+ WEBRTC_SPL_LSHIFT_W32((int32_t)A_low[i], 1);
// Round and store upper word
- A[i] = (int16_t)WEBRTC_SPL_RSHIFT_W32((temp1W32<<1)+(int32_t)32768, 16);
+ A[i] = (int16_t)(((temp1W32 << 1) + 32768) >> 16);
}
return 1; // Stable filters
}
diff --git a/common_audio/signal_processing/lpc_to_refl_coef.c b/common_audio/signal_processing/lpc_to_refl_coef.c
index b1a34d48..5fb4d859 100644
--- a/common_audio/signal_processing/lpc_to_refl_coef.c
+++ b/common_audio/signal_processing/lpc_to_refl_coef.c
@@ -32,7 +32,7 @@ void WebRtcSpl_LpcToReflCoef(int16_t* a16, int use_order, int16_t* k16)
// (1 - k^2) in Q30
tmp_inv_denom32 = ((int32_t)1073741823) - WEBRTC_SPL_MUL_16_16(k16[m], k16[m]);
// (1 - k^2) in Q15
- tmp_inv_denom16 = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp_inv_denom32, 15);
+ tmp_inv_denom16 = (int16_t)(tmp_inv_denom32 >> 15);
for (k = 1; k <= m; k++)
{
@@ -47,7 +47,7 @@ void WebRtcSpl_LpcToReflCoef(int16_t* a16, int use_order, int16_t* k16)
for (k = 1; k < m; k++)
{
- a16[k] = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp32[k], 1); //Q13>>1 => Q12
+ a16[k] = (int16_t)(tmp32[k] >> 1); // Q13>>1 => Q12
}
tmp32[m] = WEBRTC_SPL_SAT(8191, tmp32[m], -8191);
diff --git a/common_audio/signal_processing/min_max_operations_neon.S b/common_audio/signal_processing/min_max_operations_neon.S
index c84307f5..f427e681 100644
--- a/common_audio/signal_processing/min_max_operations_neon.S
+++ b/common_audio/signal_processing/min_max_operations_neon.S
@@ -209,7 +209,7 @@ DEFINE_FUNCTION WebRtcSpl_MinValueW16Neon
cmp r1, #0
ble END_MIN_VALUE_W16
- vmov.i16 q12, #0x7FFF
+ vdup.16 q12, r2
cmp r1, #8
blt LOOP_MIN_VALUE_W16
diff --git a/common_audio/signal_processing/signal_processing_unittest.cc b/common_audio/signal_processing/signal_processing_unittest.cc
index 3d9f6054..611d2bfa 100644
--- a/common_audio/signal_processing/signal_processing_unittest.cc
+++ b/common_audio/signal_processing/signal_processing_unittest.cc
@@ -41,7 +41,6 @@ TEST_F(SplTest, MacroTest) {
EXPECT_EQ(-2147483645, WEBRTC_SPL_MUL(a, b));
EXPECT_EQ(2147483651u, WEBRTC_SPL_UMUL(a, b));
b = WEBRTC_SPL_WORD16_MAX >> 1;
- EXPECT_EQ(1073627139u, WEBRTC_SPL_UMUL_16_16(a, b));
EXPECT_EQ(4294918147u, WEBRTC_SPL_UMUL_32_16(a, b));
EXPECT_EQ(-49149, WEBRTC_SPL_MUL_16_U16(a, b));
@@ -66,7 +65,6 @@ TEST_F(SplTest, MacroTest) {
// Shifting with negative numbers not allowed
// We cannot do casting here due to signed/unsigned problem
- EXPECT_EQ(8191, WEBRTC_SPL_RSHIFT_W32(a, 1));
EXPECT_EQ(32766, WEBRTC_SPL_LSHIFT_W32(a, 1));
EXPECT_EQ(8191u, WEBRTC_SPL_RSHIFT_U32(a, 1));
diff --git a/common_audio/signal_processing/spl_sqrt.c b/common_audio/signal_processing/spl_sqrt.c
index fff73c03..1de6ccd7 100644
--- a/common_audio/signal_processing/spl_sqrt.c
+++ b/common_audio/signal_processing/spl_sqrt.c
@@ -35,11 +35,10 @@ int32_t WebRtcSpl_SqrtLocal(int32_t in)
+ 0.875*((x_half)^5)
*/
- B = in;
+ B = in / 2;
- B = WEBRTC_SPL_RSHIFT_W32(B, 1); // B = in/2
B = B - ((int32_t)0x40000000); // B = in/2 - 1/2
- x_half = (int16_t)WEBRTC_SPL_RSHIFT_W32(B, 16);// x_half = x/2 = (in-1)/2
+ x_half = (int16_t)(B >> 16); // x_half = x/2 = (in-1)/2
B = B + ((int32_t)0x40000000); // B = 1 + x/2
B = B + ((int32_t)0x40000000); // Add 0.5 twice (since 1.0 does not exist in Q31)
@@ -47,19 +46,18 @@ int32_t WebRtcSpl_SqrtLocal(int32_t in)
A = -x2; // A = -(x/2)^2
B = B + (A >> 1); // B = 1 + x/2 - 0.5*(x/2)^2
- A = WEBRTC_SPL_RSHIFT_W32(A, 16);
+ A >>= 16;
A = A * A * 2; // A = (x/2)^4
- t16 = (int16_t)WEBRTC_SPL_RSHIFT_W32(A, 16);
+ t16 = (int16_t)(A >> 16);
B = B + WEBRTC_SPL_MUL_16_16(-20480, t16) * 2; // B = B - 0.625*A
// After this, B = 1 + x/2 - 0.5*(x/2)^2 - 0.625*(x/2)^4
- t16 = (int16_t)WEBRTC_SPL_RSHIFT_W32(A, 16);
A = WEBRTC_SPL_MUL_16_16(x_half, t16) * 2; // A = (x/2)^5
- t16 = (int16_t)WEBRTC_SPL_RSHIFT_W32(A, 16);
+ t16 = (int16_t)(A >> 16);
B = B + WEBRTC_SPL_MUL_16_16(28672, t16) * 2; // B = B + 0.875*A
// After this, B = 1 + x/2 - 0.5*(x/2)^2 - 0.625*(x/2)^4 + 0.875*(x/2)^5
- t16 = (int16_t)WEBRTC_SPL_RSHIFT_W32(x2, 16);
+ t16 = (int16_t)(x2 >> 16);
A = WEBRTC_SPL_MUL_16_16(x_half, t16) * 2; // A = x/2^3
B = B + (A >> 1); // B = B + 0.5*A
@@ -154,7 +152,7 @@ int32_t WebRtcSpl_Sqrt(int32_t value)
A = WEBRTC_SPL_WORD32_MAX;
}
- x_norm = (int16_t)WEBRTC_SPL_RSHIFT_W32(A, 16); // x_norm = AH
+ x_norm = (int16_t)(A >> 16); // x_norm = AH
nshift = (sh / 2);
assert(nshift >= 0);
@@ -166,17 +164,17 @@ int32_t WebRtcSpl_Sqrt(int32_t value)
if (2 * nshift == sh) {
// Even shift value case
- t16 = (int16_t)WEBRTC_SPL_RSHIFT_W32(A, 16); // t16 = AH
+ t16 = (int16_t)(A >> 16); // t16 = AH
A = WEBRTC_SPL_MUL_16_16(k_sqrt_2, t16) * 2; // A = 1/sqrt(2)*t16
A = A + ((int32_t)32768); // Round off
A = A & ((int32_t)0x7fff0000); // Round off
- A = WEBRTC_SPL_RSHIFT_W32(A, 15); // A = A>>16
+ A >>= 15; // A = A>>16
} else
{
- A = WEBRTC_SPL_RSHIFT_W32(A, 16); // A = A>>16
+ A >>= 16; // A = A>>16
}
A = A & ((int32_t)0x0000ffff);
diff --git a/common_audio/signal_processing/splitting_filter.c b/common_audio/signal_processing/splitting_filter.c
index 4f6430c2..15c37240 100644
--- a/common_audio/signal_processing/splitting_filter.c
+++ b/common_audio/signal_processing/splitting_filter.c
@@ -156,12 +156,10 @@ void WebRtcSpl_AnalysisQMF(const int16_t* in_data, int in_data_length,
// branches to get upper & lower band.
for (i = 0; i < band_length; i++)
{
- tmp = filter1[i] + filter2[i] + 1024;
- tmp = WEBRTC_SPL_RSHIFT_W32(tmp, 11);
+ tmp = (filter1[i] + filter2[i] + 1024) >> 11;
low_band[i] = WebRtcSpl_SatW32ToW16(tmp);
- tmp = filter1[i] - filter2[i] + 1024;
- tmp = WEBRTC_SPL_RSHIFT_W32(tmp, 11);
+ tmp = (filter1[i] - filter2[i] + 1024) >> 11;
high_band[i] = WebRtcSpl_SatW32ToW16(tmp);
}
}
@@ -200,10 +198,10 @@ void WebRtcSpl_SynthesisQMF(const int16_t* low_band, const int16_t* high_band,
// saturation.
for (i = 0, k = 0; i < band_length; i++)
{
- tmp = WEBRTC_SPL_RSHIFT_W32(filter2[i] + 512, 10);
+ tmp = (filter2[i] + 512) >> 10;
out_data[k++] = WebRtcSpl_SatW32ToW16(tmp);
- tmp = WEBRTC_SPL_RSHIFT_W32(filter1[i] + 512, 10);
+ tmp = (filter1[i] + 512) >> 10;
out_data[k++] = WebRtcSpl_SatW32ToW16(tmp);
}
diff --git a/common_audio/vad/include/vad.h b/common_audio/vad/include/vad.h
new file mode 100644
index 00000000..f1d12123
--- /dev/null
+++ b/common_audio/vad/include/vad.h
@@ -0,0 +1,45 @@
+/*
+ * 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 WEBRTC_COMMON_AUDIO_VAD_INCLUDE_VAD_H_
+#define WEBRTC_COMMON_AUDIO_VAD_INCLUDE_VAD_H_
+
+#include "webrtc/base/checks.h"
+#include "webrtc/common_audio/vad/include/webrtc_vad.h"
+#include "webrtc/typedefs.h"
+
+namespace webrtc {
+
+// This is a C++ wrapper class for WebRtcVad.
+class Vad {
+ public:
+ enum Aggressiveness {
+ kVadNormal = 0,
+ kVadLowBitrate = 1,
+ kVadAggressive = 2,
+ kVadVeryAggressive = 3
+ };
+
+ enum Activity { kPassive = 0, kActive = 1, kError = -1 };
+
+ explicit Vad(enum Aggressiveness mode);
+
+ virtual ~Vad();
+
+ enum Activity VoiceActivity(const int16_t* audio,
+ size_t num_samples,
+ int sample_rate_hz);
+
+ private:
+ VadInst* handle_;
+};
+
+} // namespace webrtc
+#endif // WEBRTC_COMMON_AUDIO_VAD_INCLUDE_VAD_H_
diff --git a/common_audio/vad/mock/mock_vad.h b/common_audio/vad/mock/mock_vad.h
new file mode 100644
index 00000000..f1d8c226
--- /dev/null
+++ b/common_audio/vad/mock/mock_vad.h
@@ -0,0 +1,34 @@
+/*
+ * 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 WEBRTC_COMMON_AUDIO_VAD_MOCK_MOCK_VAD_H_
+#define WEBRTC_COMMON_AUDIO_VAD_MOCK_MOCK_VAD_H_
+
+#include "webrtc/common_audio/vad/include/vad.h"
+
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace webrtc {
+
+class MockVad : public Vad {
+ public:
+ explicit MockVad(enum Aggressiveness mode) {}
+ virtual ~MockVad() { Die(); }
+ MOCK_METHOD0(Die, void());
+
+ MOCK_METHOD3(VoiceActivity,
+ enum Activity(const int16_t* audio,
+ size_t num_samples,
+ int sample_rate_hz));
+};
+
+} // namespace webrtc
+
+#endif // WEBRTC_COMMON_AUDIO_VAD_MOCK_MOCK_VAD_H_
diff --git a/common_audio/vad/vad.cc b/common_audio/vad/vad.cc
new file mode 100644
index 00000000..9cc0c198
--- /dev/null
+++ b/common_audio/vad/vad.cc
@@ -0,0 +1,43 @@
+/*
+ * 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 "webrtc/common_audio/vad/include/vad.h"
+
+#include "webrtc/base/checks.h"
+
+namespace webrtc {
+
+Vad::Vad(enum Aggressiveness mode) {
+ CHECK_EQ(WebRtcVad_Create(&handle_), 0);
+ CHECK_EQ(WebRtcVad_Init(handle_), 0);
+ CHECK_EQ(WebRtcVad_set_mode(handle_, mode), 0);
+}
+
+Vad::~Vad() {
+ WebRtcVad_Free(handle_);
+}
+
+enum Vad::Activity Vad::VoiceActivity(const int16_t* audio,
+ size_t num_samples,
+ int sample_rate_hz) {
+ int ret = WebRtcVad_Process(
+ handle_, sample_rate_hz, audio, static_cast<int>(num_samples));
+ switch (ret) {
+ case 0:
+ return kPassive;
+ case 1:
+ return kActive;
+ default:
+ DCHECK(false) << "WebRtcVad_Process returned an error.";
+ return kError;
+ }
+}
+
+} // namespace webrtc
diff --git a/common_audio/wav_file.cc b/common_audio/wav_file.cc
new file mode 100644
index 00000000..880e1ec4
--- /dev/null
+++ b/common_audio/wav_file.cc
@@ -0,0 +1,166 @@
+/*
+ * 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 "webrtc/common_audio/wav_file.h"
+
+#include <algorithm>
+#include <cstdio>
+#include <limits>
+
+#include "webrtc/base/checks.h"
+#include "webrtc/common_audio/include/audio_util.h"
+#include "webrtc/common_audio/wav_header.h"
+
+namespace webrtc {
+
+// We write 16-bit PCM WAV files.
+static const WavFormat kWavFormat = kWavFormatPcm;
+static const int kBytesPerSample = 2;
+
+WavReader::WavReader(const std::string& filename)
+ : file_handle_(fopen(filename.c_str(), "rb")) {
+ CHECK(file_handle_);
+ uint8_t header[kWavHeaderSize];
+ const size_t read =
+ fread(header, sizeof(*header), kWavHeaderSize, file_handle_);
+ CHECK_EQ(kWavHeaderSize, read);
+
+ WavFormat format;
+ int bytes_per_sample;
+ CHECK(ReadWavHeader(header, &num_channels_, &sample_rate_, &format,
+ &bytes_per_sample, &num_samples_));
+ CHECK_EQ(kWavFormat, format);
+ CHECK_EQ(kBytesPerSample, bytes_per_sample);
+}
+
+WavReader::~WavReader() {
+ Close();
+}
+
+size_t WavReader::ReadSamples(size_t num_samples, int16_t* samples) {
+#ifndef WEBRTC_ARCH_LITTLE_ENDIAN
+#error "Need to convert samples to big-endian when reading from WAV file"
+#endif
+ const size_t read =
+ fread(samples, sizeof(*samples), num_samples, file_handle_);
+ // If we didn't read what was requested, ensure we've reached the EOF.
+ CHECK(read == num_samples || feof(file_handle_));
+ return read;
+}
+
+size_t WavReader::ReadSamples(size_t num_samples, float* samples) {
+ static const size_t kChunksize = 4096 / sizeof(uint16_t);
+ size_t read = 0;
+ for (size_t i = 0; i < num_samples; i += kChunksize) {
+ int16_t isamples[kChunksize];
+ size_t chunk = std::min(kChunksize, num_samples - i);
+ chunk = ReadSamples(chunk, isamples);
+ for (size_t j = 0; j < chunk; ++j)
+ samples[i + j] = isamples[j];
+ read += chunk;
+ }
+ return read;
+}
+
+void WavReader::Close() {
+ CHECK_EQ(0, fclose(file_handle_));
+ file_handle_ = NULL;
+}
+
+WavWriter::WavWriter(const std::string& filename, int sample_rate,
+ int num_channels)
+ : sample_rate_(sample_rate),
+ num_channels_(num_channels),
+ num_samples_(0),
+ file_handle_(fopen(filename.c_str(), "wb")) {
+ CHECK(file_handle_);
+ CHECK(CheckWavParameters(num_channels_,
+ sample_rate_,
+ kWavFormat,
+ kBytesPerSample,
+ num_samples_));
+
+ // Write a blank placeholder header, since we need to know the total number
+ // of samples before we can fill in the real data.
+ static const uint8_t blank_header[kWavHeaderSize] = {0};
+ CHECK_EQ(1u, fwrite(blank_header, kWavHeaderSize, 1, file_handle_));
+}
+
+WavWriter::~WavWriter() {
+ Close();
+}
+
+void WavWriter::WriteSamples(const int16_t* samples, size_t num_samples) {
+#ifndef WEBRTC_ARCH_LITTLE_ENDIAN
+#error "Need to convert samples to little-endian when writing to WAV file"
+#endif
+ const size_t written =
+ fwrite(samples, sizeof(*samples), num_samples, file_handle_);
+ CHECK_EQ(num_samples, written);
+ num_samples_ += static_cast<uint32_t>(written);
+ CHECK(written <= std::numeric_limits<uint32_t>::max() ||
+ num_samples_ >= written); // detect uint32_t overflow
+ CHECK(CheckWavParameters(num_channels_,
+ sample_rate_,
+ kWavFormat,
+ kBytesPerSample,
+ num_samples_));
+}
+
+void WavWriter::WriteSamples(const float* samples, size_t num_samples) {
+ static const size_t kChunksize = 4096 / sizeof(uint16_t);
+ for (size_t i = 0; i < num_samples; i += kChunksize) {
+ int16_t isamples[kChunksize];
+ const size_t chunk = std::min(kChunksize, num_samples - i);
+ FloatS16ToS16(samples + i, chunk, isamples);
+ WriteSamples(isamples, chunk);
+ }
+}
+
+void WavWriter::Close() {
+ CHECK_EQ(0, fseek(file_handle_, 0, SEEK_SET));
+ uint8_t header[kWavHeaderSize];
+ WriteWavHeader(header, num_channels_, sample_rate_, kWavFormat,
+ kBytesPerSample, num_samples_);
+ CHECK_EQ(1u, fwrite(header, kWavHeaderSize, 1, file_handle_));
+ CHECK_EQ(0, fclose(file_handle_));
+ file_handle_ = NULL;
+}
+
+} // namespace webrtc
+
+rtc_WavWriter* rtc_WavOpen(const char* filename,
+ int sample_rate,
+ int num_channels) {
+ return reinterpret_cast<rtc_WavWriter*>(
+ new webrtc::WavWriter(filename, sample_rate, num_channels));
+}
+
+void rtc_WavClose(rtc_WavWriter* wf) {
+ delete reinterpret_cast<webrtc::WavWriter*>(wf);
+}
+
+void rtc_WavWriteSamples(rtc_WavWriter* wf,
+ const float* samples,
+ size_t num_samples) {
+ reinterpret_cast<webrtc::WavWriter*>(wf)->WriteSamples(samples, num_samples);
+}
+
+int rtc_WavSampleRate(const rtc_WavWriter* wf) {
+ return reinterpret_cast<const webrtc::WavWriter*>(wf)->sample_rate();
+}
+
+int rtc_WavNumChannels(const rtc_WavWriter* wf) {
+ return reinterpret_cast<const webrtc::WavWriter*>(wf)->num_channels();
+}
+
+uint32_t rtc_WavNumSamples(const rtc_WavWriter* wf) {
+ return reinterpret_cast<const webrtc::WavWriter*>(wf)->num_samples();
+}
diff --git a/common_audio/wav_file.h b/common_audio/wav_file.h
new file mode 100644
index 00000000..c6c5d6b7
--- /dev/null
+++ b/common_audio/wav_file.h
@@ -0,0 +1,98 @@
+/*
+ * 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 WEBRTC_COMMON_AUDIO_WAV_FILE_H_
+#define WEBRTC_COMMON_AUDIO_WAV_FILE_H_
+
+#ifdef __cplusplus
+
+#include <stdint.h>
+#include <cstddef>
+#include <string>
+
+namespace webrtc {
+
+// Simple C++ class for writing 16-bit PCM WAV files. All error handling is
+// by calls to CHECK(), making it unsuitable for anything but debug code.
+class WavWriter {
+ public:
+ // Open a new WAV file for writing.
+ WavWriter(const std::string& filename, int sample_rate, int num_channels);
+
+ // Close the WAV file, after writing its header.
+ ~WavWriter();
+
+ // Write additional samples to the file. Each sample is in the range
+ // [-32768,32767], and there must be the previously specified number of
+ // interleaved channels.
+ void WriteSamples(const float* samples, size_t num_samples);
+ void WriteSamples(const int16_t* samples, size_t num_samples);
+
+ int sample_rate() const { return sample_rate_; }
+ int num_channels() const { return num_channels_; }
+ uint32_t num_samples() const { return num_samples_; }
+
+ private:
+ void Close();
+ const int sample_rate_;
+ const int num_channels_;
+ uint32_t num_samples_; // Total number of samples written to file.
+ FILE* file_handle_; // Output file, owned by this class
+};
+
+// Follows the conventions of WavWriter.
+class WavReader {
+ public:
+ // Opens an existing WAV file for reading.
+ explicit WavReader(const std::string& filename);
+
+ // Close the WAV file.
+ ~WavReader();
+
+ // Returns the number of samples read. If this is less than requested,
+ // verifies that the end of the file was reached.
+ size_t ReadSamples(size_t num_samples, float* samples);
+ size_t ReadSamples(size_t num_samples, int16_t* samples);
+
+ int sample_rate() const { return sample_rate_; }
+ int num_channels() const { return num_channels_; }
+ uint32_t num_samples() const { return num_samples_; }
+
+ private:
+ void Close();
+ int sample_rate_;
+ int num_channels_;
+ uint32_t num_samples_; // Total number of samples in the file.
+ FILE* file_handle_; // Input file, owned by this class.
+};
+
+} // namespace webrtc
+
+extern "C" {
+#endif // __cplusplus
+
+// C wrappers for the WavWriter class.
+typedef struct rtc_WavWriter rtc_WavWriter;
+rtc_WavWriter* rtc_WavOpen(const char* filename,
+ int sample_rate,
+ int num_channels);
+void rtc_WavClose(rtc_WavWriter* wf);
+void rtc_WavWriteSamples(rtc_WavWriter* wf,
+ const float* samples,
+ size_t num_samples);
+int rtc_WavSampleRate(const rtc_WavWriter* wf);
+int rtc_WavNumChannels(const rtc_WavWriter* wf);
+uint32_t rtc_WavNumSamples(const rtc_WavWriter* wf);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // WEBRTC_COMMON_AUDIO_WAV_FILE_H_
diff --git a/common_audio/wav_writer_unittest.cc b/common_audio/wav_file_unittest.cc
index 9c593be6..1bdb655d 100644
--- a/common_audio/wav_writer_unittest.cc
+++ b/common_audio/wav_file_unittest.cc
@@ -17,7 +17,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/compile_assert.h"
#include "webrtc/common_audio/wav_header.h"
-#include "webrtc/common_audio/wav_writer.h"
+#include "webrtc/common_audio/wav_file.h"
#include "webrtc/test/testsupport/fileutils.h"
static const float kSamples[] = {0.0, 10.0, 4e4, -1e9};
@@ -27,7 +27,7 @@ TEST(WavWriterTest, CPP) {
const std::string outfile = webrtc::test::OutputPath() + "wavtest1.wav";
static const uint32_t kNumSamples = 3;
{
- webrtc::WavFile w(outfile, 14099, 1);
+ webrtc::WavWriter w(outfile, 14099, 1);
EXPECT_EQ(14099, w.sample_rate());
EXPECT_EQ(1, w.num_channels());
EXPECT_EQ(0u, w.num_samples());
@@ -62,12 +62,24 @@ TEST(WavWriterTest, CPP) {
ASSERT_EQ(1u, fread(contents, kContentSize, 1, f));
EXPECT_EQ(0, fclose(f));
EXPECT_EQ(0, memcmp(kExpectedContents, contents, kContentSize));
+
+ {
+ webrtc::WavReader r(outfile);
+ EXPECT_EQ(14099, r.sample_rate());
+ EXPECT_EQ(1, r.num_channels());
+ EXPECT_EQ(kNumSamples, r.num_samples());
+ static const float kTruncatedSamples[] = {0.0, 10.0, 32767.0};
+ float samples[kNumSamples];
+ EXPECT_EQ(kNumSamples, r.ReadSamples(kNumSamples, samples));
+ EXPECT_EQ(0, memcmp(kTruncatedSamples, samples, sizeof(samples)));
+ EXPECT_EQ(0u, r.ReadSamples(kNumSamples, samples));
+ }
}
// Write a tiny WAV file with the C interface and verify the result.
TEST(WavWriterTest, C) {
const std::string outfile = webrtc::test::OutputPath() + "wavtest2.wav";
- rtc_WavFile *w = rtc_WavOpen(outfile.c_str(), 11904, 2);
+ rtc_WavWriter *w = rtc_WavOpen(outfile.c_str(), 11904, 2);
EXPECT_EQ(11904, rtc_WavSampleRate(w));
EXPECT_EQ(2, rtc_WavNumChannels(w));
EXPECT_EQ(0u, rtc_WavNumSamples(w));
@@ -125,7 +137,7 @@ TEST(WavWriterTest, LargeFile) {
samples[i + 1] = std::pow(std::cos(t * 2 * 2 * M_PI), 10) * x;
}
{
- webrtc::WavFile w(outfile, kSampleRate, kNumChannels);
+ webrtc::WavWriter w(outfile, kSampleRate, kNumChannels);
EXPECT_EQ(kSampleRate, w.sample_rate());
EXPECT_EQ(kNumChannels, w.num_channels());
EXPECT_EQ(0u, w.num_samples());
@@ -134,4 +146,18 @@ TEST(WavWriterTest, LargeFile) {
}
EXPECT_EQ(sizeof(int16_t) * kNumSamples + webrtc::kWavHeaderSize,
webrtc::test::GetFileSize(outfile));
+
+ {
+ webrtc::WavReader r(outfile);
+ EXPECT_EQ(kSampleRate, r.sample_rate());
+ EXPECT_EQ(kNumChannels, r.num_channels());
+ EXPECT_EQ(kNumSamples, r.num_samples());
+
+ float read_samples[kNumSamples];
+ EXPECT_EQ(kNumSamples, r.ReadSamples(kNumSamples, read_samples));
+ for (size_t i = 0; i < kNumSamples; ++i)
+ EXPECT_NEAR(samples[i], read_samples[i], 1);
+
+ EXPECT_EQ(0u, r.ReadSamples(kNumSamples, read_samples));
+ }
}
diff --git a/common_audio/wav_header.cc b/common_audio/wav_header.cc
index ce43896f..8c781fb4 100644
--- a/common_audio/wav_header.cc
+++ b/common_audio/wav_header.cc
@@ -18,9 +18,11 @@
#include <cstring>
#include <limits>
+#include "webrtc/base/checks.h"
#include "webrtc/common_audio/include/audio_util.h"
namespace webrtc {
+namespace {
struct ChunkHeader {
uint32_t ID;
@@ -28,6 +30,34 @@ struct ChunkHeader {
};
COMPILE_ASSERT(sizeof(ChunkHeader) == 8, chunk_header_size);
+// We can't nest this definition in WavHeader, because VS2013 gives an error
+// on sizeof(WavHeader::fmt): "error C2070: 'unknown': illegal sizeof operand".
+struct FmtSubchunk {
+ ChunkHeader header;
+ uint16_t AudioFormat;
+ uint16_t NumChannels;
+ uint32_t SampleRate;
+ uint32_t ByteRate;
+ uint16_t BlockAlign;
+ uint16_t BitsPerSample;
+};
+COMPILE_ASSERT(sizeof(FmtSubchunk) == 24, fmt_subchunk_size);
+const uint32_t kFmtSubchunkSize = sizeof(FmtSubchunk) - sizeof(ChunkHeader);
+
+struct WavHeader {
+ struct {
+ ChunkHeader header;
+ uint32_t Format;
+ } riff;
+ FmtSubchunk fmt;
+ struct {
+ ChunkHeader header;
+ } data;
+};
+COMPILE_ASSERT(sizeof(WavHeader) == kWavHeaderSize, no_padding_in_header);
+
+} // namespace
+
bool CheckWavParameters(int num_channels,
int sample_rate,
WavFormat format,
@@ -91,54 +121,53 @@ static inline void WriteFourCC(uint32_t* f, char a, char b, char c, char d) {
| static_cast<uint32_t>(c) << 16
| static_cast<uint32_t>(d) << 24;
}
+
+static inline uint16_t ReadLE16(uint16_t x) { return x; }
+static inline uint32_t ReadLE32(uint32_t x) { return x; }
+static inline std::string ReadFourCC(uint32_t x) {
+ return std::string(reinterpret_cast<char*>(&x), 4);
+}
#else
#error "Write be-to-le conversion functions"
#endif
+static inline uint32_t RiffChunkSize(uint32_t bytes_in_payload) {
+ return bytes_in_payload + kWavHeaderSize - sizeof(ChunkHeader);
+}
+
+static inline uint32_t ByteRate(int num_channels, int sample_rate,
+ int bytes_per_sample) {
+ return static_cast<uint32_t>(num_channels) * sample_rate * bytes_per_sample;
+}
+
+static inline uint16_t BlockAlign(int num_channels, int bytes_per_sample) {
+ return num_channels * bytes_per_sample;
+}
+
void WriteWavHeader(uint8_t* buf,
int num_channels,
int sample_rate,
WavFormat format,
int bytes_per_sample,
uint32_t num_samples) {
- assert(CheckWavParameters(num_channels, sample_rate, format,
- bytes_per_sample, num_samples));
-
- struct {
- struct {
- ChunkHeader header;
- uint32_t Format;
- } riff;
- struct {
- ChunkHeader header;
- uint16_t AudioFormat;
- uint16_t NumChannels;
- uint32_t SampleRate;
- uint32_t ByteRate;
- uint16_t BlockAlign;
- uint16_t BitsPerSample;
- } fmt;
- struct {
- ChunkHeader header;
- } data;
- } header;
- COMPILE_ASSERT(sizeof(header) == kWavHeaderSize, no_padding_in_header);
+ CHECK(CheckWavParameters(num_channels, sample_rate, format,
+ bytes_per_sample, num_samples));
+ WavHeader header;
const uint32_t bytes_in_payload = bytes_per_sample * num_samples;
WriteFourCC(&header.riff.header.ID, 'R', 'I', 'F', 'F');
- WriteLE32(&header.riff.header.Size,
- bytes_in_payload + kWavHeaderSize - sizeof(ChunkHeader));
+ WriteLE32(&header.riff.header.Size, RiffChunkSize(bytes_in_payload));
WriteFourCC(&header.riff.Format, 'W', 'A', 'V', 'E');
WriteFourCC(&header.fmt.header.ID, 'f', 'm', 't', ' ');
- WriteLE32(&header.fmt.header.Size, sizeof(header.fmt) - sizeof(ChunkHeader));
+ WriteLE32(&header.fmt.header.Size, kFmtSubchunkSize);
WriteLE16(&header.fmt.AudioFormat, format);
WriteLE16(&header.fmt.NumChannels, num_channels);
WriteLE32(&header.fmt.SampleRate, sample_rate);
- WriteLE32(&header.fmt.ByteRate, (static_cast<uint32_t>(num_channels)
- * sample_rate * bytes_per_sample));
- WriteLE16(&header.fmt.BlockAlign, num_channels * bytes_per_sample);
+ WriteLE32(&header.fmt.ByteRate, ByteRate(num_channels, sample_rate,
+ bytes_per_sample));
+ WriteLE16(&header.fmt.BlockAlign, BlockAlign(num_channels, bytes_per_sample));
WriteLE16(&header.fmt.BitsPerSample, 8 * bytes_per_sample);
WriteFourCC(&header.data.header.ID, 'd', 'a', 't', 'a');
@@ -149,4 +178,49 @@ void WriteWavHeader(uint8_t* buf,
memcpy(buf, &header, kWavHeaderSize);
}
+bool ReadWavHeader(const uint8_t* buf,
+ int* num_channels,
+ int* sample_rate,
+ WavFormat* format,
+ int* bytes_per_sample,
+ uint32_t* num_samples) {
+ WavHeader header;
+ memcpy(&header, buf, kWavHeaderSize);
+
+ // Parse needed fields.
+ *format = static_cast<WavFormat>(ReadLE16(header.fmt.AudioFormat));
+ *num_channels = ReadLE16(header.fmt.NumChannels);
+ *sample_rate = ReadLE32(header.fmt.SampleRate);
+ *bytes_per_sample = ReadLE16(header.fmt.BitsPerSample) / 8;
+ const uint32_t bytes_in_payload = ReadLE32(header.data.header.Size);
+ if (*bytes_per_sample <= 0)
+ return false;
+ *num_samples = bytes_in_payload / *bytes_per_sample;
+
+ // Sanity check remaining fields.
+ if (ReadFourCC(header.riff.header.ID) != "RIFF")
+ return false;
+ if (ReadFourCC(header.riff.Format) != "WAVE")
+ return false;
+ if (ReadFourCC(header.fmt.header.ID) != "fmt ")
+ return false;
+ if (ReadFourCC(header.data.header.ID) != "data")
+ return false;
+
+ if (ReadLE32(header.riff.header.Size) != RiffChunkSize(bytes_in_payload))
+ return false;
+ if (ReadLE32(header.fmt.header.Size) != kFmtSubchunkSize)
+ return false;
+ if (ReadLE32(header.fmt.ByteRate) !=
+ ByteRate(*num_channels, *sample_rate, *bytes_per_sample))
+ return false;
+ if (ReadLE16(header.fmt.BlockAlign) !=
+ BlockAlign(*num_channels, *bytes_per_sample))
+ return false;
+
+ return CheckWavParameters(*num_channels, *sample_rate, *format,
+ *bytes_per_sample, *num_samples);
+}
+
+
} // namespace webrtc
diff --git a/common_audio/wav_header.h b/common_audio/wav_header.h
index f9ed8a57..37f78a6f 100644
--- a/common_audio/wav_header.h
+++ b/common_audio/wav_header.h
@@ -11,11 +11,12 @@
#ifndef WEBRTC_COMMON_AUDIO_WAV_HEADER_H_
#define WEBRTC_COMMON_AUDIO_WAV_HEADER_H_
+#include <stddef.h>
#include <stdint.h>
namespace webrtc {
-static const int kWavHeaderSize = 44;
+static const size_t kWavHeaderSize = 44;
enum WavFormat {
kWavFormatPcm = 1, // PCM, each sample of size bytes_per_sample
@@ -33,7 +34,7 @@ bool CheckWavParameters(int num_channels,
// Write a kWavHeaderSize bytes long WAV header to buf. The payload that
// follows the header is supposed to have the specified number of interleaved
// channels and contain the specified total number of samples of the specified
-// type.
+// type. CHECKs the input parameters for validity.
void WriteWavHeader(uint8_t* buf,
int num_channels,
int sample_rate,
@@ -41,6 +42,15 @@ void WriteWavHeader(uint8_t* buf,
int bytes_per_sample,
uint32_t num_samples);
+// Read a kWavHeaderSize bytes long WAV header from buf and parse the values
+// into the provided output parameters. Returns false if the header is invalid.
+bool ReadWavHeader(const uint8_t* buf,
+ int* num_channels,
+ int* sample_rate,
+ WavFormat* format,
+ int* bytes_per_sample,
+ uint32_t* num_samples);
+
} // namespace webrtc
#endif // WEBRTC_COMMON_AUDIO_WAV_HEADER_H_
diff --git a/common_audio/wav_header_unittest.cc b/common_audio/wav_header_unittest.cc
index f05160ea..677affa5 100644
--- a/common_audio/wav_header_unittest.cc
+++ b/common_audio/wav_header_unittest.cc
@@ -48,8 +48,80 @@ TEST(WavHeaderTest, CheckWavParameters) {
webrtc::CheckWavParameters(3, 8000, webrtc::kWavFormatPcm, 1, 5));
}
-// Try writing a WAV header and make sure it looks OK.
-TEST(WavHeaderTest, WriteWavHeader) {
+TEST(WavHeaderTest, ReadWavHeaderWithErrors) {
+ int num_channels = 0;
+ int sample_rate = 0;
+ webrtc::WavFormat format = webrtc::kWavFormatPcm;
+ int bytes_per_sample = 0;
+ uint32_t num_samples = 0;
+
+ // Test a few ways the header can be invalid. We start with the valid header
+ // used in WriteAndReadWavHeader, and invalidate one field per test. The
+ // invalid field is indicated in the array name, and in the comments with
+ // *BAD*.
+ static const uint8_t kBadRiffID[] = {
+ 'R', 'i', 'f', 'f', // *BAD*
+ 0xbd, 0xd0, 0x5b, 0x07, // size of whole file - 8: 123457689 + 44 - 8
+ 'W', 'A', 'V', 'E',
+ 'f', 'm', 't', ' ',
+ 16, 0, 0, 0, // size of fmt block - 8: 24 - 8
+ 6, 0, // format: A-law (6)
+ 17, 0, // channels: 17
+ 0x39, 0x30, 0, 0, // sample rate: 12345
+ 0xc9, 0x33, 0x03, 0, // byte rate: 1 * 17 * 12345
+ 17, 0, // block align: NumChannels * BytesPerSample
+ 8, 0, // bits per sample: 1 * 8
+ 'd', 'a', 't', 'a',
+ 0x99, 0xd0, 0x5b, 0x07, // size of payload: 123457689
+ 0xa4, 0xa4, 0xa4, 0xa4, // untouched bytes after header
+ };
+ EXPECT_FALSE(
+ webrtc::ReadWavHeader(kBadRiffID, &num_channels, &sample_rate,
+ &format, &bytes_per_sample, &num_samples));
+
+ static const uint8_t kBadBitsPerSample[] = {
+ 'R', 'I', 'F', 'F',
+ 0xbd, 0xd0, 0x5b, 0x07, // size of whole file - 8: 123457689 + 44 - 8
+ 'W', 'A', 'V', 'E',
+ 'f', 'm', 't', ' ',
+ 16, 0, 0, 0, // size of fmt block - 8: 24 - 8
+ 6, 0, // format: A-law (6)
+ 17, 0, // channels: 17
+ 0x39, 0x30, 0, 0, // sample rate: 12345
+ 0xc9, 0x33, 0x03, 0, // byte rate: 1 * 17 * 12345
+ 17, 0, // block align: NumChannels * BytesPerSample
+ 1, 0, // bits per sample: *BAD*
+ 'd', 'a', 't', 'a',
+ 0x99, 0xd0, 0x5b, 0x07, // size of payload: 123457689
+ 0xa4, 0xa4, 0xa4, 0xa4, // untouched bytes after header
+ };
+ EXPECT_FALSE(
+ webrtc::ReadWavHeader(kBadBitsPerSample, &num_channels, &sample_rate,
+ &format, &bytes_per_sample, &num_samples));
+
+ static const uint8_t kBadByteRate[] = {
+ 'R', 'I', 'F', 'F',
+ 0xbd, 0xd0, 0x5b, 0x07, // size of whole file - 8: 123457689 + 44 - 8
+ 'W', 'A', 'V', 'E',
+ 'f', 'm', 't', ' ',
+ 16, 0, 0, 0, // size of fmt block - 8: 24 - 8
+ 6, 0, // format: A-law (6)
+ 17, 0, // channels: 17
+ 0x39, 0x30, 0, 0, // sample rate: 12345
+ 0x00, 0x33, 0x03, 0, // byte rate: *BAD*
+ 17, 0, // block align: NumChannels * BytesPerSample
+ 8, 0, // bits per sample: 1 * 8
+ 'd', 'a', 't', 'a',
+ 0x99, 0xd0, 0x5b, 0x07, // size of payload: 123457689
+ 0xa4, 0xa4, 0xa4, 0xa4, // untouched bytes after header
+ };
+ EXPECT_FALSE(
+ webrtc::ReadWavHeader(kBadByteRate, &num_channels, &sample_rate,
+ &format, &bytes_per_sample, &num_samples));
+}
+
+// Try writing and reading a valid WAV header and make sure it looks OK.
+TEST(WavHeaderTest, WriteAndReadWavHeader) {
static const int kSize = 4 + webrtc::kWavHeaderSize + 4;
uint8_t buf[kSize];
memset(buf, 0xa4, sizeof(buf));
@@ -74,4 +146,18 @@ TEST(WavHeaderTest, WriteWavHeader) {
};
COMPILE_ASSERT(sizeof(kExpectedBuf) == kSize, buf_size);
EXPECT_EQ(0, memcmp(kExpectedBuf, buf, kSize));
+
+ int num_channels = 0;
+ int sample_rate = 0;
+ webrtc::WavFormat format = webrtc::kWavFormatPcm;
+ int bytes_per_sample = 0;
+ uint32_t num_samples = 0;
+ EXPECT_TRUE(
+ webrtc::ReadWavHeader(buf + 4, &num_channels, &sample_rate, &format,
+ &bytes_per_sample, &num_samples));
+ EXPECT_EQ(17, num_channels);
+ EXPECT_EQ(12345, sample_rate);
+ EXPECT_EQ(webrtc::kWavFormatALaw, format);
+ EXPECT_EQ(1, bytes_per_sample);
+ EXPECT_EQ(123457689u, num_samples);
}
diff --git a/common_audio/wav_writer.cc b/common_audio/wav_writer.cc
deleted file mode 100644
index 30a220c2..00000000
--- a/common_audio/wav_writer.cc
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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 "webrtc/common_audio/wav_writer.h"
-
-#include <algorithm>
-#include <cstdio>
-#include <limits>
-
-#include "webrtc/base/checks.h"
-#include "webrtc/common_audio/include/audio_util.h"
-#include "webrtc/common_audio/wav_header.h"
-
-namespace webrtc {
-
-// We write 16-bit PCM WAV files.
-static const WavFormat kWavFormat = kWavFormatPcm;
-static const int kBytesPerSample = 2;
-
-WavFile::WavFile(const std::string& filename, int sample_rate, int num_channels)
- : sample_rate_(sample_rate),
- num_channels_(num_channels),
- num_samples_(0),
- file_handle_(fopen(filename.c_str(), "wb")) {
- CHECK(file_handle_);
- CHECK(CheckWavParameters(num_channels_,
- sample_rate_,
- kWavFormat,
- kBytesPerSample,
- num_samples_));
-
- // Write a blank placeholder header, since we need to know the total number
- // of samples before we can fill in the real data.
- static const uint8_t blank_header[kWavHeaderSize] = {0};
- CHECK_EQ(1u, fwrite(blank_header, kWavHeaderSize, 1, file_handle_));
-}
-
-WavFile::~WavFile() {
- Close();
-}
-
-void WavFile::WriteSamples(const int16_t* samples, size_t num_samples) {
-#ifndef WEBRTC_ARCH_LITTLE_ENDIAN
-#error "Need to convert samples to little-endian when writing to WAV file"
-#endif
- const size_t written =
- fwrite(samples, sizeof(*samples), num_samples, file_handle_);
- CHECK_EQ(num_samples, written);
- num_samples_ += static_cast<uint32_t>(written);
- CHECK(written <= std::numeric_limits<uint32_t>::max() ||
- num_samples_ >= written); // detect uint32_t overflow
- CHECK(CheckWavParameters(num_channels_,
- sample_rate_,
- kWavFormat,
- kBytesPerSample,
- num_samples_));
-}
-
-void WavFile::WriteSamples(const float* samples, size_t num_samples) {
- static const size_t kChunksize = 4096 / sizeof(uint16_t);
- for (size_t i = 0; i < num_samples; i += kChunksize) {
- int16_t isamples[kChunksize];
- const size_t chunk = std::min(kChunksize, num_samples - i);
- RoundToInt16(samples + i, chunk, isamples);
- WriteSamples(isamples, chunk);
- }
-}
-
-void WavFile::Close() {
- CHECK_EQ(0, fseek(file_handle_, 0, SEEK_SET));
- uint8_t header[kWavHeaderSize];
- WriteWavHeader(header, num_channels_, sample_rate_, kWavFormat,
- kBytesPerSample, num_samples_);
- CHECK_EQ(1u, fwrite(header, kWavHeaderSize, 1, file_handle_));
- CHECK_EQ(0, fclose(file_handle_));
- file_handle_ = NULL;
-}
-
-} // namespace webrtc
-
-rtc_WavFile* rtc_WavOpen(const char* filename,
- int sample_rate,
- int num_channels) {
- return reinterpret_cast<rtc_WavFile*>(
- new webrtc::WavFile(filename, sample_rate, num_channels));
-}
-
-void rtc_WavClose(rtc_WavFile* wf) {
- delete reinterpret_cast<webrtc::WavFile*>(wf);
-}
-
-void rtc_WavWriteSamples(rtc_WavFile* wf,
- const float* samples,
- size_t num_samples) {
- reinterpret_cast<webrtc::WavFile*>(wf)->WriteSamples(samples, num_samples);
-}
-
-int rtc_WavSampleRate(const rtc_WavFile* wf) {
- return reinterpret_cast<const webrtc::WavFile*>(wf)->sample_rate();
-}
-
-int rtc_WavNumChannels(const rtc_WavFile* wf) {
- return reinterpret_cast<const webrtc::WavFile*>(wf)->num_channels();
-}
-
-uint32_t rtc_WavNumSamples(const rtc_WavFile* wf) {
- return reinterpret_cast<const webrtc::WavFile*>(wf)->num_samples();
-}
diff --git a/common_audio/wav_writer.h b/common_audio/wav_writer.h
deleted file mode 100644
index 09667279..00000000
--- a/common_audio/wav_writer.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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 WEBRTC_COMMON_AUDIO_WAV_WRITER_H_
-#define WEBRTC_COMMON_AUDIO_WAV_WRITER_H_
-
-#ifdef __cplusplus
-
-#include <stdint.h>
-#include <cstddef>
-#include <string>
-
-namespace webrtc {
-
-// Simple C++ class for writing 16-bit PCM WAV files. All error handling is
-// by calls to CHECK(), making it unsuitable for anything but debug code.
-class WavFile {
- public:
- // Open a new WAV file for writing.
- WavFile(const std::string& filename, int sample_rate, int num_channels);
-
- // Close the WAV file, after writing its header.
- ~WavFile();
-
- // Write additional samples to the file. Each sample is in the range
- // [-32768,32767], and there must be the previously specified number of
- // interleaved channels.
- void WriteSamples(const float* samples, size_t num_samples);
- void WriteSamples(const int16_t* samples, size_t num_samples);
-
- int sample_rate() const { return sample_rate_; }
- int num_channels() const { return num_channels_; }
- uint32_t num_samples() const { return num_samples_; }
-
- private:
- void Close();
- const int sample_rate_;
- const int num_channels_;
- uint32_t num_samples_; // total number of samples written to file
- FILE* file_handle_; // output file, owned by this class
-};
-
-} // namespace webrtc
-
-extern "C" {
-#endif // __cplusplus
-
-// C wrappers for the WavFile class.
-typedef struct rtc_WavFile rtc_WavFile;
-rtc_WavFile* rtc_WavOpen(const char* filename,
- int sample_rate,
- int num_channels);
-void rtc_WavClose(rtc_WavFile* wf);
-void rtc_WavWriteSamples(rtc_WavFile* wf,
- const float* samples,
- size_t num_samples);
-int rtc_WavSampleRate(const rtc_WavFile* wf);
-int rtc_WavNumChannels(const rtc_WavFile* wf);
-uint32_t rtc_WavNumSamples(const rtc_WavFile* wf);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // WEBRTC_COMMON_AUDIO_WAV_WRITER_H_
diff --git a/common_types.h b/common_types.h
index e607ddc7..7bcfd6d4 100644
--- a/common_types.h
+++ b/common_types.h
@@ -202,17 +202,31 @@ struct RtcpPacketTypeCounter {
RtcpPacketTypeCounter()
: nack_packets(0),
fir_packets(0),
- pli_packets(0) {}
+ pli_packets(0),
+ nack_requests(0),
+ unique_nack_requests(0) {}
void Add(const RtcpPacketTypeCounter& other) {
nack_packets += other.nack_packets;
fir_packets += other.fir_packets;
pli_packets += other.pli_packets;
+ nack_requests += other.nack_requests;
+ unique_nack_requests += other.unique_nack_requests;
}
- uint32_t nack_packets;
- uint32_t fir_packets;
- uint32_t pli_packets;
+ int UniqueNackRequestsInPercent() const {
+ if (nack_requests == 0) {
+ return 0;
+ }
+ return static_cast<int>(
+ (unique_nack_requests * 100.0f / nack_requests) + 0.5f);
+ }
+
+ uint32_t nack_packets; // Number of RTCP NACK packets.
+ uint32_t fir_packets; // Number of RTCP FIR packets.
+ uint32_t pli_packets; // Number of RTCP PLI packets.
+ uint32_t nack_requests; // Number of NACKed RTP packets.
+ uint32_t unique_nack_requests; // Number of unique NACKed RTP packets.
};
// Data usage statistics for a (rtp) stream
@@ -597,35 +611,45 @@ struct VideoCodecVP8 {
}
};
-// H264 specific.
-struct VideoCodecH264
-{
- VideoCodecProfile profile;
- bool frameDroppingOn;
- int keyFrameInterval;
- // These are NULL/0 if not externally negotiated.
- const uint8_t* spsData;
- size_t spsLen;
- const uint8_t* ppsData;
- size_t ppsLen;
+// VP9 specific
+struct VideoCodecVP9 {
+ VideoCodecComplexity complexity;
+ int resilience;
+ unsigned char numberOfTemporalLayers;
+ bool denoisingOn;
+ bool frameDroppingOn;
+ int keyFrameInterval;
+ bool adaptiveQpMode;
};
-// Video codec types
-enum VideoCodecType
-{
- kVideoCodecVP8,
- kVideoCodecH264,
- kVideoCodecI420,
- kVideoCodecRED,
- kVideoCodecULPFEC,
- kVideoCodecGeneric,
- kVideoCodecUnknown
+// H264 specific.
+struct VideoCodecH264 {
+ VideoCodecProfile profile;
+ bool frameDroppingOn;
+ int keyFrameInterval;
+ // These are NULL/0 if not externally negotiated.
+ const uint8_t* spsData;
+ size_t spsLen;
+ const uint8_t* ppsData;
+ size_t ppsLen;
};
-union VideoCodecUnion
-{
- VideoCodecVP8 VP8;
- VideoCodecH264 H264;
+// Video codec types
+enum VideoCodecType {
+ kVideoCodecVP8,
+ kVideoCodecVP9,
+ kVideoCodecH264,
+ kVideoCodecI420,
+ kVideoCodecRED,
+ kVideoCodecULPFEC,
+ kVideoCodecGeneric,
+ kVideoCodecUnknown
+};
+
+union VideoCodecUnion {
+ VideoCodecVP8 VP8;
+ VideoCodecVP9 VP9;
+ VideoCodecH264 H264;
};
diff --git a/common_video/common_video.target.darwin-arm.mk b/common_video/common_video.target.darwin-arm.mk
index f896804b..d9bdd3c4 100644
--- a/common_video/common_video.target.darwin-arm.mk
+++ b/common_video/common_video.target.darwin-arm.mk
@@ -87,11 +87,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +109,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -205,11 +208,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -225,6 +230,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_video/common_video.target.darwin-arm64.mk b/common_video/common_video.target.darwin-arm64.mk
index 79d074e2..b84c5e7a 100644
--- a/common_video/common_video.target.darwin-arm64.mk
+++ b/common_video/common_video.target.darwin-arm64.mk
@@ -76,11 +76,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -89,10 +91,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -179,11 +183,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -192,10 +198,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_video/common_video.target.darwin-mips.mk b/common_video/common_video.target.darwin-mips.mk
index c2afbeb7..0df92507 100644
--- a/common_video/common_video.target.darwin-mips.mk
+++ b/common_video/common_video.target.darwin-mips.mk
@@ -80,11 +80,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -190,11 +193,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -209,6 +214,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_video/common_video.target.darwin-mips64.mk b/common_video/common_video.target.darwin-mips64.mk
new file mode 100644
index 00000000..a7ba7250
--- /dev/null
+++ b/common_video/common_video.target.darwin-mips64.mk
@@ -0,0 +1,273 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_common_video_common_video_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/common_video/i420_video_frame.cc \
+ third_party/webrtc/common_video/libyuv/webrtc_libyuv.cc \
+ third_party/webrtc/common_video/libyuv/scaler.cc \
+ third_party/webrtc/common_video/plane.cc \
+ third_party/webrtc/common_video/texture_video_frame.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libyuv/include \
+ $(LOCAL_PATH)/third_party/libyuv
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libyuv/include \
+ $(LOCAL_PATH)/third_party/libyuv
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_common_video_common_video_gyp
+
+# Alias gyp target name.
+.PHONY: common_video
+common_video: third_party_webrtc_common_video_common_video_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/common_video/common_video.target.darwin-x86.mk b/common_video/common_video.target.darwin-x86.mk
index 137d9604..642d1818 100644
--- a/common_video/common_video.target.darwin-x86.mk
+++ b/common_video/common_video.target.darwin-x86.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -208,6 +213,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_video/common_video.target.darwin-x86_64.mk b/common_video/common_video.target.darwin-x86_64.mk
index 7d6c5913..a169d9cb 100644
--- a/common_video/common_video.target.darwin-x86_64.mk
+++ b/common_video/common_video.target.darwin-x86_64.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,6 +100,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -189,11 +192,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -206,6 +211,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_video/common_video.target.linux-arm.mk b/common_video/common_video.target.linux-arm.mk
index f896804b..d9bdd3c4 100644
--- a/common_video/common_video.target.linux-arm.mk
+++ b/common_video/common_video.target.linux-arm.mk
@@ -87,11 +87,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +109,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -205,11 +208,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -225,6 +230,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_video/common_video.target.linux-arm64.mk b/common_video/common_video.target.linux-arm64.mk
index 79d074e2..b84c5e7a 100644
--- a/common_video/common_video.target.linux-arm64.mk
+++ b/common_video/common_video.target.linux-arm64.mk
@@ -76,11 +76,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -89,10 +91,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -179,11 +183,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -192,10 +198,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_video/common_video.target.linux-mips.mk b/common_video/common_video.target.linux-mips.mk
index c2afbeb7..0df92507 100644
--- a/common_video/common_video.target.linux-mips.mk
+++ b/common_video/common_video.target.linux-mips.mk
@@ -80,11 +80,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -190,11 +193,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -209,6 +214,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_video/common_video.target.linux-mips64.mk b/common_video/common_video.target.linux-mips64.mk
new file mode 100644
index 00000000..a7ba7250
--- /dev/null
+++ b/common_video/common_video.target.linux-mips64.mk
@@ -0,0 +1,273 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_common_video_common_video_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/common_video/i420_video_frame.cc \
+ third_party/webrtc/common_video/libyuv/webrtc_libyuv.cc \
+ third_party/webrtc/common_video/libyuv/scaler.cc \
+ third_party/webrtc/common_video/plane.cc \
+ third_party/webrtc/common_video/texture_video_frame.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libyuv/include \
+ $(LOCAL_PATH)/third_party/libyuv
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libyuv/include \
+ $(LOCAL_PATH)/third_party/libyuv
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_common_video_common_video_gyp
+
+# Alias gyp target name.
+.PHONY: common_video
+common_video: third_party_webrtc_common_video_common_video_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/common_video/common_video.target.linux-x86.mk b/common_video/common_video.target.linux-x86.mk
index 137d9604..642d1818 100644
--- a/common_video/common_video.target.linux-x86.mk
+++ b/common_video/common_video.target.linux-x86.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -208,6 +213,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_video/common_video.target.linux-x86_64.mk b/common_video/common_video.target.linux-x86_64.mk
index 7d6c5913..a169d9cb 100644
--- a/common_video/common_video.target.linux-x86_64.mk
+++ b/common_video/common_video.target.linux-x86_64.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,6 +100,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -189,11 +192,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -206,6 +211,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/common_video/common_video_unittests.gyp b/common_video/common_video_unittests.gyp
index 0405ba0e..9189991e 100644
--- a/common_video/common_video_unittests.gyp
+++ b/common_video/common_video_unittests.gyp
@@ -60,7 +60,6 @@
],
'includes': [
'../build/isolate.gypi',
- 'common_video_unittests.isolate',
],
'sources': [
'common_video_unittests.isolate',
diff --git a/common_video/common_video_unittests.isolate b/common_video/common_video_unittests.isolate
index d33366c2..70823654 100644
--- a/common_video/common_video_unittests.isolate
+++ b/common_video/common_video_unittests.isolate
@@ -9,7 +9,7 @@
'conditions': [
['OS=="android"', {
'variables': {
- 'isolate_dependency_untracked': [
+ 'files': [
'<(DEPTH)/data/',
'<(DEPTH)/resources/',
],
@@ -21,15 +21,12 @@
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/common_video_unittests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'<(DEPTH)/DEPS',
'<(DEPTH)/resources/foreman_cif.yuv',
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/common_video_unittests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_untracked': [
- '<(DEPTH)/tools/swarming_client/',
- ],
},
}],
],
diff --git a/config.cc b/config.cc
index e0324b9e..70bd8706 100644
--- a/config.cc
+++ b/config.cc
@@ -39,10 +39,10 @@ std::string VideoStream::ToString() const {
ss << ", max_bitrate_bps:" << max_bitrate_bps;
ss << ", max_qp: " << max_qp;
- ss << ", temporal_layers: {";
- for (size_t i = 0; i < temporal_layers.size(); ++i) {
- ss << temporal_layers[i];
- if (i != temporal_layers.size() - 1)
+ ss << ", temporal_layer_thresholds_bps: {";
+ for (size_t i = 0; i < temporal_layer_thresholds_bps.size(); ++i) {
+ ss << temporal_layer_thresholds_bps[i];
+ if (i != temporal_layer_thresholds_bps.size() - 1)
ss << "}, {";
}
ss << '}';
@@ -50,4 +50,32 @@ std::string VideoStream::ToString() const {
ss << '}';
return ss.str();
}
+
+std::string VideoEncoderConfig::ToString() const {
+ std::stringstream ss;
+
+ ss << "{streams: {";
+ for (size_t i = 0; i < streams.size(); ++i) {
+ ss << streams[i].ToString();
+ if (i != streams.size() - 1)
+ ss << "}, {";
+ }
+ ss << '}';
+ ss << ", content_type: ";
+ switch (content_type) {
+ case kRealtimeVideo:
+ ss << "kRealtimeVideo";
+ break;
+ case kScreenshare:
+ ss << "kScreenshare";
+ break;
+ }
+ ss << ", encoder_specific_settings: ";
+ ss << (encoder_specific_settings != NULL ? "(ptr)" : "NULL");
+
+ ss << ", min_transmit_bitrate_bps: " << min_transmit_bitrate_bps;
+ ss << '}';
+ return ss.str();
+}
+
} // namespace webrtc
diff --git a/config.h b/config.h
index 6f3fb1d6..8ea28288 100644
--- a/config.h
+++ b/config.h
@@ -104,8 +104,17 @@ struct VideoStream {
int max_qp;
- // Bitrate thresholds for enabling additional temporal layers.
- std::vector<int> temporal_layers;
+ // Bitrate thresholds for enabling additional temporal layers. Since these are
+ // thresholds in between layers, we have one additional layer. One threshold
+ // gives two temporal layers, one below the threshold and one above, two give
+ // three, and so on.
+ // The VideoEncoder may redistribute bitrates over the temporal layers so a
+ // bitrate threshold of 100k and an estimate of 105k does not imply that we
+ // get 100k in one temporal layer and 5k in the other, just that the bitrate
+ // in the first temporal layer should not exceed 100k.
+ // TODO(pbos): Apart from a special case for two-layer screencast these
+ // thresholds are not propagated to the VideoEncoder. To be implemented.
+ std::vector<int> temporal_layer_thresholds_bps;
};
struct VideoEncoderConfig {
@@ -115,11 +124,21 @@ struct VideoEncoderConfig {
};
VideoEncoderConfig()
- : content_type(kRealtimeVideo), encoder_specific_settings(NULL) {}
+ : content_type(kRealtimeVideo),
+ encoder_specific_settings(NULL),
+ min_transmit_bitrate_bps(0) {}
+
+ std::string ToString() const;
std::vector<VideoStream> streams;
ContentType content_type;
void* encoder_specific_settings;
+
+ // Padding will be used up to this bitrate regardless of the bitrate produced
+ // by the encoder. Padding above what's actually produced by the encoder helps
+ // maintaining a higher bitrate estimate. Padding will however not be sent
+ // unless the estimated bandwidth indicates that the link can handle it.
+ int min_transmit_bitrate_bps;
};
} // namespace webrtc
diff --git a/engine_configurations.h b/engine_configurations.h
index e9f23097..5b093e5c 100644
--- a/engine_configurations.h
+++ b/engine_configurations.h
@@ -21,13 +21,14 @@
// [Voice] Codec settings
// ----------------------------------------------------------------------------
-// iSAC is not included in the Mozilla build, but in all other builds.
+// iSAC and G722 are not included in the Mozilla build, but in all other builds.
#ifndef WEBRTC_MOZILLA_BUILD
#ifdef WEBRTC_ARCH_ARM
#define WEBRTC_CODEC_ISACFX // Fix-point iSAC implementation.
#else
#define WEBRTC_CODEC_ISAC // Floating-point iSAC implementation (default).
#endif // WEBRTC_ARCH_ARM
+#define WEBRTC_CODEC_G722
#endif // !WEBRTC_MOZILLA_BUILD
// AVT is included in all builds, along with G.711, NetEQ and CNG
@@ -37,11 +38,10 @@
// PCM16 is useful for testing and incurs only a small binary size cost.
#define WEBRTC_CODEC_PCM16
-// iLBC, G.722, and Redundancy coding are excluded from Chromium and Mozilla
+// iLBC and Redundancy coding are excluded from Chromium and Mozilla
// builds to reduce binary size.
#if !defined(WEBRTC_CHROMIUM_BUILD) && !defined(WEBRTC_MOZILLA_BUILD)
#define WEBRTC_CODEC_ILBC
-#define WEBRTC_CODEC_G722
#define WEBRTC_CODEC_RED
#endif // !WEBRTC_CHROMIUM_BUILD && !WEBRTC_MOZILLA_BUILD
@@ -51,6 +51,7 @@
#define VIDEOCODEC_I420
#define VIDEOCODEC_VP8
+#define VIDEOCODEC_VP9
#define VIDEOCODEC_H264
// ============================================================================
diff --git a/examples/android/media_demo/build.xml b/examples/android/media_demo/build.xml
index c8a51dd5..17734886 100644
--- a/examples/android/media_demo/build.xml
+++ b/examples/android/media_demo/build.xml
@@ -1,15 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="WebRTCDemo" default="help">
+
+ <!-- The local.properties file is created and updated by the 'android' tool.
+ It contains the path to the SDK. It should *NOT* be checked into
+ Version Control Systems. -->
<property file="local.properties" />
+
+ <!-- The ant.properties file can be created by you. It is only edited by the
+ 'android' tool to add properties to it.
+ This is the place to change some Ant specific build properties.
+ Here are some properties you may want to change/update:
+
+ source.dir
+ The name of the source directory. Default is 'src'.
+ out.dir
+ The name of the output directory. Default is 'bin'.
+
+ For other overridable properties, look at the beginning of the rules
+ files in the SDK, at tools/ant/build.xml
+
+ Properties related to the SDK location or the project target should
+ be updated using the 'android' tool with the 'update' action.
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems.
+
+ -->
+ <property file="ant.properties" />
+
+ <!-- if sdk.dir was not set from one of the property file, then
+ get it from the ANDROID_HOME env var.
+ This must be done before we load project.properties since
+ the proguard config can use sdk.dir -->
<property environment="env" />
<condition property="sdk.dir" value="${env.ANDROID_SDK_ROOT}">
<isset property="env.ANDROID_SDK_ROOT" />
</condition>
+
+ <!-- The project.properties file is created and updated by the 'android'
+ tool, as well as ADT.
+
+ This contains project specific properties such as project target, and library
+ dependencies. Lower level build properties are stored in ant.properties
+ (or in .classpath for Eclipse projects).
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems. -->
<loadproperties srcFile="project.properties" />
+
+ <!-- quick check on sdk.dir -->
<fail
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_SDK_ROOT environment variable."
unless="sdk.dir"
/>
+
+ <!--
+ Import per project custom build rules if present at the root of the project.
+ This is the place to put custom intermediary targets such as:
+ -pre-build
+ -pre-compile
+ -post-compile (This is typically used for code obfuscation.
+ Compiled code location: ${out.classes.absolute.dir}
+ If this is not done in place, override ${out.dex.input.absolute.dir})
+ -post-package
+ -post-build
+ -pre-clean
+ -->
<import file="custom_rules.xml" optional="true" />
+
+ <!-- Import the actual build file.
+
+ To customize existing targets, there are two options:
+ - Customize only one target:
+ - copy/paste the target into this file, *before* the
+ <import> task.
+ - customize it to your needs.
+ - Customize the whole content of build.xml
+ - copy/paste the content of the rules files (minus the top node)
+ into this file, replacing the <import> task.
+ - customize to your needs.
+
+ ***********************
+ ****** IMPORTANT ******
+ ***********************
+ In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+ in order to avoid having your file be overridden by tools such as "android update project"
+ -->
+ <!-- version-tag: 1 -->
<import file="${sdk.dir}/tools/ant/build.xml" />
+
</project>
diff --git a/examples/android/media_demo/project.properties b/examples/android/media_demo/project.properties
index 162fe605..8ee39b95 100644
--- a/examples/android/media_demo/project.properties
+++ b/examples/android/media_demo/project.properties
@@ -11,4 +11,4 @@
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
-target=android-19
+target=android-21
diff --git a/examples/android/opensl_loopback/project.properties b/examples/android/opensl_loopback/project.properties
index 8459f9b8..47b70783 100644
--- a/examples/android/opensl_loopback/project.properties
+++ b/examples/android/opensl_loopback/project.properties
@@ -11,6 +11,6 @@
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
-target=android-19
+target=android-21
java.compilerargs=-Xlint:all -Werror
diff --git a/libjingle/xmllite/rtc_xmllite.target.darwin-arm.mk b/libjingle/xmllite/rtc_xmllite.target.darwin-arm.mk
index b7f2f9c1..92f43a72 100644
--- a/libjingle/xmllite/rtc_xmllite.target.darwin-arm.mk
+++ b/libjingle/xmllite/rtc_xmllite.target.darwin-arm.mk
@@ -89,11 +89,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -114,6 +116,7 @@ MY_DEFS_Debug := \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
'-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -207,11 +210,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -232,6 +237,7 @@ MY_DEFS_Release := \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
'-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/libjingle/xmllite/rtc_xmllite.target.darwin-arm64.mk b/libjingle/xmllite/rtc_xmllite.target.darwin-arm64.mk
index d443071f..1042becb 100644
--- a/libjingle/xmllite/rtc_xmllite.target.darwin-arm64.mk
+++ b/libjingle/xmllite/rtc_xmllite.target.darwin-arm64.mk
@@ -78,11 +78,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -91,6 +93,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
@@ -100,6 +103,7 @@ MY_DEFS_Debug := \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
'-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -181,11 +185,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -194,6 +200,7 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
@@ -203,6 +210,7 @@ MY_DEFS_Release := \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
'-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/libjingle/xmllite/rtc_xmllite.target.darwin-mips.mk b/libjingle/xmllite/rtc_xmllite.target.darwin-mips.mk
index e1e9f6e2..d7f0305a 100644
--- a/libjingle/xmllite/rtc_xmllite.target.darwin-mips.mk
+++ b/libjingle/xmllite/rtc_xmllite.target.darwin-mips.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -106,6 +108,7 @@ MY_DEFS_Debug := \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
'-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -192,11 +195,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -216,6 +221,7 @@ MY_DEFS_Release := \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
'-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/libjingle/xmllite/rtc_xmllite.target.darwin-mips64.mk b/libjingle/xmllite/rtc_xmllite.target.darwin-mips64.mk
new file mode 100644
index 00000000..106a5e0f
--- /dev/null
+++ b/libjingle/xmllite/rtc_xmllite.target.darwin-mips64.mk
@@ -0,0 +1,275 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_libjingle_xmllite_rtc_xmllite_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/libjingle/xmllite/qname.cc \
+ third_party/webrtc/libjingle/xmllite/xmlbuilder.cc \
+ third_party/webrtc/libjingle/xmllite/xmlconstants.cc \
+ third_party/webrtc/libjingle/xmllite/xmlelement.cc \
+ third_party/webrtc/libjingle/xmllite/xmlnsstack.cc \
+ third_party/webrtc/libjingle/xmllite/xmlparser.cc \
+ third_party/webrtc/libjingle/xmllite/xmlprinter.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DFEATURE_ENABLE_SSL' \
+ '-DNO_MAIN_THREAD_WRAPPING' \
+ '-DSSL_USE_OPENSSL' \
+ '-DHAVE_OPENSSL_SSL_H' \
+ '-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/expat/files/lib
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DFEATURE_ENABLE_SSL' \
+ '-DNO_MAIN_THREAD_WRAPPING' \
+ '-DSSL_USE_OPENSSL' \
+ '-DHAVE_OPENSSL_SSL_H' \
+ '-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/expat/files/lib
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_libjingle_xmllite_rtc_xmllite_gyp
+
+# Alias gyp target name.
+.PHONY: rtc_xmllite
+rtc_xmllite: third_party_webrtc_libjingle_xmllite_rtc_xmllite_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/libjingle/xmllite/rtc_xmllite.target.darwin-x86.mk b/libjingle/xmllite/rtc_xmllite.target.darwin-x86.mk
index 30644307..7d9225cb 100644
--- a/libjingle/xmllite/rtc_xmllite.target.darwin-x86.mk
+++ b/libjingle/xmllite/rtc_xmllite.target.darwin-x86.mk
@@ -84,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -106,6 +108,7 @@ MY_DEFS_Debug := \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
'-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -193,11 +196,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -215,6 +220,7 @@ MY_DEFS_Release := \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
'-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/libjingle/xmllite/rtc_xmllite.target.darwin-x86_64.mk b/libjingle/xmllite/rtc_xmllite.target.darwin-x86_64.mk
index f7426fe6..dc3674d3 100644
--- a/libjingle/xmllite/rtc_xmllite.target.darwin-x86_64.mk
+++ b/libjingle/xmllite/rtc_xmllite.target.darwin-x86_64.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -105,6 +107,7 @@ MY_DEFS_Debug := \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
'-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -213,6 +218,7 @@ MY_DEFS_Release := \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
'-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/libjingle/xmllite/rtc_xmllite.target.linux-arm.mk b/libjingle/xmllite/rtc_xmllite.target.linux-arm.mk
index b7f2f9c1..92f43a72 100644
--- a/libjingle/xmllite/rtc_xmllite.target.linux-arm.mk
+++ b/libjingle/xmllite/rtc_xmllite.target.linux-arm.mk
@@ -89,11 +89,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -114,6 +116,7 @@ MY_DEFS_Debug := \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
'-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -207,11 +210,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -232,6 +237,7 @@ MY_DEFS_Release := \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
'-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/libjingle/xmllite/rtc_xmllite.target.linux-arm64.mk b/libjingle/xmllite/rtc_xmllite.target.linux-arm64.mk
index d443071f..1042becb 100644
--- a/libjingle/xmllite/rtc_xmllite.target.linux-arm64.mk
+++ b/libjingle/xmllite/rtc_xmllite.target.linux-arm64.mk
@@ -78,11 +78,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -91,6 +93,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
@@ -100,6 +103,7 @@ MY_DEFS_Debug := \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
'-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -181,11 +185,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -194,6 +200,7 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
@@ -203,6 +210,7 @@ MY_DEFS_Release := \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
'-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/libjingle/xmllite/rtc_xmllite.target.linux-mips.mk b/libjingle/xmllite/rtc_xmllite.target.linux-mips.mk
index e1e9f6e2..d7f0305a 100644
--- a/libjingle/xmllite/rtc_xmllite.target.linux-mips.mk
+++ b/libjingle/xmllite/rtc_xmllite.target.linux-mips.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -106,6 +108,7 @@ MY_DEFS_Debug := \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
'-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -192,11 +195,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -216,6 +221,7 @@ MY_DEFS_Release := \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
'-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/libjingle/xmllite/rtc_xmllite.target.linux-mips64.mk b/libjingle/xmllite/rtc_xmllite.target.linux-mips64.mk
new file mode 100644
index 00000000..106a5e0f
--- /dev/null
+++ b/libjingle/xmllite/rtc_xmllite.target.linux-mips64.mk
@@ -0,0 +1,275 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_libjingle_xmllite_rtc_xmllite_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/libjingle/xmllite/qname.cc \
+ third_party/webrtc/libjingle/xmllite/xmlbuilder.cc \
+ third_party/webrtc/libjingle/xmllite/xmlconstants.cc \
+ third_party/webrtc/libjingle/xmllite/xmlelement.cc \
+ third_party/webrtc/libjingle/xmllite/xmlnsstack.cc \
+ third_party/webrtc/libjingle/xmllite/xmlparser.cc \
+ third_party/webrtc/libjingle/xmllite/xmlprinter.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DFEATURE_ENABLE_SSL' \
+ '-DNO_MAIN_THREAD_WRAPPING' \
+ '-DSSL_USE_OPENSSL' \
+ '-DHAVE_OPENSSL_SSL_H' \
+ '-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/expat/files/lib
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DFEATURE_ENABLE_SSL' \
+ '-DNO_MAIN_THREAD_WRAPPING' \
+ '-DSSL_USE_OPENSSL' \
+ '-DHAVE_OPENSSL_SSL_H' \
+ '-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/expat/files/lib
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_libjingle_xmllite_rtc_xmllite_gyp
+
+# Alias gyp target name.
+.PHONY: rtc_xmllite
+rtc_xmllite: third_party_webrtc_libjingle_xmllite_rtc_xmllite_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/libjingle/xmllite/rtc_xmllite.target.linux-x86.mk b/libjingle/xmllite/rtc_xmllite.target.linux-x86.mk
index 30644307..7d9225cb 100644
--- a/libjingle/xmllite/rtc_xmllite.target.linux-x86.mk
+++ b/libjingle/xmllite/rtc_xmllite.target.linux-x86.mk
@@ -84,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -106,6 +108,7 @@ MY_DEFS_Debug := \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
'-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -193,11 +196,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -215,6 +220,7 @@ MY_DEFS_Release := \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
'-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/libjingle/xmllite/rtc_xmllite.target.linux-x86_64.mk b/libjingle/xmllite/rtc_xmllite.target.linux-x86_64.mk
index f7426fe6..dc3674d3 100644
--- a/libjingle/xmllite/rtc_xmllite.target.linux-x86_64.mk
+++ b/libjingle/xmllite/rtc_xmllite.target.linux-x86_64.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -105,6 +107,7 @@ MY_DEFS_Debug := \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
'-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -213,6 +218,7 @@ MY_DEFS_Release := \
'-DSSL_USE_OPENSSL' \
'-DHAVE_OPENSSL_SSL_H' \
'-DXML_STATIC' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/libjingle/xmpp/OWNERS b/libjingle/xmpp/OWNERS
new file mode 100644
index 00000000..1a24a6a8
--- /dev/null
+++ b/libjingle/xmpp/OWNERS
@@ -0,0 +1,13 @@
+henrika@webrtc.org
+henrike@webrtc.org
+henrikg@webrtc.org
+hta@webrtc.org
+jiayl@webrtc.org
+juberti@webrtc.org
+mflodman@webrtc.org
+perkj@webrtc.org
+pthatcher@webrtc.org
+sergeyu@chromium.org
+tommi@webrtc.org
+
+per-file BUILD.gn=kjellander@webrtc.org
diff --git a/libjingle/xmpp/asyncsocket.h b/libjingle/xmpp/asyncsocket.h
new file mode 100644
index 00000000..6d77ce08
--- /dev/null
+++ b/libjingle/xmpp/asyncsocket.h
@@ -0,0 +1,72 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_ASYNCSOCKET_H_
+#define WEBRTC_LIBJINGLE_XMPP_ASYNCSOCKET_H_
+
+#include <string>
+
+#include "webrtc/base/sigslot.h"
+
+namespace rtc {
+ class SocketAddress;
+}
+
+namespace buzz {
+
+class AsyncSocket {
+public:
+ enum State {
+ STATE_CLOSED = 0, //!< Socket is not open.
+ STATE_CLOSING, //!< Socket is closing but can have buffered data
+ STATE_CONNECTING, //!< In the process of
+ STATE_OPEN, //!< Socket is connected
+#if defined(FEATURE_ENABLE_SSL)
+ STATE_TLS_CONNECTING, //!< Establishing TLS connection
+ STATE_TLS_OPEN, //!< TLS connected
+#endif
+ };
+
+ enum Error {
+ ERROR_NONE = 0, //!< No error
+ ERROR_WINSOCK, //!< Winsock error
+ ERROR_DNS, //!< Couldn't resolve host name
+ ERROR_WRONGSTATE, //!< Call made while socket is in the wrong state
+#if defined(FEATURE_ENABLE_SSL)
+ ERROR_SSL, //!< Something went wrong with OpenSSL
+#endif
+ };
+
+ virtual ~AsyncSocket() {}
+ virtual State state() = 0;
+ virtual Error error() = 0;
+ virtual int GetError() = 0; // winsock error code
+
+ virtual bool Connect(const rtc::SocketAddress& addr) = 0;
+ virtual bool Read(char * data, size_t len, size_t* len_read) = 0;
+ virtual bool Write(const char * data, size_t len) = 0;
+ virtual bool Close() = 0;
+#if defined(FEATURE_ENABLE_SSL)
+ // We allow matching any passed domain. This allows us to avoid
+ // handling the valuable certificates for logins into proxies. If
+ // both names are passed as empty, we do not require a match.
+ virtual bool StartTls(const std::string & domainname) = 0;
+#endif
+
+ sigslot::signal0<> SignalConnected;
+ sigslot::signal0<> SignalSSLConnected;
+ sigslot::signal0<> SignalClosed;
+ sigslot::signal0<> SignalRead;
+ sigslot::signal0<> SignalError;
+};
+
+}
+
+#endif // WEBRTC_LIBJINGLE_XMPP_ASYNCSOCKET_H_
diff --git a/libjingle/xmpp/chatroommodule.h b/libjingle/xmpp/chatroommodule.h
new file mode 100644
index 00000000..a68f82b3
--- /dev/null
+++ b/libjingle/xmpp/chatroommodule.h
@@ -0,0 +1,253 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_CHATROOMMODULE_H_
+#define WEBRTC_LIBJINGLE_XMPP_CHATROOMMODULE_H_
+
+#include "webrtc/libjingle/xmpp/module.h"
+#include "webrtc/libjingle/xmpp/rostermodule.h"
+
+namespace buzz {
+
+// forward declarations
+class XmppChatroomModule;
+class XmppChatroomHandler;
+class XmppChatroomMember;
+class XmppChatroomMemberEnumerator;
+
+enum XmppChatroomState {
+ XMPP_CHATROOM_STATE_NOT_IN_ROOM = 0,
+ XMPP_CHATROOM_STATE_REQUESTED_ENTER = 1,
+ XMPP_CHATROOM_STATE_IN_ROOM = 2,
+ XMPP_CHATROOM_STATE_REQUESTED_EXIT = 3,
+};
+
+//! Module that encapsulates a chatroom.
+class XmppChatroomModule : public XmppModule {
+public:
+
+ //! Creates a new XmppChatroomModule
+ static XmppChatroomModule* Create();
+ virtual ~XmppChatroomModule() {}
+
+ //! Sets the chatroom handler (callbacks) for the chatroom
+ virtual XmppReturnStatus set_chatroom_handler(XmppChatroomHandler* handler) = 0;
+
+ //! Gets the chatroom handler for the module
+ virtual XmppChatroomHandler* chatroom_handler() = 0;
+
+ //! Sets the jid of the chatroom.
+ //! Has to be set before entering the chatroom and can't be changed
+ //! while in the chatroom
+ virtual XmppReturnStatus set_chatroom_jid(const Jid& chatroom_jid) = 0;
+
+ //! The jid for the chatroom
+ virtual const Jid& chatroom_jid() const = 0;
+
+ //! Sets the nickname of the member
+ //! Has to be set before entering the chatroom and can't be changed
+ //! while in the chatroom
+ virtual XmppReturnStatus set_nickname(const std::string& nickname) = 0;
+
+ //! The nickname of the member in the chatroom
+ virtual const std::string& nickname() const = 0;
+
+ //! Returns the jid of the member (this is the chatroom_jid plus the
+ //! nickname as the resource name)
+ virtual const Jid member_jid() const = 0;
+
+ //! Requests that the user enter a chatroom
+ //! The EnterChatroom callback will be called when the request is complete.
+ //! Password should be empty for a room that doesn't require a password
+ //! If the room doesn't exist, the server will create an "Instant Room" if the
+ //! server policy supports this action.
+ //! There will be different methods for creating/configuring a "Reserved Room"
+ //! Async callback for this method is ChatroomEnteredStatus
+ virtual XmppReturnStatus RequestEnterChatroom(const std::string& password,
+ const std::string& client_version,
+ const std::string& locale) = 0;
+
+ //! Requests that the user exit a chatroom
+ //! Async callback for this method is ChatroomExitedStatus
+ virtual XmppReturnStatus RequestExitChatroom() = 0;
+
+ //! Requests a status change
+ //! status is the standard XMPP status code
+ //! extended_status is the extended status when status is XMPP_PRESENCE_XA
+ virtual XmppReturnStatus RequestConnectionStatusChange(
+ XmppPresenceConnectionStatus connection_status) = 0;
+
+ //! Returns the number of members in the room
+ virtual size_t GetChatroomMemberCount() = 0;
+
+ //! Gets an enumerator for the members in the chatroom
+ //! The caller must delete the enumerator when the caller is finished with it.
+ //! The caller must also ensure that the lifetime of the enumerator is
+ //! scoped by the XmppChatRoomModule that created it.
+ virtual XmppReturnStatus CreateMemberEnumerator(XmppChatroomMemberEnumerator** enumerator) = 0;
+
+ //! Gets the subject of the chatroom
+ virtual const std::string subject() = 0;
+
+ //! Returns the current state of the user with respect to the chatroom
+ virtual XmppChatroomState state() = 0;
+
+ virtual XmppReturnStatus SendMessage(const XmlElement& message) = 0;
+};
+
+//! Class for enumerating participatns
+class XmppChatroomMemberEnumerator {
+public:
+ virtual ~XmppChatroomMemberEnumerator() { }
+ //! Returns the member at the current position
+ //! Returns null if the enumerator is before the beginning
+ //! or after the end of the collection
+ virtual XmppChatroomMember* current() = 0;
+
+ //! Returns whether the enumerator is valid
+ //! This returns true if the collection has changed
+ //! since the enumerator was created
+ virtual bool IsValid() = 0;
+
+ //! Returns whether the enumerator is before the beginning
+ //! This is the initial state of the enumerator
+ virtual bool IsBeforeBeginning() = 0;
+
+ //! Returns whether the enumerator is after the end
+ virtual bool IsAfterEnd() = 0;
+
+ //! Advances the enumerator to the next position
+ //! Returns false is the enumerator is advanced
+ //! off the end of the collection
+ virtual bool Next() = 0;
+
+ //! Advances the enumerator to the previous position
+ //! Returns false is the enumerator is advanced
+ //! off the end of the collection
+ virtual bool Prev() = 0;
+};
+
+
+//! Represents a single member in a chatroom
+class XmppChatroomMember {
+public:
+ virtual ~XmppChatroomMember() { }
+
+ //! The jid for the member in the chatroom
+ virtual const Jid member_jid() const = 0;
+
+ //! The full jid for the member
+ //! This is only available in non-anonymous rooms.
+ //! If the room is anonymous, this returns JID_EMPTY
+ virtual const Jid full_jid() const = 0;
+
+ //! Returns the backing presence for this member
+ virtual const XmppPresence* presence() const = 0;
+
+ //! The nickname for this member
+ virtual const std::string name() const = 0;
+};
+
+//! Status codes for ChatroomEnteredStatus callback
+enum XmppChatroomEnteredStatus
+{
+ //! User successfully entered the room
+ XMPP_CHATROOM_ENTERED_SUCCESS = 0,
+ //! The nickname confliced with somebody already in the room
+ XMPP_CHATROOM_ENTERED_FAILURE_NICKNAME_CONFLICT = 1,
+ //! A password is required to enter the room
+ XMPP_CHATROOM_ENTERED_FAILURE_PASSWORD_REQUIRED = 2,
+ //! The specified password was incorrect
+ XMPP_CHATROOM_ENTERED_FAILURE_PASSWORD_INCORRECT = 3,
+ //! The user is not a member of a member-only room
+ XMPP_CHATROOM_ENTERED_FAILURE_NOT_A_MEMBER = 4,
+ //! The user cannot enter because the user has been banned
+ XMPP_CHATROOM_ENTERED_FAILURE_MEMBER_BANNED = 5,
+ //! The room has the maximum number of users already
+ XMPP_CHATROOM_ENTERED_FAILURE_MAX_USERS = 6,
+ //! The room has been locked by an administrator
+ XMPP_CHATROOM_ENTERED_FAILURE_ROOM_LOCKED = 7,
+ //! Someone in the room has blocked you
+ XMPP_CHATROOM_ENTERED_FAILURE_MEMBER_BLOCKED = 8,
+ //! You have blocked someone in the room
+ XMPP_CHATROOM_ENTERED_FAILURE_MEMBER_BLOCKING = 9,
+ //! Client is old. User must upgrade to a more recent version for
+ // hangouts to work.
+ XMPP_CHATROOM_ENTERED_FAILURE_OUTDATED_CLIENT = 10,
+ //! Some other reason
+ XMPP_CHATROOM_ENTERED_FAILURE_UNSPECIFIED = 2000,
+};
+
+//! Status codes for ChatroomExitedStatus callback
+enum XmppChatroomExitedStatus
+{
+ //! The user requested to exit and did so
+ XMPP_CHATROOM_EXITED_REQUESTED = 0,
+ //! The user was banned from the room
+ XMPP_CHATROOM_EXITED_BANNED = 1,
+ //! The user has been kicked out of the room
+ XMPP_CHATROOM_EXITED_KICKED = 2,
+ //! The user has been removed from the room because the
+ //! user is no longer a member of a member-only room
+ //! or the room has changed to membership-only
+ XMPP_CHATROOM_EXITED_NOT_A_MEMBER = 3,
+ //! The system is shutting down
+ XMPP_CHATROOM_EXITED_SYSTEM_SHUTDOWN = 4,
+ //! For some other reason
+ XMPP_CHATROOM_EXITED_UNSPECIFIED = 5,
+};
+
+//! The XmppChatroomHandler is the interface for callbacks from the
+//! the chatroom
+class XmppChatroomHandler {
+public:
+ virtual ~XmppChatroomHandler() {}
+
+ //! Indicates the response to RequestEnterChatroom method
+ //! XMPP_CHATROOM_SUCCESS represents success.
+ //! Other status codes are for errors
+ virtual void ChatroomEnteredStatus(XmppChatroomModule* room,
+ const XmppPresence* presence,
+ XmppChatroomEnteredStatus status) = 0;
+
+
+ //! Indicates that the user has exited the chatroom, either due to
+ //! a call to RequestExitChatroom or for some other reason.
+ //! status indicates the reason the user exited
+ virtual void ChatroomExitedStatus(XmppChatroomModule* room,
+ XmppChatroomExitedStatus status) = 0;
+
+ //! Indicates a member entered the room.
+ //! It can be called before ChatroomEnteredStatus.
+ virtual void MemberEntered(XmppChatroomModule* room,
+ const XmppChatroomMember* entered_member) = 0;
+
+ //! Indicates that a member exited the room.
+ virtual void MemberExited(XmppChatroomModule* room,
+ const XmppChatroomMember* exited_member) = 0;
+
+ //! Indicates that the data for the member has changed
+ //! (such as the nickname or presence)
+ virtual void MemberChanged(XmppChatroomModule* room,
+ const XmppChatroomMember* changed_member) = 0;
+
+ //! Indicates a new message has been received
+ //! message is the message -
+ // $TODO - message should be changed
+ //! to a strongly-typed message class that contains info
+ //! such as the sender, message bodies, etc.,
+ virtual void MessageReceived(XmppChatroomModule* room,
+ const XmlElement& message) = 0;
+};
+
+
+}
+
+#endif // WEBRTC_LIBJINGLE_XMPP_CHATROOMMODULE_H_
diff --git a/libjingle/xmpp/chatroommodule_unittest.cc b/libjingle/xmpp/chatroommodule_unittest.cc
new file mode 100644
index 00000000..27b52111
--- /dev/null
+++ b/libjingle/xmpp/chatroommodule_unittest.cc
@@ -0,0 +1,280 @@
+/*
+ * 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 <iostream>
+#include <sstream>
+#include <string>
+#include "buzz/chatroommodule.h"
+#include "buzz/constants.h"
+#include "buzz/xmlelement.h"
+#include "buzz/xmppengine.h"
+#include "common/common.h"
+#include "engine/util_unittest.h"
+#include "test/unittest-inl.h"
+#include "test/unittest.h"
+
+#define TEST_OK(x) TEST_EQ((x),XMPP_RETURN_OK)
+#define TEST_BADARGUMENT(x) TEST_EQ((x),XMPP_RETURN_BADARGUMENT)
+
+namespace buzz {
+
+class MultiUserChatModuleTest;
+
+static void
+WriteEnteredStatus(std::ostream& os, XmppChatroomEnteredStatus status) {
+ switch(status) {
+ case XMPP_CHATROOM_ENTERED_SUCCESS:
+ os<<"success";
+ break;
+ case XMPP_CHATROOM_ENTERED_FAILURE_NICKNAME_CONFLICT:
+ os<<"failure(nickname conflict)";
+ break;
+ case XMPP_CHATROOM_ENTERED_FAILURE_PASSWORD_REQUIRED:
+ os<<"failure(password required)";
+ break;
+ case XMPP_CHATROOM_ENTERED_FAILURE_PASSWORD_INCORRECT:
+ os<<"failure(password incorrect)";
+ break;
+ case XMPP_CHATROOM_ENTERED_FAILURE_NOT_A_MEMBER:
+ os<<"failure(not a member)";
+ break;
+ case XMPP_CHATROOM_ENTERED_FAILURE_MEMBER_BANNED:
+ os<<"failure(member banned)";
+ break;
+ case XMPP_CHATROOM_ENTERED_FAILURE_MAX_USERS:
+ os<<"failure(max users)";
+ break;
+ case XMPP_CHATROOM_ENTERED_FAILURE_ROOM_LOCKED:
+ os<<"failure(room locked)";
+ break;
+ case XMPP_CHATROOM_ENTERED_FAILURE_UNSPECIFIED:
+ os<<"failure(unspecified)";
+ break;
+ default:
+ os<<"unknown";
+ break;
+ }
+}
+
+static void
+WriteExitedStatus(std::ostream& os, XmppChatroomExitedStatus status) {
+ switch (status) {
+ case XMPP_CHATROOM_EXITED_REQUESTED:
+ os<<"requested";
+ break;
+ case XMPP_CHATROOM_EXITED_BANNED:
+ os<<"banned";
+ break;
+ case XMPP_CHATROOM_EXITED_KICKED:
+ os<<"kicked";
+ break;
+ case XMPP_CHATROOM_EXITED_NOT_A_MEMBER:
+ os<<"not member";
+ break;
+ case XMPP_CHATROOM_EXITED_SYSTEM_SHUTDOWN:
+ os<<"system shutdown";
+ break;
+ case XMPP_CHATROOM_EXITED_UNSPECIFIED:
+ os<<"unspecified";
+ break;
+ default:
+ os<<"unknown";
+ break;
+ }
+}
+
+//! This session handler saves all calls to a string. These are events and
+//! data delivered form the engine to application code.
+class XmppTestChatroomHandler : public XmppChatroomHandler {
+public:
+ XmppTestChatroomHandler() {}
+ virtual ~XmppTestChatroomHandler() {}
+
+ void ChatroomEnteredStatus(XmppChatroomModule* room,
+ XmppChatroomEnteredStatus status) {
+ RTC_UNUSED(room);
+ ss_ <<"[ChatroomEnteredStatus status: ";
+ WriteEnteredStatus(ss_, status);
+ ss_ <<"]";
+ }
+
+
+ void ChatroomExitedStatus(XmppChatroomModule* room,
+ XmppChatroomExitedStatus status) {
+ RTC_UNUSED(room);
+ ss_ <<"[ChatroomExitedStatus status: ";
+ WriteExitedStatus(ss_, status);
+ ss_ <<"]";
+ }
+
+ void MemberEntered(XmppChatroomModule* room,
+ const XmppChatroomMember* entered_member) {
+ RTC_UNUSED(room);
+ ss_ << "[MemberEntered " << entered_member->member_jid().Str() << "]";
+ }
+
+ void MemberExited(XmppChatroomModule* room,
+ const XmppChatroomMember* exited_member) {
+ RTC_UNUSED(room);
+ ss_ << "[MemberExited " << exited_member->member_jid().Str() << "]";
+ }
+
+ void MemberChanged(XmppChatroomModule* room,
+ const XmppChatroomMember* changed_member) {
+ RTC_UNUSED(room);
+ ss_ << "[MemberChanged " << changed_member->member_jid().Str() << "]";
+ }
+
+ virtual void MessageReceived(XmppChatroomModule* room, const XmlElement& message) {
+ RTC_UNUSED2(room, message);
+ }
+
+
+ std::string Str() {
+ return ss_.str();
+ }
+
+ std::string StrClear() {
+ std::string result = ss_.str();
+ ss_.str("");
+ return result;
+ }
+
+private:
+ std::stringstream ss_;
+};
+
+//! This is the class that holds all of the unit test code for the
+//! roster module
+class XmppChatroomModuleTest : public UnitTest {
+public:
+ XmppChatroomModuleTest() {}
+
+ void TestEnterExitChatroom() {
+ std::stringstream dump;
+
+ // Configure the engine
+ scoped_ptr<XmppEngine> engine(XmppEngine::Create());
+ XmppTestHandler handler(engine.get());
+
+ // Configure the module and handler
+ scoped_ptr<XmppChatroomModule> chatroom(XmppChatroomModule::Create());
+
+ // Configure the module handler
+ chatroom->RegisterEngine(engine.get());
+
+ // Set up callbacks
+ engine->SetOutputHandler(&handler);
+ engine->AddStanzaHandler(&handler);
+ engine->SetSessionHandler(&handler);
+
+ // Set up minimal login info
+ engine->SetUser(Jid("david@my-server"));
+ engine->SetPassword("david");
+
+ // Do the whole login handshake
+ RunLogin(this, engine.get(), &handler);
+ TEST_EQ("", handler.OutputActivity());
+
+ // Get the chatroom and set the handler
+ XmppTestChatroomHandler chatroom_handler;
+ chatroom->set_chatroom_handler(static_cast<XmppChatroomHandler*>(&chatroom_handler));
+
+ // try to enter the chatroom
+ TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_NOT_IN_ROOM);
+ chatroom->set_nickname("thirdwitch");
+ chatroom->set_chatroom_jid(Jid("darkcave@my-server"));
+ chatroom->RequestEnterChatroom("", XMPP_CONNECTION_STATUS_UNKNOWN, "en");
+ TEST_EQ(chatroom_handler.StrClear(), "");
+ TEST_EQ(handler.OutputActivity(),
+ "<presence to=\"darkcave@my-server/thirdwitch\">"
+ "<muc:x xmlns:muc=\"http://jabber.org/protocol/muc\"/>"
+ "</presence>");
+ TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_REQUESTED_ENTER);
+
+ // simulate the server and test the client
+ std::string input;
+ input = "<presence from=\"darkcave@my-server/firstwitch\" to=\"david@my-server\">"
+ "<x xmlns=\"http://jabber.org/protocol/muc#user\">"
+ "<item affiliation=\"owner\" role=\"participant\"/>"
+ "</x>"
+ "</presence>";
+ TEST_OK(engine->HandleInput(input.c_str(), input.length()));
+ TEST_EQ(chatroom_handler.StrClear(), "");
+ TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_REQUESTED_ENTER);
+
+ input = "<presence from=\"darkcave@my-server/secondwitch\" to=\"david@my-server\">"
+ "<x xmlns=\"http://jabber.org/protocol/muc#user\">"
+ "<item affiliation=\"member\" role=\"participant\"/>"
+ "</x>"
+ "</presence>";
+ TEST_OK(engine->HandleInput(input.c_str(), input.length()));
+ TEST_EQ(chatroom_handler.StrClear(), "");
+ TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_REQUESTED_ENTER);
+
+ input = "<presence from=\"darkcave@my-server/thirdwitch\" to=\"david@my-server\">"
+ "<x xmlns=\"http://jabber.org/protocol/muc#user\">"
+ "<item affiliation=\"member\" role=\"participant\"/>"
+ "</x>"
+ "</presence>";
+ TEST_OK(engine->HandleInput(input.c_str(), input.length()));
+ TEST_EQ(chatroom_handler.StrClear(),
+ "[ChatroomEnteredStatus status: success]");
+ TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_IN_ROOM);
+
+ // simulate somebody else entering the room after we entered
+ input = "<presence from=\"darkcave@my-server/fourthwitch\" to=\"david@my-server\">"
+ "<x xmlns=\"http://jabber.org/protocol/muc#user\">"
+ "<item affiliation=\"member\" role=\"participant\"/>"
+ "</x>"
+ "</presence>";
+ TEST_OK(engine->HandleInput(input.c_str(), input.length()));
+ TEST_EQ(chatroom_handler.StrClear(), "[MemberEntered darkcave@my-server/fourthwitch]");
+ TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_IN_ROOM);
+
+ // simulate somebody else leaving the room after we entered
+ input = "<presence from=\"darkcave@my-server/secondwitch\" to=\"david@my-server\" type=\"unavailable\">"
+ "<x xmlns=\"http://jabber.org/protocol/muc#user\">"
+ "<item affiliation=\"member\" role=\"participant\"/>"
+ "</x>"
+ "</presence>";
+ TEST_OK(engine->HandleInput(input.c_str(), input.length()));
+ TEST_EQ(chatroom_handler.StrClear(), "[MemberExited darkcave@my-server/secondwitch]");
+ TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_IN_ROOM);
+
+ // try to leave the room
+ chatroom->RequestExitChatroom();
+ TEST_EQ(chatroom_handler.StrClear(), "");
+ TEST_EQ(handler.OutputActivity(),
+ "<presence to=\"darkcave@my-server/thirdwitch\" type=\"unavailable\"/>");
+ TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_REQUESTED_EXIT);
+
+ // simulate the server and test the client
+ input = "<presence from=\"darkcave@my-server/thirdwitch\" to=\"david@my-server\" type=\"unavailable\">"
+ "<x xmlns=\"http://jabber.org/protocol/muc#user\">"
+ "<item affiliation=\"member\" role=\"participant\"/>"
+ "</x>"
+ "</presence>";
+ TEST_OK(engine->HandleInput(input.c_str(), input.length()));
+ TEST_EQ(chatroom_handler.StrClear(),
+ "[ChatroomExitedStatus status: requested]");
+ TEST_EQ(chatroom->state(), XMPP_CHATROOM_STATE_NOT_IN_ROOM);
+ }
+
+};
+
+// A global function that creates the test suite for this set of tests.
+TestBase* ChatroomModuleTest_Create() {
+ TestSuite* suite = new TestSuite("ChatroomModuleTest");
+ ADD_TEST(suite, XmppChatroomModuleTest, TestEnterExitChatroom);
+ return suite;
+}
+
+}
diff --git a/libjingle/xmpp/chatroommoduleimpl.cc b/libjingle/xmpp/chatroommoduleimpl.cc
new file mode 100644
index 00000000..546aa75f
--- /dev/null
+++ b/libjingle/xmpp/chatroommoduleimpl.cc
@@ -0,0 +1,735 @@
+/*
+ * 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 <algorithm>
+#include <iostream>
+#include <map>
+#include <sstream>
+#include <string>
+#include <vector>
+#include "webrtc/libjingle/xmpp/chatroommodule.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/moduleimpl.h"
+#include "webrtc/base/common.h"
+
+namespace buzz {
+
+// forward declarations
+class XmppChatroomImpl;
+class XmppChatroomMemberImpl;
+
+//! Module that encapsulates multiple chatrooms.
+//! Each chatroom is represented by an XmppChatroomImpl instance
+class XmppChatroomModuleImpl : public XmppChatroomModule,
+ public XmppModuleImpl, public XmppIqHandler {
+public:
+ IMPLEMENT_XMPPMODULE
+
+ // Creates a chatroom with specified Jid
+ XmppChatroomModuleImpl();
+ ~XmppChatroomModuleImpl();
+
+ // XmppChatroomModule
+ virtual XmppReturnStatus set_chatroom_handler(XmppChatroomHandler* handler);
+ virtual XmppChatroomHandler* chatroom_handler();
+ virtual XmppReturnStatus set_chatroom_jid(const Jid& chatroom_jid);
+ virtual const Jid& chatroom_jid() const;
+ virtual XmppReturnStatus set_nickname(const std::string& nickname);
+ virtual const std::string& nickname() const;
+ virtual const Jid member_jid() const;
+ virtual XmppReturnStatus RequestEnterChatroom(const std::string& password,
+ const std::string& client_version,
+ const std::string& locale);
+ virtual XmppReturnStatus RequestExitChatroom();
+ virtual XmppReturnStatus RequestConnectionStatusChange(
+ XmppPresenceConnectionStatus connection_status);
+ virtual size_t GetChatroomMemberCount();
+ virtual XmppReturnStatus CreateMemberEnumerator(XmppChatroomMemberEnumerator** enumerator);
+ virtual const std::string subject();
+ virtual XmppChatroomState state() { return chatroom_state_; }
+ virtual XmppReturnStatus SendMessage(const XmlElement& message);
+
+ // XmppModule
+ virtual void IqResponse(XmppIqCookie cookie, const XmlElement * pelStanza) {RTC_UNUSED2(cookie, pelStanza);}
+ virtual bool HandleStanza(const XmlElement *);
+
+private:
+ friend class XmppChatroomMemberEnumeratorImpl;
+
+ XmppReturnStatus ServerChangeMyPresence(const XmlElement& presence);
+ XmppReturnStatus ClientChangeMyPresence(XmppChatroomState new_state);
+ XmppReturnStatus ChangePresence(XmppChatroomState new_state, const XmlElement* presence, bool isServer);
+ XmppReturnStatus ServerChangedOtherPresence(const XmlElement& presence_element);
+ XmppChatroomEnteredStatus GetEnterFailureFromXml(const XmlElement* presence);
+ XmppChatroomExitedStatus GetExitFailureFromXml(const XmlElement* presence);
+
+ bool CheckEnterChatroomStateOk();
+
+ void FireEnteredStatus(const XmlElement* presence,
+ XmppChatroomEnteredStatus status);
+ void FireExitStatus(XmppChatroomExitedStatus status);
+ void FireMessageReceived(const XmlElement& message);
+ void FireMemberEntered(const XmppChatroomMember* entered_member);
+ void FireMemberChanged(const XmppChatroomMember* changed_member);
+ void FireMemberExited(const XmppChatroomMember* exited_member);
+
+
+ typedef std::map<Jid, XmppChatroomMemberImpl*> JidMemberMap;
+
+ XmppChatroomHandler* chatroom_handler_;
+ Jid chatroom_jid_;
+ std::string nickname_;
+ XmppChatroomState chatroom_state_;
+ JidMemberMap chatroom_jid_members_;
+ int chatroom_jid_members_version_;
+};
+
+
+class XmppChatroomMemberImpl : public XmppChatroomMember {
+public:
+ ~XmppChatroomMemberImpl() {}
+ XmppReturnStatus SetPresence(const XmppPresence* presence);
+
+ // XmppChatroomMember
+ const Jid member_jid() const;
+ const Jid full_jid() const;
+ const std::string name() const;
+ const XmppPresence* presence() const;
+
+private:
+ rtc::scoped_ptr<XmppPresence> presence_;
+};
+
+class XmppChatroomMemberEnumeratorImpl :
+ public XmppChatroomMemberEnumerator {
+public:
+ XmppChatroomMemberEnumeratorImpl(XmppChatroomModuleImpl::JidMemberMap* chatroom_jid_members,
+ int* map_version);
+
+ // XmppChatroomMemberEnumerator
+ virtual XmppChatroomMember* current();
+ virtual bool Next();
+ virtual bool Prev();
+ virtual bool IsValid();
+ virtual bool IsBeforeBeginning();
+ virtual bool IsAfterEnd();
+
+private:
+ XmppChatroomModuleImpl::JidMemberMap* map_;
+ int map_version_created_;
+ int* map_version_;
+ XmppChatroomModuleImpl::JidMemberMap::iterator iterator_;
+ bool before_beginning_;
+};
+
+
+// XmppChatroomModuleImpl ------------------------------------------------
+XmppChatroomModule *
+XmppChatroomModule::Create() {
+ return new XmppChatroomModuleImpl();
+}
+
+XmppChatroomModuleImpl::XmppChatroomModuleImpl() :
+ chatroom_handler_(NULL),
+ chatroom_jid_(STR_EMPTY),
+ chatroom_state_(XMPP_CHATROOM_STATE_NOT_IN_ROOM),
+ chatroom_jid_members_version_(0) {
+}
+
+XmppChatroomModuleImpl::~XmppChatroomModuleImpl() {
+ JidMemberMap::iterator iterator = chatroom_jid_members_.begin();
+ while (iterator != chatroom_jid_members_.end()) {
+ delete iterator->second;
+ iterator++;
+ }
+}
+
+
+bool
+XmppChatroomModuleImpl::HandleStanza(const XmlElement* stanza) {
+ ASSERT(engine() != NULL);
+
+ // we handle stanzas that are for one of our chatrooms
+ Jid from_jid = Jid(stanza->Attr(QN_FROM));
+ // see if it's one of our chatrooms
+ if (chatroom_jid_ != from_jid.BareJid()) {
+ return false; // not one of our chatrooms
+ } else {
+ // handle presence stanza
+ if (stanza->Name() == QN_PRESENCE) {
+ if (from_jid == member_jid()) {
+ ServerChangeMyPresence(*stanza);
+ } else {
+ ServerChangedOtherPresence(*stanza);
+ }
+ } else if (stanza->Name() == QN_MESSAGE) {
+ FireMessageReceived(*stanza);
+ }
+ return true;
+ }
+}
+
+
+XmppReturnStatus
+XmppChatroomModuleImpl::set_chatroom_handler(XmppChatroomHandler* handler) {
+ // Calling with NULL removes the handler.
+ chatroom_handler_ = handler;
+ return XMPP_RETURN_OK;
+}
+
+
+XmppChatroomHandler*
+XmppChatroomModuleImpl::chatroom_handler() {
+ return chatroom_handler_;
+}
+
+XmppReturnStatus
+XmppChatroomModuleImpl::set_chatroom_jid(const Jid& chatroom_jid) {
+ if (chatroom_state_ != XMPP_CHATROOM_STATE_NOT_IN_ROOM) {
+ return XMPP_RETURN_BADSTATE; // $TODO - this isn't a bad state, it's a bad call, diff error code?
+ }
+ if (chatroom_jid != chatroom_jid.BareJid()) {
+ // chatroom_jid must be a bare jid
+ return XMPP_RETURN_BADARGUMENT;
+ }
+
+ chatroom_jid_ = chatroom_jid;
+ return XMPP_RETURN_OK;
+}
+
+const Jid&
+XmppChatroomModuleImpl::chatroom_jid() const {
+ return chatroom_jid_;
+}
+
+ XmppReturnStatus
+ XmppChatroomModuleImpl::set_nickname(const std::string& nickname) {
+ if (chatroom_state_ != XMPP_CHATROOM_STATE_NOT_IN_ROOM) {
+ return XMPP_RETURN_BADSTATE; // $TODO - this isn't a bad state, it's a bad call, diff error code?
+ }
+ nickname_ = nickname;
+ return XMPP_RETURN_OK;
+ }
+
+ const std::string&
+ XmppChatroomModuleImpl::nickname() const {
+ return nickname_;
+ }
+
+const Jid
+XmppChatroomModuleImpl::member_jid() const {
+ return Jid(chatroom_jid_.node(), chatroom_jid_.domain(), nickname_);
+}
+
+
+bool
+XmppChatroomModuleImpl::CheckEnterChatroomStateOk() {
+ if (chatroom_jid_.IsValid() == false) {
+ ASSERT(0);
+ return false;
+ }
+ if (nickname_ == STR_EMPTY) {
+ ASSERT(0);
+ return false;
+ }
+ return true;
+}
+
+std::string GetAttrValueFor(XmppPresenceConnectionStatus connection_status) {
+ switch (connection_status) {
+ default:
+ case XMPP_CONNECTION_STATUS_UNKNOWN:
+ return "";
+ case XMPP_CONNECTION_STATUS_CONNECTING:
+ return STR_PSTN_CONFERENCE_STATUS_CONNECTING;
+ case XMPP_CONNECTION_STATUS_CONNECTED:
+ return STR_PSTN_CONFERENCE_STATUS_CONNECTED;
+ }
+}
+
+XmppReturnStatus
+XmppChatroomModuleImpl::RequestEnterChatroom(
+ const std::string& password,
+ const std::string& client_version,
+ const std::string& locale) {
+ RTC_UNUSED(password);
+ if (!engine())
+ return XMPP_RETURN_BADSTATE;
+
+ if (chatroom_state_ != XMPP_CHATROOM_STATE_NOT_IN_ROOM)
+ return XMPP_RETURN_BADSTATE; // $TODO - this isn't a bad state, it's a bad call, diff error code?
+
+ if (CheckEnterChatroomStateOk() == false) {
+ return XMPP_RETURN_BADSTATE;
+ }
+
+ // entering a chatroom is a presence request to the server
+ XmlElement element(QN_PRESENCE);
+ element.AddAttr(QN_TO, member_jid().Str());
+
+ XmlElement* muc_x = new XmlElement(QN_MUC_X);
+ element.AddElement(muc_x);
+
+ if (!client_version.empty()) {
+ XmlElement* client_version_element = new XmlElement(QN_CLIENT_VERSION,
+ false);
+ client_version_element->SetBodyText(client_version);
+ muc_x->AddElement(client_version_element);
+ }
+
+ if (!locale.empty()) {
+ XmlElement* locale_element = new XmlElement(QN_LOCALE, false);
+
+ locale_element->SetBodyText(locale);
+ muc_x->AddElement(locale_element);
+ }
+
+ XmppReturnStatus status = engine()->SendStanza(&element);
+ if (status == XMPP_RETURN_OK) {
+ return ClientChangeMyPresence(XMPP_CHATROOM_STATE_REQUESTED_ENTER);
+ }
+ return status;
+}
+
+XmppReturnStatus
+XmppChatroomModuleImpl::RequestExitChatroom() {
+ if (!engine())
+ return XMPP_RETURN_BADSTATE;
+
+ // exiting a chatroom is a presence request to the server
+ XmlElement element(QN_PRESENCE);
+ element.AddAttr(QN_TO, member_jid().Str());
+ element.AddAttr(QN_TYPE, "unavailable");
+ XmppReturnStatus status = engine()->SendStanza(&element);
+ if (status == XMPP_RETURN_OK &&
+ chatroom_state_ == XMPP_CHATROOM_STATE_IN_ROOM) {
+ return ClientChangeMyPresence(XMPP_CHATROOM_STATE_REQUESTED_EXIT);
+ }
+ return status;
+}
+
+XmppReturnStatus
+XmppChatroomModuleImpl::RequestConnectionStatusChange(
+ XmppPresenceConnectionStatus connection_status) {
+ if (!engine())
+ return XMPP_RETURN_BADSTATE;
+
+ if (chatroom_state_ != XMPP_CHATROOM_STATE_IN_ROOM) {
+ // $TODO - this isn't a bad state, it's a bad call, diff error code?
+ return XMPP_RETURN_BADSTATE;
+ }
+
+ if (CheckEnterChatroomStateOk() == false) {
+ return XMPP_RETURN_BADSTATE;
+ }
+
+ // entering a chatroom is a presence request to the server
+ XmlElement element(QN_PRESENCE);
+ element.AddAttr(QN_TO, member_jid().Str());
+ element.AddElement(new XmlElement(QN_MUC_X));
+ if (connection_status != XMPP_CONNECTION_STATUS_UNKNOWN) {
+ XmlElement* con_status_element =
+ new XmlElement(QN_GOOGLE_PSTN_CONFERENCE_STATUS);
+ con_status_element->AddAttr(QN_STATUS, GetAttrValueFor(connection_status));
+ element.AddElement(con_status_element);
+ }
+ XmppReturnStatus status = engine()->SendStanza(&element);
+
+ return status;
+}
+
+size_t
+XmppChatroomModuleImpl::GetChatroomMemberCount() {
+ return chatroom_jid_members_.size();
+}
+
+XmppReturnStatus
+XmppChatroomModuleImpl::CreateMemberEnumerator(XmppChatroomMemberEnumerator** enumerator) {
+ *enumerator = new XmppChatroomMemberEnumeratorImpl(&chatroom_jid_members_, &chatroom_jid_members_version_);
+ return XMPP_RETURN_OK;
+}
+
+const std::string
+XmppChatroomModuleImpl::subject() {
+ return ""; //NYI
+}
+
+XmppReturnStatus
+XmppChatroomModuleImpl::SendMessage(const XmlElement& message) {
+ XmppReturnStatus xmpp_status = XMPP_RETURN_OK;
+
+ // can only send a message if we're in the room
+ if (chatroom_state_ != XMPP_CHATROOM_STATE_IN_ROOM) {
+ return XMPP_RETURN_BADSTATE; // $TODO - this isn't a bad state, it's a bad call, diff error code?
+ }
+
+ if (message.Name() != QN_MESSAGE) {
+ IFR(XMPP_RETURN_BADARGUMENT);
+ }
+
+ const std::string& type = message.Attr(QN_TYPE);
+ if (type != "groupchat") {
+ IFR(XMPP_RETURN_BADARGUMENT);
+ }
+
+ if (message.HasAttr(QN_FROM)) {
+ IFR(XMPP_RETURN_BADARGUMENT);
+ }
+
+ if (message.Attr(QN_TO) != chatroom_jid_.Str()) {
+ IFR(XMPP_RETURN_BADARGUMENT);
+ }
+
+ IFR(engine()->SendStanza(&message));
+
+ return xmpp_status;
+}
+
+enum TransitionType {
+ TRANSITION_TYPE_NONE = 0,
+ TRANSITION_TYPE_ENTER_SUCCESS = 1,
+ TRANSITION_TYPE_ENTER_FAILURE = 2,
+ TRANSITION_TYPE_EXIT_VOLUNTARILY = 3,
+ TRANSITION_TYPE_EXIT_INVOLUNTARILY = 4,
+};
+
+struct StateTransitionDescription {
+ XmppChatroomState old_state;
+ XmppChatroomState new_state;
+ bool is_valid_server_transition;
+ bool is_valid_client_transition;
+ TransitionType transition_type;
+};
+
+StateTransitionDescription Transitions[] = {
+ { XMPP_CHATROOM_STATE_NOT_IN_ROOM, XMPP_CHATROOM_STATE_REQUESTED_ENTER, false, true, TRANSITION_TYPE_NONE, },
+ { XMPP_CHATROOM_STATE_NOT_IN_ROOM, XMPP_CHATROOM_STATE_IN_ROOM, false, false, TRANSITION_TYPE_ENTER_SUCCESS, },
+ { XMPP_CHATROOM_STATE_NOT_IN_ROOM, XMPP_CHATROOM_STATE_REQUESTED_EXIT, false, false, TRANSITION_TYPE_NONE, },
+ { XMPP_CHATROOM_STATE_REQUESTED_ENTER, XMPP_CHATROOM_STATE_NOT_IN_ROOM, true, false, TRANSITION_TYPE_ENTER_FAILURE, },
+ { XMPP_CHATROOM_STATE_REQUESTED_ENTER, XMPP_CHATROOM_STATE_IN_ROOM, true, false, TRANSITION_TYPE_ENTER_SUCCESS, },
+ { XMPP_CHATROOM_STATE_REQUESTED_ENTER, XMPP_CHATROOM_STATE_REQUESTED_EXIT, false, false, TRANSITION_TYPE_NONE, },
+ { XMPP_CHATROOM_STATE_IN_ROOM, XMPP_CHATROOM_STATE_NOT_IN_ROOM, true, false, TRANSITION_TYPE_EXIT_INVOLUNTARILY, },
+ { XMPP_CHATROOM_STATE_IN_ROOM, XMPP_CHATROOM_STATE_REQUESTED_ENTER, false, false, TRANSITION_TYPE_NONE, },
+ { XMPP_CHATROOM_STATE_IN_ROOM, XMPP_CHATROOM_STATE_REQUESTED_EXIT, false, true, TRANSITION_TYPE_NONE, },
+ { XMPP_CHATROOM_STATE_REQUESTED_EXIT, XMPP_CHATROOM_STATE_NOT_IN_ROOM, true, false, TRANSITION_TYPE_EXIT_VOLUNTARILY, },
+ { XMPP_CHATROOM_STATE_REQUESTED_EXIT, XMPP_CHATROOM_STATE_REQUESTED_ENTER, false, false, TRANSITION_TYPE_NONE, },
+ { XMPP_CHATROOM_STATE_REQUESTED_EXIT, XMPP_CHATROOM_STATE_IN_ROOM, false, false, TRANSITION_TYPE_NONE, },
+};
+
+
+
+void
+XmppChatroomModuleImpl::FireEnteredStatus(const XmlElement* presence,
+ XmppChatroomEnteredStatus status) {
+ if (chatroom_handler_) {
+ rtc::scoped_ptr<XmppPresence> xmpp_presence(XmppPresence::Create());
+ xmpp_presence->set_raw_xml(presence);
+ chatroom_handler_->ChatroomEnteredStatus(this, xmpp_presence.get(), status);
+ }
+}
+
+void
+XmppChatroomModuleImpl::FireExitStatus(XmppChatroomExitedStatus status) {
+ if (chatroom_handler_)
+ chatroom_handler_->ChatroomExitedStatus(this, status);
+}
+
+void
+XmppChatroomModuleImpl::FireMessageReceived(const XmlElement& message) {
+ if (chatroom_handler_)
+ chatroom_handler_->MessageReceived(this, message);
+}
+
+void
+XmppChatroomModuleImpl::FireMemberEntered(const XmppChatroomMember* entered_member) {
+ if (chatroom_handler_)
+ chatroom_handler_->MemberEntered(this, entered_member);
+}
+
+void
+XmppChatroomModuleImpl::FireMemberChanged(
+ const XmppChatroomMember* changed_member) {
+ if (chatroom_handler_)
+ chatroom_handler_->MemberChanged(this, changed_member);
+}
+
+void
+XmppChatroomModuleImpl::FireMemberExited(const XmppChatroomMember* exited_member) {
+ if (chatroom_handler_)
+ chatroom_handler_->MemberExited(this, exited_member);
+}
+
+
+XmppReturnStatus
+XmppChatroomModuleImpl::ServerChangedOtherPresence(const XmlElement&
+ presence_element) {
+ XmppReturnStatus xmpp_status = XMPP_RETURN_OK;
+ rtc::scoped_ptr<XmppPresence> presence(XmppPresence::Create());
+ IFR(presence->set_raw_xml(&presence_element));
+
+ JidMemberMap::iterator pos = chatroom_jid_members_.find(presence->jid());
+
+ if (pos == chatroom_jid_members_.end()) {
+ if (presence->available() == XMPP_PRESENCE_AVAILABLE) {
+ XmppChatroomMemberImpl* member = new XmppChatroomMemberImpl();
+ member->SetPresence(presence.get());
+ chatroom_jid_members_.insert(std::make_pair(member->member_jid(), member));
+ chatroom_jid_members_version_++;
+ FireMemberEntered(member);
+ }
+ } else {
+ XmppChatroomMemberImpl* member = pos->second;
+ if (presence->available() == XMPP_PRESENCE_AVAILABLE) {
+ member->SetPresence(presence.get());
+ chatroom_jid_members_version_++;
+ FireMemberChanged(member);
+ }
+ else if (presence->available() == XMPP_PRESENCE_UNAVAILABLE) {
+ member->SetPresence(presence.get());
+ chatroom_jid_members_.erase(pos);
+ chatroom_jid_members_version_++;
+ FireMemberExited(member);
+ delete member;
+ }
+ }
+
+ return xmpp_status;
+}
+
+XmppReturnStatus
+XmppChatroomModuleImpl::ClientChangeMyPresence(XmppChatroomState new_state) {
+ return ChangePresence(new_state, NULL, false);
+}
+
+XmppReturnStatus
+XmppChatroomModuleImpl::ServerChangeMyPresence(const XmlElement& presence) {
+ XmppChatroomState new_state;
+
+ if (presence.HasAttr(QN_TYPE) == false) {
+ new_state = XMPP_CHATROOM_STATE_IN_ROOM;
+ } else {
+ new_state = XMPP_CHATROOM_STATE_NOT_IN_ROOM;
+ }
+ return ChangePresence(new_state, &presence, true);
+
+}
+
+XmppReturnStatus
+XmppChatroomModuleImpl::ChangePresence(XmppChatroomState new_state,
+ const XmlElement* presence,
+ bool isServer) {
+ RTC_UNUSED(presence);
+
+ XmppChatroomState old_state = chatroom_state_;
+
+ // do nothing if state hasn't changed
+ if (old_state == new_state)
+ return XMPP_RETURN_OK;
+
+ // find the right transition description
+ StateTransitionDescription* transition_desc = NULL;
+ for (int i=0; i < ARRAY_SIZE(Transitions); i++) {
+ if (Transitions[i].old_state == old_state &&
+ Transitions[i].new_state == new_state) {
+ transition_desc = &Transitions[i];
+ break;
+ }
+ }
+
+ if (transition_desc == NULL) {
+ ASSERT(0);
+ return XMPP_RETURN_BADSTATE;
+ }
+
+ // we assert for any invalid transition states, and we'll
+ if (isServer) {
+ // $TODO send original stanza back to server and log an error?
+ // Disable the assert because of b/6133072
+ // ASSERT(transition_desc->is_valid_server_transition);
+ if (!transition_desc->is_valid_server_transition) {
+ return XMPP_RETURN_BADSTATE;
+ }
+ } else {
+ if (transition_desc->is_valid_client_transition == false) {
+ ASSERT(0);
+ return XMPP_RETURN_BADARGUMENT;
+ }
+ }
+
+ // set the new state and then fire any notifications to the handler
+ chatroom_state_ = new_state;
+
+ switch (transition_desc->transition_type) {
+ case TRANSITION_TYPE_ENTER_SUCCESS:
+ FireEnteredStatus(presence, XMPP_CHATROOM_ENTERED_SUCCESS);
+ break;
+ case TRANSITION_TYPE_ENTER_FAILURE:
+ FireEnteredStatus(presence, GetEnterFailureFromXml(presence));
+ break;
+ case TRANSITION_TYPE_EXIT_INVOLUNTARILY:
+ FireExitStatus(GetExitFailureFromXml(presence));
+ break;
+ case TRANSITION_TYPE_EXIT_VOLUNTARILY:
+ FireExitStatus(XMPP_CHATROOM_EXITED_REQUESTED);
+ break;
+ case TRANSITION_TYPE_NONE:
+ break;
+ }
+
+ return XMPP_RETURN_OK;
+}
+
+XmppChatroomEnteredStatus
+XmppChatroomModuleImpl::GetEnterFailureFromXml(const XmlElement* presence) {
+ XmppChatroomEnteredStatus status = XMPP_CHATROOM_ENTERED_FAILURE_UNSPECIFIED;
+ const XmlElement* error = presence->FirstNamed(QN_ERROR);
+ if (error != NULL && error->HasAttr(QN_CODE)) {
+ int code = atoi(error->Attr(QN_CODE).c_str());
+ switch (code) {
+ case 401: status = XMPP_CHATROOM_ENTERED_FAILURE_PASSWORD_REQUIRED; break;
+ case 403: {
+ status = XMPP_CHATROOM_ENTERED_FAILURE_MEMBER_BANNED;
+ if (error->FirstNamed(QN_GOOGLE_SESSION_BLOCKED)) {
+ status = XMPP_CHATROOM_ENTERED_FAILURE_MEMBER_BLOCKED;
+ } else if (error->FirstNamed(QN_GOOGLE_SESSION_BLOCKING)) {
+ status = XMPP_CHATROOM_ENTERED_FAILURE_MEMBER_BLOCKING;
+ }
+ break;
+ }
+ case 405: status = XMPP_CHATROOM_ENTERED_FAILURE_ROOM_LOCKED; break;
+ case 406: status = XMPP_CHATROOM_ENTERED_FAILURE_OUTDATED_CLIENT; break;
+ case 407: status = XMPP_CHATROOM_ENTERED_FAILURE_NOT_A_MEMBER; break;
+ case 409: status = XMPP_CHATROOM_ENTERED_FAILURE_NICKNAME_CONFLICT; break;
+ // http://xmpp.org/extensions/xep-0045.html#enter-maxusers
+ case 503: status = XMPP_CHATROOM_ENTERED_FAILURE_MAX_USERS; break;
+ }
+ }
+ return status;
+}
+
+XmppChatroomExitedStatus
+XmppChatroomModuleImpl::GetExitFailureFromXml(const XmlElement* presence) {
+ XmppChatroomExitedStatus status = XMPP_CHATROOM_EXITED_UNSPECIFIED;
+ const XmlElement* muc_user = presence->FirstNamed(QN_MUC_USER_X);
+ if (muc_user != NULL) {
+ const XmlElement* user_status = muc_user->FirstNamed(QN_MUC_USER_STATUS);
+ if (user_status != NULL && user_status->HasAttr(QN_CODE)) {
+ int code = atoi(user_status->Attr(QN_CODE).c_str());
+ switch (code) {
+ case 307: status = XMPP_CHATROOM_EXITED_KICKED; break;
+ case 322: status = XMPP_CHATROOM_EXITED_NOT_A_MEMBER; break;
+ case 332: status = XMPP_CHATROOM_EXITED_SYSTEM_SHUTDOWN; break;
+ }
+ }
+ }
+ return status;
+}
+
+XmppReturnStatus
+XmppChatroomMemberImpl::SetPresence(const XmppPresence* presence) {
+ ASSERT(presence != NULL);
+
+ // copy presence
+ presence_.reset(XmppPresence::Create());
+ presence_->set_raw_xml(presence->raw_xml());
+ return XMPP_RETURN_OK;
+}
+
+const Jid
+XmppChatroomMemberImpl::member_jid() const {
+ return presence_->jid();
+}
+
+const Jid
+XmppChatroomMemberImpl::full_jid() const {
+ return Jid("");
+}
+
+const std::string
+XmppChatroomMemberImpl::name() const {
+ return member_jid().resource();
+}
+
+const XmppPresence*
+XmppChatroomMemberImpl::presence() const {
+ return presence_.get();
+}
+
+
+// XmppChatroomMemberEnumeratorImpl --------------------------------------
+XmppChatroomMemberEnumeratorImpl::XmppChatroomMemberEnumeratorImpl(
+ XmppChatroomModuleImpl::JidMemberMap* map, int* map_version) {
+ map_ = map;
+ map_version_ = map_version;
+ map_version_created_ = *map_version_;
+ iterator_ = map->begin();
+ before_beginning_ = true;
+}
+
+XmppChatroomMember*
+XmppChatroomMemberEnumeratorImpl::current() {
+ if (IsValid() == false) {
+ return NULL;
+ } else if (IsBeforeBeginning() || IsAfterEnd()) {
+ return NULL;
+ } else {
+ return iterator_->second;
+ }
+}
+
+bool
+XmppChatroomMemberEnumeratorImpl::Prev() {
+ if (IsValid() == false) {
+ return false;
+ } else if (IsBeforeBeginning()) {
+ return false;
+ } else if (iterator_ == map_->begin()) {
+ before_beginning_ = true;
+ return false;
+ } else {
+ iterator_--;
+ return current() != NULL;
+ }
+}
+
+bool
+XmppChatroomMemberEnumeratorImpl::Next() {
+ if (IsValid() == false) {
+ return false;
+ } else if (IsBeforeBeginning()) {
+ before_beginning_ = false;
+ iterator_ = map_->begin();
+ return current() != NULL;
+ } else if (IsAfterEnd()) {
+ return false;
+ } else {
+ iterator_++;
+ return current() != NULL;
+ }
+}
+
+bool
+XmppChatroomMemberEnumeratorImpl::IsValid() {
+ return map_version_created_ == *map_version_;
+}
+
+bool
+XmppChatroomMemberEnumeratorImpl::IsBeforeBeginning() {
+ return before_beginning_;
+}
+
+bool
+XmppChatroomMemberEnumeratorImpl::IsAfterEnd() {
+ return (iterator_ == map_->end());
+}
+
+
+
+} // namespace buzz
diff --git a/libjingle/xmpp/constants.cc b/libjingle/xmpp/constants.cc
new file mode 100644
index 00000000..38e0cec4
--- /dev/null
+++ b/libjingle/xmpp/constants.cc
@@ -0,0 +1,614 @@
+/*
+ * 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 "webrtc/libjingle/xmpp/constants.h"
+
+#include <string>
+
+#include "webrtc/libjingle/xmllite/qname.h"
+#include "webrtc/libjingle/xmllite/xmlconstants.h"
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/jid.h"
+#include "webrtc/base/basicdefs.h"
+
+namespace buzz {
+
+// TODO: Remove static objects of complex types, particularly
+// Jid and QName.
+
+const char NS_CLIENT[] = "jabber:client";
+const char NS_SERVER[] = "jabber:server";
+const char NS_STREAM[] = "http://etherx.jabber.org/streams";
+const char NS_XSTREAM[] = "urn:ietf:params:xml:ns:xmpp-streams";
+const char NS_TLS[] = "urn:ietf:params:xml:ns:xmpp-tls";
+const char NS_SASL[] = "urn:ietf:params:xml:ns:xmpp-sasl";
+const char NS_BIND[] = "urn:ietf:params:xml:ns:xmpp-bind";
+const char NS_DIALBACK[] = "jabber:server:dialback";
+const char NS_SESSION[] = "urn:ietf:params:xml:ns:xmpp-session";
+const char NS_STANZA[] = "urn:ietf:params:xml:ns:xmpp-stanzas";
+const char NS_PRIVACY[] = "jabber:iq:privacy";
+const char NS_ROSTER[] = "jabber:iq:roster";
+const char NS_VCARD[] = "vcard-temp";
+const char NS_AVATAR_HASH[] = "google:avatar";
+const char NS_VCARD_UPDATE[] = "vcard-temp:x:update";
+const char STR_CLIENT[] = "client";
+const char STR_SERVER[] = "server";
+const char STR_STREAM[] = "stream";
+
+const char STR_GET[] = "get";
+const char STR_SET[] = "set";
+const char STR_RESULT[] = "result";
+const char STR_ERROR[] = "error";
+
+const char STR_FORM[] = "form";
+const char STR_SUBMIT[] = "submit";
+const char STR_TEXT_SINGLE[] = "text-single";
+const char STR_LIST_SINGLE[] = "list-single";
+const char STR_LIST_MULTI[] = "list-multi";
+const char STR_HIDDEN[] = "hidden";
+const char STR_FORM_TYPE[] = "FORM_TYPE";
+
+const char STR_FROM[] = "from";
+const char STR_TO[] = "to";
+const char STR_BOTH[] = "both";
+const char STR_REMOVE[] = "remove";
+const char STR_TRUE[] = "true";
+
+const char STR_TYPE[] = "type";
+const char STR_NAME[] = "name";
+const char STR_ID[] = "id";
+const char STR_JID[] = "jid";
+const char STR_SUBSCRIPTION[] = "subscription";
+const char STR_ASK[] = "ask";
+const char STR_X[] = "x";
+const char STR_GOOGLE_COM[] = "google.com";
+const char STR_GMAIL_COM[] = "gmail.com";
+const char STR_GOOGLEMAIL_COM[] = "googlemail.com";
+const char STR_DEFAULT_DOMAIN[] = "default.talk.google.com";
+const char STR_TALK_GOOGLE_COM[] = "talk.google.com";
+const char STR_TALKX_L_GOOGLE_COM[] = "talkx.l.google.com";
+const char STR_XMPP_GOOGLE_COM[] = "xmpp.google.com";
+const char STR_XMPPX_L_GOOGLE_COM[] = "xmppx.l.google.com";
+
+#ifdef FEATURE_ENABLE_VOICEMAIL
+const char STR_VOICEMAIL[] = "voicemail";
+const char STR_OUTGOINGVOICEMAIL[] = "outgoingvoicemail";
+#endif
+
+const char STR_UNAVAILABLE[] = "unavailable";
+
+const char NS_PING[] = "urn:xmpp:ping";
+const StaticQName QN_PING = { NS_PING, "ping" };
+
+const char NS_MUC_UNIQUE[] = "http://jabber.org/protocol/muc#unique";
+const StaticQName QN_MUC_UNIQUE_QUERY = { NS_MUC_UNIQUE, "unique" };
+const StaticQName QN_HANGOUT_ID = { STR_EMPTY, "hangout-id" };
+
+const char STR_GOOGLE_MUC_LOOKUP_JID[] = "lookup.groupchat.google.com";
+
+const char STR_MUC_ROOMCONFIG_ROOMNAME[] = "muc#roomconfig_roomname";
+const char STR_MUC_ROOMCONFIG_FEATURES[] = "muc#roomconfig_features";
+const char STR_MUC_ROOM_FEATURE_ENTERPRISE[] = "muc_enterprise";
+const char STR_MUC_ROOMCONFIG[] = "http://jabber.org/protocol/muc#roomconfig";
+const char STR_MUC_ROOM_FEATURE_HANGOUT[] = "muc_es";
+const char STR_MUC_ROOM_FEATURE_HANGOUT_LITE[] = "muc_lite";
+const char STR_MUC_ROOM_FEATURE_BROADCAST[] = "broadcast";
+const char STR_MUC_ROOM_FEATURE_MULTI_USER_VC[] = "muc_muvc";
+const char STR_MUC_ROOM_FEATURE_RECORDABLE[] = "recordable";
+const char STR_MUC_ROOM_FEATURE_CUSTOM_RECORDING[] = "custom_recording";
+const char STR_MUC_ROOM_OWNER_PROFILE_ID[] = "muc#roominfo_owner_profile_id";
+const char STR_MUC_ROOM_FEATURE_ABUSE_RECORDABLE[] = "abuse_recordable";
+
+const char STR_ID_TYPE_CONVERSATION[] = "conversation";
+const char NS_GOOGLE_MUC_HANGOUT[] = "google:muc#hangout";
+const StaticQName QN_GOOGLE_MUC_HANGOUT_INVITE =
+ { NS_GOOGLE_MUC_HANGOUT, "invite" };
+const StaticQName QN_GOOGLE_MUC_HANGOUT_INVITE_TYPE =
+ { NS_GOOGLE_MUC_HANGOUT, "invite-type" };
+const StaticQName QN_ATTR_CREATE_ACTIVITY =
+ { STR_EMPTY, "create-activity" };
+const StaticQName QN_GOOGLE_MUC_HANGOUT_PUBLIC =
+ { NS_GOOGLE_MUC_HANGOUT, "public" };
+const StaticQName QN_GOOGLE_MUC_HANGOUT_INVITEE =
+ { NS_GOOGLE_MUC_HANGOUT, "invitee" };
+const StaticQName QN_GOOGLE_MUC_HANGOUT_NOTIFICATION_STATUS =
+ { NS_GOOGLE_MUC_HANGOUT, "notification-status" };
+const StaticQName QN_GOOGLE_MUC_HANGOUT_NOTIFICATION_TYPE = {
+ NS_GOOGLE_MUC_HANGOUT, "notification-type" };
+const StaticQName QN_GOOGLE_MUC_HANGOUT_HANGOUT_START_CONTEXT = {
+ NS_GOOGLE_MUC_HANGOUT, "hangout-start-context" };
+const StaticQName QN_GOOGLE_MUC_HANGOUT_CONVERSATION_ID = {
+ NS_GOOGLE_MUC_HANGOUT, "conversation-id" };
+
+const StaticQName QN_STREAM_STREAM = { NS_STREAM, STR_STREAM };
+const StaticQName QN_STREAM_FEATURES = { NS_STREAM, "features" };
+const StaticQName QN_STREAM_ERROR = { NS_STREAM, "error" };
+
+const StaticQName QN_XSTREAM_BAD_FORMAT = { NS_XSTREAM, "bad-format" };
+const StaticQName QN_XSTREAM_BAD_NAMESPACE_PREFIX =
+ { NS_XSTREAM, "bad-namespace-prefix" };
+const StaticQName QN_XSTREAM_CONFLICT = { NS_XSTREAM, "conflict" };
+const StaticQName QN_XSTREAM_CONNECTION_TIMEOUT =
+ { NS_XSTREAM, "connection-timeout" };
+const StaticQName QN_XSTREAM_HOST_GONE = { NS_XSTREAM, "host-gone" };
+const StaticQName QN_XSTREAM_HOST_UNKNOWN = { NS_XSTREAM, "host-unknown" };
+const StaticQName QN_XSTREAM_IMPROPER_ADDRESSIING =
+ { NS_XSTREAM, "improper-addressing" };
+const StaticQName QN_XSTREAM_INTERNAL_SERVER_ERROR =
+ { NS_XSTREAM, "internal-server-error" };
+const StaticQName QN_XSTREAM_INVALID_FROM = { NS_XSTREAM, "invalid-from" };
+const StaticQName QN_XSTREAM_INVALID_ID = { NS_XSTREAM, "invalid-id" };
+const StaticQName QN_XSTREAM_INVALID_NAMESPACE =
+ { NS_XSTREAM, "invalid-namespace" };
+const StaticQName QN_XSTREAM_INVALID_XML = { NS_XSTREAM, "invalid-xml" };
+const StaticQName QN_XSTREAM_NOT_AUTHORIZED = { NS_XSTREAM, "not-authorized" };
+const StaticQName QN_XSTREAM_POLICY_VIOLATION =
+ { NS_XSTREAM, "policy-violation" };
+const StaticQName QN_XSTREAM_REMOTE_CONNECTION_FAILED =
+ { NS_XSTREAM, "remote-connection-failed" };
+const StaticQName QN_XSTREAM_RESOURCE_CONSTRAINT =
+ { NS_XSTREAM, "resource-constraint" };
+const StaticQName QN_XSTREAM_RESTRICTED_XML = { NS_XSTREAM, "restricted-xml" };
+const StaticQName QN_XSTREAM_SEE_OTHER_HOST = { NS_XSTREAM, "see-other-host" };
+const StaticQName QN_XSTREAM_SYSTEM_SHUTDOWN =
+ { NS_XSTREAM, "system-shutdown" };
+const StaticQName QN_XSTREAM_UNDEFINED_CONDITION =
+ { NS_XSTREAM, "undefined-condition" };
+const StaticQName QN_XSTREAM_UNSUPPORTED_ENCODING =
+ { NS_XSTREAM, "unsupported-encoding" };
+const StaticQName QN_XSTREAM_UNSUPPORTED_STANZA_TYPE =
+ { NS_XSTREAM, "unsupported-stanza-type" };
+const StaticQName QN_XSTREAM_UNSUPPORTED_VERSION =
+ { NS_XSTREAM, "unsupported-version" };
+const StaticQName QN_XSTREAM_XML_NOT_WELL_FORMED =
+ { NS_XSTREAM, "xml-not-well-formed" };
+const StaticQName QN_XSTREAM_TEXT = { NS_XSTREAM, "text" };
+
+const StaticQName QN_TLS_STARTTLS = { NS_TLS, "starttls" };
+const StaticQName QN_TLS_REQUIRED = { NS_TLS, "required" };
+const StaticQName QN_TLS_PROCEED = { NS_TLS, "proceed" };
+const StaticQName QN_TLS_FAILURE = { NS_TLS, "failure" };
+
+const StaticQName QN_SASL_MECHANISMS = { NS_SASL, "mechanisms" };
+const StaticQName QN_SASL_MECHANISM = { NS_SASL, "mechanism" };
+const StaticQName QN_SASL_AUTH = { NS_SASL, "auth" };
+const StaticQName QN_SASL_CHALLENGE = { NS_SASL, "challenge" };
+const StaticQName QN_SASL_RESPONSE = { NS_SASL, "response" };
+const StaticQName QN_SASL_ABORT = { NS_SASL, "abort" };
+const StaticQName QN_SASL_SUCCESS = { NS_SASL, "success" };
+const StaticQName QN_SASL_FAILURE = { NS_SASL, "failure" };
+const StaticQName QN_SASL_ABORTED = { NS_SASL, "aborted" };
+const StaticQName QN_SASL_INCORRECT_ENCODING =
+ { NS_SASL, "incorrect-encoding" };
+const StaticQName QN_SASL_INVALID_AUTHZID = { NS_SASL, "invalid-authzid" };
+const StaticQName QN_SASL_INVALID_MECHANISM = { NS_SASL, "invalid-mechanism" };
+const StaticQName QN_SASL_MECHANISM_TOO_WEAK =
+ { NS_SASL, "mechanism-too-weak" };
+const StaticQName QN_SASL_NOT_AUTHORIZED = { NS_SASL, "not-authorized" };
+const StaticQName QN_SASL_TEMPORARY_AUTH_FAILURE =
+ { NS_SASL, "temporary-auth-failure" };
+
+// These are non-standard.
+const char NS_GOOGLE_AUTH_PROTOCOL[] =
+ "http://www.google.com/talk/protocol/auth";
+const StaticQName QN_GOOGLE_AUTH_CLIENT_USES_FULL_BIND_RESULT =
+ { NS_GOOGLE_AUTH_PROTOCOL, "client-uses-full-bind-result" };
+const StaticQName QN_GOOGLE_ALLOW_NON_GOOGLE_ID_XMPP_LOGIN =
+ { NS_GOOGLE_AUTH_PROTOCOL, "allow-non-google-login" };
+const StaticQName QN_GOOGLE_AUTH_SERVICE =
+ { NS_GOOGLE_AUTH_PROTOCOL, "service" };
+
+const StaticQName QN_DIALBACK_RESULT = { NS_DIALBACK, "result" };
+const StaticQName QN_DIALBACK_VERIFY = { NS_DIALBACK, "verify" };
+
+const StaticQName QN_STANZA_BAD_REQUEST = { NS_STANZA, "bad-request" };
+const StaticQName QN_STANZA_CONFLICT = { NS_STANZA, "conflict" };
+const StaticQName QN_STANZA_FEATURE_NOT_IMPLEMENTED =
+ { NS_STANZA, "feature-not-implemented" };
+const StaticQName QN_STANZA_FORBIDDEN = { NS_STANZA, "forbidden" };
+const StaticQName QN_STANZA_GONE = { NS_STANZA, "gone" };
+const StaticQName QN_STANZA_INTERNAL_SERVER_ERROR =
+ { NS_STANZA, "internal-server-error" };
+const StaticQName QN_STANZA_ITEM_NOT_FOUND = { NS_STANZA, "item-not-found" };
+const StaticQName QN_STANZA_JID_MALFORMED = { NS_STANZA, "jid-malformed" };
+const StaticQName QN_STANZA_NOT_ACCEPTABLE = { NS_STANZA, "not-acceptable" };
+const StaticQName QN_STANZA_NOT_ALLOWED = { NS_STANZA, "not-allowed" };
+const StaticQName QN_STANZA_PAYMENT_REQUIRED =
+ { NS_STANZA, "payment-required" };
+const StaticQName QN_STANZA_RECIPIENT_UNAVAILABLE =
+ { NS_STANZA, "recipient-unavailable" };
+const StaticQName QN_STANZA_REDIRECT = { NS_STANZA, "redirect" };
+const StaticQName QN_STANZA_REGISTRATION_REQUIRED =
+ { NS_STANZA, "registration-required" };
+const StaticQName QN_STANZA_REMOTE_SERVER_NOT_FOUND =
+ { NS_STANZA, "remote-server-not-found" };
+const StaticQName QN_STANZA_REMOTE_SERVER_TIMEOUT =
+ { NS_STANZA, "remote-server-timeout" };
+const StaticQName QN_STANZA_RESOURCE_CONSTRAINT =
+ { NS_STANZA, "resource-constraint" };
+const StaticQName QN_STANZA_SERVICE_UNAVAILABLE =
+ { NS_STANZA, "service-unavailable" };
+const StaticQName QN_STANZA_SUBSCRIPTION_REQUIRED =
+ { NS_STANZA, "subscription-required" };
+const StaticQName QN_STANZA_UNDEFINED_CONDITION =
+ { NS_STANZA, "undefined-condition" };
+const StaticQName QN_STANZA_UNEXPECTED_REQUEST =
+ { NS_STANZA, "unexpected-request" };
+const StaticQName QN_STANZA_TEXT = { NS_STANZA, "text" };
+
+const StaticQName QN_BIND_BIND = { NS_BIND, "bind" };
+const StaticQName QN_BIND_RESOURCE = { NS_BIND, "resource" };
+const StaticQName QN_BIND_JID = { NS_BIND, "jid" };
+
+const StaticQName QN_MESSAGE = { NS_CLIENT, "message" };
+const StaticQName QN_BODY = { NS_CLIENT, "body" };
+const StaticQName QN_SUBJECT = { NS_CLIENT, "subject" };
+const StaticQName QN_THREAD = { NS_CLIENT, "thread" };
+const StaticQName QN_PRESENCE = { NS_CLIENT, "presence" };
+const StaticQName QN_SHOW = { NS_CLIENT, "show" };
+const StaticQName QN_STATUS = { NS_CLIENT, "status" };
+const StaticQName QN_LANG = { NS_CLIENT, "lang" };
+const StaticQName QN_PRIORITY = { NS_CLIENT, "priority" };
+const StaticQName QN_IQ = { NS_CLIENT, "iq" };
+const StaticQName QN_ERROR = { NS_CLIENT, "error" };
+
+const StaticQName QN_SERVER_MESSAGE = { NS_SERVER, "message" };
+const StaticQName QN_SERVER_BODY = { NS_SERVER, "body" };
+const StaticQName QN_SERVER_SUBJECT = { NS_SERVER, "subject" };
+const StaticQName QN_SERVER_THREAD = { NS_SERVER, "thread" };
+const StaticQName QN_SERVER_PRESENCE = { NS_SERVER, "presence" };
+const StaticQName QN_SERVER_SHOW = { NS_SERVER, "show" };
+const StaticQName QN_SERVER_STATUS = { NS_SERVER, "status" };
+const StaticQName QN_SERVER_LANG = { NS_SERVER, "lang" };
+const StaticQName QN_SERVER_PRIORITY = { NS_SERVER, "priority" };
+const StaticQName QN_SERVER_IQ = { NS_SERVER, "iq" };
+const StaticQName QN_SERVER_ERROR = { NS_SERVER, "error" };
+
+const StaticQName QN_SESSION_SESSION = { NS_SESSION, "session" };
+
+const StaticQName QN_PRIVACY_QUERY = { NS_PRIVACY, "query" };
+const StaticQName QN_PRIVACY_ACTIVE = { NS_PRIVACY, "active" };
+const StaticQName QN_PRIVACY_DEFAULT = { NS_PRIVACY, "default" };
+const StaticQName QN_PRIVACY_LIST = { NS_PRIVACY, "list" };
+const StaticQName QN_PRIVACY_ITEM = { NS_PRIVACY, "item" };
+const StaticQName QN_PRIVACY_IQ = { NS_PRIVACY, "iq" };
+const StaticQName QN_PRIVACY_MESSAGE = { NS_PRIVACY, "message" };
+const StaticQName QN_PRIVACY_PRESENCE_IN = { NS_PRIVACY, "presence-in" };
+const StaticQName QN_PRIVACY_PRESENCE_OUT = { NS_PRIVACY, "presence-out" };
+
+const StaticQName QN_ROSTER_QUERY = { NS_ROSTER, "query" };
+const StaticQName QN_ROSTER_ITEM = { NS_ROSTER, "item" };
+const StaticQName QN_ROSTER_GROUP = { NS_ROSTER, "group" };
+
+const StaticQName QN_VCARD = { NS_VCARD, "vCard" };
+const StaticQName QN_VCARD_FN = { NS_VCARD, "FN" };
+const StaticQName QN_VCARD_PHOTO = { NS_VCARD, "PHOTO" };
+const StaticQName QN_VCARD_PHOTO_BINVAL = { NS_VCARD, "BINVAL" };
+const StaticQName QN_VCARD_AVATAR_HASH = { NS_AVATAR_HASH, "hash" };
+const StaticQName QN_VCARD_AVATAR_HASH_MODIFIED =
+ { NS_AVATAR_HASH, "modified" };
+
+const StaticQName QN_NAME = { STR_EMPTY, "name" };
+const StaticQName QN_AFFILIATION = { STR_EMPTY, "affiliation" };
+const StaticQName QN_ROLE = { STR_EMPTY, "role" };
+
+#if defined(FEATURE_ENABLE_PSTN)
+const StaticQName QN_VCARD_TEL = { NS_VCARD, "TEL" };
+const StaticQName QN_VCARD_VOICE = { NS_VCARD, "VOICE" };
+const StaticQName QN_VCARD_HOME = { NS_VCARD, "HOME" };
+const StaticQName QN_VCARD_WORK = { NS_VCARD, "WORK" };
+const StaticQName QN_VCARD_CELL = { NS_VCARD, "CELL" };
+const StaticQName QN_VCARD_NUMBER = { NS_VCARD, "NUMBER" };
+#endif
+
+const StaticQName QN_XML_LANG = { NS_XML, "lang" };
+
+const StaticQName QN_ENCODING = { STR_EMPTY, STR_ENCODING };
+const StaticQName QN_VERSION = { STR_EMPTY, STR_VERSION };
+const StaticQName QN_TO = { STR_EMPTY, "to" };
+const StaticQName QN_FROM = { STR_EMPTY, "from" };
+const StaticQName QN_TYPE = { STR_EMPTY, "type" };
+const StaticQName QN_ID = { STR_EMPTY, "id" };
+const StaticQName QN_CODE = { STR_EMPTY, "code" };
+
+const StaticQName QN_VALUE = { STR_EMPTY, "value" };
+const StaticQName QN_ACTION = { STR_EMPTY, "action" };
+const StaticQName QN_ORDER = { STR_EMPTY, "order" };
+const StaticQName QN_MECHANISM = { STR_EMPTY, "mechanism" };
+const StaticQName QN_ASK = { STR_EMPTY, "ask" };
+const StaticQName QN_JID = { STR_EMPTY, "jid" };
+const StaticQName QN_NICK = { STR_EMPTY, "nick" };
+const StaticQName QN_SUBSCRIPTION = { STR_EMPTY, "subscription" };
+const StaticQName QN_TITLE1 = { STR_EMPTY, "title1" };
+const StaticQName QN_TITLE2 = { STR_EMPTY, "title2" };
+
+const StaticQName QN_XMLNS_CLIENT = { NS_XMLNS, STR_CLIENT };
+const StaticQName QN_XMLNS_SERVER = { NS_XMLNS, STR_SERVER };
+const StaticQName QN_XMLNS_STREAM = { NS_XMLNS, STR_STREAM };
+
+
+// Presence
+const char STR_SHOW_AWAY[] = "away";
+const char STR_SHOW_CHAT[] = "chat";
+const char STR_SHOW_DND[] = "dnd";
+const char STR_SHOW_XA[] = "xa";
+const char STR_SHOW_OFFLINE[] = "offline";
+
+const char NS_GOOGLE_PSTN_CONFERENCE[] = "http://www.google.com/pstn-conference";
+const StaticQName QN_GOOGLE_PSTN_CONFERENCE_STATUS = { NS_GOOGLE_PSTN_CONFERENCE, "status" };
+const StaticQName QN_ATTR_STATUS = { STR_EMPTY, "status" };
+
+// Presence connection status
+const char STR_PSTN_CONFERENCE_STATUS_CONNECTING[] = "connecting";
+const char STR_PSTN_CONFERENCE_STATUS_JOINING[] = "joining";
+const char STR_PSTN_CONFERENCE_STATUS_CONNECTED[] = "connected";
+const char STR_PSTN_CONFERENCE_STATUS_HANGUP[] = "hangup";
+
+// Subscription
+const char STR_SUBSCRIBE[] = "subscribe";
+const char STR_SUBSCRIBED[] = "subscribed";
+const char STR_UNSUBSCRIBE[] = "unsubscribe";
+const char STR_UNSUBSCRIBED[] = "unsubscribed";
+
+// Google Invite
+const char NS_GOOGLE_SUBSCRIBE[] = "google:subscribe";
+const StaticQName QN_INVITATION = { NS_GOOGLE_SUBSCRIBE, "invitation" };
+const StaticQName QN_INVITE_NAME = { NS_GOOGLE_SUBSCRIBE, "name" };
+const StaticQName QN_INVITE_SUBJECT = { NS_GOOGLE_SUBSCRIBE, "subject" };
+const StaticQName QN_INVITE_MESSAGE = { NS_GOOGLE_SUBSCRIBE, "body" };
+
+// Kick
+const char NS_GOOGLE_MUC_ADMIN[] = "google:muc#admin";
+const StaticQName QN_GOOGLE_MUC_ADMIN_QUERY = { NS_GOOGLE_MUC_ADMIN, "query" };
+const StaticQName QN_GOOGLE_MUC_ADMIN_QUERY_ITEM =
+ { NS_GOOGLE_MUC_ADMIN, "item" };
+const StaticQName QN_GOOGLE_MUC_ADMIN_QUERY_ITEM_REASON =
+ { NS_GOOGLE_MUC_ADMIN, "reason" };
+
+// PubSub: http://xmpp.org/extensions/xep-0060.html
+const char NS_PUBSUB[] = "http://jabber.org/protocol/pubsub";
+const StaticQName QN_PUBSUB = { NS_PUBSUB, "pubsub" };
+const StaticQName QN_PUBSUB_ITEMS = { NS_PUBSUB, "items" };
+const StaticQName QN_PUBSUB_ITEM = { NS_PUBSUB, "item" };
+const StaticQName QN_PUBSUB_PUBLISH = { NS_PUBSUB, "publish" };
+const StaticQName QN_PUBSUB_RETRACT = { NS_PUBSUB, "retract" };
+const StaticQName QN_ATTR_PUBLISHER = { STR_EMPTY, "publisher" };
+
+const char NS_PUBSUB_EVENT[] = "http://jabber.org/protocol/pubsub#event";
+const StaticQName QN_NODE = { STR_EMPTY, "node" };
+const StaticQName QN_PUBSUB_EVENT = { NS_PUBSUB_EVENT, "event" };
+const StaticQName QN_PUBSUB_EVENT_ITEMS = { NS_PUBSUB_EVENT, "items" };
+const StaticQName QN_PUBSUB_EVENT_ITEM = { NS_PUBSUB_EVENT, "item" };
+const StaticQName QN_PUBSUB_EVENT_RETRACT = { NS_PUBSUB_EVENT, "retract" };
+const StaticQName QN_NOTIFY = { STR_EMPTY, "notify" };
+
+const char NS_PRESENTER[] = "google:presenter";
+const StaticQName QN_PRESENTER_PRESENTER = { NS_PRESENTER, "presenter" };
+const StaticQName QN_PRESENTER_PRESENTATION_ITEM =
+ { NS_PRESENTER, "presentation-item" };
+const StaticQName QN_PRESENTER_PRESENTATION_TYPE =
+ { NS_PRESENTER, "presentation-type" };
+const StaticQName QN_PRESENTER_PRESENTATION_ID =
+ { NS_PRESENTER, "presentation-id" };
+
+// JEP 0030
+const StaticQName QN_CATEGORY = { STR_EMPTY, "category" };
+const StaticQName QN_VAR = { STR_EMPTY, "var" };
+const char NS_DISCO_INFO[] = "http://jabber.org/protocol/disco#info";
+const char NS_DISCO_ITEMS[] = "http://jabber.org/protocol/disco#items";
+const StaticQName QN_DISCO_INFO_QUERY = { NS_DISCO_INFO, "query" };
+const StaticQName QN_DISCO_IDENTITY = { NS_DISCO_INFO, "identity" };
+const StaticQName QN_DISCO_FEATURE = { NS_DISCO_INFO, "feature" };
+
+const StaticQName QN_DISCO_ITEMS_QUERY = { NS_DISCO_ITEMS, "query" };
+const StaticQName QN_DISCO_ITEM = { NS_DISCO_ITEMS, "item" };
+
+// JEP 0020
+const char NS_FEATURE[] = "http://jabber.org/protocol/feature-neg";
+const StaticQName QN_FEATURE_FEATURE = { NS_FEATURE, "feature" };
+
+// JEP 0004
+const char NS_XDATA[] = "jabber:x:data";
+const StaticQName QN_XDATA_X = { NS_XDATA, "x" };
+const StaticQName QN_XDATA_INSTRUCTIONS = { NS_XDATA, "instructions" };
+const StaticQName QN_XDATA_TITLE = { NS_XDATA, "title" };
+const StaticQName QN_XDATA_FIELD = { NS_XDATA, "field" };
+const StaticQName QN_XDATA_REPORTED = { NS_XDATA, "reported" };
+const StaticQName QN_XDATA_ITEM = { NS_XDATA, "item" };
+const StaticQName QN_XDATA_DESC = { NS_XDATA, "desc" };
+const StaticQName QN_XDATA_REQUIRED = { NS_XDATA, "required" };
+const StaticQName QN_XDATA_VALUE = { NS_XDATA, "value" };
+const StaticQName QN_XDATA_OPTION = { NS_XDATA, "option" };
+
+// JEP 0045
+const char NS_MUC[] = "http://jabber.org/protocol/muc";
+const StaticQName QN_MUC_X = { NS_MUC, "x" };
+const StaticQName QN_MUC_ITEM = { NS_MUC, "item" };
+const StaticQName QN_MUC_AFFILIATION = { NS_MUC, "affiliation" };
+const StaticQName QN_MUC_ROLE = { NS_MUC, "role" };
+const char STR_AFFILIATION_NONE[] = "none";
+const char STR_ROLE_PARTICIPANT[] = "participant";
+
+const char NS_GOOGLE_SESSION[] = "http://www.google.com/session";
+const StaticQName QN_GOOGLE_CIRCLE_ID = { STR_EMPTY, "google-circle-id" };
+const StaticQName QN_GOOGLE_USER_ID = { STR_EMPTY, "google-user-id" };
+const StaticQName QN_GOOGLE_SESSION_BLOCKED = { NS_GOOGLE_SESSION, "blocked" };
+const StaticQName QN_GOOGLE_SESSION_BLOCKING =
+ { NS_GOOGLE_SESSION, "blocking" };
+
+const char NS_MUC_OWNER[] = "http://jabber.org/protocol/muc#owner";
+const StaticQName QN_MUC_OWNER_QUERY = { NS_MUC_OWNER, "query" };
+
+const char NS_MUC_USER[] = "http://jabber.org/protocol/muc#user";
+const StaticQName QN_MUC_USER_CONTINUE = { NS_MUC_USER, "continue" };
+const StaticQName QN_MUC_USER_X = { NS_MUC_USER, "x" };
+const StaticQName QN_MUC_USER_ITEM = { NS_MUC_USER, "item" };
+const StaticQName QN_MUC_USER_STATUS = { NS_MUC_USER, "status" };
+const StaticQName QN_MUC_USER_REASON = { NS_MUC_USER, "reason" };
+const StaticQName QN_MUC_USER_ABUSE_VIOLATION = { NS_MUC_USER, "abuse-violation" };
+
+// JEP 0055 - Jabber Search
+const char NS_SEARCH[] = "jabber:iq:search";
+const StaticQName QN_SEARCH_QUERY = { NS_SEARCH, "query" };
+const StaticQName QN_SEARCH_ITEM = { NS_SEARCH, "item" };
+const StaticQName QN_SEARCH_ROOM_NAME = { NS_SEARCH, "room-name" };
+const StaticQName QN_SEARCH_ROOM_DOMAIN = { NS_SEARCH, "room-domain" };
+const StaticQName QN_SEARCH_ROOM_JID = { NS_SEARCH, "room-jid" };
+const StaticQName QN_SEARCH_HANGOUT_ID = { NS_SEARCH, "hangout-id" };
+const StaticQName QN_SEARCH_EXTERNAL_ID = { NS_SEARCH, "external-id" };
+
+// JEP 0115
+const char NS_CAPS[] = "http://jabber.org/protocol/caps";
+const StaticQName QN_CAPS_C = { NS_CAPS, "c" };
+const StaticQName QN_VER = { STR_EMPTY, "ver" };
+const StaticQName QN_EXT = { STR_EMPTY, "ext" };
+
+// JEP 0153
+const char kNSVCard[] = "vcard-temp:x:update";
+const StaticQName kQnVCardX = { kNSVCard, "x" };
+const StaticQName kQnVCardPhoto = { kNSVCard, "photo" };
+
+// JEP 0172 User Nickname
+const char NS_NICKNAME[] = "http://jabber.org/protocol/nick";
+const StaticQName QN_NICKNAME = { NS_NICKNAME, "nick" };
+
+// JEP 0085 chat state
+const char NS_CHATSTATE[] = "http://jabber.org/protocol/chatstates";
+const StaticQName QN_CS_ACTIVE = { NS_CHATSTATE, "active" };
+const StaticQName QN_CS_COMPOSING = { NS_CHATSTATE, "composing" };
+const StaticQName QN_CS_PAUSED = { NS_CHATSTATE, "paused" };
+const StaticQName QN_CS_INACTIVE = { NS_CHATSTATE, "inactive" };
+const StaticQName QN_CS_GONE = { NS_CHATSTATE, "gone" };
+
+// JEP 0091 Delayed Delivery
+const char kNSDelay[] = "jabber:x:delay";
+const StaticQName kQnDelayX = { kNSDelay, "x" };
+const StaticQName kQnStamp = { STR_EMPTY, "stamp" };
+
+// Google time stamping (higher resolution)
+const char kNSTimestamp[] = "google:timestamp";
+const StaticQName kQnTime = { kNSTimestamp, "time" };
+const StaticQName kQnMilliseconds = { STR_EMPTY, "ms" };
+
+// Jingle Info
+const char NS_JINGLE_INFO[] = "google:jingleinfo";
+const StaticQName QN_JINGLE_INFO_QUERY = { NS_JINGLE_INFO, "query" };
+const StaticQName QN_JINGLE_INFO_STUN = { NS_JINGLE_INFO, "stun" };
+const StaticQName QN_JINGLE_INFO_RELAY = { NS_JINGLE_INFO, "relay" };
+const StaticQName QN_JINGLE_INFO_SERVER = { NS_JINGLE_INFO, "server" };
+const StaticQName QN_JINGLE_INFO_TOKEN = { NS_JINGLE_INFO, "token" };
+const StaticQName QN_JINGLE_INFO_HOST = { STR_EMPTY, "host" };
+const StaticQName QN_JINGLE_INFO_TCP = { STR_EMPTY, "tcp" };
+const StaticQName QN_JINGLE_INFO_UDP = { STR_EMPTY, "udp" };
+const StaticQName QN_JINGLE_INFO_TCPSSL = { STR_EMPTY, "tcpssl" };
+
+// Call Performance Logging
+const char NS_GOOGLE_CALLPERF_STATS[] = "google:call-perf-stats";
+const StaticQName QN_CALLPERF_STATS =
+ { NS_GOOGLE_CALLPERF_STATS, "callPerfStats" };
+const StaticQName QN_CALLPERF_SESSIONID = { STR_EMPTY, "sessionId" };
+const StaticQName QN_CALLPERF_LOCALUSER = { STR_EMPTY, "localUser" };
+const StaticQName QN_CALLPERF_REMOTEUSER = { STR_EMPTY, "remoteUser" };
+const StaticQName QN_CALLPERF_STARTTIME = { STR_EMPTY, "startTime" };
+const StaticQName QN_CALLPERF_CALL_LENGTH = { STR_EMPTY, "callLength" };
+const StaticQName QN_CALLPERF_CALL_ACCEPTED = { STR_EMPTY, "callAccepted" };
+const StaticQName QN_CALLPERF_CALL_ERROR_CODE = { STR_EMPTY, "callErrorCode" };
+const StaticQName QN_CALLPERF_TERMINATE_CODE = { STR_EMPTY, "terminateCode" };
+const StaticQName QN_CALLPERF_DATAPOINT =
+ { NS_GOOGLE_CALLPERF_STATS, "dataPoint" };
+const StaticQName QN_CALLPERF_DATAPOINT_TIME = { STR_EMPTY, "timeStamp" };
+const StaticQName QN_CALLPERF_DATAPOINT_FRACTION_LOST =
+ { STR_EMPTY, "fraction_lost" };
+const StaticQName QN_CALLPERF_DATAPOINT_CUM_LOST = { STR_EMPTY, "cum_lost" };
+const StaticQName QN_CALLPERF_DATAPOINT_EXT_MAX = { STR_EMPTY, "ext_max" };
+const StaticQName QN_CALLPERF_DATAPOINT_JITTER = { STR_EMPTY, "jitter" };
+const StaticQName QN_CALLPERF_DATAPOINT_RTT = { STR_EMPTY, "RTT" };
+const StaticQName QN_CALLPERF_DATAPOINT_BYTES_R =
+ { STR_EMPTY, "bytesReceived" };
+const StaticQName QN_CALLPERF_DATAPOINT_PACKETS_R =
+ { STR_EMPTY, "packetsReceived" };
+const StaticQName QN_CALLPERF_DATAPOINT_BYTES_S = { STR_EMPTY, "bytesSent" };
+const StaticQName QN_CALLPERF_DATAPOINT_PACKETS_S =
+ { STR_EMPTY, "packetsSent" };
+const StaticQName QN_CALLPERF_DATAPOINT_PROCESS_CPU =
+ { STR_EMPTY, "processCpu" };
+const StaticQName QN_CALLPERF_DATAPOINT_SYSTEM_CPU = { STR_EMPTY, "systemCpu" };
+const StaticQName QN_CALLPERF_DATAPOINT_CPUS = { STR_EMPTY, "cpus" };
+const StaticQName QN_CALLPERF_CONNECTION =
+ { NS_GOOGLE_CALLPERF_STATS, "connection" };
+const StaticQName QN_CALLPERF_CONNECTION_LOCAL_ADDRESS =
+ { STR_EMPTY, "localAddress" };
+const StaticQName QN_CALLPERF_CONNECTION_REMOTE_ADDRESS =
+ { STR_EMPTY, "remoteAddress" };
+const StaticQName QN_CALLPERF_CONNECTION_FLAGS = { STR_EMPTY, "flags" };
+const StaticQName QN_CALLPERF_CONNECTION_RTT = { STR_EMPTY, "rtt" };
+const StaticQName QN_CALLPERF_CONNECTION_TOTAL_BYTES_S =
+ { STR_EMPTY, "totalBytesSent" };
+const StaticQName QN_CALLPERF_CONNECTION_BYTES_SECOND_S =
+ { STR_EMPTY, "bytesSecondSent" };
+const StaticQName QN_CALLPERF_CONNECTION_TOTAL_BYTES_R =
+ { STR_EMPTY, "totalBytesRecv" };
+const StaticQName QN_CALLPERF_CONNECTION_BYTES_SECOND_R =
+ { STR_EMPTY, "bytesSecondRecv" };
+const StaticQName QN_CALLPERF_CANDIDATE =
+ { NS_GOOGLE_CALLPERF_STATS, "candidate" };
+const StaticQName QN_CALLPERF_CANDIDATE_ENDPOINT = { STR_EMPTY, "endpoint" };
+const StaticQName QN_CALLPERF_CANDIDATE_PROTOCOL = { STR_EMPTY, "protocol" };
+const StaticQName QN_CALLPERF_CANDIDATE_ADDRESS = { STR_EMPTY, "address" };
+const StaticQName QN_CALLPERF_MEDIA = { NS_GOOGLE_CALLPERF_STATS, "media" };
+const StaticQName QN_CALLPERF_MEDIA_DIRECTION = { STR_EMPTY, "direction" };
+const StaticQName QN_CALLPERF_MEDIA_SSRC = { STR_EMPTY, "SSRC" };
+const StaticQName QN_CALLPERF_MEDIA_ENERGY = { STR_EMPTY, "energy" };
+const StaticQName QN_CALLPERF_MEDIA_FIR = { STR_EMPTY, "fir" };
+const StaticQName QN_CALLPERF_MEDIA_NACK = { STR_EMPTY, "nack" };
+const StaticQName QN_CALLPERF_MEDIA_FPS = { STR_EMPTY, "fps" };
+const StaticQName QN_CALLPERF_MEDIA_FPS_NETWORK = { STR_EMPTY, "fpsNetwork" };
+const StaticQName QN_CALLPERF_MEDIA_FPS_DECODED = { STR_EMPTY, "fpsDecoded" };
+const StaticQName QN_CALLPERF_MEDIA_JITTER_BUFFER_SIZE =
+ { STR_EMPTY, "jitterBufferSize" };
+const StaticQName QN_CALLPERF_MEDIA_PREFERRED_JITTER_BUFFER_SIZE =
+ { STR_EMPTY, "preferredJitterBufferSize" };
+const StaticQName QN_CALLPERF_MEDIA_TOTAL_PLAYOUT_DELAY =
+ { STR_EMPTY, "totalPlayoutDelay" };
+
+// Muc invites.
+const StaticQName QN_MUC_USER_INVITE = { NS_MUC_USER, "invite" };
+
+// Multiway audio/video.
+const char NS_GOOGLE_MUC_USER[] = "google:muc#user";
+const StaticQName QN_GOOGLE_MUC_USER_AVAILABLE_MEDIA =
+ { NS_GOOGLE_MUC_USER, "available-media" };
+const StaticQName QN_GOOGLE_MUC_USER_ENTRY = { NS_GOOGLE_MUC_USER, "entry" };
+const StaticQName QN_GOOGLE_MUC_USER_MEDIA = { NS_GOOGLE_MUC_USER, "media" };
+const StaticQName QN_GOOGLE_MUC_USER_TYPE = { NS_GOOGLE_MUC_USER, "type" };
+const StaticQName QN_GOOGLE_MUC_USER_SRC_ID = { NS_GOOGLE_MUC_USER, "src-id" };
+const StaticQName QN_GOOGLE_MUC_USER_STATUS = { NS_GOOGLE_MUC_USER, "status" };
+const StaticQName QN_CLIENT_VERSION = { NS_GOOGLE_MUC_USER, "client-version" };
+const StaticQName QN_LOCALE = { NS_GOOGLE_MUC_USER, "locale" };
+const StaticQName QN_LABEL = { STR_EMPTY, "label" };
+
+const char NS_GOOGLE_MUC_MEDIA[] = "google:muc#media";
+const StaticQName QN_GOOGLE_MUC_AUDIO_MUTE =
+ { NS_GOOGLE_MUC_MEDIA, "audio-mute" };
+const StaticQName QN_GOOGLE_MUC_VIDEO_MUTE =
+ { NS_GOOGLE_MUC_MEDIA, "video-mute" };
+const StaticQName QN_GOOGLE_MUC_VIDEO_PAUSE =
+ { NS_GOOGLE_MUC_MEDIA, "video-pause" };
+const StaticQName QN_GOOGLE_MUC_RECORDING =
+ { NS_GOOGLE_MUC_MEDIA, "recording" };
+const StaticQName QN_GOOGLE_MUC_MEDIA_BLOCK = { NS_GOOGLE_MUC_MEDIA, "block" };
+const StaticQName QN_STATE_ATTR = { STR_EMPTY, "state" };
+
+const char AUTH_MECHANISM_GOOGLE_COOKIE[] = "X-GOOGLE-COOKIE";
+const char AUTH_MECHANISM_GOOGLE_TOKEN[] = "X-GOOGLE-TOKEN";
+const char AUTH_MECHANISM_OAUTH2[] = "X-OAUTH2";
+const char AUTH_MECHANISM_PLAIN[] = "PLAIN";
+
+} // namespace buzz
diff --git a/libjingle/xmpp/constants.h b/libjingle/xmpp/constants.h
new file mode 100644
index 00000000..5c1967e5
--- /dev/null
+++ b/libjingle/xmpp/constants.h
@@ -0,0 +1,551 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_CONSTANTS_H_
+#define WEBRTC_LIBJINGLE_XMPP_CONSTANTS_H_
+
+#include <string>
+#include "webrtc/libjingle/xmllite/qname.h"
+#include "webrtc/libjingle/xmpp/jid.h"
+
+namespace buzz {
+
+extern const char NS_CLIENT[];
+extern const char NS_SERVER[];
+extern const char NS_STREAM[];
+extern const char NS_XSTREAM[];
+extern const char NS_TLS[];
+extern const char NS_SASL[];
+extern const char NS_BIND[];
+extern const char NS_DIALBACK[];
+extern const char NS_SESSION[];
+extern const char NS_STANZA[];
+extern const char NS_PRIVACY[];
+extern const char NS_ROSTER[];
+extern const char NS_VCARD[];
+extern const char NS_AVATAR_HASH[];
+extern const char NS_VCARD_UPDATE[];
+extern const char STR_CLIENT[];
+extern const char STR_SERVER[];
+extern const char STR_STREAM[];
+
+extern const char STR_GET[];
+extern const char STR_SET[];
+extern const char STR_RESULT[];
+extern const char STR_ERROR[];
+
+extern const char STR_FORM[];
+extern const char STR_SUBMIT[];
+extern const char STR_TEXT_SINGLE[];
+extern const char STR_LIST_SINGLE[];
+extern const char STR_LIST_MULTI[];
+extern const char STR_HIDDEN[];
+extern const char STR_FORM_TYPE[];
+
+extern const char STR_FROM[];
+extern const char STR_TO[];
+extern const char STR_BOTH[];
+extern const char STR_REMOVE[];
+extern const char STR_TRUE[];
+
+extern const char STR_TYPE[];
+extern const char STR_NAME[];
+extern const char STR_ID[];
+extern const char STR_JID[];
+extern const char STR_SUBSCRIPTION[];
+extern const char STR_ASK[];
+extern const char STR_X[];
+extern const char STR_GOOGLE_COM[];
+extern const char STR_GMAIL_COM[];
+extern const char STR_GOOGLEMAIL_COM[];
+extern const char STR_DEFAULT_DOMAIN[];
+extern const char STR_TALK_GOOGLE_COM[];
+extern const char STR_TALKX_L_GOOGLE_COM[];
+extern const char STR_XMPP_GOOGLE_COM[];
+extern const char STR_XMPPX_L_GOOGLE_COM[];
+
+#ifdef FEATURE_ENABLE_VOICEMAIL
+extern const char STR_VOICEMAIL[];
+extern const char STR_OUTGOINGVOICEMAIL[];
+#endif
+
+extern const char STR_UNAVAILABLE[];
+
+extern const char NS_PING[];
+extern const StaticQName QN_PING;
+
+extern const char NS_MUC_UNIQUE[];
+extern const StaticQName QN_MUC_UNIQUE_QUERY;
+extern const StaticQName QN_HANGOUT_ID;
+
+extern const char STR_GOOGLE_MUC_LOOKUP_JID[];
+extern const char STR_MUC_ROOMCONFIG_ROOMNAME[];
+extern const char STR_MUC_ROOMCONFIG_FEATURES[];
+extern const char STR_MUC_ROOM_FEATURE_ENTERPRISE[];
+extern const char STR_MUC_ROOMCONFIG[];
+extern const char STR_MUC_ROOM_FEATURE_HANGOUT[];
+extern const char STR_MUC_ROOM_FEATURE_HANGOUT_LITE[];
+extern const char STR_MUC_ROOM_FEATURE_BROADCAST[];
+extern const char STR_MUC_ROOM_FEATURE_MULTI_USER_VC[];
+extern const char STR_MUC_ROOM_FEATURE_RECORDABLE[];
+extern const char STR_MUC_ROOM_FEATURE_CUSTOM_RECORDING[];
+extern const char STR_MUC_ROOM_OWNER_PROFILE_ID[];
+extern const char STR_MUC_ROOM_FEATURE_ABUSE_RECORDABLE[];
+
+extern const char STR_ID_TYPE_CONVERSATION[];
+extern const char NS_GOOGLE_MUC_HANGOUT[];
+extern const StaticQName QN_GOOGLE_MUC_HANGOUT_INVITE;
+extern const StaticQName QN_GOOGLE_MUC_HANGOUT_INVITE_TYPE;
+extern const StaticQName QN_ATTR_CREATE_ACTIVITY;
+extern const StaticQName QN_GOOGLE_MUC_HANGOUT_PUBLIC;
+extern const StaticQName QN_GOOGLE_MUC_HANGOUT_INVITEE;
+extern const StaticQName QN_GOOGLE_MUC_HANGOUT_NOTIFICATION_STATUS;
+extern const StaticQName QN_GOOGLE_MUC_HANGOUT_NOTIFICATION_TYPE;
+extern const StaticQName QN_GOOGLE_MUC_HANGOUT_HANGOUT_START_CONTEXT;
+extern const StaticQName QN_GOOGLE_MUC_HANGOUT_CONVERSATION_ID;
+
+extern const StaticQName QN_STREAM_STREAM;
+extern const StaticQName QN_STREAM_FEATURES;
+extern const StaticQName QN_STREAM_ERROR;
+
+extern const StaticQName QN_XSTREAM_BAD_FORMAT;
+extern const StaticQName QN_XSTREAM_BAD_NAMESPACE_PREFIX;
+extern const StaticQName QN_XSTREAM_CONFLICT;
+extern const StaticQName QN_XSTREAM_CONNECTION_TIMEOUT;
+extern const StaticQName QN_XSTREAM_HOST_GONE;
+extern const StaticQName QN_XSTREAM_HOST_UNKNOWN;
+extern const StaticQName QN_XSTREAM_IMPROPER_ADDRESSIING;
+extern const StaticQName QN_XSTREAM_INTERNAL_SERVER_ERROR;
+extern const StaticQName QN_XSTREAM_INVALID_FROM;
+extern const StaticQName QN_XSTREAM_INVALID_ID;
+extern const StaticQName QN_XSTREAM_INVALID_NAMESPACE;
+extern const StaticQName QN_XSTREAM_INVALID_XML;
+extern const StaticQName QN_XSTREAM_NOT_AUTHORIZED;
+extern const StaticQName QN_XSTREAM_POLICY_VIOLATION;
+extern const StaticQName QN_XSTREAM_REMOTE_CONNECTION_FAILED;
+extern const StaticQName QN_XSTREAM_RESOURCE_CONSTRAINT;
+extern const StaticQName QN_XSTREAM_RESTRICTED_XML;
+extern const StaticQName QN_XSTREAM_SEE_OTHER_HOST;
+extern const StaticQName QN_XSTREAM_SYSTEM_SHUTDOWN;
+extern const StaticQName QN_XSTREAM_UNDEFINED_CONDITION;
+extern const StaticQName QN_XSTREAM_UNSUPPORTED_ENCODING;
+extern const StaticQName QN_XSTREAM_UNSUPPORTED_STANZA_TYPE;
+extern const StaticQName QN_XSTREAM_UNSUPPORTED_VERSION;
+extern const StaticQName QN_XSTREAM_XML_NOT_WELL_FORMED;
+extern const StaticQName QN_XSTREAM_TEXT;
+
+extern const StaticQName QN_TLS_STARTTLS;
+extern const StaticQName QN_TLS_REQUIRED;
+extern const StaticQName QN_TLS_PROCEED;
+extern const StaticQName QN_TLS_FAILURE;
+
+extern const StaticQName QN_SASL_MECHANISMS;
+extern const StaticQName QN_SASL_MECHANISM;
+extern const StaticQName QN_SASL_AUTH;
+extern const StaticQName QN_SASL_CHALLENGE;
+extern const StaticQName QN_SASL_RESPONSE;
+extern const StaticQName QN_SASL_ABORT;
+extern const StaticQName QN_SASL_SUCCESS;
+extern const StaticQName QN_SASL_FAILURE;
+extern const StaticQName QN_SASL_ABORTED;
+extern const StaticQName QN_SASL_INCORRECT_ENCODING;
+extern const StaticQName QN_SASL_INVALID_AUTHZID;
+extern const StaticQName QN_SASL_INVALID_MECHANISM;
+extern const StaticQName QN_SASL_MECHANISM_TOO_WEAK;
+extern const StaticQName QN_SASL_NOT_AUTHORIZED;
+extern const StaticQName QN_SASL_TEMPORARY_AUTH_FAILURE;
+
+// These are non-standard.
+extern const char NS_GOOGLE_AUTH[];
+extern const char NS_GOOGLE_AUTH_PROTOCOL[];
+extern const StaticQName QN_GOOGLE_AUTH_CLIENT_USES_FULL_BIND_RESULT;
+extern const StaticQName QN_GOOGLE_ALLOW_NON_GOOGLE_ID_XMPP_LOGIN;
+extern const StaticQName QN_GOOGLE_AUTH_SERVICE;
+
+extern const StaticQName QN_DIALBACK_RESULT;
+extern const StaticQName QN_DIALBACK_VERIFY;
+
+extern const StaticQName QN_STANZA_BAD_REQUEST;
+extern const StaticQName QN_STANZA_CONFLICT;
+extern const StaticQName QN_STANZA_FEATURE_NOT_IMPLEMENTED;
+extern const StaticQName QN_STANZA_FORBIDDEN;
+extern const StaticQName QN_STANZA_GONE;
+extern const StaticQName QN_STANZA_INTERNAL_SERVER_ERROR;
+extern const StaticQName QN_STANZA_ITEM_NOT_FOUND;
+extern const StaticQName QN_STANZA_JID_MALFORMED;
+extern const StaticQName QN_STANZA_NOT_ACCEPTABLE;
+extern const StaticQName QN_STANZA_NOT_ALLOWED;
+extern const StaticQName QN_STANZA_PAYMENT_REQUIRED;
+extern const StaticQName QN_STANZA_RECIPIENT_UNAVAILABLE;
+extern const StaticQName QN_STANZA_REDIRECT;
+extern const StaticQName QN_STANZA_REGISTRATION_REQUIRED;
+extern const StaticQName QN_STANZA_REMOTE_SERVER_NOT_FOUND;
+extern const StaticQName QN_STANZA_REMOTE_SERVER_TIMEOUT;
+extern const StaticQName QN_STANZA_RESOURCE_CONSTRAINT;
+extern const StaticQName QN_STANZA_SERVICE_UNAVAILABLE;
+extern const StaticQName QN_STANZA_SUBSCRIPTION_REQUIRED;
+extern const StaticQName QN_STANZA_UNDEFINED_CONDITION;
+extern const StaticQName QN_STANZA_UNEXPECTED_REQUEST;
+extern const StaticQName QN_STANZA_TEXT;
+
+extern const StaticQName QN_BIND_BIND;
+extern const StaticQName QN_BIND_RESOURCE;
+extern const StaticQName QN_BIND_JID;
+
+extern const StaticQName QN_MESSAGE;
+extern const StaticQName QN_BODY;
+extern const StaticQName QN_SUBJECT;
+extern const StaticQName QN_THREAD;
+extern const StaticQName QN_PRESENCE;
+extern const StaticQName QN_SHOW;
+extern const StaticQName QN_STATUS;
+extern const StaticQName QN_LANG;
+extern const StaticQName QN_PRIORITY;
+extern const StaticQName QN_IQ;
+extern const StaticQName QN_ERROR;
+
+extern const StaticQName QN_SERVER_MESSAGE;
+extern const StaticQName QN_SERVER_BODY;
+extern const StaticQName QN_SERVER_SUBJECT;
+extern const StaticQName QN_SERVER_THREAD;
+extern const StaticQName QN_SERVER_PRESENCE;
+extern const StaticQName QN_SERVER_SHOW;
+extern const StaticQName QN_SERVER_STATUS;
+extern const StaticQName QN_SERVER_LANG;
+extern const StaticQName QN_SERVER_PRIORITY;
+extern const StaticQName QN_SERVER_IQ;
+extern const StaticQName QN_SERVER_ERROR;
+
+extern const StaticQName QN_SESSION_SESSION;
+
+extern const StaticQName QN_PRIVACY_QUERY;
+extern const StaticQName QN_PRIVACY_ACTIVE;
+extern const StaticQName QN_PRIVACY_DEFAULT;
+extern const StaticQName QN_PRIVACY_LIST;
+extern const StaticQName QN_PRIVACY_ITEM;
+extern const StaticQName QN_PRIVACY_IQ;
+extern const StaticQName QN_PRIVACY_MESSAGE;
+extern const StaticQName QN_PRIVACY_PRESENCE_IN;
+extern const StaticQName QN_PRIVACY_PRESENCE_OUT;
+
+extern const StaticQName QN_ROSTER_QUERY;
+extern const StaticQName QN_ROSTER_ITEM;
+extern const StaticQName QN_ROSTER_GROUP;
+
+extern const StaticQName QN_VCARD;
+extern const StaticQName QN_VCARD_FN;
+extern const StaticQName QN_VCARD_PHOTO;
+extern const StaticQName QN_VCARD_PHOTO_BINVAL;
+extern const StaticQName QN_VCARD_AVATAR_HASH;
+extern const StaticQName QN_VCARD_AVATAR_HASH_MODIFIED;
+
+#if defined(FEATURE_ENABLE_PSTN)
+extern const StaticQName QN_VCARD_TEL;
+extern const StaticQName QN_VCARD_VOICE;
+extern const StaticQName QN_VCARD_HOME;
+extern const StaticQName QN_VCARD_WORK;
+extern const StaticQName QN_VCARD_CELL;
+extern const StaticQName QN_VCARD_NUMBER;
+#endif
+
+#if defined(FEATURE_ENABLE_RICHPROFILES)
+extern const StaticQName QN_USER_PROFILE_QUERY;
+extern const StaticQName QN_USER_PROFILE_URL;
+
+extern const StaticQName QN_ATOM_FEED;
+extern const StaticQName QN_ATOM_ENTRY;
+extern const StaticQName QN_ATOM_TITLE;
+extern const StaticQName QN_ATOM_ID;
+extern const StaticQName QN_ATOM_MODIFIED;
+extern const StaticQName QN_ATOM_IMAGE;
+extern const StaticQName QN_ATOM_LINK;
+extern const StaticQName QN_ATOM_HREF;
+#endif
+
+extern const StaticQName QN_XML_LANG;
+
+extern const StaticQName QN_ENCODING;
+extern const StaticQName QN_VERSION;
+extern const StaticQName QN_TO;
+extern const StaticQName QN_FROM;
+extern const StaticQName QN_TYPE;
+extern const StaticQName QN_ID;
+extern const StaticQName QN_CODE;
+extern const StaticQName QN_NAME;
+extern const StaticQName QN_VALUE;
+extern const StaticQName QN_ACTION;
+extern const StaticQName QN_ORDER;
+extern const StaticQName QN_MECHANISM;
+extern const StaticQName QN_ASK;
+extern const StaticQName QN_JID;
+extern const StaticQName QN_NICK;
+extern const StaticQName QN_SUBSCRIPTION;
+extern const StaticQName QN_TITLE1;
+extern const StaticQName QN_TITLE2;
+extern const StaticQName QN_AFFILIATION;
+extern const StaticQName QN_ROLE;
+extern const StaticQName QN_TIME;
+
+extern const StaticQName QN_XMLNS_CLIENT;
+extern const StaticQName QN_XMLNS_SERVER;
+extern const StaticQName QN_XMLNS_STREAM;
+
+// Presence
+extern const char STR_SHOW_AWAY[];
+extern const char STR_SHOW_CHAT[];
+extern const char STR_SHOW_DND[];
+extern const char STR_SHOW_XA[];
+extern const char STR_SHOW_OFFLINE[];
+
+extern const char NS_GOOGLE_PSTN_CONFERENCE[];
+extern const StaticQName QN_GOOGLE_PSTN_CONFERENCE_STATUS;
+extern const StaticQName QN_ATTR_STATUS;
+
+// Presence connection status
+extern const char STR_PSTN_CONFERENCE_STATUS_CONNECTING[];
+extern const char STR_PSTN_CONFERENCE_STATUS_JOINING[];
+extern const char STR_PSTN_CONFERENCE_STATUS_CONNECTED[];
+extern const char STR_PSTN_CONFERENCE_STATUS_HANGUP[];
+
+// Subscription
+extern const char STR_SUBSCRIBE[];
+extern const char STR_SUBSCRIBED[];
+extern const char STR_UNSUBSCRIBE[];
+extern const char STR_UNSUBSCRIBED[];
+
+// Google Invite
+extern const char NS_GOOGLE_SUBSCRIBE[];
+extern const StaticQName QN_INVITATION;
+extern const StaticQName QN_INVITE_NAME;
+extern const StaticQName QN_INVITE_SUBJECT;
+extern const StaticQName QN_INVITE_MESSAGE;
+
+// Kick
+extern const char NS_GOOGLE_MUC_ADMIN[];
+extern const StaticQName QN_GOOGLE_MUC_ADMIN_QUERY;
+extern const StaticQName QN_GOOGLE_MUC_ADMIN_QUERY_ITEM;
+extern const StaticQName QN_GOOGLE_MUC_ADMIN_QUERY_ITEM_REASON;
+
+// PubSub: http://xmpp.org/extensions/xep-0060.html
+extern const char NS_PUBSUB[];
+extern const StaticQName QN_PUBSUB;
+extern const StaticQName QN_PUBSUB_ITEMS;
+extern const StaticQName QN_PUBSUB_ITEM;
+extern const StaticQName QN_PUBSUB_PUBLISH;
+extern const StaticQName QN_PUBSUB_RETRACT;
+extern const StaticQName QN_ATTR_PUBLISHER;
+
+extern const char NS_PUBSUB_EVENT[];
+extern const StaticQName QN_NODE;
+extern const StaticQName QN_PUBSUB_EVENT;
+extern const StaticQName QN_PUBSUB_EVENT_ITEMS;
+extern const StaticQName QN_PUBSUB_EVENT_ITEM;
+extern const StaticQName QN_PUBSUB_EVENT_RETRACT;
+extern const StaticQName QN_NOTIFY;
+
+extern const char NS_PRESENTER[];
+extern const StaticQName QN_PRESENTER_PRESENTER;
+extern const StaticQName QN_PRESENTER_PRESENTATION_ITEM;
+extern const StaticQName QN_PRESENTER_PRESENTATION_TYPE;
+extern const StaticQName QN_PRESENTER_PRESENTATION_ID;
+
+// JEP 0030
+extern const StaticQName QN_CATEGORY;
+extern const StaticQName QN_VAR;
+extern const char NS_DISCO_INFO[];
+extern const char NS_DISCO_ITEMS[];
+
+extern const StaticQName QN_DISCO_INFO_QUERY;
+extern const StaticQName QN_DISCO_IDENTITY;
+extern const StaticQName QN_DISCO_FEATURE;
+
+extern const StaticQName QN_DISCO_ITEMS_QUERY;
+extern const StaticQName QN_DISCO_ITEM;
+
+// JEP 0020
+extern const char NS_FEATURE[];
+extern const StaticQName QN_FEATURE_FEATURE;
+
+// JEP 0004
+extern const char NS_XDATA[];
+extern const StaticQName QN_XDATA_X;
+extern const StaticQName QN_XDATA_INSTRUCTIONS;
+extern const StaticQName QN_XDATA_TITLE;
+extern const StaticQName QN_XDATA_FIELD;
+extern const StaticQName QN_XDATA_REPORTED;
+extern const StaticQName QN_XDATA_ITEM;
+extern const StaticQName QN_XDATA_DESC;
+extern const StaticQName QN_XDATA_REQUIRED;
+extern const StaticQName QN_XDATA_VALUE;
+extern const StaticQName QN_XDATA_OPTION;
+
+// JEP 0045
+extern const char NS_MUC[];
+extern const StaticQName QN_MUC_X;
+extern const StaticQName QN_MUC_ITEM;
+extern const StaticQName QN_MUC_AFFILIATION;
+extern const StaticQName QN_MUC_ROLE;
+extern const StaticQName QN_CLIENT_VERSION;
+extern const StaticQName QN_LOCALE;
+extern const char STR_AFFILIATION_NONE[];
+extern const char STR_ROLE_PARTICIPANT[];
+
+extern const char NS_GOOGLE_SESSION[];
+extern const StaticQName QN_GOOGLE_USER_ID;
+extern const StaticQName QN_GOOGLE_CIRCLE_ID;
+extern const StaticQName QN_GOOGLE_SESSION_BLOCKED;
+extern const StaticQName QN_GOOGLE_SESSION_BLOCKING;
+
+extern const char NS_MUC_OWNER[];
+extern const StaticQName QN_MUC_OWNER_QUERY;
+
+extern const char NS_MUC_USER[];
+extern const StaticQName QN_MUC_USER_CONTINUE;
+extern const StaticQName QN_MUC_USER_X;
+extern const StaticQName QN_MUC_USER_ITEM;
+extern const StaticQName QN_MUC_USER_STATUS;
+extern const StaticQName QN_MUC_USER_REASON;
+extern const StaticQName QN_MUC_USER_ABUSE_VIOLATION;
+
+// JEP 0055 - Jabber Search
+extern const char NS_SEARCH[];
+extern const StaticQName QN_SEARCH_QUERY;
+extern const StaticQName QN_SEARCH_ITEM;
+extern const StaticQName QN_SEARCH_ROOM_NAME;
+extern const StaticQName QN_SEARCH_ROOM_JID;
+extern const StaticQName QN_SEARCH_ROOM_DOMAIN;
+extern const StaticQName QN_SEARCH_HANGOUT_ID;
+extern const StaticQName QN_SEARCH_EXTERNAL_ID;
+
+// JEP 0115
+extern const char NS_CAPS[];
+extern const StaticQName QN_CAPS_C;
+extern const StaticQName QN_VER;
+extern const StaticQName QN_EXT;
+
+
+// Avatar - JEP 0153
+extern const char kNSVCard[];
+extern const StaticQName kQnVCardX;
+extern const StaticQName kQnVCardPhoto;
+
+// JEP 0172 User Nickname
+extern const char NS_NICKNAME[];
+extern const StaticQName QN_NICKNAME;
+
+// JEP 0085 chat state
+extern const char NS_CHATSTATE[];
+extern const StaticQName QN_CS_ACTIVE;
+extern const StaticQName QN_CS_COMPOSING;
+extern const StaticQName QN_CS_PAUSED;
+extern const StaticQName QN_CS_INACTIVE;
+extern const StaticQName QN_CS_GONE;
+
+// JEP 0091 Delayed Delivery
+extern const char kNSDelay[];
+extern const StaticQName kQnDelayX;
+extern const StaticQName kQnStamp;
+
+// Google time stamping (higher resolution)
+extern const char kNSTimestamp[];
+extern const StaticQName kQnTime;
+extern const StaticQName kQnMilliseconds;
+
+extern const char NS_JINGLE_INFO[];
+extern const StaticQName QN_JINGLE_INFO_QUERY;
+extern const StaticQName QN_JINGLE_INFO_STUN;
+extern const StaticQName QN_JINGLE_INFO_RELAY;
+extern const StaticQName QN_JINGLE_INFO_SERVER;
+extern const StaticQName QN_JINGLE_INFO_TOKEN;
+extern const StaticQName QN_JINGLE_INFO_HOST;
+extern const StaticQName QN_JINGLE_INFO_TCP;
+extern const StaticQName QN_JINGLE_INFO_UDP;
+extern const StaticQName QN_JINGLE_INFO_TCPSSL;
+
+extern const char NS_GOOGLE_CALLPERF_STATS[];
+extern const StaticQName QN_CALLPERF_STATS;
+extern const StaticQName QN_CALLPERF_SESSIONID;
+extern const StaticQName QN_CALLPERF_LOCALUSER;
+extern const StaticQName QN_CALLPERF_REMOTEUSER;
+extern const StaticQName QN_CALLPERF_STARTTIME;
+extern const StaticQName QN_CALLPERF_CALL_LENGTH;
+extern const StaticQName QN_CALLPERF_CALL_ACCEPTED;
+extern const StaticQName QN_CALLPERF_CALL_ERROR_CODE;
+extern const StaticQName QN_CALLPERF_TERMINATE_CODE;
+extern const StaticQName QN_CALLPERF_DATAPOINT;
+extern const StaticQName QN_CALLPERF_DATAPOINT_TIME;
+extern const StaticQName QN_CALLPERF_DATAPOINT_FRACTION_LOST;
+extern const StaticQName QN_CALLPERF_DATAPOINT_CUM_LOST;
+extern const StaticQName QN_CALLPERF_DATAPOINT_EXT_MAX;
+extern const StaticQName QN_CALLPERF_DATAPOINT_JITTER;
+extern const StaticQName QN_CALLPERF_DATAPOINT_RTT;
+extern const StaticQName QN_CALLPERF_DATAPOINT_BYTES_R;
+extern const StaticQName QN_CALLPERF_DATAPOINT_PACKETS_R;
+extern const StaticQName QN_CALLPERF_DATAPOINT_BYTES_S;
+extern const StaticQName QN_CALLPERF_DATAPOINT_PACKETS_S;
+extern const StaticQName QN_CALLPERF_DATAPOINT_PROCESS_CPU;
+extern const StaticQName QN_CALLPERF_DATAPOINT_SYSTEM_CPU;
+extern const StaticQName QN_CALLPERF_DATAPOINT_CPUS;
+extern const StaticQName QN_CALLPERF_CONNECTION;
+extern const StaticQName QN_CALLPERF_CONNECTION_LOCAL_ADDRESS;
+extern const StaticQName QN_CALLPERF_CONNECTION_REMOTE_ADDRESS;
+extern const StaticQName QN_CALLPERF_CONNECTION_FLAGS;
+extern const StaticQName QN_CALLPERF_CONNECTION_RTT;
+extern const StaticQName QN_CALLPERF_CONNECTION_TOTAL_BYTES_S;
+extern const StaticQName QN_CALLPERF_CONNECTION_BYTES_SECOND_S;
+extern const StaticQName QN_CALLPERF_CONNECTION_TOTAL_BYTES_R;
+extern const StaticQName QN_CALLPERF_CONNECTION_BYTES_SECOND_R;
+extern const StaticQName QN_CALLPERF_CANDIDATE;
+extern const StaticQName QN_CALLPERF_CANDIDATE_ENDPOINT;
+extern const StaticQName QN_CALLPERF_CANDIDATE_PROTOCOL;
+extern const StaticQName QN_CALLPERF_CANDIDATE_ADDRESS;
+extern const StaticQName QN_CALLPERF_MEDIA;
+extern const StaticQName QN_CALLPERF_MEDIA_DIRECTION;
+extern const StaticQName QN_CALLPERF_MEDIA_SSRC;
+extern const StaticQName QN_CALLPERF_MEDIA_ENERGY;
+extern const StaticQName QN_CALLPERF_MEDIA_FIR;
+extern const StaticQName QN_CALLPERF_MEDIA_NACK;
+extern const StaticQName QN_CALLPERF_MEDIA_FPS;
+extern const StaticQName QN_CALLPERF_MEDIA_FPS_NETWORK;
+extern const StaticQName QN_CALLPERF_MEDIA_FPS_DECODED;
+extern const StaticQName QN_CALLPERF_MEDIA_JITTER_BUFFER_SIZE;
+extern const StaticQName QN_CALLPERF_MEDIA_PREFERRED_JITTER_BUFFER_SIZE;
+extern const StaticQName QN_CALLPERF_MEDIA_TOTAL_PLAYOUT_DELAY;
+
+// Muc invites.
+extern const StaticQName QN_MUC_USER_INVITE;
+
+// Multiway audio/video.
+extern const char NS_GOOGLE_MUC_USER[];
+extern const StaticQName QN_GOOGLE_MUC_USER_AVAILABLE_MEDIA;
+extern const StaticQName QN_GOOGLE_MUC_USER_ENTRY;
+extern const StaticQName QN_GOOGLE_MUC_USER_MEDIA;
+extern const StaticQName QN_GOOGLE_MUC_USER_TYPE;
+extern const StaticQName QN_GOOGLE_MUC_USER_SRC_ID;
+extern const StaticQName QN_GOOGLE_MUC_USER_STATUS;
+extern const StaticQName QN_LABEL;
+
+extern const char NS_GOOGLE_MUC_MEDIA[];
+extern const StaticQName QN_GOOGLE_MUC_AUDIO_MUTE;
+extern const StaticQName QN_GOOGLE_MUC_VIDEO_MUTE;
+extern const StaticQName QN_GOOGLE_MUC_VIDEO_PAUSE;
+extern const StaticQName QN_GOOGLE_MUC_RECORDING;
+extern const StaticQName QN_GOOGLE_MUC_MEDIA_BLOCK;
+extern const StaticQName QN_STATE_ATTR;
+
+
+extern const char AUTH_MECHANISM_GOOGLE_COOKIE[];
+extern const char AUTH_MECHANISM_GOOGLE_TOKEN[];
+extern const char AUTH_MECHANISM_OAUTH2[];
+extern const char AUTH_MECHANISM_PLAIN[];
+
+} // namespace buzz
+
+#endif // WEBRTC_LIBJINGLE_XMPP_CONSTANTS_H_
diff --git a/libjingle/xmpp/discoitemsquerytask.cc b/libjingle/xmpp/discoitemsquerytask.cc
new file mode 100644
index 00000000..765ee143
--- /dev/null
+++ b/libjingle/xmpp/discoitemsquerytask.cc
@@ -0,0 +1,62 @@
+/*
+ * 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 "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/discoitemsquerytask.h"
+#include "webrtc/libjingle/xmpp/xmpptask.h"
+#include "webrtc/base/scoped_ptr.h"
+
+namespace buzz {
+
+DiscoItemsQueryTask::DiscoItemsQueryTask(XmppTaskParentInterface* parent,
+ const Jid& to,
+ const std::string& node)
+ : IqTask(parent, STR_GET, to, MakeRequest(node)) {
+}
+
+XmlElement* DiscoItemsQueryTask::MakeRequest(const std::string& node) {
+ XmlElement* element = new XmlElement(QN_DISCO_ITEMS_QUERY, true);
+ if (!node.empty()) {
+ element->AddAttr(QN_NODE, node);
+ }
+ return element;
+}
+
+void DiscoItemsQueryTask::HandleResult(const XmlElement* stanza) {
+ const XmlElement* query = stanza->FirstNamed(QN_DISCO_ITEMS_QUERY);
+ if (query) {
+ std::vector<DiscoItem> items;
+ for (const buzz::XmlChild* child = query->FirstChild(); child;
+ child = child->NextChild()) {
+ DiscoItem item;
+ const buzz::XmlElement* child_element = child->AsElement();
+ if (ParseItem(child_element, &item)) {
+ items.push_back(item);
+ }
+ }
+ SignalResult(items);
+ } else {
+ SignalError(this, NULL);
+ }
+}
+
+bool DiscoItemsQueryTask::ParseItem(const XmlElement* element,
+ DiscoItem* item) {
+ if (element->HasAttr(QN_JID)) {
+ return false;
+ }
+
+ item->jid = element->Attr(QN_JID);
+ item->name = element->Attr(QN_NAME);
+ item->node = element->Attr(QN_NODE);
+ return true;
+}
+
+} // namespace buzz
diff --git a/libjingle/xmpp/discoitemsquerytask.h b/libjingle/xmpp/discoitemsquerytask.h
new file mode 100644
index 00000000..62e862e1
--- /dev/null
+++ b/libjingle/xmpp/discoitemsquerytask.h
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+// Fires a disco items query, such as the following example:
+//
+// <iq type='get'
+// from='foo@gmail.com/asdf'
+// to='bar@google.com'
+// id='1234'>
+// <query xmlns=' http://jabber.org/protocol/disco#items'
+// node='blah '/>
+// </iq>
+//
+// Sample response:
+//
+// <iq type='result'
+// from=' hendriks@google.com'
+// to='rsturgell@google.com/asdf'
+// id='1234'>
+// <query xmlns=' http://jabber.org/protocol/disco#items '
+// node='blah'>
+// <item something='somethingelse'/>
+// </query>
+// </iq>
+
+
+#ifndef WEBRTC_LIBJINGLE_XMPP_DISCOITEMSQUERYTASK_H_
+#define WEBRTC_LIBJINGLE_XMPP_DISCOITEMSQUERYTASK_H_
+
+#include <string>
+#include <vector>
+
+#include "webrtc/libjingle/xmpp/iqtask.h"
+
+namespace buzz {
+
+struct DiscoItem {
+ std::string jid;
+ std::string node;
+ std::string name;
+};
+
+class DiscoItemsQueryTask : public IqTask {
+ public:
+ DiscoItemsQueryTask(XmppTaskParentInterface* parent,
+ const Jid& to, const std::string& node);
+
+ sigslot::signal1<std::vector<DiscoItem> > SignalResult;
+
+ private:
+ static XmlElement* MakeRequest(const std::string& node);
+ virtual void HandleResult(const XmlElement* result);
+ static bool ParseItem(const XmlElement* element, DiscoItem* item);
+};
+
+} // namespace buzz
+
+#endif // WEBRTC_LIBJINGLE_XMPP_DISCOITEMSQUERYTASK_H_
diff --git a/libjingle/xmpp/fakexmppclient.h b/libjingle/xmpp/fakexmppclient.h
new file mode 100644
index 00000000..453a7c86
--- /dev/null
+++ b/libjingle/xmpp/fakexmppclient.h
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+// A fake XmppClient for use in unit tests.
+
+#ifndef WEBRTC_LIBJINGLE_XMPP_FAKEXMPPCLIENT_H_
+#define WEBRTC_LIBJINGLE_XMPP_FAKEXMPPCLIENT_H_
+
+#include <string>
+#include <vector>
+
+#include "webrtc/libjingle/xmpp/xmpptask.h"
+
+namespace buzz {
+
+class XmlElement;
+
+class FakeXmppClient : public XmppTaskParentInterface,
+ public XmppClientInterface {
+ public:
+ explicit FakeXmppClient(rtc::TaskParent* parent)
+ : XmppTaskParentInterface(parent) {
+ }
+
+ // As XmppTaskParentInterface
+ virtual XmppClientInterface* GetClient() {
+ return this;
+ }
+
+ virtual int ProcessStart() {
+ return STATE_RESPONSE;
+ }
+
+ // As XmppClientInterface
+ virtual XmppEngine::State GetState() const {
+ return XmppEngine::STATE_OPEN;
+ }
+
+ virtual const Jid& jid() const {
+ return jid_;
+ }
+
+ virtual std::string NextId() {
+ // Implement if needed for tests.
+ return "0";
+ }
+
+ virtual XmppReturnStatus SendStanza(const XmlElement* stanza) {
+ sent_stanzas_.push_back(stanza);
+ return XMPP_RETURN_OK;
+ }
+
+ const std::vector<const XmlElement*>& sent_stanzas() {
+ return sent_stanzas_;
+ }
+
+ virtual XmppReturnStatus SendStanzaError(
+ const XmlElement * pelOriginal,
+ XmppStanzaError code,
+ const std::string & text) {
+ // Implement if needed for tests.
+ return XMPP_RETURN_OK;
+ }
+
+ virtual void AddXmppTask(XmppTask* task,
+ XmppEngine::HandlerLevel level) {
+ tasks_.push_back(task);
+ }
+
+ virtual void RemoveXmppTask(XmppTask* task) {
+ std::remove(tasks_.begin(), tasks_.end(), task);
+ }
+
+ // As FakeXmppClient
+ void set_jid(const Jid& jid) {
+ jid_ = jid;
+ }
+
+ // Takes ownership of stanza.
+ void HandleStanza(XmlElement* stanza) {
+ for (std::vector<XmppTask*>::iterator task = tasks_.begin();
+ task != tasks_.end(); ++task) {
+ if ((*task)->HandleStanza(stanza)) {
+ delete stanza;
+ return;
+ }
+ }
+ delete stanza;
+ }
+
+ private:
+ Jid jid_;
+ std::vector<XmppTask*> tasks_;
+ std::vector<const XmlElement*> sent_stanzas_;
+};
+
+} // namespace buzz
+
+#endif // WEBRTC_LIBJINGLE_XMPP_FAKEXMPPCLIENT_H_
diff --git a/libjingle/xmpp/hangoutpubsubclient.cc b/libjingle/xmpp/hangoutpubsubclient.cc
new file mode 100644
index 00000000..db1ac314
--- /dev/null
+++ b/libjingle/xmpp/hangoutpubsubclient.cc
@@ -0,0 +1,400 @@
+/*
+ * 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.
+ */
+
+#include "webrtc/libjingle/xmpp/hangoutpubsubclient.h"
+
+#include "webrtc/libjingle/xmllite/qname.h"
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/jid.h"
+#include "webrtc/base/logging.h"
+
+
+// Gives a high-level API for MUC call PubSub needs such as
+// presenter state, recording state, mute state, and remote mute.
+
+namespace buzz {
+
+namespace {
+const char kPresenting[] = "s";
+const char kNotPresenting[] = "o";
+
+} // namespace
+
+// A simple serialiazer where presence of item => true, lack of item
+// => false.
+class BoolStateSerializer : public PubSubStateSerializer<bool> {
+ virtual XmlElement* Write(const QName& state_name, const bool& state) {
+ if (!state) {
+ return NULL;
+ }
+
+ return new XmlElement(state_name, true);
+ }
+
+ virtual void Parse(const XmlElement* state_elem, bool *state_out) {
+ *state_out = state_elem != NULL;
+ }
+};
+
+class PresenterStateClient : public PubSubStateClient<bool> {
+ public:
+ PresenterStateClient(const std::string& publisher_nick,
+ PubSubClient* client,
+ const QName& state_name,
+ bool default_state)
+ : PubSubStateClient<bool>(
+ publisher_nick, client, state_name, default_state,
+ new PublishedNickKeySerializer(), NULL) {
+ }
+
+ virtual void Publish(const std::string& published_nick,
+ const bool& state,
+ std::string* task_id_out) {
+ XmlElement* presenter_elem = new XmlElement(QN_PRESENTER_PRESENTER, true);
+ presenter_elem->AddAttr(QN_NICK, published_nick);
+
+ XmlElement* presentation_item_elem =
+ new XmlElement(QN_PRESENTER_PRESENTATION_ITEM, false);
+ const std::string& presentation_type = state ? kPresenting : kNotPresenting;
+ presentation_item_elem->AddAttr(
+ QN_PRESENTER_PRESENTATION_TYPE, presentation_type);
+
+ // The Presenter state is kind of dumb in that it doesn't always use
+ // retracts. It relies on setting the "type" to a special value.
+ std::string itemid = published_nick;
+ std::vector<XmlElement*> children;
+ children.push_back(presenter_elem);
+ children.push_back(presentation_item_elem);
+ client()->PublishItem(itemid, children, task_id_out);
+ }
+
+ protected:
+ virtual bool ParseStateItem(const PubSubItem& item,
+ StateItemInfo* info_out,
+ bool* state_out) {
+ const XmlElement* presenter_elem =
+ item.elem->FirstNamed(QN_PRESENTER_PRESENTER);
+ const XmlElement* presentation_item_elem =
+ item.elem->FirstNamed(QN_PRESENTER_PRESENTATION_ITEM);
+ if (presentation_item_elem == NULL || presenter_elem == NULL) {
+ return false;
+ }
+
+ info_out->publisher_nick =
+ client()->GetPublisherNickFromPubSubItem(item.elem);
+ info_out->published_nick = presenter_elem->Attr(QN_NICK);
+ *state_out = (presentation_item_elem->Attr(
+ QN_PRESENTER_PRESENTATION_TYPE) != kNotPresenting);
+ return true;
+ }
+
+ virtual bool StatesEqual(const bool& state1, const bool& state2) {
+ // Make every item trigger an event, even if state doesn't change.
+ return false;
+ }
+};
+
+HangoutPubSubClient::HangoutPubSubClient(XmppTaskParentInterface* parent,
+ const Jid& mucjid,
+ const std::string& nick)
+ : mucjid_(mucjid),
+ nick_(nick) {
+ presenter_client_.reset(new PubSubClient(parent, mucjid, NS_PRESENTER));
+ presenter_client_->SignalRequestError.connect(
+ this, &HangoutPubSubClient::OnPresenterRequestError);
+
+ media_client_.reset(new PubSubClient(parent, mucjid, NS_GOOGLE_MUC_MEDIA));
+ media_client_->SignalRequestError.connect(
+ this, &HangoutPubSubClient::OnMediaRequestError);
+
+ presenter_state_client_.reset(new PresenterStateClient(
+ nick_, presenter_client_.get(), QN_PRESENTER_PRESENTER, false));
+ presenter_state_client_->SignalStateChange.connect(
+ this, &HangoutPubSubClient::OnPresenterStateChange);
+ presenter_state_client_->SignalPublishResult.connect(
+ this, &HangoutPubSubClient::OnPresenterPublishResult);
+ presenter_state_client_->SignalPublishError.connect(
+ this, &HangoutPubSubClient::OnPresenterPublishError);
+
+ audio_mute_state_client_.reset(new PubSubStateClient<bool>(
+ nick_, media_client_.get(), QN_GOOGLE_MUC_AUDIO_MUTE, false,
+ new PublishedNickKeySerializer(), new BoolStateSerializer()));
+ // Can't just repeat because we need to watch for remote mutes.
+ audio_mute_state_client_->SignalStateChange.connect(
+ this, &HangoutPubSubClient::OnAudioMuteStateChange);
+ audio_mute_state_client_->SignalPublishResult.connect(
+ this, &HangoutPubSubClient::OnAudioMutePublishResult);
+ audio_mute_state_client_->SignalPublishError.connect(
+ this, &HangoutPubSubClient::OnAudioMutePublishError);
+
+ video_mute_state_client_.reset(new PubSubStateClient<bool>(
+ nick_, media_client_.get(), QN_GOOGLE_MUC_VIDEO_MUTE, false,
+ new PublishedNickKeySerializer(), new BoolStateSerializer()));
+ // Can't just repeat because we need to watch for remote mutes.
+ video_mute_state_client_->SignalStateChange.connect(
+ this, &HangoutPubSubClient::OnVideoMuteStateChange);
+ video_mute_state_client_->SignalPublishResult.connect(
+ this, &HangoutPubSubClient::OnVideoMutePublishResult);
+ video_mute_state_client_->SignalPublishError.connect(
+ this, &HangoutPubSubClient::OnVideoMutePublishError);
+
+ video_pause_state_client_.reset(new PubSubStateClient<bool>(
+ nick_, media_client_.get(), QN_GOOGLE_MUC_VIDEO_PAUSE, false,
+ new PublishedNickKeySerializer(), new BoolStateSerializer()));
+ video_pause_state_client_->SignalStateChange.connect(
+ this, &HangoutPubSubClient::OnVideoPauseStateChange);
+ video_pause_state_client_->SignalPublishResult.connect(
+ this, &HangoutPubSubClient::OnVideoPausePublishResult);
+ video_pause_state_client_->SignalPublishError.connect(
+ this, &HangoutPubSubClient::OnVideoPausePublishError);
+
+ recording_state_client_.reset(new PubSubStateClient<bool>(
+ nick_, media_client_.get(), QN_GOOGLE_MUC_RECORDING, false,
+ new PublishedNickKeySerializer(), new BoolStateSerializer()));
+ recording_state_client_->SignalStateChange.connect(
+ this, &HangoutPubSubClient::OnRecordingStateChange);
+ recording_state_client_->SignalPublishResult.connect(
+ this, &HangoutPubSubClient::OnRecordingPublishResult);
+ recording_state_client_->SignalPublishError.connect(
+ this, &HangoutPubSubClient::OnRecordingPublishError);
+
+ media_block_state_client_.reset(new PubSubStateClient<bool>(
+ nick_, media_client_.get(), QN_GOOGLE_MUC_MEDIA_BLOCK, false,
+ new PublisherAndPublishedNicksKeySerializer(),
+ new BoolStateSerializer()));
+ media_block_state_client_->SignalStateChange.connect(
+ this, &HangoutPubSubClient::OnMediaBlockStateChange);
+ media_block_state_client_->SignalPublishResult.connect(
+ this, &HangoutPubSubClient::OnMediaBlockPublishResult);
+ media_block_state_client_->SignalPublishError.connect(
+ this, &HangoutPubSubClient::OnMediaBlockPublishError);
+}
+
+HangoutPubSubClient::~HangoutPubSubClient() {
+}
+
+void HangoutPubSubClient::RequestAll() {
+ presenter_client_->RequestItems();
+ media_client_->RequestItems();
+}
+
+void HangoutPubSubClient::OnPresenterRequestError(
+ PubSubClient* client, const XmlElement* stanza) {
+ SignalRequestError(client->node(), stanza);
+}
+
+void HangoutPubSubClient::OnMediaRequestError(
+ PubSubClient* client, const XmlElement* stanza) {
+ SignalRequestError(client->node(), stanza);
+}
+
+void HangoutPubSubClient::PublishPresenterState(
+ bool presenting, std::string* task_id_out) {
+ presenter_state_client_->Publish(nick_, presenting, task_id_out);
+}
+
+void HangoutPubSubClient::PublishAudioMuteState(
+ bool muted, std::string* task_id_out) {
+ audio_mute_state_client_->Publish(nick_, muted, task_id_out);
+}
+
+void HangoutPubSubClient::PublishVideoMuteState(
+ bool muted, std::string* task_id_out) {
+ video_mute_state_client_->Publish(nick_, muted, task_id_out);
+}
+
+void HangoutPubSubClient::PublishVideoPauseState(
+ bool paused, std::string* task_id_out) {
+ video_pause_state_client_->Publish(nick_, paused, task_id_out);
+}
+
+void HangoutPubSubClient::PublishRecordingState(
+ bool recording, std::string* task_id_out) {
+ recording_state_client_->Publish(nick_, recording, task_id_out);
+}
+
+// Remote mute is accomplished by setting another client's mute state.
+void HangoutPubSubClient::RemoteMute(
+ const std::string& mutee_nick, std::string* task_id_out) {
+ audio_mute_state_client_->Publish(mutee_nick, true, task_id_out);
+}
+
+// Block media is accomplished by setting another client's block
+// state, kind of like remote mute.
+void HangoutPubSubClient::BlockMedia(
+ const std::string& blockee_nick, std::string* task_id_out) {
+ media_block_state_client_->Publish(blockee_nick, true, task_id_out);
+}
+
+void HangoutPubSubClient::OnPresenterStateChange(
+ const PubSubStateChange<bool>& change) {
+ SignalPresenterStateChange(
+ change.published_nick, change.old_state, change.new_state);
+}
+
+void HangoutPubSubClient::OnPresenterPublishResult(
+ const std::string& task_id, const XmlElement* item) {
+ SignalPublishPresenterResult(task_id);
+}
+
+void HangoutPubSubClient::OnPresenterPublishError(
+ const std::string& task_id, const XmlElement* item,
+ const XmlElement* stanza) {
+ SignalPublishPresenterError(task_id, stanza);
+}
+
+// Since a remote mute is accomplished by another client setting our
+// mute state, if our state changes to muted, we should mute ourselves.
+// Note that remote un-muting is disallowed by the RoomServer.
+void HangoutPubSubClient::OnAudioMuteStateChange(
+ const PubSubStateChange<bool>& change) {
+ bool was_muted = change.old_state;
+ bool is_muted = change.new_state;
+ bool remote_action = (!change.publisher_nick.empty() &&
+ (change.publisher_nick != change.published_nick));
+
+ if (remote_action) {
+ const std::string& mutee_nick = change.published_nick;
+ const std::string& muter_nick = change.publisher_nick;
+ if (!is_muted) {
+ // The server should prevent remote un-mute.
+ LOG(LS_WARNING) << muter_nick << " remote unmuted " << mutee_nick;
+ return;
+ }
+ bool should_mute_locally = (mutee_nick == nick_);
+ SignalRemoteMute(mutee_nick, muter_nick, should_mute_locally);
+ }
+ SignalAudioMuteStateChange(change.published_nick, was_muted, is_muted);
+}
+
+const std::string GetAudioMuteNickFromItem(const XmlElement* item) {
+ if (item != NULL) {
+ const XmlElement* audio_mute_state =
+ item->FirstNamed(QN_GOOGLE_MUC_AUDIO_MUTE);
+ if (audio_mute_state != NULL) {
+ return audio_mute_state->Attr(QN_NICK);
+ }
+ }
+ return std::string();
+}
+
+const std::string GetBlockeeNickFromItem(const XmlElement* item) {
+ if (item != NULL) {
+ const XmlElement* media_block_state =
+ item->FirstNamed(QN_GOOGLE_MUC_MEDIA_BLOCK);
+ if (media_block_state != NULL) {
+ return media_block_state->Attr(QN_NICK);
+ }
+ }
+ return std::string();
+}
+
+void HangoutPubSubClient::OnAudioMutePublishResult(
+ const std::string& task_id, const XmlElement* item) {
+ const std::string& mutee_nick = GetAudioMuteNickFromItem(item);
+ if (mutee_nick != nick_) {
+ SignalRemoteMuteResult(task_id, mutee_nick);
+ } else {
+ SignalPublishAudioMuteResult(task_id);
+ }
+}
+
+void HangoutPubSubClient::OnAudioMutePublishError(
+ const std::string& task_id, const XmlElement* item,
+ const XmlElement* stanza) {
+ const std::string& mutee_nick = GetAudioMuteNickFromItem(item);
+ if (mutee_nick != nick_) {
+ SignalRemoteMuteError(task_id, mutee_nick, stanza);
+ } else {
+ SignalPublishAudioMuteError(task_id, stanza);
+ }
+}
+
+void HangoutPubSubClient::OnVideoMuteStateChange(
+ const PubSubStateChange<bool>& change) {
+ SignalVideoMuteStateChange(
+ change.published_nick, change.old_state, change.new_state);
+}
+
+void HangoutPubSubClient::OnVideoMutePublishResult(
+ const std::string& task_id, const XmlElement* item) {
+ SignalPublishVideoMuteResult(task_id);
+}
+
+void HangoutPubSubClient::OnVideoMutePublishError(
+ const std::string& task_id, const XmlElement* item,
+ const XmlElement* stanza) {
+ SignalPublishVideoMuteError(task_id, stanza);
+}
+
+void HangoutPubSubClient::OnVideoPauseStateChange(
+ const PubSubStateChange<bool>& change) {
+ SignalVideoPauseStateChange(
+ change.published_nick, change.old_state, change.new_state);
+}
+
+void HangoutPubSubClient::OnVideoPausePublishResult(
+ const std::string& task_id, const XmlElement* item) {
+ SignalPublishVideoPauseResult(task_id);
+}
+
+void HangoutPubSubClient::OnVideoPausePublishError(
+ const std::string& task_id, const XmlElement* item,
+ const XmlElement* stanza) {
+ SignalPublishVideoPauseError(task_id, stanza);
+}
+
+void HangoutPubSubClient::OnRecordingStateChange(
+ const PubSubStateChange<bool>& change) {
+ SignalRecordingStateChange(
+ change.published_nick, change.old_state, change.new_state);
+}
+
+void HangoutPubSubClient::OnRecordingPublishResult(
+ const std::string& task_id, const XmlElement* item) {
+ SignalPublishRecordingResult(task_id);
+}
+
+void HangoutPubSubClient::OnRecordingPublishError(
+ const std::string& task_id, const XmlElement* item,
+ const XmlElement* stanza) {
+ SignalPublishRecordingError(task_id, stanza);
+}
+
+void HangoutPubSubClient::OnMediaBlockStateChange(
+ const PubSubStateChange<bool>& change) {
+ const std::string& blockee_nick = change.published_nick;
+ const std::string& blocker_nick = change.publisher_nick;
+
+ bool was_blockee = change.old_state;
+ bool is_blockee = change.new_state;
+ if (!was_blockee && is_blockee) {
+ SignalMediaBlock(blockee_nick, blocker_nick);
+ }
+ // TODO: Should we bother signaling unblock? Currently
+ // it isn't allowed, but it might happen when a participant leaves
+ // the room and the item is retracted.
+}
+
+void HangoutPubSubClient::OnMediaBlockPublishResult(
+ const std::string& task_id, const XmlElement* item) {
+ const std::string& blockee_nick = GetBlockeeNickFromItem(item);
+ SignalMediaBlockResult(task_id, blockee_nick);
+}
+
+void HangoutPubSubClient::OnMediaBlockPublishError(
+ const std::string& task_id, const XmlElement* item,
+ const XmlElement* stanza) {
+ const std::string& blockee_nick = GetBlockeeNickFromItem(item);
+ SignalMediaBlockError(task_id, blockee_nick, stanza);
+}
+
+} // namespace buzz
diff --git a/libjingle/xmpp/hangoutpubsubclient.h b/libjingle/xmpp/hangoutpubsubclient.h
new file mode 100644
index 00000000..2586768e
--- /dev/null
+++ b/libjingle/xmpp/hangoutpubsubclient.h
@@ -0,0 +1,178 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_HANGOUTPUBSUBCLIENT_H_
+#define WEBRTC_LIBJINGLE_XMPP_HANGOUTPUBSUBCLIENT_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "webrtc/libjingle/xmpp/jid.h"
+#include "webrtc/libjingle/xmpp/pubsubclient.h"
+#include "webrtc/libjingle/xmpp/pubsubstateclient.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/sigslot.h"
+#include "webrtc/base/sigslotrepeater.h"
+
+// Gives a high-level API for MUC call PubSub needs such as
+// presenter state, recording state, mute state, and remote mute.
+
+namespace buzz {
+
+class Jid;
+class XmlElement;
+class XmppTaskParentInterface;
+
+// A client tied to a specific MUC jid and local nick. Provides ways
+// to get updates and publish state and events. Must call
+// RequestAll() to start getting updates.
+class HangoutPubSubClient : public sigslot::has_slots<> {
+ public:
+ HangoutPubSubClient(XmppTaskParentInterface* parent,
+ const Jid& mucjid,
+ const std::string& nick);
+ ~HangoutPubSubClient();
+ const Jid& mucjid() const { return mucjid_; }
+ const std::string& nick() const { return nick_; }
+
+ // Requests all of the different states and subscribes for updates.
+ // Responses and updates will be signalled via the various signals.
+ void RequestAll();
+ // Signal (nick, was_presenting, is_presenting)
+ sigslot::signal3<const std::string&, bool, bool> SignalPresenterStateChange;
+ // Signal (nick, was_muted, is_muted)
+ sigslot::signal3<const std::string&, bool, bool> SignalAudioMuteStateChange;
+ // Signal (nick, was_muted, is_muted)
+ sigslot::signal3<const std::string&, bool, bool> SignalVideoMuteStateChange;
+ // Signal (nick, was_paused, is_paused)
+ sigslot::signal3<const std::string&, bool, bool> SignalVideoPauseStateChange;
+ // Signal (nick, was_recording, is_recording)
+ sigslot::signal3<const std::string&, bool, bool> SignalRecordingStateChange;
+ // Signal (mutee_nick, muter_nick, should_mute_locally)
+ sigslot::signal3<const std::string&,
+ const std::string&,
+ bool> SignalRemoteMute;
+ // Signal (blockee_nick, blocker_nick)
+ sigslot::signal2<const std::string&, const std::string&> SignalMediaBlock;
+
+ // Signal (node, error stanza)
+ sigslot::signal2<const std::string&, const XmlElement*> SignalRequestError;
+
+ // On each of these, provide a task_id_out to get the task_id, which
+ // can be correlated to the error and result signals.
+ void PublishPresenterState(
+ bool presenting, std::string* task_id_out = NULL);
+ void PublishAudioMuteState(
+ bool muted, std::string* task_id_out = NULL);
+ void PublishVideoMuteState(
+ bool muted, std::string* task_id_out = NULL);
+ void PublishVideoPauseState(
+ bool paused, std::string* task_id_out = NULL);
+ void PublishRecordingState(
+ bool recording, std::string* task_id_out = NULL);
+ void RemoteMute(
+ const std::string& mutee_nick, std::string* task_id_out = NULL);
+ void BlockMedia(
+ const std::string& blockee_nick, std::string* task_id_out = NULL);
+
+ // Signal task_id
+ sigslot::signal1<const std::string&> SignalPublishAudioMuteResult;
+ sigslot::signal1<const std::string&> SignalPublishVideoMuteResult;
+ sigslot::signal1<const std::string&> SignalPublishVideoPauseResult;
+ sigslot::signal1<const std::string&> SignalPublishPresenterResult;
+ sigslot::signal1<const std::string&> SignalPublishRecordingResult;
+ // Signal (task_id, mutee_nick)
+ sigslot::signal2<const std::string&,
+ const std::string&> SignalRemoteMuteResult;
+ // Signal (task_id, blockee_nick)
+ sigslot::signal2<const std::string&,
+ const std::string&> SignalMediaBlockResult;
+
+ // Signal (task_id, error stanza)
+ sigslot::signal2<const std::string&,
+ const XmlElement*> SignalPublishAudioMuteError;
+ sigslot::signal2<const std::string&,
+ const XmlElement*> SignalPublishVideoMuteError;
+ sigslot::signal2<const std::string&,
+ const XmlElement*> SignalPublishVideoPauseError;
+ sigslot::signal2<const std::string&,
+ const XmlElement*> SignalPublishPresenterError;
+ sigslot::signal2<const std::string&,
+ const XmlElement*> SignalPublishRecordingError;
+ sigslot::signal2<const std::string&,
+ const XmlElement*> SignalPublishMediaBlockError;
+ // Signal (task_id, mutee_nick, error stanza)
+ sigslot::signal3<const std::string&,
+ const std::string&,
+ const XmlElement*> SignalRemoteMuteError;
+ // Signal (task_id, blockee_nick, error stanza)
+ sigslot::signal3<const std::string&,
+ const std::string&,
+ const XmlElement*> SignalMediaBlockError;
+
+
+ private:
+ void OnPresenterRequestError(PubSubClient* client,
+ const XmlElement* stanza);
+ void OnMediaRequestError(PubSubClient* client,
+ const XmlElement* stanza);
+
+ void OnPresenterStateChange(const PubSubStateChange<bool>& change);
+ void OnPresenterPublishResult(const std::string& task_id,
+ const XmlElement* item);
+ void OnPresenterPublishError(const std::string& task_id,
+ const XmlElement* item,
+ const XmlElement* stanza);
+ void OnAudioMuteStateChange(const PubSubStateChange<bool>& change);
+ void OnAudioMutePublishResult(const std::string& task_id,
+ const XmlElement* item);
+ void OnAudioMutePublishError(const std::string& task_id,
+ const XmlElement* item,
+ const XmlElement* stanza);
+ void OnVideoMuteStateChange(const PubSubStateChange<bool>& change);
+ void OnVideoMutePublishResult(const std::string& task_id,
+ const XmlElement* item);
+ void OnVideoMutePublishError(const std::string& task_id,
+ const XmlElement* item,
+ const XmlElement* stanza);
+ void OnVideoPauseStateChange(const PubSubStateChange<bool>& change);
+ void OnVideoPausePublishResult(const std::string& task_id,
+ const XmlElement* item);
+ void OnVideoPausePublishError(const std::string& task_id,
+ const XmlElement* item,
+ const XmlElement* stanza);
+ void OnRecordingStateChange(const PubSubStateChange<bool>& change);
+ void OnRecordingPublishResult(const std::string& task_id,
+ const XmlElement* item);
+ void OnRecordingPublishError(const std::string& task_id,
+ const XmlElement* item,
+ const XmlElement* stanza);
+ void OnMediaBlockStateChange(const PubSubStateChange<bool>& change);
+ void OnMediaBlockPublishResult(const std::string& task_id,
+ const XmlElement* item);
+ void OnMediaBlockPublishError(const std::string& task_id,
+ const XmlElement* item,
+ const XmlElement* stanza);
+ Jid mucjid_;
+ std::string nick_;
+ rtc::scoped_ptr<PubSubClient> media_client_;
+ rtc::scoped_ptr<PubSubClient> presenter_client_;
+ rtc::scoped_ptr<PubSubStateClient<bool> > presenter_state_client_;
+ rtc::scoped_ptr<PubSubStateClient<bool> > audio_mute_state_client_;
+ rtc::scoped_ptr<PubSubStateClient<bool> > video_mute_state_client_;
+ rtc::scoped_ptr<PubSubStateClient<bool> > video_pause_state_client_;
+ rtc::scoped_ptr<PubSubStateClient<bool> > recording_state_client_;
+ rtc::scoped_ptr<PubSubStateClient<bool> > media_block_state_client_;
+};
+
+} // namespace buzz
+
+#endif // WEBRTC_LIBJINGLE_XMPP_HANGOUTPUBSUBCLIENT_H_
diff --git a/libjingle/xmpp/hangoutpubsubclient_unittest.cc b/libjingle/xmpp/hangoutpubsubclient_unittest.cc
new file mode 100644
index 00000000..7c6ea58f
--- /dev/null
+++ b/libjingle/xmpp/hangoutpubsubclient_unittest.cc
@@ -0,0 +1,753 @@
+/*
+ * 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.
+ */
+
+#include <string>
+
+#include "webrtc/libjingle/xmllite/qname.h"
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/fakexmppclient.h"
+#include "webrtc/libjingle/xmpp/hangoutpubsubclient.h"
+#include "webrtc/libjingle/xmpp/jid.h"
+#include "webrtc/base/faketaskrunner.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/sigslot.h"
+
+class TestHangoutPubSubListener : public sigslot::has_slots<> {
+ public:
+ TestHangoutPubSubListener() :
+ request_error_count(0),
+ publish_audio_mute_error_count(0),
+ publish_video_mute_error_count(0),
+ publish_video_pause_error_count(0),
+ publish_presenter_error_count(0),
+ publish_recording_error_count(0),
+ remote_mute_error_count(0) {
+ }
+
+ void OnPresenterStateChange(
+ const std::string& nick, bool was_presenting, bool is_presenting) {
+ last_presenter_nick = nick;
+ last_was_presenting = was_presenting;
+ last_is_presenting = is_presenting;
+ }
+
+ void OnAudioMuteStateChange(
+ const std::string& nick, bool was_muted, bool is_muted) {
+ last_audio_muted_nick = nick;
+ last_was_audio_muted = was_muted;
+ last_is_audio_muted = is_muted;
+ }
+
+ void OnVideoMuteStateChange(
+ const std::string& nick, bool was_muted, bool is_muted) {
+ last_video_muted_nick = nick;
+ last_was_video_muted = was_muted;
+ last_is_video_muted = is_muted;
+ }
+
+ void OnVideoPauseStateChange(
+ const std::string& nick, bool was_paused, bool is_paused) {
+ last_video_paused_nick = nick;
+ last_was_video_paused = was_paused;
+ last_is_video_paused = is_paused;
+ }
+
+ void OnRecordingStateChange(
+ const std::string& nick, bool was_recording, bool is_recording) {
+ last_recording_nick = nick;
+ last_was_recording = was_recording;
+ last_is_recording = is_recording;
+ }
+
+ void OnRemoteMute(
+ const std::string& mutee_nick,
+ const std::string& muter_nick,
+ bool should_mute_locally) {
+ last_mutee_nick = mutee_nick;
+ last_muter_nick = muter_nick;
+ last_should_mute = should_mute_locally;
+ }
+
+ void OnMediaBlock(
+ const std::string& blockee_nick,
+ const std::string& blocker_nick) {
+ last_blockee_nick = blockee_nick;
+ last_blocker_nick = blocker_nick;
+ }
+
+ void OnRequestError(const std::string& node, const buzz::XmlElement* stanza) {
+ ++request_error_count;
+ request_error_node = node;
+ }
+
+ void OnPublishAudioMuteError(const std::string& task_id,
+ const buzz::XmlElement* stanza) {
+ ++publish_audio_mute_error_count;
+ error_task_id = task_id;
+ }
+
+ void OnPublishVideoMuteError(const std::string& task_id,
+ const buzz::XmlElement* stanza) {
+ ++publish_video_mute_error_count;
+ error_task_id = task_id;
+ }
+
+ void OnPublishVideoPauseError(const std::string& task_id,
+ const buzz::XmlElement* stanza) {
+ ++publish_video_pause_error_count;
+ error_task_id = task_id;
+ }
+
+ void OnPublishPresenterError(const std::string& task_id,
+ const buzz::XmlElement* stanza) {
+ ++publish_presenter_error_count;
+ error_task_id = task_id;
+ }
+
+ void OnPublishRecordingError(const std::string& task_id,
+ const buzz::XmlElement* stanza) {
+ ++publish_recording_error_count;
+ error_task_id = task_id;
+ }
+
+ void OnRemoteMuteResult(const std::string& task_id,
+ const std::string& mutee_nick) {
+ result_task_id = task_id;
+ remote_mute_mutee_nick = mutee_nick;
+ }
+
+ void OnRemoteMuteError(const std::string& task_id,
+ const std::string& mutee_nick,
+ const buzz::XmlElement* stanza) {
+ ++remote_mute_error_count;
+ error_task_id = task_id;
+ remote_mute_mutee_nick = mutee_nick;
+ }
+
+ void OnMediaBlockResult(const std::string& task_id,
+ const std::string& blockee_nick) {
+ result_task_id = task_id;
+ media_blockee_nick = blockee_nick;
+ }
+
+ void OnMediaBlockError(const std::string& task_id,
+ const std::string& blockee_nick,
+ const buzz::XmlElement* stanza) {
+ ++media_block_error_count;
+ error_task_id = task_id;
+ media_blockee_nick = blockee_nick;
+ }
+
+ std::string last_presenter_nick;
+ bool last_is_presenting;
+ bool last_was_presenting;
+ std::string last_audio_muted_nick;
+ bool last_is_audio_muted;
+ bool last_was_audio_muted;
+ std::string last_video_muted_nick;
+ bool last_is_video_muted;
+ bool last_was_video_muted;
+ std::string last_video_paused_nick;
+ bool last_is_video_paused;
+ bool last_was_video_paused;
+ std::string last_recording_nick;
+ bool last_is_recording;
+ bool last_was_recording;
+ std::string last_mutee_nick;
+ std::string last_muter_nick;
+ bool last_should_mute;
+ std::string last_blockee_nick;
+ std::string last_blocker_nick;
+
+ int request_error_count;
+ std::string request_error_node;
+ int publish_audio_mute_error_count;
+ int publish_video_mute_error_count;
+ int publish_video_pause_error_count;
+ int publish_presenter_error_count;
+ int publish_recording_error_count;
+ int remote_mute_error_count;
+ std::string result_task_id;
+ std::string error_task_id;
+ std::string remote_mute_mutee_nick;
+ int media_block_error_count;
+ std::string media_blockee_nick;
+};
+
+class HangoutPubSubClientTest : public testing::Test {
+ public:
+ HangoutPubSubClientTest() :
+ pubsubjid("room@domain.com"),
+ nick("me") {
+
+ runner.reset(new rtc::FakeTaskRunner());
+ xmpp_client = new buzz::FakeXmppClient(runner.get());
+ client.reset(new buzz::HangoutPubSubClient(xmpp_client, pubsubjid, nick));
+ listener.reset(new TestHangoutPubSubListener());
+ client->SignalPresenterStateChange.connect(
+ listener.get(), &TestHangoutPubSubListener::OnPresenterStateChange);
+ client->SignalAudioMuteStateChange.connect(
+ listener.get(), &TestHangoutPubSubListener::OnAudioMuteStateChange);
+ client->SignalVideoMuteStateChange.connect(
+ listener.get(), &TestHangoutPubSubListener::OnVideoMuteStateChange);
+ client->SignalVideoPauseStateChange.connect(
+ listener.get(), &TestHangoutPubSubListener::OnVideoPauseStateChange);
+ client->SignalRecordingStateChange.connect(
+ listener.get(), &TestHangoutPubSubListener::OnRecordingStateChange);
+ client->SignalRemoteMute.connect(
+ listener.get(), &TestHangoutPubSubListener::OnRemoteMute);
+ client->SignalMediaBlock.connect(
+ listener.get(), &TestHangoutPubSubListener::OnMediaBlock);
+ client->SignalRequestError.connect(
+ listener.get(), &TestHangoutPubSubListener::OnRequestError);
+ client->SignalPublishAudioMuteError.connect(
+ listener.get(), &TestHangoutPubSubListener::OnPublishAudioMuteError);
+ client->SignalPublishVideoMuteError.connect(
+ listener.get(), &TestHangoutPubSubListener::OnPublishVideoMuteError);
+ client->SignalPublishVideoPauseError.connect(
+ listener.get(), &TestHangoutPubSubListener::OnPublishVideoPauseError);
+ client->SignalPublishPresenterError.connect(
+ listener.get(), &TestHangoutPubSubListener::OnPublishPresenterError);
+ client->SignalPublishRecordingError.connect(
+ listener.get(), &TestHangoutPubSubListener::OnPublishRecordingError);
+ client->SignalRemoteMuteResult.connect(
+ listener.get(), &TestHangoutPubSubListener::OnRemoteMuteResult);
+ client->SignalRemoteMuteError.connect(
+ listener.get(), &TestHangoutPubSubListener::OnRemoteMuteError);
+ client->SignalMediaBlockResult.connect(
+ listener.get(), &TestHangoutPubSubListener::OnMediaBlockResult);
+ client->SignalMediaBlockError.connect(
+ listener.get(), &TestHangoutPubSubListener::OnMediaBlockError);
+ }
+
+ rtc::scoped_ptr<rtc::FakeTaskRunner> runner;
+ // xmpp_client deleted by deleting runner.
+ buzz::FakeXmppClient* xmpp_client;
+ rtc::scoped_ptr<buzz::HangoutPubSubClient> client;
+ rtc::scoped_ptr<TestHangoutPubSubListener> listener;
+ buzz::Jid pubsubjid;
+ std::string nick;
+};
+
+TEST_F(HangoutPubSubClientTest, TestRequest) {
+ ASSERT_EQ(0U, xmpp_client->sent_stanzas().size());
+
+ client->RequestAll();
+ std::string expected_presenter_request =
+ "<cli:iq type=\"get\" to=\"room@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<pub:pubsub xmlns:pub=\"http://jabber.org/protocol/pubsub\">"
+ "<pub:items node=\"google:presenter\"/>"
+ "</pub:pubsub>"
+ "</cli:iq>";
+
+ std::string expected_media_request =
+ "<cli:iq type=\"get\" to=\"room@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<pub:pubsub xmlns:pub=\"http://jabber.org/protocol/pubsub\">"
+ "<pub:items node=\"google:muc#media\"/>"
+ "</pub:pubsub>"
+ "</cli:iq>";
+
+ ASSERT_EQ(2U, xmpp_client->sent_stanzas().size());
+ EXPECT_EQ(expected_presenter_request, xmpp_client->sent_stanzas()[0]->Str());
+ EXPECT_EQ(expected_media_request, xmpp_client->sent_stanzas()[1]->Str());
+
+ std::string presenter_response =
+ "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'>"
+ " <pubsub xmlns='http://jabber.org/protocol/pubsub'>"
+ " <items node='google:presenter'>"
+ " <item id='12344'>"
+ " <presenter xmlns='google:presenter' nick='presenting-nick2'/>"
+ " <pre:presentation-item xmlns:pre='google:presenter'"
+ " pre:presentation-type='s'/>"
+ " </item>"
+ " <item id='12345'>"
+ " <presenter xmlns='google:presenter' nick='presenting-nick'/>"
+ " <pre:presentation-item xmlns:pre='google:presenter'"
+ " pre:presentation-type='o'/>"
+ " </item>"
+ // Some clients are "bad" in that they'll jam multiple states in
+ // all at once. We have to deal with it.
+ " <item id='12346'>"
+ " <presenter xmlns='google:presenter' nick='presenting-nick'/>"
+ " <pre:presentation-item xmlns:pre='google:presenter'"
+ " pre:presentation-type='s'/>"
+ " </item>"
+ " </items>"
+ " </pubsub>"
+ "</iq>";
+
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(presenter_response));
+ EXPECT_EQ("presenting-nick", listener->last_presenter_nick);
+ EXPECT_FALSE(listener->last_was_presenting);
+ EXPECT_TRUE(listener->last_is_presenting);
+
+ std::string media_response =
+ "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'>"
+ " <pubsub xmlns='http://jabber.org/protocol/pubsub'>"
+ " <items node='google:muc#media'>"
+ " <item id='audio-mute:muted-nick'>"
+ " <audio-mute nick='muted-nick' xmlns='google:muc#media'/>"
+ " </item>"
+ " <item id='video-mute:video-muted-nick'>"
+ " <video-mute nick='video-muted-nick' xmlns='google:muc#media'/>"
+ " </item>"
+ " <item id='video-pause:video-paused-nick'>"
+ " <video-pause nick='video-paused-nick' xmlns='google:muc#media'/>"
+ " </item>"
+ " <item id='recording:recording-nick'>"
+ " <recording nick='recording-nick' xmlns='google:muc#media'/>"
+ " </item>"
+ " </items>"
+ " </pubsub>"
+ "</iq>";
+
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(media_response));
+ EXPECT_EQ("muted-nick", listener->last_audio_muted_nick);
+ EXPECT_FALSE(listener->last_was_audio_muted);
+ EXPECT_TRUE(listener->last_is_audio_muted);
+
+ EXPECT_EQ("video-muted-nick", listener->last_video_muted_nick);
+ EXPECT_FALSE(listener->last_was_video_muted);
+ EXPECT_TRUE(listener->last_is_video_muted);
+
+ EXPECT_EQ("video-paused-nick", listener->last_video_paused_nick);
+ EXPECT_FALSE(listener->last_was_video_paused);
+ EXPECT_TRUE(listener->last_is_video_paused);
+
+ EXPECT_EQ("recording-nick", listener->last_recording_nick);
+ EXPECT_FALSE(listener->last_was_recording);
+ EXPECT_TRUE(listener->last_is_recording);
+
+ std::string incoming_presenter_resets_message =
+ "<message xmlns='jabber:client' from='room@domain.com'>"
+ " <event xmlns='http://jabber.org/protocol/pubsub#event'>"
+ " <items node='google:presenter'>"
+ " <item id='12348'>"
+ " <presenter xmlns='google:presenter' nick='presenting-nick'/>"
+ " <pre:presentation-item xmlns:pre='google:presenter'"
+ " pre:presentation-type='o'/>"
+ " </item>"
+ " </items>"
+ " </event>"
+ "</message>";
+
+ xmpp_client->HandleStanza(
+ buzz::XmlElement::ForStr(incoming_presenter_resets_message));
+ EXPECT_EQ("presenting-nick", listener->last_presenter_nick);
+ //EXPECT_TRUE(listener->last_was_presenting);
+ EXPECT_FALSE(listener->last_is_presenting);
+
+ std::string incoming_presenter_retracts_message =
+ "<message xmlns='jabber:client' from='room@domain.com'>"
+ " <event xmlns='http://jabber.org/protocol/pubsub#event'>"
+ " <items node='google:presenter'>"
+ " <retract id='12344'/>"
+ " </items>"
+ " </event>"
+ "</message>";
+
+ xmpp_client->HandleStanza(
+ buzz::XmlElement::ForStr(incoming_presenter_retracts_message));
+ EXPECT_EQ("presenting-nick2", listener->last_presenter_nick);
+ EXPECT_TRUE(listener->last_was_presenting);
+ EXPECT_FALSE(listener->last_is_presenting);
+
+ std::string incoming_media_retracts_message =
+ "<message xmlns='jabber:client' from='room@domain.com'>"
+ " <event xmlns='http://jabber.org/protocol/pubsub#event'>"
+ " <items node='google:muc#media'>"
+ " <item id='audio-mute:muted-nick'>"
+ " </item>"
+ " <retract id='video-mute:video-muted-nick'/>"
+ " <retract id='video-pause:video-paused-nick'/>"
+ " <retract id='recording:recording-nick'/>"
+ " </items>"
+ " </event>"
+ "</message>";
+
+ xmpp_client->HandleStanza(
+ buzz::XmlElement::ForStr(incoming_media_retracts_message));
+ EXPECT_EQ("muted-nick", listener->last_audio_muted_nick);
+ EXPECT_TRUE(listener->last_was_audio_muted);
+ EXPECT_FALSE(listener->last_is_audio_muted);
+
+ EXPECT_EQ("video-paused-nick", listener->last_video_paused_nick);
+ EXPECT_TRUE(listener->last_was_video_paused);
+ EXPECT_FALSE(listener->last_is_video_paused);
+
+ EXPECT_EQ("recording-nick", listener->last_recording_nick);
+ EXPECT_TRUE(listener->last_was_recording);
+ EXPECT_FALSE(listener->last_is_recording);
+
+ std::string incoming_presenter_changes_message =
+ "<message xmlns='jabber:client' from='room@domain.com'>"
+ " <event xmlns='http://jabber.org/protocol/pubsub#event'>"
+ " <items node='google:presenter'>"
+ " <item id='presenting-nick2'>"
+ " <presenter xmlns='google:presenter' nick='presenting-nick2'/>"
+ " <pre:presentation-item xmlns:pre='google:presenter'"
+ " pre:presentation-type='s'/>"
+ " </item>"
+ " </items>"
+ " </event>"
+ "</message>";
+
+ xmpp_client->HandleStanza(
+ buzz::XmlElement::ForStr(incoming_presenter_changes_message));
+ EXPECT_EQ("presenting-nick2", listener->last_presenter_nick);
+ EXPECT_FALSE(listener->last_was_presenting);
+ EXPECT_TRUE(listener->last_is_presenting);
+
+ xmpp_client->HandleStanza(
+ buzz::XmlElement::ForStr(incoming_presenter_changes_message));
+ EXPECT_EQ("presenting-nick2", listener->last_presenter_nick);
+ EXPECT_TRUE(listener->last_was_presenting);
+ EXPECT_TRUE(listener->last_is_presenting);
+
+ std::string incoming_media_changes_message =
+ "<message xmlns='jabber:client' from='room@domain.com'>"
+ " <event xmlns='http://jabber.org/protocol/pubsub#event'>"
+ " <items node='google:muc#media'>"
+ " <item id='audio-mute:muted-nick2'>"
+ " <audio-mute nick='muted-nick2' xmlns='google:muc#media'/>"
+ " </item>"
+ " <item id='video-pause:video-paused-nick2'>"
+ " <video-pause nick='video-paused-nick2' xmlns='google:muc#media'/>"
+ " </item>"
+ " <item id='recording:recording-nick2'>"
+ " <recording nick='recording-nick2' xmlns='google:muc#media'/>"
+ " </item>"
+ " </items>"
+ " </event>"
+ "</message>";
+
+ xmpp_client->HandleStanza(
+ buzz::XmlElement::ForStr(incoming_media_changes_message));
+ EXPECT_EQ("muted-nick2", listener->last_audio_muted_nick);
+ EXPECT_FALSE(listener->last_was_audio_muted);
+ EXPECT_TRUE(listener->last_is_audio_muted);
+
+ EXPECT_EQ("video-paused-nick2", listener->last_video_paused_nick);
+ EXPECT_FALSE(listener->last_was_video_paused);
+ EXPECT_TRUE(listener->last_is_video_paused);
+
+ EXPECT_EQ("recording-nick2", listener->last_recording_nick);
+ EXPECT_FALSE(listener->last_was_recording);
+ EXPECT_TRUE(listener->last_is_recording);
+
+ std::string incoming_remote_mute_message =
+ "<message xmlns='jabber:client' from='room@domain.com'>"
+ " <event xmlns='http://jabber.org/protocol/pubsub#event'>"
+ " <items node='google:muc#media'>"
+ " <item id='audio-mute:mutee' publisher='room@domain.com/muter'>"
+ " <audio-mute nick='mutee' xmlns='google:muc#media'/>"
+ " </item>"
+ " </items>"
+ " </event>"
+ "</message>";
+
+ listener->last_is_audio_muted = false;
+ xmpp_client->HandleStanza(
+ buzz::XmlElement::ForStr(incoming_remote_mute_message));
+ EXPECT_EQ("mutee", listener->last_mutee_nick);
+ EXPECT_EQ("muter", listener->last_muter_nick);
+ EXPECT_FALSE(listener->last_should_mute);
+ EXPECT_EQ("mutee", listener->last_audio_muted_nick);
+ EXPECT_TRUE(listener->last_is_audio_muted);
+
+ std::string incoming_remote_mute_me_message =
+ "<message xmlns='jabber:client' from='room@domain.com'>"
+ " <event xmlns='http://jabber.org/protocol/pubsub#event'>"
+ " <items node='google:muc#media'>"
+ " <item id='audio-mute:me' publisher='room@domain.com/muter'>"
+ " <audio-mute nick='me' xmlns='google:muc#media'/>"
+ " </item>"
+ " </items>"
+ " </event>"
+ "</message>";
+
+ listener->last_is_audio_muted = false;
+ xmpp_client->HandleStanza(
+ buzz::XmlElement::ForStr(incoming_remote_mute_me_message));
+ EXPECT_EQ("me", listener->last_mutee_nick);
+ EXPECT_EQ("muter", listener->last_muter_nick);
+ EXPECT_TRUE(listener->last_should_mute);
+ EXPECT_EQ("me", listener->last_audio_muted_nick);
+ EXPECT_TRUE(listener->last_is_audio_muted);
+
+ std::string incoming_media_block_message =
+ "<message xmlns='jabber:client' from='room@domain.com'>"
+ " <event xmlns='http://jabber.org/protocol/pubsub#event'>"
+ " <items node='google:muc#media'>"
+ " <item id='block:blocker:blockee'"
+ " publisher='room@domain.com/blocker'>"
+ " <block nick='blockee' xmlns='google:muc#media'/>"
+ " </item>"
+ " </items>"
+ " </event>"
+ "</message>";
+
+ xmpp_client->HandleStanza(
+ buzz::XmlElement::ForStr(incoming_media_block_message));
+ EXPECT_EQ("blockee", listener->last_blockee_nick);
+ EXPECT_EQ("blocker", listener->last_blocker_nick);
+}
+
+TEST_F(HangoutPubSubClientTest, TestRequestError) {
+ client->RequestAll();
+ std::string result_iq =
+ "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'>"
+ " <error type='auth'>"
+ " <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
+ " </error>"
+ "</iq>";
+
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
+ EXPECT_EQ(1, listener->request_error_count);
+ EXPECT_EQ("google:presenter", listener->request_error_node);
+}
+
+TEST_F(HangoutPubSubClientTest, TestPublish) {
+ client->PublishPresenterState(true);
+ std::string expected_presenter_iq =
+ "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
+ "<publish node=\"google:presenter\">"
+ "<item id=\"me\">"
+ "<presenter xmlns=\"google:presenter\""
+ " nick=\"me\"/>"
+ "<pre:presentation-item"
+ " pre:presentation-type=\"s\" xmlns:pre=\"google:presenter\"/>"
+ "</item>"
+ "</publish>"
+ "</pubsub>"
+ "</cli:iq>";
+
+ ASSERT_EQ(1U, xmpp_client->sent_stanzas().size());
+ EXPECT_EQ(expected_presenter_iq,
+ xmpp_client->sent_stanzas()[0]->Str());
+
+ client->PublishAudioMuteState(true);
+ std::string expected_audio_mute_iq =
+ "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
+ "<publish node=\"google:muc#media\">"
+ "<item id=\"audio-mute:me\">"
+ "<audio-mute xmlns=\"google:muc#media\" nick=\"me\"/>"
+ "</item>"
+ "</publish>"
+ "</pubsub>"
+ "</cli:iq>";
+
+ ASSERT_EQ(2U, xmpp_client->sent_stanzas().size());
+ EXPECT_EQ(expected_audio_mute_iq, xmpp_client->sent_stanzas()[1]->Str());
+
+ client->PublishVideoPauseState(true);
+ std::string expected_video_pause_iq =
+ "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
+ "<publish node=\"google:muc#media\">"
+ "<item id=\"video-pause:me\">"
+ "<video-pause xmlns=\"google:muc#media\" nick=\"me\"/>"
+ "</item>"
+ "</publish>"
+ "</pubsub>"
+ "</cli:iq>";
+
+ ASSERT_EQ(3U, xmpp_client->sent_stanzas().size());
+ EXPECT_EQ(expected_video_pause_iq, xmpp_client->sent_stanzas()[2]->Str());
+
+ client->PublishRecordingState(true);
+ std::string expected_recording_iq =
+ "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
+ "<publish node=\"google:muc#media\">"
+ "<item id=\"recording:me\">"
+ "<recording xmlns=\"google:muc#media\" nick=\"me\"/>"
+ "</item>"
+ "</publish>"
+ "</pubsub>"
+ "</cli:iq>";
+
+ ASSERT_EQ(4U, xmpp_client->sent_stanzas().size());
+ EXPECT_EQ(expected_recording_iq, xmpp_client->sent_stanzas()[3]->Str());
+
+ client->RemoteMute("mutee");
+ std::string expected_remote_mute_iq =
+ "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
+ "<publish node=\"google:muc#media\">"
+ "<item id=\"audio-mute:mutee\">"
+ "<audio-mute xmlns=\"google:muc#media\" nick=\"mutee\"/>"
+ "</item>"
+ "</publish>"
+ "</pubsub>"
+ "</cli:iq>";
+
+ ASSERT_EQ(5U, xmpp_client->sent_stanzas().size());
+ EXPECT_EQ(expected_remote_mute_iq, xmpp_client->sent_stanzas()[4]->Str());
+
+ client->PublishPresenterState(false);
+ std::string expected_presenter_retract_iq =
+ "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
+ "<publish node=\"google:presenter\">"
+ "<item id=\"me\">"
+ "<presenter xmlns=\"google:presenter\""
+ " nick=\"me\"/>"
+ "<pre:presentation-item"
+ " pre:presentation-type=\"o\" xmlns:pre=\"google:presenter\"/>"
+ "</item>"
+ "</publish>"
+ "</pubsub>"
+ "</cli:iq>";
+
+ ASSERT_EQ(6U, xmpp_client->sent_stanzas().size());
+ EXPECT_EQ(expected_presenter_retract_iq,
+ xmpp_client->sent_stanzas()[5]->Str());
+
+ client->PublishAudioMuteState(false);
+ std::string expected_audio_mute_retract_iq =
+ "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
+ "<retract node=\"google:muc#media\" notify=\"true\">"
+ "<item id=\"audio-mute:me\"/>"
+ "</retract>"
+ "</pubsub>"
+ "</cli:iq>";
+
+ ASSERT_EQ(7U, xmpp_client->sent_stanzas().size());
+ EXPECT_EQ(expected_audio_mute_retract_iq,
+ xmpp_client->sent_stanzas()[6]->Str());
+
+ client->PublishVideoPauseState(false);
+ std::string expected_video_pause_retract_iq =
+ "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
+ "<retract node=\"google:muc#media\" notify=\"true\">"
+ "<item id=\"video-pause:me\"/>"
+ "</retract>"
+ "</pubsub>"
+ "</cli:iq>";
+
+ ASSERT_EQ(8U, xmpp_client->sent_stanzas().size());
+ EXPECT_EQ(expected_video_pause_retract_iq,
+ xmpp_client->sent_stanzas()[7]->Str());
+
+ client->BlockMedia("blockee");
+ std::string expected_media_block_iq =
+ "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
+ "<publish node=\"google:muc#media\">"
+ "<item id=\"block:me:blockee\">"
+ "<block xmlns=\"google:muc#media\" nick=\"blockee\"/>"
+ "</item>"
+ "</publish>"
+ "</pubsub>"
+ "</cli:iq>";
+
+ ASSERT_EQ(9U, xmpp_client->sent_stanzas().size());
+ EXPECT_EQ(expected_media_block_iq, xmpp_client->sent_stanzas()[8]->Str());
+}
+
+TEST_F(HangoutPubSubClientTest, TestPublishPresenterError) {
+ std::string result_iq =
+ "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'/>";
+
+ client->PublishPresenterState(true);
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
+ EXPECT_EQ(1, listener->publish_presenter_error_count);
+ EXPECT_EQ("0", listener->error_task_id);
+}
+
+
+TEST_F(HangoutPubSubClientTest, TestPublishAudioMuteError) {
+ std::string result_iq =
+ "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'/>";
+
+ client->PublishAudioMuteState(true);
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
+ EXPECT_EQ(1, listener->publish_audio_mute_error_count);
+ EXPECT_EQ("0", listener->error_task_id);
+}
+
+TEST_F(HangoutPubSubClientTest, TestPublishVideoPauseError) {
+ std::string result_iq =
+ "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'/>";
+
+ client->PublishVideoPauseState(true);
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
+ EXPECT_EQ(1, listener->publish_video_pause_error_count);
+ EXPECT_EQ("0", listener->error_task_id);
+}
+
+TEST_F(HangoutPubSubClientTest, TestPublishRecordingError) {
+ std::string result_iq =
+ "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'/>";
+
+ client->PublishRecordingState(true);
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
+ EXPECT_EQ(1, listener->publish_recording_error_count);
+ EXPECT_EQ("0", listener->error_task_id);
+}
+
+TEST_F(HangoutPubSubClientTest, TestPublishRemoteMuteResult) {
+ std::string result_iq =
+ "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'/>";
+
+ client->RemoteMute("joe");
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
+ EXPECT_EQ("joe", listener->remote_mute_mutee_nick);
+ EXPECT_EQ("0", listener->result_task_id);
+}
+
+TEST_F(HangoutPubSubClientTest, TestRemoteMuteError) {
+ std::string result_iq =
+ "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'/>";
+
+ client->RemoteMute("joe");
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
+ EXPECT_EQ(1, listener->remote_mute_error_count);
+ EXPECT_EQ("joe", listener->remote_mute_mutee_nick);
+ EXPECT_EQ("0", listener->error_task_id);
+}
+
+TEST_F(HangoutPubSubClientTest, TestPublishMediaBlockResult) {
+ std::string result_iq =
+ "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'/>";
+
+ client->BlockMedia("joe");
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
+ EXPECT_EQ("joe", listener->media_blockee_nick);
+ EXPECT_EQ("0", listener->result_task_id);
+}
+
+TEST_F(HangoutPubSubClientTest, TestMediaBlockError) {
+ std::string result_iq =
+ "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'/>";
+
+ client->BlockMedia("joe");
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
+ EXPECT_EQ(1, listener->remote_mute_error_count);
+ EXPECT_EQ("joe", listener->media_blockee_nick);
+ EXPECT_EQ("0", listener->error_task_id);
+}
diff --git a/libjingle/xmpp/iqtask.cc b/libjingle/xmpp/iqtask.cc
new file mode 100644
index 00000000..a7a41ee5
--- /dev/null
+++ b/libjingle/xmpp/iqtask.cc
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+#include "webrtc/libjingle/xmpp/iqtask.h"
+
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/xmppclient.h"
+
+namespace buzz {
+
+static const int kDefaultIqTimeoutSecs = 15;
+
+IqTask::IqTask(XmppTaskParentInterface* parent,
+ const std::string& verb,
+ const buzz::Jid& to,
+ buzz::XmlElement* el)
+ : buzz::XmppTask(parent, buzz::XmppEngine::HL_SINGLE),
+ to_(to),
+ stanza_(MakeIq(verb, to_, task_id())) {
+ stanza_->AddElement(el);
+ set_timeout_seconds(kDefaultIqTimeoutSecs);
+}
+
+int IqTask::ProcessStart() {
+ buzz::XmppReturnStatus ret = SendStanza(stanza_.get());
+ // TODO: HandleError(NULL) if SendStanza fails?
+ return (ret == buzz::XMPP_RETURN_OK) ? STATE_RESPONSE : STATE_ERROR;
+}
+
+bool IqTask::HandleStanza(const buzz::XmlElement* stanza) {
+ if (!MatchResponseIq(stanza, to_, task_id()))
+ return false;
+
+ if (stanza->Attr(buzz::QN_TYPE) != buzz::STR_RESULT &&
+ stanza->Attr(buzz::QN_TYPE) != buzz::STR_ERROR) {
+ return false;
+ }
+
+ QueueStanza(stanza);
+ return true;
+}
+
+int IqTask::ProcessResponse() {
+ const buzz::XmlElement* stanza = NextStanza();
+ if (stanza == NULL)
+ return STATE_BLOCKED;
+
+ bool success = (stanza->Attr(buzz::QN_TYPE) == buzz::STR_RESULT);
+ if (success) {
+ HandleResult(stanza);
+ } else {
+ SignalError(this, stanza->FirstNamed(QN_ERROR));
+ }
+ return STATE_DONE;
+}
+
+int IqTask::OnTimeout() {
+ SignalError(this, NULL);
+ return XmppTask::OnTimeout();
+}
+
+} // namespace buzz
diff --git a/libjingle/xmpp/iqtask.h b/libjingle/xmpp/iqtask.h
new file mode 100644
index 00000000..1d50c383
--- /dev/null
+++ b/libjingle/xmpp/iqtask.h
@@ -0,0 +1,48 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_IQTASK_H_
+#define WEBRTC_LIBJINGLE_XMPP_IQTASK_H_
+
+#include <string>
+
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+#include "webrtc/libjingle/xmpp/xmpptask.h"
+
+namespace buzz {
+
+class IqTask : public XmppTask {
+ public:
+ IqTask(XmppTaskParentInterface* parent,
+ const std::string& verb, const Jid& to,
+ XmlElement* el);
+ virtual ~IqTask() {}
+
+ const XmlElement* stanza() const { return stanza_.get(); }
+
+ sigslot::signal2<IqTask*,
+ const XmlElement*> SignalError;
+
+ protected:
+ virtual void HandleResult(const XmlElement* element) = 0;
+
+ private:
+ virtual int ProcessStart();
+ virtual bool HandleStanza(const XmlElement* stanza);
+ virtual int ProcessResponse();
+ virtual int OnTimeout();
+
+ Jid to_;
+ rtc::scoped_ptr<XmlElement> stanza_;
+};
+
+} // namespace buzz
+
+#endif // WEBRTC_LIBJINGLE_XMPP_IQTASK_H_
diff --git a/libjingle/xmpp/jid.cc b/libjingle/xmpp/jid.cc
new file mode 100644
index 00000000..ad053805
--- /dev/null
+++ b/libjingle/xmpp/jid.cc
@@ -0,0 +1,379 @@
+/*
+ * 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 "webrtc/libjingle/xmpp/jid.h"
+
+#include <ctype.h>
+
+#include <algorithm>
+#include <string>
+
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/logging.h"
+
+namespace buzz {
+
+Jid::Jid() {
+}
+
+Jid::Jid(const std::string& jid_string) {
+ if (jid_string.empty())
+ return;
+
+ // First find the slash and slice off that part
+ size_t slash = jid_string.find('/');
+ resource_name_ = (slash == std::string::npos ? STR_EMPTY :
+ jid_string.substr(slash + 1));
+
+ // Now look for the node
+ size_t at = jid_string.find('@');
+ size_t domain_begin;
+ if (at < slash && at != std::string::npos) {
+ node_name_ = jid_string.substr(0, at);
+ domain_begin = at + 1;
+ } else {
+ domain_begin = 0;
+ }
+
+ // Now take what is left as the domain
+ size_t domain_length = (slash == std::string::npos) ?
+ (jid_string.length() - domain_begin) : (slash - domain_begin);
+ domain_name_ = jid_string.substr(domain_begin, domain_length);
+
+ ValidateOrReset();
+}
+
+Jid::Jid(const std::string& node_name,
+ const std::string& domain_name,
+ const std::string& resource_name)
+ : node_name_(node_name),
+ domain_name_(domain_name),
+ resource_name_(resource_name) {
+ ValidateOrReset();
+}
+
+void Jid::ValidateOrReset() {
+ bool valid_node;
+ bool valid_domain;
+ bool valid_resource;
+
+ node_name_ = PrepNode(node_name_, &valid_node);
+ domain_name_ = PrepDomain(domain_name_, &valid_domain);
+ resource_name_ = PrepResource(resource_name_, &valid_resource);
+
+ if (!valid_node || !valid_domain || !valid_resource) {
+ node_name_.clear();
+ domain_name_.clear();
+ resource_name_.clear();
+ }
+}
+
+std::string Jid::Str() const {
+ if (!IsValid())
+ return STR_EMPTY;
+
+ std::string ret;
+
+ if (!node_name_.empty())
+ ret = node_name_ + "@";
+
+ ASSERT(domain_name_ != STR_EMPTY);
+ ret += domain_name_;
+
+ if (!resource_name_.empty())
+ ret += "/" + resource_name_;
+
+ return ret;
+}
+
+Jid::~Jid() {
+}
+
+bool Jid::IsEmpty() const {
+ return (node_name_.empty() && domain_name_.empty() &&
+ resource_name_.empty());
+}
+
+bool Jid::IsValid() const {
+ return !domain_name_.empty();
+}
+
+bool Jid::IsBare() const {
+ if (IsEmpty()) {
+ LOG(LS_VERBOSE) << "Warning: Calling IsBare() on the empty jid.";
+ return true;
+ }
+ return IsValid() && resource_name_.empty();
+}
+
+bool Jid::IsFull() const {
+ return IsValid() && !resource_name_.empty();
+}
+
+Jid Jid::BareJid() const {
+ if (!IsValid())
+ return Jid();
+ if (!IsFull())
+ return *this;
+ return Jid(node_name_, domain_name_, STR_EMPTY);
+}
+
+bool Jid::BareEquals(const Jid& other) const {
+ return other.node_name_ == node_name_ &&
+ other.domain_name_ == domain_name_;
+}
+
+void Jid::CopyFrom(const Jid& jid) {
+ this->node_name_ = jid.node_name_;
+ this->domain_name_ = jid.domain_name_;
+ this->resource_name_ = jid.resource_name_;
+}
+
+bool Jid::operator==(const Jid& other) const {
+ return other.node_name_ == node_name_ &&
+ other.domain_name_ == domain_name_ &&
+ other.resource_name_ == resource_name_;
+}
+
+int Jid::Compare(const Jid& other) const {
+ int compare_result;
+ compare_result = node_name_.compare(other.node_name_);
+ if (0 != compare_result)
+ return compare_result;
+ compare_result = domain_name_.compare(other.domain_name_);
+ if (0 != compare_result)
+ return compare_result;
+ compare_result = resource_name_.compare(other.resource_name_);
+ return compare_result;
+}
+
+// --- JID parsing code: ---
+
+// Checks and normalizes the node part of a JID.
+std::string Jid::PrepNode(const std::string& node, bool* valid) {
+ *valid = false;
+ std::string result;
+
+ for (std::string::const_iterator i = node.begin(); i < node.end(); ++i) {
+ bool char_valid = true;
+ unsigned char ch = *i;
+ if (ch <= 0x7F) {
+ result += PrepNodeAscii(ch, &char_valid);
+ }
+ else {
+ // TODO: implement the correct stringprep protocol for these
+ result += tolower(ch);
+ }
+ if (!char_valid) {
+ return STR_EMPTY;
+ }
+ }
+
+ if (result.length() > 1023) {
+ return STR_EMPTY;
+ }
+ *valid = true;
+ return result;
+}
+
+
+// Returns the appropriate mapping for an ASCII character in a node.
+char Jid::PrepNodeAscii(char ch, bool* valid) {
+ *valid = true;
+ switch (ch) {
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
+ case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
+ case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
+ case 'V': case 'W': case 'X': case 'Y': case 'Z':
+ return (char)(ch + ('a' - 'A'));
+
+ case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05:
+ case 0x06: case 0x07: case 0x08: case 0x09: case 0x0A: case 0x0B:
+ case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x10: case 0x11:
+ case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
+ case ' ': case '&': case '/': case ':': case '<': case '>': case '@':
+ case '\"': case '\'':
+ case 0x7F:
+ *valid = false;
+ return 0;
+
+ default:
+ return ch;
+ }
+}
+
+
+// Checks and normalizes the resource part of a JID.
+std::string Jid::PrepResource(const std::string& resource, bool* valid) {
+ *valid = false;
+ std::string result;
+
+ for (std::string::const_iterator i = resource.begin();
+ i < resource.end(); ++i) {
+ bool char_valid = true;
+ unsigned char ch = *i;
+ if (ch <= 0x7F) {
+ result += PrepResourceAscii(ch, &char_valid);
+ }
+ else {
+ // TODO: implement the correct stringprep protocol for these
+ result += ch;
+ }
+ }
+
+ if (result.length() > 1023) {
+ return STR_EMPTY;
+ }
+ *valid = true;
+ return result;
+}
+
+// Returns the appropriate mapping for an ASCII character in a resource.
+char Jid::PrepResourceAscii(char ch, bool* valid) {
+ *valid = true;
+ switch (ch) {
+ case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05:
+ case 0x06: case 0x07: case 0x08: case 0x09: case 0x0A: case 0x0B:
+ case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x10: case 0x11:
+ case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
+ case 0x7F:
+ *valid = false;
+ return 0;
+
+ default:
+ return ch;
+ }
+}
+
+// Checks and normalizes the domain part of a JID.
+std::string Jid::PrepDomain(const std::string& domain, bool* valid) {
+ *valid = false;
+ std::string result;
+
+ // TODO: if the domain contains a ':', then we should parse it
+ // as an IPv6 address rather than giving an error about illegal domain.
+ PrepDomain(domain, &result, valid);
+ if (!*valid) {
+ return STR_EMPTY;
+ }
+
+ if (result.length() > 1023) {
+ return STR_EMPTY;
+ }
+ *valid = true;
+ return result;
+}
+
+
+// Checks and normalizes an IDNA domain.
+void Jid::PrepDomain(const std::string& domain, std::string* buf, bool* valid) {
+ *valid = false;
+ std::string::const_iterator last = domain.begin();
+ for (std::string::const_iterator i = domain.begin(); i < domain.end(); ++i) {
+ bool label_valid = true;
+ char ch = *i;
+ switch (ch) {
+ case 0x002E:
+#if 0 // FIX: This isn't UTF-8-aware.
+ case 0x3002:
+ case 0xFF0E:
+ case 0xFF61:
+#endif
+ PrepDomainLabel(last, i, buf, &label_valid);
+ *buf += '.';
+ last = i + 1;
+ break;
+ }
+ if (!label_valid) {
+ return;
+ }
+ }
+ PrepDomainLabel(last, domain.end(), buf, valid);
+}
+
+// Checks and normalizes a domain label.
+void Jid::PrepDomainLabel(
+ std::string::const_iterator start, std::string::const_iterator end,
+ std::string* buf, bool* valid) {
+ *valid = false;
+
+ int start_len = static_cast<int>(buf->length());
+ for (std::string::const_iterator i = start; i < end; ++i) {
+ bool char_valid = true;
+ unsigned char ch = *i;
+ if (ch <= 0x7F) {
+ *buf += PrepDomainLabelAscii(ch, &char_valid);
+ }
+ else {
+ // TODO: implement ToASCII for these
+ *buf += ch;
+ }
+ if (!char_valid) {
+ return;
+ }
+ }
+
+ int count = static_cast<int>(buf->length() - start_len);
+ if (count == 0) {
+ return;
+ }
+ else if (count > 63) {
+ return;
+ }
+
+ // Is this check needed? See comment in PrepDomainLabelAscii.
+ if ((*buf)[start_len] == '-') {
+ return;
+ }
+ if ((*buf)[buf->length() - 1] == '-') {
+ return;
+ }
+ *valid = true;
+}
+
+
+// Returns the appropriate mapping for an ASCII character in a domain label.
+char Jid::PrepDomainLabelAscii(char ch, bool* valid) {
+ *valid = true;
+ // TODO: A literal reading of the spec seems to say that we do
+ // not need to check for these illegal characters (an "internationalized
+ // domain label" runs ToASCII with UseSTD3... set to false). But that
+ // can't be right. We should at least be checking that there are no '/'
+ // or '@' characters in the domain. Perhaps we should see what others
+ // do in this case.
+
+ switch (ch) {
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
+ case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
+ case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
+ case 'V': case 'W': case 'X': case 'Y': case 'Z':
+ return (char)(ch + ('a' - 'A'));
+
+ case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05:
+ case 0x06: case 0x07: case 0x08: case 0x09: case 0x0A: case 0x0B:
+ case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x10: case 0x11:
+ case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
+ case 0x18: case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D:
+ case 0x1E: case 0x1F: case 0x20: case 0x21: case 0x22: case 0x23:
+ case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29:
+ case 0x2A: case 0x2B: case 0x2C: case 0x2E: case 0x2F: case 0x3A:
+ case 0x3B: case 0x3C: case 0x3D: case 0x3E: case 0x3F: case 0x40:
+ case 0x5B: case 0x5C: case 0x5D: case 0x5E: case 0x5F: case 0x60:
+ case 0x7B: case 0x7C: case 0x7D: case 0x7E: case 0x7F:
+ *valid = false;
+ return 0;
+
+ default:
+ return ch;
+ }
+}
+
+} // namespace buzz
diff --git a/libjingle/xmpp/jid.h b/libjingle/xmpp/jid.h
new file mode 100644
index 00000000..94ad7c83
--- /dev/null
+++ b/libjingle/xmpp/jid.h
@@ -0,0 +1,81 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_JID_H_
+#define WEBRTC_LIBJINGLE_XMPP_JID_H_
+
+#include <string>
+#include "webrtc/libjingle/xmllite/xmlconstants.h"
+#include "webrtc/base/basictypes.h"
+
+namespace buzz {
+
+// The Jid class encapsulates and provides parsing help for Jids. A Jid
+// consists of three parts: the node, the domain and the resource, e.g.:
+//
+// node@domain/resource
+//
+// The node and resource are both optional. A valid jid is defined to have
+// a domain. A bare jid is defined to not have a resource and a full jid
+// *does* have a resource.
+class Jid {
+public:
+ explicit Jid();
+ explicit Jid(const std::string& jid_string);
+ explicit Jid(const std::string& node_name,
+ const std::string& domain_name,
+ const std::string& resource_name);
+ ~Jid();
+
+ const std::string & node() const { return node_name_; }
+ const std::string & domain() const { return domain_name_; }
+ const std::string & resource() const { return resource_name_; }
+
+ std::string Str() const;
+ Jid BareJid() const;
+
+ bool IsEmpty() const;
+ bool IsValid() const;
+ bool IsBare() const;
+ bool IsFull() const;
+
+ bool BareEquals(const Jid& other) const;
+ void CopyFrom(const Jid& jid);
+ bool operator==(const Jid& other) const;
+ bool operator!=(const Jid& other) const { return !operator==(other); }
+
+ bool operator<(const Jid& other) const { return Compare(other) < 0; };
+ bool operator>(const Jid& other) const { return Compare(other) > 0; };
+
+ int Compare(const Jid & other) const;
+
+private:
+ void ValidateOrReset();
+
+ static std::string PrepNode(const std::string& node, bool* valid);
+ static char PrepNodeAscii(char ch, bool* valid);
+ static std::string PrepResource(const std::string& start, bool* valid);
+ static char PrepResourceAscii(char ch, bool* valid);
+ static std::string PrepDomain(const std::string& domain, bool* valid);
+ static void PrepDomain(const std::string& domain,
+ std::string* buf, bool* valid);
+ static void PrepDomainLabel(
+ std::string::const_iterator start, std::string::const_iterator end,
+ std::string* buf, bool* valid);
+ static char PrepDomainLabelAscii(char ch, bool *valid);
+
+ std::string node_name_;
+ std::string domain_name_;
+ std::string resource_name_;
+};
+
+}
+
+#endif // WEBRTC_LIBJINGLE_XMPP_JID_H_
diff --git a/libjingle/xmpp/jid_unittest.cc b/libjingle/xmpp/jid_unittest.cc
new file mode 100644
index 00000000..e22f6a26
--- /dev/null
+++ b/libjingle/xmpp/jid_unittest.cc
@@ -0,0 +1,122 @@
+/*
+ * 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 "webrtc/libjingle/xmpp/jid.h"
+#include "webrtc/base/gunit.h"
+
+using buzz::Jid;
+
+TEST(JidTest, TestDomain) {
+ Jid jid("dude");
+ EXPECT_EQ("", jid.node());
+ EXPECT_EQ("dude", jid.domain());
+ EXPECT_EQ("", jid.resource());
+ EXPECT_EQ("dude", jid.Str());
+ EXPECT_EQ("dude", jid.BareJid().Str());
+ EXPECT_TRUE(jid.IsValid());
+ EXPECT_TRUE(jid.IsBare());
+ EXPECT_FALSE(jid.IsFull());
+}
+
+TEST(JidTest, TestNodeDomain) {
+ Jid jid("walter@dude");
+ EXPECT_EQ("walter", jid.node());
+ EXPECT_EQ("dude", jid.domain());
+ EXPECT_EQ("", jid.resource());
+ EXPECT_EQ("walter@dude", jid.Str());
+ EXPECT_EQ("walter@dude", jid.BareJid().Str());
+ EXPECT_TRUE(jid.IsValid());
+ EXPECT_TRUE(jid.IsBare());
+ EXPECT_FALSE(jid.IsFull());
+}
+
+TEST(JidTest, TestDomainResource) {
+ Jid jid("dude/bowlingalley");
+ EXPECT_EQ("", jid.node());
+ EXPECT_EQ("dude", jid.domain());
+ EXPECT_EQ("bowlingalley", jid.resource());
+ EXPECT_EQ("dude/bowlingalley", jid.Str());
+ EXPECT_EQ("dude", jid.BareJid().Str());
+ EXPECT_TRUE(jid.IsValid());
+ EXPECT_FALSE(jid.IsBare());
+ EXPECT_TRUE(jid.IsFull());
+}
+
+TEST(JidTest, TestNodeDomainResource) {
+ Jid jid("walter@dude/bowlingalley");
+ EXPECT_EQ("walter", jid.node());
+ EXPECT_EQ("dude", jid.domain());
+ EXPECT_EQ("bowlingalley", jid.resource());
+ EXPECT_EQ("walter@dude/bowlingalley", jid.Str());
+ EXPECT_EQ("walter@dude", jid.BareJid().Str());
+ EXPECT_TRUE(jid.IsValid());
+ EXPECT_FALSE(jid.IsBare());
+ EXPECT_TRUE(jid.IsFull());
+}
+
+TEST(JidTest, TestNode) {
+ Jid jid("walter@");
+ EXPECT_EQ("", jid.node());
+ EXPECT_EQ("", jid.domain());
+ EXPECT_EQ("", jid.resource());
+ EXPECT_EQ("", jid.Str());
+ EXPECT_EQ("", jid.BareJid().Str());
+ EXPECT_FALSE(jid.IsValid());
+ EXPECT_TRUE(jid.IsBare());
+ EXPECT_FALSE(jid.IsFull());
+}
+
+TEST(JidTest, TestResource) {
+ Jid jid("/bowlingalley");
+ EXPECT_EQ("", jid.node());
+ EXPECT_EQ("", jid.domain());
+ EXPECT_EQ("", jid.resource());
+ EXPECT_EQ("", jid.Str());
+ EXPECT_EQ("", jid.BareJid().Str());
+ EXPECT_FALSE(jid.IsValid());
+ EXPECT_TRUE(jid.IsBare());
+ EXPECT_FALSE(jid.IsFull());
+}
+
+TEST(JidTest, TestNodeResource) {
+ Jid jid("walter@/bowlingalley");
+ EXPECT_EQ("", jid.node());
+ EXPECT_EQ("", jid.domain());
+ EXPECT_EQ("", jid.resource());
+ EXPECT_EQ("", jid.Str());
+ EXPECT_EQ("", jid.BareJid().Str());
+ EXPECT_FALSE(jid.IsValid());
+ EXPECT_TRUE(jid.IsBare());
+ EXPECT_FALSE(jid.IsFull());
+}
+
+TEST(JidTest, TestFunky) {
+ Jid jid("bowling@muchat/walter@dude");
+ EXPECT_EQ("bowling", jid.node());
+ EXPECT_EQ("muchat", jid.domain());
+ EXPECT_EQ("walter@dude", jid.resource());
+ EXPECT_EQ("bowling@muchat/walter@dude", jid.Str());
+ EXPECT_EQ("bowling@muchat", jid.BareJid().Str());
+ EXPECT_TRUE(jid.IsValid());
+ EXPECT_FALSE(jid.IsBare());
+ EXPECT_TRUE(jid.IsFull());
+}
+
+TEST(JidTest, TestFunky2) {
+ Jid jid("muchat/walter@dude");
+ EXPECT_EQ("", jid.node());
+ EXPECT_EQ("muchat", jid.domain());
+ EXPECT_EQ("walter@dude", jid.resource());
+ EXPECT_EQ("muchat/walter@dude", jid.Str());
+ EXPECT_EQ("muchat", jid.BareJid().Str());
+ EXPECT_TRUE(jid.IsValid());
+ EXPECT_FALSE(jid.IsBare());
+ EXPECT_TRUE(jid.IsFull());
+}
diff --git a/libjingle/xmpp/jingleinfotask.cc b/libjingle/xmpp/jingleinfotask.cc
new file mode 100644
index 00000000..a5a07121
--- /dev/null
+++ b/libjingle/xmpp/jingleinfotask.cc
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2010 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can 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 "webrtc/libjingle/xmpp/jingleinfotask.h"
+
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/xmppclient.h"
+#include "webrtc/libjingle/xmpp/xmpptask.h"
+#include "webrtc/base/socketaddress.h"
+
+namespace buzz {
+
+class JingleInfoTask::JingleInfoGetTask : public XmppTask {
+ public:
+ explicit JingleInfoGetTask(XmppTaskParentInterface* parent)
+ : XmppTask(parent, XmppEngine::HL_SINGLE),
+ done_(false) {}
+
+ virtual int ProcessStart() {
+ rtc::scoped_ptr<XmlElement> get(
+ MakeIq(STR_GET, Jid(), task_id()));
+ get->AddElement(new XmlElement(QN_JINGLE_INFO_QUERY, true));
+ if (SendStanza(get.get()) != XMPP_RETURN_OK) {
+ return STATE_ERROR;
+ }
+ return STATE_RESPONSE;
+ }
+ virtual int ProcessResponse() {
+ if (done_)
+ return STATE_DONE;
+ return STATE_BLOCKED;
+ }
+
+ protected:
+ virtual bool HandleStanza(const XmlElement * stanza) {
+ if (!MatchResponseIq(stanza, Jid(), task_id()))
+ return false;
+
+ if (stanza->Attr(QN_TYPE) != STR_RESULT)
+ return false;
+
+ // Queue the stanza with the parent so these don't get handled out of order
+ JingleInfoTask* parent = static_cast<JingleInfoTask*>(GetParent());
+ parent->QueueStanza(stanza);
+
+ // Wake ourselves so we can go into the done state
+ done_ = true;
+ Wake();
+ return true;
+ }
+
+ bool done_;
+};
+
+
+void JingleInfoTask::RefreshJingleInfoNow() {
+ JingleInfoGetTask* get_task = new JingleInfoGetTask(this);
+ get_task->Start();
+}
+
+bool
+JingleInfoTask::HandleStanza(const XmlElement * stanza) {
+ if (!MatchRequestIq(stanza, "set", QN_JINGLE_INFO_QUERY))
+ return false;
+
+ // only respect relay push from the server
+ Jid from(stanza->Attr(QN_FROM));
+ if (!from.IsEmpty() &&
+ !from.BareEquals(GetClient()->jid()) &&
+ from != Jid(GetClient()->jid().domain()))
+ return false;
+
+ QueueStanza(stanza);
+ return true;
+}
+
+int
+JingleInfoTask::ProcessStart() {
+ std::vector<std::string> relay_hosts;
+ std::vector<rtc::SocketAddress> stun_hosts;
+ std::string relay_token;
+ const XmlElement * stanza = NextStanza();
+ if (stanza == NULL)
+ return STATE_BLOCKED;
+ const XmlElement * query = stanza->FirstNamed(QN_JINGLE_INFO_QUERY);
+ if (query == NULL)
+ return STATE_START;
+ const XmlElement *stun = query->FirstNamed(QN_JINGLE_INFO_STUN);
+ if (stun) {
+ for (const XmlElement *server = stun->FirstNamed(QN_JINGLE_INFO_SERVER);
+ server != NULL; server = server->NextNamed(QN_JINGLE_INFO_SERVER)) {
+ std::string host = server->Attr(QN_JINGLE_INFO_HOST);
+ std::string port = server->Attr(QN_JINGLE_INFO_UDP);
+ if (host != STR_EMPTY && host != STR_EMPTY) {
+ stun_hosts.push_back(rtc::SocketAddress(host, atoi(port.c_str())));
+ }
+ }
+ }
+
+ const XmlElement *relay = query->FirstNamed(QN_JINGLE_INFO_RELAY);
+ if (relay) {
+ relay_token = relay->TextNamed(QN_JINGLE_INFO_TOKEN);
+ for (const XmlElement *server = relay->FirstNamed(QN_JINGLE_INFO_SERVER);
+ server != NULL; server = server->NextNamed(QN_JINGLE_INFO_SERVER)) {
+ std::string host = server->Attr(QN_JINGLE_INFO_HOST);
+ if (host != STR_EMPTY) {
+ relay_hosts.push_back(host);
+ }
+ }
+ }
+ SignalJingleInfo(relay_token, relay_hosts, stun_hosts);
+ return STATE_START;
+}
+}
diff --git a/libjingle/xmpp/jingleinfotask.h b/libjingle/xmpp/jingleinfotask.h
new file mode 100644
index 00000000..6ed701de
--- /dev/null
+++ b/libjingle/xmpp/jingleinfotask.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2010 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_LIBJINGLE_XMPP_JINGLEINFOTASK_H_
+#define WEBRTC_LIBJINGLE_XMPP_JINGLEINFOTASK_H_
+
+#include <vector>
+
+#include "webrtc/p2p/client/httpportallocator.h"
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+#include "webrtc/libjingle/xmpp/xmpptask.h"
+#include "webrtc/base/sigslot.h"
+
+namespace buzz {
+
+class JingleInfoTask : public XmppTask {
+ public:
+ explicit JingleInfoTask(XmppTaskParentInterface* parent) :
+ XmppTask(parent, XmppEngine::HL_TYPE) {}
+
+ virtual int ProcessStart();
+ void RefreshJingleInfoNow();
+
+ sigslot::signal3<const std::string &,
+ const std::vector<std::string> &,
+ const std::vector<rtc::SocketAddress> &>
+ SignalJingleInfo;
+
+ protected:
+ class JingleInfoGetTask;
+ friend class JingleInfoGetTask;
+
+ virtual bool HandleStanza(const XmlElement * stanza);
+};
+}
+
+#endif // WEBRTC_LIBJINGLE_XMPP_JINGLEINFOTASK_H_
diff --git a/libjingle/xmpp/module.h b/libjingle/xmpp/module.h
new file mode 100644
index 00000000..fa26df34
--- /dev/null
+++ b/libjingle/xmpp/module.h
@@ -0,0 +1,35 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_MODULE_H_
+#define WEBRTC_LIBJINGLE_XMPP_MODULE_H_
+
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+
+namespace buzz {
+
+class XmppEngine;
+
+//! This is the base class for extension modules.
+//! An engine is registered with the module and the module then hooks the
+//! appropriate parts of the engine to implement that set of features. It is
+//! important to unregister modules before destructing the engine.
+class XmppModule {
+public:
+ virtual ~XmppModule() {}
+
+ //! Register the engine with the module. Only one engine can be associated
+ //! with a module at a time. This method will return an error if there is
+ //! already an engine registered.
+ virtual XmppReturnStatus RegisterEngine(XmppEngine* engine) = 0;
+};
+
+}
+#endif // WEBRTC_LIBJINGLE_XMPP_MODULE_H_
diff --git a/libjingle/xmpp/moduleimpl.cc b/libjingle/xmpp/moduleimpl.cc
new file mode 100644
index 00000000..b5337a64
--- /dev/null
+++ b/libjingle/xmpp/moduleimpl.cc
@@ -0,0 +1,48 @@
+/*
+ * 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 "webrtc/libjingle/xmpp/moduleimpl.h"
+#include "webrtc/base/common.h"
+
+namespace buzz {
+
+XmppModuleImpl::XmppModuleImpl() :
+ engine_(NULL),
+ stanza_handler_(this) {
+}
+
+XmppModuleImpl::~XmppModuleImpl()
+{
+ if (engine_ != NULL) {
+ engine_->RemoveStanzaHandler(&stanza_handler_);
+ engine_ = NULL;
+ }
+}
+
+XmppReturnStatus
+XmppModuleImpl::RegisterEngine(XmppEngine* engine)
+{
+ if (NULL == engine || NULL != engine_)
+ return XMPP_RETURN_BADARGUMENT;
+
+ engine->AddStanzaHandler(&stanza_handler_);
+ engine_ = engine;
+
+ return XMPP_RETURN_OK;
+}
+
+XmppEngine*
+XmppModuleImpl::engine() {
+ ASSERT(NULL != engine_);
+ return engine_;
+}
+
+}
+
diff --git a/libjingle/xmpp/moduleimpl.h b/libjingle/xmpp/moduleimpl.h
new file mode 100644
index 00000000..5a7c6e36
--- /dev/null
+++ b/libjingle/xmpp/moduleimpl.h
@@ -0,0 +1,76 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_MODULEIMPL_H_
+#define WEBRTC_LIBJINGLE_XMPP_MODULEIMPL_H_
+
+#include "webrtc/libjingle/xmpp/module.h"
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+
+namespace buzz {
+
+//! This is the base implementation class for extension modules.
+//! An engine is registered with the module and the module then hooks the
+//! appropriate parts of the engine to implement that set of features. It is
+//! important to unregister modules before destructing the engine.
+class XmppModuleImpl {
+protected:
+ XmppModuleImpl();
+ virtual ~XmppModuleImpl();
+
+ //! Register the engine with the module. Only one engine can be associated
+ //! with a module at a time. This method will return an error if there is
+ //! already an engine registered.
+ XmppReturnStatus RegisterEngine(XmppEngine* engine);
+
+ //! Gets the engine that this module is attached to.
+ XmppEngine* engine();
+
+ //! Process the given stanza.
+ //! The module must return true if it has handled the stanza.
+ //! A false return value causes the stanza to be passed on to
+ //! the next registered handler.
+ virtual bool HandleStanza(const XmlElement *) { return false; };
+
+private:
+
+ //! The ModuleSessionHelper nested class allows the Module
+ //! to hook into and get stanzas and events from the engine.
+ class ModuleStanzaHandler : public XmppStanzaHandler {
+ friend class XmppModuleImpl;
+
+ ModuleStanzaHandler(XmppModuleImpl* module) :
+ module_(module) {
+ }
+
+ bool HandleStanza(const XmlElement* stanza) {
+ return module_->HandleStanza(stanza);
+ }
+
+ XmppModuleImpl* module_;
+ };
+
+ friend class ModuleStanzaHandler;
+
+ XmppEngine* engine_;
+ ModuleStanzaHandler stanza_handler_;
+};
+
+
+// This macro will implement the XmppModule interface for a class
+// that derives from both XmppModuleImpl and XmppModule
+#define IMPLEMENT_XMPPMODULE \
+ XmppReturnStatus RegisterEngine(XmppEngine* engine) { \
+ return XmppModuleImpl::RegisterEngine(engine); \
+ }
+
+}
+
+#endif // WEBRTC_LIBJINGLE_XMPP_MODULEIMPL_H_
diff --git a/libjingle/xmpp/mucroomconfigtask.cc b/libjingle/xmpp/mucroomconfigtask.cc
new file mode 100644
index 00000000..08b10650
--- /dev/null
+++ b/libjingle/xmpp/mucroomconfigtask.cc
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+#include <string>
+#include <vector>
+
+#include "webrtc/libjingle/xmpp/mucroomconfigtask.h"
+
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/base/scoped_ptr.h"
+
+namespace buzz {
+
+MucRoomConfigTask::MucRoomConfigTask(
+ XmppTaskParentInterface* parent,
+ const Jid& room_jid,
+ const std::string& room_name,
+ const std::vector<std::string>& room_features)
+ : IqTask(parent, STR_SET, room_jid,
+ MakeRequest(room_name, room_features)),
+ room_jid_(room_jid) {
+}
+
+XmlElement* MucRoomConfigTask::MakeRequest(
+ const std::string& room_name,
+ const std::vector<std::string>& room_features) {
+ buzz::XmlElement* owner_query = new
+ buzz::XmlElement(buzz::QN_MUC_OWNER_QUERY, true);
+
+ buzz::XmlElement* x_form = new buzz::XmlElement(buzz::QN_XDATA_X, true);
+ x_form->SetAttr(buzz::QN_TYPE, buzz::STR_FORM);
+
+ buzz::XmlElement* roomname_field =
+ new buzz::XmlElement(buzz::QN_XDATA_FIELD, false);
+ roomname_field->SetAttr(buzz::QN_VAR, buzz::STR_MUC_ROOMCONFIG_ROOMNAME);
+ roomname_field->SetAttr(buzz::QN_TYPE, buzz::STR_TEXT_SINGLE);
+
+ buzz::XmlElement* roomname_value =
+ new buzz::XmlElement(buzz::QN_XDATA_VALUE, false);
+ roomname_value->SetBodyText(room_name);
+
+ roomname_field->AddElement(roomname_value);
+ x_form->AddElement(roomname_field);
+
+ buzz::XmlElement* features_field =
+ new buzz::XmlElement(buzz::QN_XDATA_FIELD, false);
+ features_field->SetAttr(buzz::QN_VAR, buzz::STR_MUC_ROOMCONFIG_FEATURES);
+ features_field->SetAttr(buzz::QN_TYPE, buzz::STR_LIST_MULTI);
+
+ for (std::vector<std::string>::const_iterator feature = room_features.begin();
+ feature != room_features.end(); ++feature) {
+ buzz::XmlElement* features_value =
+ new buzz::XmlElement(buzz::QN_XDATA_VALUE, false);
+ features_value->SetBodyText(*feature);
+ features_field->AddElement(features_value);
+ }
+
+ x_form->AddElement(features_field);
+ owner_query->AddElement(x_form);
+ return owner_query;
+}
+
+void MucRoomConfigTask::HandleResult(const XmlElement* element) {
+ SignalResult(this);
+}
+
+} // namespace buzz
diff --git a/libjingle/xmpp/mucroomconfigtask.h b/libjingle/xmpp/mucroomconfigtask.h
new file mode 100644
index 00000000..d297d027
--- /dev/null
+++ b/libjingle/xmpp/mucroomconfigtask.h
@@ -0,0 +1,47 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_MUCROOMCONFIGTASK_H_
+#define WEBRTC_LIBJINGLE_XMPP_MUCROOMCONFIGTASK_H_
+
+#include <string>
+#include "webrtc/libjingle/xmpp/iqtask.h"
+
+namespace buzz {
+
+// This task configures the muc room for document sharing and other enterprise
+// specific goodies.
+class MucRoomConfigTask : public IqTask {
+ public:
+ MucRoomConfigTask(XmppTaskParentInterface* parent,
+ const Jid& room_jid,
+ const std::string& room_name,
+ const std::vector<std::string>& room_features);
+
+ // Room configuration does not return any reasonable error
+ // values. The First config request configures the room, subseqent
+ // ones are just ignored by server and server returns empty
+ // response.
+ sigslot::signal1<MucRoomConfigTask*> SignalResult;
+
+ const Jid& room_jid() const { return room_jid_; }
+
+ protected:
+ virtual void HandleResult(const XmlElement* stanza);
+
+ private:
+ static XmlElement* MakeRequest(const std::string& room_name,
+ const std::vector<std::string>& room_features);
+ Jid room_jid_;
+};
+
+} // namespace buzz
+
+#endif // WEBRTC_LIBJINGLE_XMPP_MUCROOMCONFIGTASK_H_
diff --git a/libjingle/xmpp/mucroomconfigtask_unittest.cc b/libjingle/xmpp/mucroomconfigtask_unittest.cc
new file mode 100644
index 00000000..a86dd14f
--- /dev/null
+++ b/libjingle/xmpp/mucroomconfigtask_unittest.cc
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ */
+
+#include <string>
+#include <vector>
+
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/fakexmppclient.h"
+#include "webrtc/libjingle/xmpp/mucroomconfigtask.h"
+#include "webrtc/base/faketaskrunner.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/sigslot.h"
+
+class MucRoomConfigListener : public sigslot::has_slots<> {
+ public:
+ MucRoomConfigListener() : result_count(0), error_count(0) {}
+
+ void OnResult(buzz::MucRoomConfigTask*) {
+ ++result_count;
+ }
+
+ void OnError(buzz::IqTask* task,
+ const buzz::XmlElement* error) {
+ ++error_count;
+ }
+
+ int result_count;
+ int error_count;
+};
+
+class MucRoomConfigTaskTest : public testing::Test {
+ public:
+ MucRoomConfigTaskTest() :
+ room_jid("muc-jid-ponies@domain.com"),
+ room_name("ponies") {
+ }
+
+ virtual void SetUp() {
+ runner = new rtc::FakeTaskRunner();
+ xmpp_client = new buzz::FakeXmppClient(runner);
+ listener = new MucRoomConfigListener();
+ }
+
+ virtual void TearDown() {
+ delete listener;
+ // delete xmpp_client; Deleted by deleting runner.
+ delete runner;
+ }
+
+ rtc::FakeTaskRunner* runner;
+ buzz::FakeXmppClient* xmpp_client;
+ MucRoomConfigListener* listener;
+ buzz::Jid room_jid;
+ std::string room_name;
+};
+
+TEST_F(MucRoomConfigTaskTest, TestConfigEnterprise) {
+ ASSERT_EQ(0U, xmpp_client->sent_stanzas().size());
+
+ std::vector<std::string> room_features;
+ room_features.push_back("feature1");
+ room_features.push_back("feature2");
+ buzz::MucRoomConfigTask* task = new buzz::MucRoomConfigTask(
+ xmpp_client, room_jid, "ponies", room_features);
+ EXPECT_EQ(room_jid, task->room_jid());
+
+ task->SignalResult.connect(listener, &MucRoomConfigListener::OnResult);
+ task->Start();
+
+ std::string expected_iq =
+ "<cli:iq type=\"set\" to=\"muc-jid-ponies@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<query xmlns=\"http://jabber.org/protocol/muc#owner\">"
+ "<x xmlns=\"jabber:x:data\" type=\"form\">"
+ "<field var=\"muc#roomconfig_roomname\" type=\"text-single\">"
+ "<value>ponies</value>"
+ "</field>"
+ "<field var=\"muc#roomconfig_features\" type=\"list-multi\">"
+ "<value>feature1</value>"
+ "<value>feature2</value>"
+ "</field>"
+ "</x>"
+ "</query>"
+ "</cli:iq>";
+
+ ASSERT_EQ(1U, xmpp_client->sent_stanzas().size());
+ EXPECT_EQ(expected_iq, xmpp_client->sent_stanzas()[0]->Str());
+
+ EXPECT_EQ(0, listener->result_count);
+ EXPECT_EQ(0, listener->error_count);
+
+ std::string response_iq =
+ "<iq xmlns='jabber:client' id='0' type='result'"
+ " from='muc-jid-ponies@domain.com'>"
+ "</iq>";
+
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(response_iq));
+
+ EXPECT_EQ(1, listener->result_count);
+ EXPECT_EQ(0, listener->error_count);
+}
+
+TEST_F(MucRoomConfigTaskTest, TestError) {
+ std::vector<std::string> room_features;
+ buzz::MucRoomConfigTask* task = new buzz::MucRoomConfigTask(
+ xmpp_client, room_jid, "ponies", room_features);
+ task->SignalError.connect(listener, &MucRoomConfigListener::OnError);
+ task->Start();
+
+ std::string error_iq =
+ "<iq xmlns='jabber:client' id='0' type='error'"
+ " from='muc-jid-ponies@domain.com'>"
+ "</iq>";
+
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(error_iq));
+
+ EXPECT_EQ(0, listener->result_count);
+ EXPECT_EQ(1, listener->error_count);
+}
diff --git a/libjingle/xmpp/mucroomdiscoverytask.cc b/libjingle/xmpp/mucroomdiscoverytask.cc
new file mode 100644
index 00000000..05a56716
--- /dev/null
+++ b/libjingle/xmpp/mucroomdiscoverytask.cc
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+#include "webrtc/libjingle/xmpp/mucroomdiscoverytask.h"
+
+#include "webrtc/libjingle/xmpp/constants.h"
+
+namespace buzz {
+
+MucRoomDiscoveryTask::MucRoomDiscoveryTask(
+ XmppTaskParentInterface* parent,
+ const Jid& room_jid)
+ : IqTask(parent, STR_GET, room_jid,
+ new buzz::XmlElement(buzz::QN_DISCO_INFO_QUERY)) {
+}
+
+void MucRoomDiscoveryTask::HandleResult(const XmlElement* stanza) {
+ const XmlElement* query = stanza->FirstNamed(QN_DISCO_INFO_QUERY);
+ if (query == NULL) {
+ SignalError(this, NULL);
+ return;
+ }
+
+ std::set<std::string> features;
+ std::map<std::string, std::string> extended_info;
+ const XmlElement* identity = query->FirstNamed(QN_DISCO_IDENTITY);
+ if (identity == NULL || !identity->HasAttr(QN_NAME)) {
+ SignalResult(this, false, "", "", features, extended_info);
+ return;
+ }
+
+ const std::string name(identity->Attr(QN_NAME));
+
+ // Get the conversation id
+ const XmlElement* conversation =
+ identity->FirstNamed(QN_GOOGLE_MUC_HANGOUT_CONVERSATION_ID);
+ std::string conversation_id;
+ if (conversation != NULL) {
+ conversation_id = conversation->BodyText();
+ }
+
+ for (const XmlElement* feature = query->FirstNamed(QN_DISCO_FEATURE);
+ feature != NULL; feature = feature->NextNamed(QN_DISCO_FEATURE)) {
+ features.insert(feature->Attr(QN_VAR));
+ }
+
+ const XmlElement* data_x = query->FirstNamed(QN_XDATA_X);
+ if (data_x != NULL) {
+ for (const XmlElement* field = data_x->FirstNamed(QN_XDATA_FIELD);
+ field != NULL; field = field->NextNamed(QN_XDATA_FIELD)) {
+ const std::string key(field->Attr(QN_VAR));
+ extended_info[key] = field->Attr(QN_XDATA_VALUE);
+ }
+ }
+
+ SignalResult(this, true, name, conversation_id, features, extended_info);
+}
+
+} // namespace buzz
diff --git a/libjingle/xmpp/mucroomdiscoverytask.h b/libjingle/xmpp/mucroomdiscoverytask.h
new file mode 100644
index 00000000..3e332bd2
--- /dev/null
+++ b/libjingle/xmpp/mucroomdiscoverytask.h
@@ -0,0 +1,41 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_MUCROOMDISCOVERYTASK_H_
+#define WEBRTC_LIBJINGLE_XMPP_MUCROOMDISCOVERYTASK_H_
+
+#include <map>
+#include <string>
+#include "webrtc/libjingle/xmpp/iqtask.h"
+
+namespace buzz {
+
+// This task requests the feature capabilities of the room. It is based on
+// XEP-0030, and extended using XEP-0004.
+class MucRoomDiscoveryTask : public IqTask {
+ public:
+ MucRoomDiscoveryTask(XmppTaskParentInterface* parent,
+ const Jid& room_jid);
+
+ // Signal (exists, name, conversationId, features, extended_info)
+ sigslot::signal6<MucRoomDiscoveryTask*,
+ bool,
+ const std::string&,
+ const std::string&,
+ const std::set<std::string>&,
+ const std::map<std::string, std::string>& > SignalResult;
+
+ protected:
+ virtual void HandleResult(const XmlElement* stanza);
+};
+
+} // namespace buzz
+
+#endif // WEBRTC_LIBJINGLE_XMPP_MUCROOMDISCOVERYTASK_H_
diff --git a/libjingle/xmpp/mucroomdiscoverytask_unittest.cc b/libjingle/xmpp/mucroomdiscoverytask_unittest.cc
new file mode 100644
index 00000000..cdb50c21
--- /dev/null
+++ b/libjingle/xmpp/mucroomdiscoverytask_unittest.cc
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ */
+
+#include <string>
+#include <vector>
+
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/fakexmppclient.h"
+#include "webrtc/libjingle/xmpp/mucroomdiscoverytask.h"
+#include "webrtc/base/faketaskrunner.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/sigslot.h"
+
+class MucRoomDiscoveryListener : public sigslot::has_slots<> {
+ public:
+ MucRoomDiscoveryListener() : error_count(0) {}
+
+ void OnResult(buzz::MucRoomDiscoveryTask* task,
+ bool exists,
+ const std::string& name,
+ const std::string& conversation_id,
+ const std::set<std::string>& features,
+ const std::map<std::string, std::string>& extended_info) {
+ last_exists = exists;
+ last_name = name;
+ last_conversation_id = conversation_id;
+ last_features = features;
+ last_extended_info = extended_info;
+ }
+
+ void OnError(buzz::IqTask* task,
+ const buzz::XmlElement* error) {
+ ++error_count;
+ }
+
+ bool last_exists;
+ std::string last_name;
+ std::string last_conversation_id;
+ std::set<std::string> last_features;
+ std::map<std::string, std::string> last_extended_info;
+ int error_count;
+};
+
+class MucRoomDiscoveryTaskTest : public testing::Test {
+ public:
+ MucRoomDiscoveryTaskTest() :
+ room_jid("muc-jid-ponies@domain.com"),
+ room_name("ponies"),
+ conversation_id("test_conversation_id") {
+ }
+
+ virtual void SetUp() {
+ runner = new rtc::FakeTaskRunner();
+ xmpp_client = new buzz::FakeXmppClient(runner);
+ listener = new MucRoomDiscoveryListener();
+ }
+
+ virtual void TearDown() {
+ delete listener;
+ // delete xmpp_client; Deleted by deleting runner.
+ delete runner;
+ }
+
+ rtc::FakeTaskRunner* runner;
+ buzz::FakeXmppClient* xmpp_client;
+ MucRoomDiscoveryListener* listener;
+ buzz::Jid room_jid;
+ std::string room_name;
+ std::string conversation_id;
+};
+
+TEST_F(MucRoomDiscoveryTaskTest, TestDiscovery) {
+ ASSERT_EQ(0U, xmpp_client->sent_stanzas().size());
+
+ buzz::MucRoomDiscoveryTask* task = new buzz::MucRoomDiscoveryTask(
+ xmpp_client, room_jid);
+ task->SignalResult.connect(listener, &MucRoomDiscoveryListener::OnResult);
+ task->Start();
+
+ std::string expected_iq =
+ "<cli:iq type=\"get\" to=\"muc-jid-ponies@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<info:query xmlns:info=\"http://jabber.org/protocol/disco#info\"/>"
+ "</cli:iq>";
+
+ ASSERT_EQ(1U, xmpp_client->sent_stanzas().size());
+ EXPECT_EQ(expected_iq, xmpp_client->sent_stanzas()[0]->Str());
+
+ EXPECT_EQ("", listener->last_name);
+ EXPECT_EQ("", listener->last_conversation_id);
+
+ std::string response_iq =
+ "<iq xmlns='jabber:client'"
+ " from='muc-jid-ponies@domain.com' id='0' type='result'>"
+ " <info:query xmlns:info='http://jabber.org/protocol/disco#info'>"
+ " <info:identity name='ponies'>"
+ " <han:conversation-id xmlns:han='google:muc#hangout'>"
+ "test_conversation_id</han:conversation-id>"
+ " </info:identity>"
+ " <info:feature var='feature1'/>"
+ " <info:feature var='feature2'/>"
+ " <data:x xmlns:data='jabber:x:data'>"
+ " <data:field var='var1' data:value='value1' />"
+ " <data:field var='var2' data:value='value2' />"
+ " </data:x>"
+ " </info:query>"
+ "</iq>";
+
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(response_iq));
+
+ EXPECT_EQ(true, listener->last_exists);
+ EXPECT_EQ(room_name, listener->last_name);
+ EXPECT_EQ(conversation_id, listener->last_conversation_id);
+ EXPECT_EQ(2U, listener->last_features.size());
+ EXPECT_EQ(1U, listener->last_features.count("feature1"));
+ EXPECT_EQ(2U, listener->last_extended_info.size());
+ EXPECT_EQ("value1", listener->last_extended_info["var1"]);
+ EXPECT_EQ(0, listener->error_count);
+}
+
+TEST_F(MucRoomDiscoveryTaskTest, TestMissingName) {
+ buzz::MucRoomDiscoveryTask* task = new buzz::MucRoomDiscoveryTask(
+ xmpp_client, room_jid);
+ task->SignalError.connect(listener, &MucRoomDiscoveryListener::OnError);
+ task->Start();
+
+ std::string error_iq =
+ "<iq xmlns='jabber:client'"
+ " from='muc-jid-ponies@domain.com' id='0' type='result'>"
+ " <info:query xmlns:info='http://jabber.org/protocol/disco#info'>"
+ " <info:identity />"
+ " </info:query>"
+ "</iq>";
+ EXPECT_EQ(0, listener->error_count);
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(error_iq));
+ EXPECT_EQ(0, listener->error_count);
+}
diff --git a/libjingle/xmpp/mucroomlookuptask.cc b/libjingle/xmpp/mucroomlookuptask.cc
new file mode 100644
index 00000000..8c0a4d78
--- /dev/null
+++ b/libjingle/xmpp/mucroomlookuptask.cc
@@ -0,0 +1,159 @@
+/*
+ * 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.
+ */
+
+#include "webrtc/libjingle/xmpp/mucroomlookuptask.h"
+
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/scoped_ptr.h"
+
+
+namespace buzz {
+
+MucRoomLookupTask*
+MucRoomLookupTask::CreateLookupTaskForRoomName(XmppTaskParentInterface* parent,
+ const Jid& lookup_server_jid,
+ const std::string& room_name,
+ const std::string& room_domain) {
+ return new MucRoomLookupTask(parent, lookup_server_jid,
+ MakeNameQuery(room_name, room_domain));
+}
+
+MucRoomLookupTask*
+MucRoomLookupTask::CreateLookupTaskForRoomJid(XmppTaskParentInterface* parent,
+ const Jid& lookup_server_jid,
+ const Jid& room_jid) {
+ return new MucRoomLookupTask(parent, lookup_server_jid,
+ MakeJidQuery(room_jid));
+}
+
+MucRoomLookupTask*
+MucRoomLookupTask::CreateLookupTaskForHangoutId(XmppTaskParentInterface* parent,
+ const Jid& lookup_server_jid,
+ const std::string& hangout_id) {
+ return new MucRoomLookupTask(parent, lookup_server_jid,
+ MakeHangoutIdQuery(hangout_id));
+}
+
+MucRoomLookupTask*
+MucRoomLookupTask::CreateLookupTaskForExternalId(
+ XmppTaskParentInterface* parent,
+ const Jid& lookup_server_jid,
+ const std::string& external_id,
+ const std::string& type) {
+ return new MucRoomLookupTask(parent, lookup_server_jid,
+ MakeExternalIdQuery(external_id, type));
+}
+
+MucRoomLookupTask::MucRoomLookupTask(XmppTaskParentInterface* parent,
+ const Jid& lookup_server_jid,
+ XmlElement* query)
+ : IqTask(parent, STR_SET, lookup_server_jid, query) {
+}
+
+XmlElement* MucRoomLookupTask::MakeNameQuery(
+ const std::string& room_name, const std::string& room_domain) {
+ XmlElement* name_elem = new XmlElement(QN_SEARCH_ROOM_NAME, false);
+ name_elem->SetBodyText(room_name);
+
+ XmlElement* domain_elem = new XmlElement(QN_SEARCH_ROOM_DOMAIN, false);
+ domain_elem->SetBodyText(room_domain);
+
+ XmlElement* query = new XmlElement(QN_SEARCH_QUERY, true);
+ query->AddElement(name_elem);
+ query->AddElement(domain_elem);
+ return query;
+}
+
+XmlElement* MucRoomLookupTask::MakeJidQuery(const Jid& room_jid) {
+ XmlElement* jid_elem = new XmlElement(QN_SEARCH_ROOM_JID);
+ jid_elem->SetBodyText(room_jid.Str());
+
+ XmlElement* query = new XmlElement(QN_SEARCH_QUERY);
+ query->AddElement(jid_elem);
+ return query;
+}
+
+XmlElement* MucRoomLookupTask::MakeExternalIdQuery(
+ const std::string& external_id, const std::string& type) {
+ XmlElement* external_id_elem = new XmlElement(QN_SEARCH_EXTERNAL_ID);
+ external_id_elem->SetAttr(QN_TYPE, type);
+ external_id_elem->SetBodyText(external_id);
+
+ XmlElement* query = new XmlElement(QN_SEARCH_QUERY);
+ query->AddElement(external_id_elem);
+ return query;
+}
+
+// Construct a stanza to lookup the muc jid for a given hangout id. eg:
+//
+// <query xmlns="jabber:iq:search">
+// <hangout-id>0b48ad092c893a53b7bfc87422caf38e93978798e</hangout-id>
+// </query>
+XmlElement* MucRoomLookupTask::MakeHangoutIdQuery(
+ const std::string& hangout_id) {
+ XmlElement* hangout_id_elem = new XmlElement(QN_SEARCH_HANGOUT_ID, false);
+ hangout_id_elem->SetBodyText(hangout_id);
+
+ XmlElement* query = new XmlElement(QN_SEARCH_QUERY, true);
+ query->AddElement(hangout_id_elem);
+ return query;
+}
+
+// Handle a response like the following:
+//
+// <query xmlns="jabber:iq:search">
+// <item jid="muvc-private-chat-guid@groupchat.google.com">
+// <room-name>0b48ad092c893a53b7bfc87422caf38e93978798e</room-name>
+// <room-domain>hangout.google.com</room-domain>
+// </item>
+// </query>
+void MucRoomLookupTask::HandleResult(const XmlElement* stanza) {
+ const XmlElement* query_elem = stanza->FirstNamed(QN_SEARCH_QUERY);
+ if (query_elem == NULL) {
+ SignalError(this, stanza);
+ return;
+ }
+
+ const XmlElement* item_elem = query_elem->FirstNamed(QN_SEARCH_ITEM);
+ if (item_elem == NULL) {
+ SignalError(this, stanza);
+ return;
+ }
+
+ MucRoomInfo room;
+ room.jid = Jid(item_elem->Attr(buzz::QN_JID));
+ if (!room.jid.IsValid()) {
+ SignalError(this, stanza);
+ return;
+ }
+
+ const XmlElement* room_name_elem =
+ item_elem->FirstNamed(QN_SEARCH_ROOM_NAME);
+ if (room_name_elem != NULL) {
+ room.name = room_name_elem->BodyText();
+ }
+
+ const XmlElement* room_domain_elem =
+ item_elem->FirstNamed(QN_SEARCH_ROOM_DOMAIN);
+ if (room_domain_elem != NULL) {
+ room.domain = room_domain_elem->BodyText();
+ }
+
+ const XmlElement* hangout_id_elem =
+ item_elem->FirstNamed(QN_SEARCH_HANGOUT_ID);
+ if (hangout_id_elem != NULL) {
+ room.hangout_id = hangout_id_elem->BodyText();
+ }
+
+ SignalResult(this, room);
+}
+
+} // namespace buzz
diff --git a/libjingle/xmpp/mucroomlookuptask.h b/libjingle/xmpp/mucroomlookuptask.h
new file mode 100644
index 00000000..d87b3da2
--- /dev/null
+++ b/libjingle/xmpp/mucroomlookuptask.h
@@ -0,0 +1,76 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_MUCROOMLOOKUPTASK_H_
+#define WEBRTC_LIBJINGLE_XMPP_MUCROOMLOOKUPTASK_H_
+
+#include <string>
+#include "webrtc/libjingle/xmpp/iqtask.h"
+
+namespace buzz {
+
+struct MucRoomInfo {
+ Jid jid;
+ std::string name;
+ std::string domain;
+ std::string hangout_id;
+
+ std::string full_name() const {
+ return name + "@" + domain;
+ }
+};
+
+class MucRoomLookupTask : public IqTask {
+ public:
+ enum IdType {
+ ID_TYPE_CONVERSATION,
+ ID_TYPE_HANGOUT
+ };
+
+ static MucRoomLookupTask*
+ CreateLookupTaskForRoomName(XmppTaskParentInterface* parent,
+ const Jid& lookup_server_jid,
+ const std::string& room_name,
+ const std::string& room_domain);
+ static MucRoomLookupTask*
+ CreateLookupTaskForRoomJid(XmppTaskParentInterface* parent,
+ const Jid& lookup_server_jid,
+ const Jid& room_jid);
+ static MucRoomLookupTask*
+ CreateLookupTaskForHangoutId(XmppTaskParentInterface* parent,
+ const Jid& lookup_server_jid,
+ const std::string& hangout_id);
+ static MucRoomLookupTask*
+ CreateLookupTaskForExternalId(XmppTaskParentInterface* parent,
+ const Jid& lookup_server_jid,
+ const std::string& external_id,
+ const std::string& type);
+
+ sigslot::signal2<MucRoomLookupTask*,
+ const MucRoomInfo&> SignalResult;
+
+ protected:
+ virtual void HandleResult(const XmlElement* element);
+
+ private:
+ MucRoomLookupTask(XmppTaskParentInterface* parent,
+ const Jid& lookup_server_jid,
+ XmlElement* query);
+ static XmlElement* MakeNameQuery(const std::string& room_name,
+ const std::string& room_domain);
+ static XmlElement* MakeJidQuery(const Jid& room_jid);
+ static XmlElement* MakeHangoutIdQuery(const std::string& hangout_id);
+ static XmlElement* MakeExternalIdQuery(const std::string& external_id,
+ const std::string& type);
+};
+
+} // namespace buzz
+
+#endif // WEBRTC_LIBJINGLE_XMPP_MUCROOMLOOKUPTASK_H_
diff --git a/libjingle/xmpp/mucroomlookuptask_unittest.cc b/libjingle/xmpp/mucroomlookuptask_unittest.cc
new file mode 100644
index 00000000..da5b1458
--- /dev/null
+++ b/libjingle/xmpp/mucroomlookuptask_unittest.cc
@@ -0,0 +1,187 @@
+/*
+ * 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.
+ */
+
+#include <string>
+#include <vector>
+
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/fakexmppclient.h"
+#include "webrtc/libjingle/xmpp/mucroomlookuptask.h"
+#include "webrtc/base/faketaskrunner.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/sigslot.h"
+
+class MucRoomLookupListener : public sigslot::has_slots<> {
+ public:
+ MucRoomLookupListener() : error_count(0) {}
+
+ void OnResult(buzz::MucRoomLookupTask* task,
+ const buzz::MucRoomInfo& room) {
+ last_room = room;
+ }
+
+ void OnError(buzz::IqTask* task,
+ const buzz::XmlElement* error) {
+ ++error_count;
+ }
+
+ buzz::MucRoomInfo last_room;
+ int error_count;
+};
+
+class MucRoomLookupTaskTest : public testing::Test {
+ public:
+ MucRoomLookupTaskTest() :
+ lookup_server_jid("lookup@domain.com"),
+ room_jid("muc-jid-ponies@domain.com"),
+ room_name("ponies"),
+ room_domain("domain.com"),
+ room_full_name("ponies@domain.com"),
+ hangout_id("some_hangout_id") {
+ }
+
+ virtual void SetUp() {
+ runner = new rtc::FakeTaskRunner();
+ xmpp_client = new buzz::FakeXmppClient(runner);
+ listener = new MucRoomLookupListener();
+ }
+
+ virtual void TearDown() {
+ delete listener;
+ // delete xmpp_client; Deleted by deleting runner.
+ delete runner;
+ }
+
+ rtc::FakeTaskRunner* runner;
+ buzz::FakeXmppClient* xmpp_client;
+ MucRoomLookupListener* listener;
+ buzz::Jid lookup_server_jid;
+ buzz::Jid room_jid;
+ std::string room_name;
+ std::string room_domain;
+ std::string room_full_name;
+ std::string hangout_id;
+};
+
+TEST_F(MucRoomLookupTaskTest, TestLookupName) {
+ ASSERT_EQ(0U, xmpp_client->sent_stanzas().size());
+
+ buzz::MucRoomLookupTask* task =
+ buzz::MucRoomLookupTask::CreateLookupTaskForRoomName(
+ xmpp_client, lookup_server_jid, room_name, room_domain);
+ task->SignalResult.connect(listener, &MucRoomLookupListener::OnResult);
+ task->Start();
+
+ std::string expected_iq =
+ "<cli:iq type=\"set\" to=\"lookup@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<query xmlns=\"jabber:iq:search\">"
+ "<room-name>ponies</room-name>"
+ "<room-domain>domain.com</room-domain>"
+ "</query>"
+ "</cli:iq>";
+
+ ASSERT_EQ(1U, xmpp_client->sent_stanzas().size());
+ EXPECT_EQ(expected_iq, xmpp_client->sent_stanzas()[0]->Str());
+
+ EXPECT_EQ("", listener->last_room.name);
+
+ std::string response_iq =
+ "<iq xmlns='jabber:client' from='lookup@domain.com' id='0' type='result'>"
+ " <query xmlns='jabber:iq:search'>"
+ " <item jid='muc-jid-ponies@domain.com'>"
+ " <room-name>ponies</room-name>"
+ " <room-domain>domain.com</room-domain>"
+ " </item>"
+ " </query>"
+ "</iq>";
+
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(response_iq));
+
+ EXPECT_EQ(room_name, listener->last_room.name);
+ EXPECT_EQ(room_domain, listener->last_room.domain);
+ EXPECT_EQ(room_jid, listener->last_room.jid);
+ EXPECT_EQ(room_full_name, listener->last_room.full_name());
+ EXPECT_EQ(0, listener->error_count);
+}
+
+TEST_F(MucRoomLookupTaskTest, TestLookupHangoutId) {
+ ASSERT_EQ(0U, xmpp_client->sent_stanzas().size());
+
+ buzz::MucRoomLookupTask* task = buzz::MucRoomLookupTask::CreateLookupTaskForHangoutId(
+ xmpp_client, lookup_server_jid, hangout_id);
+ task->SignalResult.connect(listener, &MucRoomLookupListener::OnResult);
+ task->Start();
+
+ std::string expected_iq =
+ "<cli:iq type=\"set\" to=\"lookup@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<query xmlns=\"jabber:iq:search\">"
+ "<hangout-id>some_hangout_id</hangout-id>"
+ "</query>"
+ "</cli:iq>";
+
+ ASSERT_EQ(1U, xmpp_client->sent_stanzas().size());
+ EXPECT_EQ(expected_iq, xmpp_client->sent_stanzas()[0]->Str());
+
+ EXPECT_EQ("", listener->last_room.name);
+
+ std::string response_iq =
+ "<iq xmlns='jabber:client' from='lookup@domain.com' id='0' type='result'>"
+ " <query xmlns='jabber:iq:search'>"
+ " <item jid='muc-jid-ponies@domain.com'>"
+ " <room-name>some_hangout_id</room-name>"
+ " <room-domain>domain.com</room-domain>"
+ " </item>"
+ " </query>"
+ "</iq>";
+
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(response_iq));
+
+ EXPECT_EQ(hangout_id, listener->last_room.name);
+ EXPECT_EQ(room_domain, listener->last_room.domain);
+ EXPECT_EQ(room_jid, listener->last_room.jid);
+ EXPECT_EQ(0, listener->error_count);
+}
+
+TEST_F(MucRoomLookupTaskTest, TestError) {
+ buzz::MucRoomLookupTask* task = buzz::MucRoomLookupTask::CreateLookupTaskForRoomName(
+ xmpp_client, lookup_server_jid, room_name, room_domain);
+ task->SignalError.connect(listener, &MucRoomLookupListener::OnError);
+ task->Start();
+
+ std::string error_iq =
+ "<iq xmlns='jabber:client' id='0' type='error'"
+ " from='lookup@domain.com'>"
+ "</iq>";
+
+ EXPECT_EQ(0, listener->error_count);
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(error_iq));
+ EXPECT_EQ(1, listener->error_count);
+}
+
+TEST_F(MucRoomLookupTaskTest, TestBadJid) {
+ buzz::MucRoomLookupTask* task = buzz::MucRoomLookupTask::CreateLookupTaskForRoomName(
+ xmpp_client, lookup_server_jid, room_name, room_domain);
+ task->SignalError.connect(listener, &MucRoomLookupListener::OnError);
+ task->Start();
+
+ std::string response_iq =
+ "<iq xmlns='jabber:client' from='lookup@domain.com' id='0' type='result'>"
+ " <query xmlns='jabber:iq:search'>"
+ " <item/>"
+ " </query>"
+ "</iq>";
+
+ EXPECT_EQ(0, listener->error_count);
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(response_iq));
+ EXPECT_EQ(1, listener->error_count);
+}
diff --git a/libjingle/xmpp/mucroomuniquehangoutidtask.cc b/libjingle/xmpp/mucroomuniquehangoutidtask.cc
new file mode 100644
index 00000000..79ccc29f
--- /dev/null
+++ b/libjingle/xmpp/mucroomuniquehangoutidtask.cc
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+#include "webrtc/libjingle/xmpp/mucroomuniquehangoutidtask.h"
+
+#include "webrtc/libjingle/xmpp/constants.h"
+
+namespace buzz {
+
+MucRoomUniqueHangoutIdTask::MucRoomUniqueHangoutIdTask(XmppTaskParentInterface* parent,
+ const Jid& lookup_server_jid)
+ : IqTask(parent, STR_GET, lookup_server_jid, MakeUniqueRequestXml()) {
+}
+
+// Construct a stanza to request a unique room id. eg:
+//
+// <unique hangout-id="true" xmlns="http://jabber.org/protocol/muc#unique"/>
+XmlElement* MucRoomUniqueHangoutIdTask::MakeUniqueRequestXml() {
+ XmlElement* xml = new XmlElement(QN_MUC_UNIQUE_QUERY, false);
+ xml->SetAttr(QN_HANGOUT_ID, STR_TRUE);
+ return xml;
+}
+
+// Handle a response like the following:
+//
+// <unique hangout-id="hangout_id"
+// xmlns="http://jabber.org/protocol/muc#unique"/>
+// muvc-private-chat-guid@groupchat.google.com
+// </unique>
+void MucRoomUniqueHangoutIdTask::HandleResult(const XmlElement* stanza) {
+
+ const XmlElement* unique_elem = stanza->FirstNamed(QN_MUC_UNIQUE_QUERY);
+ if (unique_elem == NULL ||
+ !unique_elem->HasAttr(QN_HANGOUT_ID)) {
+ SignalError(this, stanza);
+ return;
+ }
+
+ std::string hangout_id = unique_elem->Attr(QN_HANGOUT_ID);
+
+ SignalResult(this, hangout_id);
+}
+
+} // namespace buzz
diff --git a/libjingle/xmpp/mucroomuniquehangoutidtask.h b/libjingle/xmpp/mucroomuniquehangoutidtask.h
new file mode 100644
index 00000000..ac662503
--- /dev/null
+++ b/libjingle/xmpp/mucroomuniquehangoutidtask.h
@@ -0,0 +1,38 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_MUCROOMUNIQUEHANGOUTIDTASK_H_
+#define WEBRTC_LIBJINGLE_XMPP_MUCROOMUNIQUEHANGOUTIDTASK_H_
+
+#include "webrtc/libjingle/xmpp/iqtask.h"
+
+namespace buzz {
+
+// Task to request a unique hangout id to be used when starting a hangout.
+// The protocol is described in https://docs.google.com/a/google.com/
+// document/d/1EFLT6rCYPDVdqQXSQliXwqB3iUkpZJ9B_MNFeOZgN7g/edit
+class MucRoomUniqueHangoutIdTask : public buzz::IqTask {
+ public:
+ MucRoomUniqueHangoutIdTask(buzz::XmppTaskParentInterface* parent,
+ const Jid& lookup_server_jid);
+ // signal(task, hangout_id)
+ sigslot::signal2<MucRoomUniqueHangoutIdTask*, const std::string&> SignalResult;
+
+ protected:
+ virtual void HandleResult(const buzz::XmlElement* stanza);
+
+ private:
+ static buzz::XmlElement* MakeUniqueRequestXml();
+
+};
+
+} // namespace buzz
+
+#endif // WEBRTC_LIBJINGLE_XMPP_MUCROOMUNIQUEHANGOUTIDTASK_H_
diff --git a/libjingle/xmpp/mucroomuniquehangoutidtask_unittest.cc b/libjingle/xmpp/mucroomuniquehangoutidtask_unittest.cc
new file mode 100644
index 00000000..2480528b
--- /dev/null
+++ b/libjingle/xmpp/mucroomuniquehangoutidtask_unittest.cc
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+
+#include <string>
+#include <vector>
+
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/fakexmppclient.h"
+#include "webrtc/libjingle/xmpp/mucroomuniquehangoutidtask.h"
+#include "webrtc/base/faketaskrunner.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/sigslot.h"
+
+class MucRoomUniqueHangoutIdListener : public sigslot::has_slots<> {
+ public:
+ MucRoomUniqueHangoutIdListener() : error_count(0) {}
+
+ void OnResult(buzz::MucRoomUniqueHangoutIdTask* task,
+ const std::string& hangout_id) {
+ last_hangout_id = hangout_id;
+ }
+
+ void OnError(buzz::IqTask* task,
+ const buzz::XmlElement* error) {
+ ++error_count;
+ }
+
+ std::string last_hangout_id;
+ int error_count;
+};
+
+class MucRoomUniqueHangoutIdTaskTest : public testing::Test {
+ public:
+ MucRoomUniqueHangoutIdTaskTest() :
+ lookup_server_jid("lookup@domain.com"),
+ hangout_id("some_hangout_id") {
+ }
+
+ virtual void SetUp() {
+ runner = new rtc::FakeTaskRunner();
+ xmpp_client = new buzz::FakeXmppClient(runner);
+ listener = new MucRoomUniqueHangoutIdListener();
+ }
+
+ virtual void TearDown() {
+ delete listener;
+ // delete xmpp_client; Deleted by deleting runner.
+ delete runner;
+ }
+
+ rtc::FakeTaskRunner* runner;
+ buzz::FakeXmppClient* xmpp_client;
+ MucRoomUniqueHangoutIdListener* listener;
+ buzz::Jid lookup_server_jid;
+ std::string hangout_id;
+};
+
+TEST_F(MucRoomUniqueHangoutIdTaskTest, Test) {
+ ASSERT_EQ(0U, xmpp_client->sent_stanzas().size());
+
+ buzz::MucRoomUniqueHangoutIdTask* task = new buzz::MucRoomUniqueHangoutIdTask(
+ xmpp_client, lookup_server_jid);
+ task->SignalResult.connect(listener, &MucRoomUniqueHangoutIdListener::OnResult);
+ task->Start();
+
+ std::string expected_iq =
+ "<cli:iq type=\"get\" to=\"lookup@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<uni:unique hangout-id=\"true\" "
+ "xmlns:uni=\"http://jabber.org/protocol/muc#unique\"/>"
+ "</cli:iq>";
+
+ ASSERT_EQ(1U, xmpp_client->sent_stanzas().size());
+ EXPECT_EQ(expected_iq, xmpp_client->sent_stanzas()[0]->Str());
+
+ EXPECT_EQ("", listener->last_hangout_id);
+
+ std::string response_iq =
+ "<iq xmlns='jabber:client' from='lookup@domain.com' id='0' type='result'>"
+ "<unique hangout-id=\"some_hangout_id\" "
+ "xmlns=\"http://jabber.org/protocol/muc#unique\">"
+ "muvc-private-chat-00001234-5678-9abc-def0-123456789abc"
+ "</unique>"
+ "</iq>";
+
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(response_iq));
+
+ EXPECT_EQ(hangout_id, listener->last_hangout_id);
+ EXPECT_EQ(0, listener->error_count);
+}
+
diff --git a/libjingle/xmpp/pingtask.cc b/libjingle/xmpp/pingtask.cc
new file mode 100644
index 00000000..d44a6d1d
--- /dev/null
+++ b/libjingle/xmpp/pingtask.cc
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+#include "webrtc/libjingle/xmpp/pingtask.h"
+
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/scoped_ptr.h"
+
+namespace buzz {
+
+PingTask::PingTask(buzz::XmppTaskParentInterface* parent,
+ rtc::MessageQueue* message_queue,
+ uint32 ping_period_millis,
+ uint32 ping_timeout_millis)
+ : buzz::XmppTask(parent, buzz::XmppEngine::HL_SINGLE),
+ message_queue_(message_queue),
+ ping_period_millis_(ping_period_millis),
+ ping_timeout_millis_(ping_timeout_millis),
+ next_ping_time_(0),
+ ping_response_deadline_(0) {
+ ASSERT(ping_period_millis >= ping_timeout_millis);
+}
+
+bool PingTask::HandleStanza(const buzz::XmlElement* stanza) {
+ if (!MatchResponseIq(stanza, Jid(STR_EMPTY), task_id())) {
+ return false;
+ }
+
+ if (stanza->Attr(buzz::QN_TYPE) != buzz::STR_RESULT &&
+ stanza->Attr(buzz::QN_TYPE) != buzz::STR_ERROR) {
+ return false;
+ }
+
+ QueueStanza(stanza);
+ return true;
+}
+
+// This task runs indefinitely and remains in either the start or blocked
+// states.
+int PingTask::ProcessStart() {
+ if (ping_period_millis_ < ping_timeout_millis_) {
+ LOG(LS_ERROR) << "ping_period_millis should be >= ping_timeout_millis";
+ return STATE_ERROR;
+ }
+ const buzz::XmlElement* stanza = NextStanza();
+ if (stanza != NULL) {
+ // Received a ping response of some sort (don't care what it is).
+ ping_response_deadline_ = 0;
+ }
+
+ uint32 now = rtc::Time();
+
+ // If the ping timed out, signal.
+ if (ping_response_deadline_ != 0 && now >= ping_response_deadline_) {
+ SignalTimeout();
+ return STATE_ERROR;
+ }
+
+ // Send a ping if it's time.
+ if (now >= next_ping_time_) {
+ rtc::scoped_ptr<buzz::XmlElement> stanza(
+ MakeIq(buzz::STR_GET, Jid(STR_EMPTY), task_id()));
+ stanza->AddElement(new buzz::XmlElement(QN_PING));
+ SendStanza(stanza.get());
+
+ ping_response_deadline_ = now + ping_timeout_millis_;
+ next_ping_time_ = now + ping_period_millis_;
+
+ // Wake ourselves up when it's time to send another ping or when the ping
+ // times out (so we can fire a signal).
+ message_queue_->PostDelayed(ping_timeout_millis_, this);
+ message_queue_->PostDelayed(ping_period_millis_, this);
+ }
+
+ return STATE_BLOCKED;
+}
+
+void PingTask::OnMessage(rtc::Message* msg) {
+ // Get the task manager to run this task so we can send a ping or signal or
+ // process a ping response.
+ Wake();
+}
+
+} // namespace buzz
diff --git a/libjingle/xmpp/pingtask.h b/libjingle/xmpp/pingtask.h
new file mode 100644
index 00000000..9ea905b0
--- /dev/null
+++ b/libjingle/xmpp/pingtask.h
@@ -0,0 +1,54 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_PINGTASK_H_
+#define WEBRTC_LIBJINGLE_XMPP_PINGTASK_H_
+
+#include "webrtc/libjingle/xmpp/xmpptask.h"
+#include "webrtc/base/messagehandler.h"
+#include "webrtc/base/messagequeue.h"
+
+namespace buzz {
+
+// Task to periodically send pings to the server to ensure that the network
+// connection is valid, implementing XEP-0199.
+//
+// This is especially useful on cellular networks because:
+// 1. It keeps the connections alive through the cellular network's NATs or
+// proxies.
+// 2. It detects when the server has crashed or any other case in which the
+// connection has broken without a fin or reset packet being sent to us.
+class PingTask : public buzz::XmppTask, private rtc::MessageHandler {
+ public:
+ PingTask(buzz::XmppTaskParentInterface* parent,
+ rtc::MessageQueue* message_queue, uint32 ping_period_millis,
+ uint32 ping_timeout_millis);
+
+ virtual bool HandleStanza(const buzz::XmlElement* stanza);
+ virtual int ProcessStart();
+
+ // Raised if there is no response to a ping within ping_timeout_millis.
+ // The task is automatically aborted after a timeout.
+ sigslot::signal0<> SignalTimeout;
+
+ private:
+ // Implementation of MessageHandler.
+ virtual void OnMessage(rtc::Message* msg);
+
+ rtc::MessageQueue* message_queue_;
+ uint32 ping_period_millis_;
+ uint32 ping_timeout_millis_;
+ uint32 next_ping_time_;
+ uint32 ping_response_deadline_; // 0 if the response has been received
+};
+
+} // namespace buzz
+
+#endif // WEBRTC_LIBJINGLE_XMPP_PINGTASK_H_
diff --git a/libjingle/xmpp/pingtask_unittest.cc b/libjingle/xmpp/pingtask_unittest.cc
new file mode 100644
index 00000000..08a5770c
--- /dev/null
+++ b/libjingle/xmpp/pingtask_unittest.cc
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+#include <string>
+#include <vector>
+
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/fakexmppclient.h"
+#include "webrtc/libjingle/xmpp/pingtask.h"
+#include "webrtc/base/faketaskrunner.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/sigslot.h"
+
+class PingTaskTest;
+
+class PingXmppClient : public buzz::FakeXmppClient {
+ public:
+ PingXmppClient(rtc::TaskParent* parent, PingTaskTest* tst) :
+ FakeXmppClient(parent), test(tst) {
+ }
+
+ buzz::XmppReturnStatus SendStanza(const buzz::XmlElement* stanza);
+
+ private:
+ PingTaskTest* test;
+};
+
+class PingTaskTest : public testing::Test, public sigslot::has_slots<> {
+ public:
+ PingTaskTest() : respond_to_pings(true), timed_out(false) {
+ }
+
+ virtual void SetUp() {
+ runner = new rtc::FakeTaskRunner();
+ xmpp_client = new PingXmppClient(runner, this);
+ }
+
+ virtual void TearDown() {
+ // delete xmpp_client; Deleted by deleting runner.
+ delete runner;
+ }
+
+ void ConnectTimeoutSignal(buzz::PingTask* task) {
+ task->SignalTimeout.connect(this, &PingTaskTest::OnPingTimeout);
+ }
+
+ void OnPingTimeout() {
+ timed_out = true;
+ }
+
+ rtc::FakeTaskRunner* runner;
+ PingXmppClient* xmpp_client;
+ bool respond_to_pings;
+ bool timed_out;
+};
+
+buzz::XmppReturnStatus PingXmppClient::SendStanza(
+ const buzz::XmlElement* stanza) {
+ buzz::XmppReturnStatus result = FakeXmppClient::SendStanza(stanza);
+ if (test->respond_to_pings && (stanza->FirstNamed(buzz::QN_PING) != NULL)) {
+ std::string ping_response =
+ "<iq xmlns=\'jabber:client\' id='0' type='result'/>";
+ HandleStanza(buzz::XmlElement::ForStr(ping_response));
+ }
+ return result;
+}
+
+TEST_F(PingTaskTest, TestSuccess) {
+ uint32 ping_period_millis = 100;
+ buzz::PingTask* task = new buzz::PingTask(xmpp_client,
+ rtc::Thread::Current(),
+ ping_period_millis, ping_period_millis / 10);
+ ConnectTimeoutSignal(task);
+ task->Start();
+ unsigned int expected_ping_count = 5U;
+ EXPECT_EQ_WAIT(xmpp_client->sent_stanzas().size(), expected_ping_count,
+ ping_period_millis * (expected_ping_count + 1));
+ EXPECT_FALSE(task->IsDone());
+ EXPECT_FALSE(timed_out);
+}
+
+TEST_F(PingTaskTest, TestTimeout) {
+ respond_to_pings = false;
+ uint32 ping_timeout_millis = 200;
+ buzz::PingTask* task = new buzz::PingTask(xmpp_client,
+ rtc::Thread::Current(),
+ ping_timeout_millis * 10, ping_timeout_millis);
+ ConnectTimeoutSignal(task);
+ task->Start();
+ WAIT(false, ping_timeout_millis / 2);
+ EXPECT_FALSE(timed_out);
+ EXPECT_TRUE_WAIT(timed_out, ping_timeout_millis * 2);
+}
diff --git a/libjingle/xmpp/plainsaslhandler.h b/libjingle/xmpp/plainsaslhandler.h
new file mode 100644
index 00000000..aa6a791e
--- /dev/null
+++ b/libjingle/xmpp/plainsaslhandler.h
@@ -0,0 +1,64 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_PLAINSASLHANDLER_H_
+#define WEBRTC_LIBJINGLE_XMPP_PLAINSASLHANDLER_H_
+
+#include <algorithm>
+#include "webrtc/libjingle/xmpp/saslhandler.h"
+#include "webrtc/libjingle/xmpp/saslplainmechanism.h"
+#include "webrtc/base/cryptstring.h"
+
+namespace buzz {
+
+class PlainSaslHandler : public SaslHandler {
+public:
+ PlainSaslHandler(const Jid & jid, const rtc::CryptString & password,
+ bool allow_plain) : jid_(jid), password_(password),
+ allow_plain_(allow_plain) {}
+
+ virtual ~PlainSaslHandler() {}
+
+ // Should pick the best method according to this handler
+ // returns the empty string if none are suitable
+ virtual std::string ChooseBestSaslMechanism(const std::vector<std::string> & mechanisms, bool encrypted) {
+
+ if (!encrypted && !allow_plain_) {
+ return "";
+ }
+
+ std::vector<std::string>::const_iterator it = std::find(mechanisms.begin(), mechanisms.end(), "PLAIN");
+ if (it == mechanisms.end()) {
+ return "";
+ }
+ else {
+ return "PLAIN";
+ }
+ }
+
+ // Creates a SaslMechanism for the given mechanism name (you own it
+ // once you get it). If not handled, return NULL.
+ virtual SaslMechanism * CreateSaslMechanism(const std::string & mechanism) {
+ if (mechanism == "PLAIN") {
+ return new SaslPlainMechanism(jid_, password_);
+ }
+ return NULL;
+ }
+
+private:
+ Jid jid_;
+ rtc::CryptString password_;
+ bool allow_plain_;
+};
+
+
+}
+
+#endif // WEBRTC_LIBJINGLE_XMPP_PLAINSASLHANDLER_H_
diff --git a/libjingle/xmpp/presenceouttask.cc b/libjingle/xmpp/presenceouttask.cc
new file mode 100644
index 00000000..aa19c9dd
--- /dev/null
+++ b/libjingle/xmpp/presenceouttask.cc
@@ -0,0 +1,140 @@
+/*
+ * 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 <time.h>
+#include <sstream>
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/presenceouttask.h"
+#include "webrtc/libjingle/xmpp/xmppclient.h"
+#include "webrtc/base/stringencode.h"
+
+namespace buzz {
+
+XmppReturnStatus
+PresenceOutTask::Send(const PresenceStatus & s) {
+ if (GetState() != STATE_INIT && GetState() != STATE_START)
+ return XMPP_RETURN_BADSTATE;
+
+ XmlElement * presence = TranslateStatus(s);
+ QueueStanza(presence);
+ delete presence;
+ return XMPP_RETURN_OK;
+}
+
+XmppReturnStatus
+PresenceOutTask::SendDirected(const Jid & j, const PresenceStatus & s) {
+ if (GetState() != STATE_INIT && GetState() != STATE_START)
+ return XMPP_RETURN_BADSTATE;
+
+ XmlElement * presence = TranslateStatus(s);
+ presence->AddAttr(QN_TO, j.Str());
+ QueueStanza(presence);
+ delete presence;
+ return XMPP_RETURN_OK;
+}
+
+XmppReturnStatus PresenceOutTask::SendProbe(const Jid & jid) {
+ if (GetState() != STATE_INIT && GetState() != STATE_START)
+ return XMPP_RETURN_BADSTATE;
+
+ XmlElement * presence = new XmlElement(QN_PRESENCE);
+ presence->AddAttr(QN_TO, jid.Str());
+ presence->AddAttr(QN_TYPE, "probe");
+
+ QueueStanza(presence);
+ delete presence;
+ return XMPP_RETURN_OK;
+}
+
+int
+PresenceOutTask::ProcessStart() {
+ const XmlElement * stanza = NextStanza();
+ if (stanza == NULL)
+ return STATE_BLOCKED;
+
+ if (SendStanza(stanza) != XMPP_RETURN_OK)
+ return STATE_ERROR;
+
+ return STATE_START;
+}
+
+XmlElement *
+PresenceOutTask::TranslateStatus(const PresenceStatus & s) {
+ XmlElement * result = new XmlElement(QN_PRESENCE);
+ if (!s.available()) {
+ result->AddAttr(QN_TYPE, STR_UNAVAILABLE);
+ }
+ else {
+ if (s.show() != PresenceStatus::SHOW_ONLINE &&
+ s.show() != PresenceStatus::SHOW_OFFLINE) {
+ result->AddElement(new XmlElement(QN_SHOW));
+ switch (s.show()) {
+ default:
+ result->AddText(STR_SHOW_AWAY, 1);
+ break;
+ case PresenceStatus::SHOW_XA:
+ result->AddText(STR_SHOW_XA, 1);
+ break;
+ case PresenceStatus::SHOW_DND:
+ result->AddText(STR_SHOW_DND, 1);
+ break;
+ case PresenceStatus::SHOW_CHAT:
+ result->AddText(STR_SHOW_CHAT, 1);
+ break;
+ }
+ }
+
+ result->AddElement(new XmlElement(QN_STATUS));
+ result->AddText(s.status(), 1);
+
+ if (!s.nick().empty()) {
+ result->AddElement(new XmlElement(QN_NICKNAME));
+ result->AddText(s.nick(), 1);
+ }
+
+ std::string pri;
+ rtc::ToString(s.priority(), &pri);
+
+ result->AddElement(new XmlElement(QN_PRIORITY));
+ result->AddText(pri, 1);
+
+ if (s.know_capabilities()) {
+ result->AddElement(new XmlElement(QN_CAPS_C, true));
+ result->AddAttr(QN_NODE, s.caps_node(), 1);
+ result->AddAttr(QN_VER, s.version(), 1);
+
+ std::string caps;
+ caps.append(s.voice_capability() ? "voice-v1" : "");
+ caps.append(s.pmuc_capability() ? " pmuc-v1" : "");
+ caps.append(s.video_capability() ? " video-v1" : "");
+ caps.append(s.camera_capability() ? " camera-v1" : "");
+
+ result->AddAttr(QN_EXT, caps, 1);
+ }
+
+ // Put the delay mark on the presence according to JEP-0091
+ {
+ result->AddElement(new XmlElement(kQnDelayX, true));
+
+ // This here is why we *love* the C runtime
+ time_t current_time_seconds;
+ time(&current_time_seconds);
+ struct tm* current_time = gmtime(&current_time_seconds);
+ char output[256];
+ strftime(output, ARRAY_SIZE(output), "%Y%m%dT%H:%M:%S", current_time);
+ result->AddAttr(kQnStamp, output, 1);
+ }
+ }
+
+ return result;
+}
+
+
+}
diff --git a/libjingle/xmpp/presenceouttask.h b/libjingle/xmpp/presenceouttask.h
new file mode 100644
index 00000000..88869df3
--- /dev/null
+++ b/libjingle/xmpp/presenceouttask.h
@@ -0,0 +1,37 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_PRESENCEOUTTASK_H_
+#define WEBRTC_LIBJINGLE_XMPP_PRESENCEOUTTASK_H_
+
+#include "webrtc/libjingle/xmpp/presencestatus.h"
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+#include "webrtc/libjingle/xmpp/xmpptask.h"
+
+namespace buzz {
+
+class PresenceOutTask : public XmppTask {
+public:
+ explicit PresenceOutTask(XmppTaskParentInterface* parent)
+ : XmppTask(parent) {}
+ virtual ~PresenceOutTask() {}
+
+ XmppReturnStatus Send(const PresenceStatus & s);
+ XmppReturnStatus SendDirected(const Jid & j, const PresenceStatus & s);
+ XmppReturnStatus SendProbe(const Jid& jid);
+
+ virtual int ProcessStart();
+private:
+ XmlElement * TranslateStatus(const PresenceStatus & s);
+};
+
+}
+
+#endif // WEBRTC_LIBJINGLE_XMPP_PRESENCEOUTTASK_H_
diff --git a/libjingle/xmpp/presencereceivetask.cc b/libjingle/xmpp/presencereceivetask.cc
new file mode 100644
index 00000000..3ea7274c
--- /dev/null
+++ b/libjingle/xmpp/presencereceivetask.cc
@@ -0,0 +1,141 @@
+/*
+ * 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 "webrtc/libjingle/xmpp/presencereceivetask.h"
+
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/base/stringencode.h"
+
+namespace buzz {
+
+static bool IsUtf8FirstByte(int c) {
+ return (((c)&0x80)==0) || // is single byte
+ ((unsigned char)((c)-0xc0)<0x3e); // or is lead byte
+}
+
+PresenceReceiveTask::PresenceReceiveTask(XmppTaskParentInterface* parent)
+ : XmppTask(parent, XmppEngine::HL_TYPE) {
+}
+
+PresenceReceiveTask::~PresenceReceiveTask() {
+ Stop();
+}
+
+int PresenceReceiveTask::ProcessStart() {
+ const XmlElement * stanza = NextStanza();
+ if (stanza == NULL) {
+ return STATE_BLOCKED;
+ }
+
+ Jid from(stanza->Attr(QN_FROM));
+ HandlePresence(from, stanza);
+
+ return STATE_START;
+}
+
+bool PresenceReceiveTask::HandleStanza(const XmlElement * stanza) {
+ // Verify that this is a presence stanze
+ if (stanza->Name() != QN_PRESENCE) {
+ return false; // not sure if this ever happens.
+ }
+
+ // Queue it up
+ QueueStanza(stanza);
+
+ return true;
+}
+
+void PresenceReceiveTask::HandlePresence(const Jid& from,
+ const XmlElement* stanza) {
+ if (stanza->Attr(QN_TYPE) == STR_ERROR) {
+ return;
+ }
+
+ PresenceStatus status;
+ DecodeStatus(from, stanza, &status);
+ PresenceUpdate(status);
+}
+
+void PresenceReceiveTask::DecodeStatus(const Jid& from,
+ const XmlElement* stanza,
+ PresenceStatus* presence_status) {
+ presence_status->set_jid(from);
+ if (stanza->Attr(QN_TYPE) == STR_UNAVAILABLE) {
+ presence_status->set_available(false);
+ } else {
+ presence_status->set_available(true);
+ const XmlElement * status_elem = stanza->FirstNamed(QN_STATUS);
+ if (status_elem != NULL) {
+ presence_status->set_status(status_elem->BodyText());
+
+ // Truncate status messages longer than 300 bytes
+ if (presence_status->status().length() > 300) {
+ size_t len = 300;
+
+ // Be careful not to split legal utf-8 chars in half
+ while (!IsUtf8FirstByte(presence_status->status()[len]) && len > 0) {
+ len -= 1;
+ }
+ std::string truncated(presence_status->status(), 0, len);
+ presence_status->set_status(truncated);
+ }
+ }
+
+ const XmlElement * priority = stanza->FirstNamed(QN_PRIORITY);
+ if (priority != NULL) {
+ int pri;
+ if (rtc::FromString(priority->BodyText(), &pri)) {
+ presence_status->set_priority(pri);
+ }
+ }
+
+ const XmlElement * show = stanza->FirstNamed(QN_SHOW);
+ if (show == NULL || show->FirstChild() == NULL) {
+ presence_status->set_show(PresenceStatus::SHOW_ONLINE);
+ } else if (show->BodyText() == "away") {
+ presence_status->set_show(PresenceStatus::SHOW_AWAY);
+ } else if (show->BodyText() == "xa") {
+ presence_status->set_show(PresenceStatus::SHOW_XA);
+ } else if (show->BodyText() == "dnd") {
+ presence_status->set_show(PresenceStatus::SHOW_DND);
+ } else if (show->BodyText() == "chat") {
+ presence_status->set_show(PresenceStatus::SHOW_CHAT);
+ } else {
+ presence_status->set_show(PresenceStatus::SHOW_ONLINE);
+ }
+
+ const XmlElement * caps = stanza->FirstNamed(QN_CAPS_C);
+ if (caps != NULL) {
+ std::string node = caps->Attr(QN_NODE);
+ std::string ver = caps->Attr(QN_VER);
+ std::string exts = caps->Attr(QN_EXT);
+
+ presence_status->set_know_capabilities(true);
+ presence_status->set_caps_node(node);
+ presence_status->set_version(ver);
+ }
+
+ const XmlElement* delay = stanza->FirstNamed(kQnDelayX);
+ if (delay != NULL) {
+ // Ideally we would parse this according to the Psuedo ISO-8601 rules
+ // that are laid out in JEP-0082:
+ // http://www.jabber.org/jeps/jep-0082.html
+ std::string stamp = delay->Attr(kQnStamp);
+ presence_status->set_sent_time(stamp);
+ }
+
+ const XmlElement* nick = stanza->FirstNamed(QN_NICKNAME);
+ if (nick) {
+ presence_status->set_nick(nick->BodyText());
+ }
+ }
+}
+
+} // namespace buzz
diff --git a/libjingle/xmpp/presencereceivetask.h b/libjingle/xmpp/presencereceivetask.h
new file mode 100644
index 00000000..20e6c793
--- /dev/null
+++ b/libjingle/xmpp/presencereceivetask.h
@@ -0,0 +1,56 @@
+/*
+ * 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 THIRD_PARTY_LIBJINGLE_FILES_WEBRTC_LIBJINGLE_XMPP_PRESENCERECEIVETASK_H_
+#define THIRD_PARTY_LIBJINGLE_FILES_WEBRTC_LIBJINGLE_XMPP_PRESENCERECEIVETASK_H_
+
+#include "webrtc/base/sigslot.h"
+
+#include "webrtc/libjingle/xmpp/presencestatus.h"
+#include "webrtc/libjingle/xmpp/xmpptask.h"
+
+namespace buzz {
+
+// A task to receive presence status callbacks from the XMPP server.
+class PresenceReceiveTask : public XmppTask {
+ public:
+ // Arguments:
+ // parent a reference to task interface associated withe the XMPP client.
+ explicit PresenceReceiveTask(XmppTaskParentInterface* parent);
+
+ // Shuts down the thread associated with this task.
+ virtual ~PresenceReceiveTask();
+
+ // Starts pulling queued status messages and dispatching them to the
+ // PresenceUpdate() callback.
+ virtual int ProcessStart();
+
+ // Slot for presence message callbacks
+ sigslot::signal1<const PresenceStatus&> PresenceUpdate;
+
+ protected:
+ // Called by the XMPP engine when presence stanzas are received from the
+ // server.
+ virtual bool HandleStanza(const XmlElement * stanza);
+
+ private:
+ // Handles presence stanzas by converting the data to PresenceStatus
+ // objects and passing those along to the SignalStatusUpadate() callback.
+ void HandlePresence(const Jid& from, const XmlElement * stanza);
+
+ // Extracts presence information for the presence stanza sent form the
+ // server.
+ static void DecodeStatus(const Jid& from, const XmlElement * stanza,
+ PresenceStatus* status);
+};
+
+} // namespace buzz
+
+#endif // THIRD_PARTY_LIBJINGLE_FILES_WEBRTC_LIBJINGLE_XMPP_PRESENCERECEIVETASK_H_
diff --git a/libjingle/xmpp/presencestatus.cc b/libjingle/xmpp/presencestatus.cc
new file mode 100644
index 00000000..da6c64f1
--- /dev/null
+++ b/libjingle/xmpp/presencestatus.cc
@@ -0,0 +1,45 @@
+/*
+ * 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 "webrtc/libjingle/xmpp/presencestatus.h"
+
+namespace buzz {
+PresenceStatus::PresenceStatus()
+ : pri_(0),
+ show_(SHOW_NONE),
+ available_(false),
+ e_code_(0),
+ feedback_probation_(false),
+ know_capabilities_(false),
+ voice_capability_(false),
+ pmuc_capability_(false),
+ video_capability_(false),
+ camera_capability_(false) {
+}
+
+void PresenceStatus::UpdateWith(const PresenceStatus& new_value) {
+ if (!new_value.know_capabilities()) {
+ bool k = know_capabilities();
+ bool p = voice_capability();
+ std::string node = caps_node();
+ std::string v = version();
+
+ *this = new_value;
+
+ set_know_capabilities(k);
+ set_caps_node(node);
+ set_voice_capability(p);
+ set_version(v);
+ } else {
+ *this = new_value;
+ }
+}
+
+} // namespace buzz
diff --git a/libjingle/xmpp/presencestatus.h b/libjingle/xmpp/presencestatus.h
new file mode 100644
index 00000000..0261c72b
--- /dev/null
+++ b/libjingle/xmpp/presencestatus.h
@@ -0,0 +1,188 @@
+/*
+ * 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 THIRD_PARTY_LIBJINGLE_FILES_WEBRTC_LIBJINGLE_XMPP_PRESENCESTATUS_H_
+#define THIRD_PARTY_LIBJINGLE_FILES_WEBRTC_LIBJINGLE_XMPP_PRESENCESTATUS_H_
+
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/jid.h"
+
+namespace buzz {
+
+class PresenceStatus {
+public:
+ PresenceStatus();
+ ~PresenceStatus() {}
+
+ // These are arranged in "priority order", i.e., if we see
+ // two statuses at the same priority but with different Shows,
+ // we will show the one with the highest show in the following
+ // order.
+ enum Show {
+ SHOW_NONE = 0,
+ SHOW_OFFLINE = 1,
+ SHOW_XA = 2,
+ SHOW_AWAY = 3,
+ SHOW_DND = 4,
+ SHOW_ONLINE = 5,
+ SHOW_CHAT = 6,
+ };
+
+ const Jid& jid() const { return jid_; }
+ int priority() const { return pri_; }
+ Show show() const { return show_; }
+ const std::string& status() const { return status_; }
+ const std::string& nick() const { return nick_; }
+ bool available() const { return available_ ; }
+ int error_code() const { return e_code_; }
+ const std::string& error_string() const { return e_str_; }
+ bool know_capabilities() const { return know_capabilities_; }
+ bool voice_capability() const { return voice_capability_; }
+ bool pmuc_capability() const { return pmuc_capability_; }
+ bool video_capability() const { return video_capability_; }
+ bool camera_capability() const { return camera_capability_; }
+ const std::string& caps_node() const { return caps_node_; }
+ const std::string& version() const { return version_; }
+ bool feedback_probation() const { return feedback_probation_; }
+ const std::string& sent_time() const { return sent_time_; }
+
+ void set_jid(const Jid& jid) { jid_ = jid; }
+ void set_priority(int pri) { pri_ = pri; }
+ void set_show(Show show) { show_ = show; }
+ void set_status(const std::string& status) { status_ = status; }
+ void set_nick(const std::string& nick) { nick_ = nick; }
+ void set_available(bool a) { available_ = a; }
+ void set_error(int e_code, const std::string e_str)
+ { e_code_ = e_code; e_str_ = e_str; }
+ void set_know_capabilities(bool f) { know_capabilities_ = f; }
+ void set_voice_capability(bool f) { voice_capability_ = f; }
+ void set_pmuc_capability(bool f) { pmuc_capability_ = f; }
+ void set_video_capability(bool f) { video_capability_ = f; }
+ void set_camera_capability(bool f) { camera_capability_ = f; }
+ void set_caps_node(const std::string& f) { caps_node_ = f; }
+ void set_version(const std::string& v) { version_ = v; }
+ void set_feedback_probation(bool f) { feedback_probation_ = f; }
+ void set_sent_time(const std::string& time) { sent_time_ = time; }
+
+ void UpdateWith(const PresenceStatus& new_value);
+
+ bool HasQuietStatus() const {
+ if (status_.empty())
+ return false;
+ return !(QuietStatus().empty());
+ }
+
+ // Knowledge of other clients' silly automatic status strings -
+ // Don't show these.
+ std::string QuietStatus() const {
+ if (jid_.resource().find("Psi") != std::string::npos) {
+ if (status_ == "Online" ||
+ status_.find("Auto Status") != std::string::npos)
+ return STR_EMPTY;
+ }
+ if (jid_.resource().find("Gaim") != std::string::npos) {
+ if (status_ == "Sorry, I ran out for a bit!")
+ return STR_EMPTY;
+ }
+ return TrimStatus(status_);
+ }
+
+ std::string ExplicitStatus() const {
+ std::string result = QuietStatus();
+ if (result.empty()) {
+ result = ShowStatus();
+ }
+ return result;
+ }
+
+ std::string ShowStatus() const {
+ std::string result;
+ if (!available()) {
+ result = "Offline";
+ }
+ else {
+ switch (show()) {
+ case SHOW_AWAY:
+ case SHOW_XA:
+ result = "Idle";
+ break;
+ case SHOW_DND:
+ result = "Busy";
+ break;
+ case SHOW_CHAT:
+ result = "Chatty";
+ break;
+ default:
+ result = "Available";
+ break;
+ }
+ }
+ return result;
+ }
+
+ static std::string TrimStatus(const std::string& st) {
+ std::string s(st);
+ int j = 0;
+ bool collapsing = true;
+ for (unsigned int i = 0; i < s.length(); i+= 1) {
+ if (s[i] <= ' ' && s[i] >= 0) {
+ if (collapsing) {
+ continue;
+ }
+ else {
+ s[j] = ' ';
+ j += 1;
+ collapsing = true;
+ }
+ }
+ else {
+ s[j] = s[i];
+ j += 1;
+ collapsing = false;
+ }
+ }
+ if (collapsing && j > 0) {
+ j -= 1;
+ }
+ s.erase(j, s.length());
+ return s;
+ }
+
+private:
+ Jid jid_;
+ int pri_;
+ Show show_;
+ std::string status_;
+ std::string nick_;
+ bool available_;
+ int e_code_;
+ std::string e_str_;
+ bool feedback_probation_;
+
+ // capabilities (valid only if know_capabilities_
+ bool know_capabilities_;
+ bool voice_capability_;
+ bool pmuc_capability_;
+ bool video_capability_;
+ bool camera_capability_;
+ std::string caps_node_;
+ std::string version_;
+
+ std::string sent_time_; // from the jabber:x:delay element
+};
+
+class MucPresenceStatus : public PresenceStatus {
+};
+
+} // namespace buzz
+
+
+#endif // THIRD_PARTY_LIBJINGLE_FILES_WEBRTC_LIBJINGLE_XMPP_PRESENCESTATUS_H_
+
diff --git a/libjingle/xmpp/prexmppauth.h b/libjingle/xmpp/prexmppauth.h
new file mode 100644
index 00000000..3a1e6106
--- /dev/null
+++ b/libjingle/xmpp/prexmppauth.h
@@ -0,0 +1,71 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_PREXMPPAUTH_H_
+#define WEBRTC_LIBJINGLE_XMPP_PREXMPPAUTH_H_
+
+#include "webrtc/libjingle/xmpp/saslhandler.h"
+#include "webrtc/base/cryptstring.h"
+#include "webrtc/base/sigslot.h"
+
+namespace rtc {
+ class SocketAddress;
+}
+
+namespace buzz {
+
+class Jid;
+class SaslMechanism;
+
+class CaptchaChallenge {
+ public:
+ CaptchaChallenge() : captcha_needed_(false) {}
+ CaptchaChallenge(const std::string& token, const std::string& url)
+ : captcha_needed_(true), captcha_token_(token), captcha_image_url_(url) {
+ }
+
+ bool captcha_needed() const { return captcha_needed_; }
+ const std::string& captcha_token() const { return captcha_token_; }
+
+ // This url is relative to the gaia server. Once we have better tools
+ // for cracking URLs, we should probably make this a full URL
+ const std::string& captcha_image_url() const { return captcha_image_url_; }
+
+ private:
+ bool captcha_needed_;
+ std::string captcha_token_;
+ std::string captcha_image_url_;
+};
+
+class PreXmppAuth : public SaslHandler {
+public:
+ virtual ~PreXmppAuth() {}
+
+ virtual void StartPreXmppAuth(
+ const Jid& jid,
+ const rtc::SocketAddress& server,
+ const rtc::CryptString& pass,
+ const std::string& auth_mechanism,
+ const std::string& auth_token) = 0;
+
+ sigslot::signal0<> SignalAuthDone;
+
+ virtual bool IsAuthDone() const = 0;
+ virtual bool IsAuthorized() const = 0;
+ virtual bool HadError() const = 0;
+ virtual int GetError() const = 0;
+ virtual CaptchaChallenge GetCaptchaChallenge() const = 0;
+ virtual std::string GetAuthMechanism() const = 0;
+ virtual std::string GetAuthToken() const = 0;
+};
+
+}
+
+#endif // WEBRTC_LIBJINGLE_XMPP_PREXMPPAUTH_H_
diff --git a/libjingle/xmpp/pubsub_task.cc b/libjingle/xmpp/pubsub_task.cc
new file mode 100644
index 00000000..f30c0518
--- /dev/null
+++ b/libjingle/xmpp/pubsub_task.cc
@@ -0,0 +1,200 @@
+/*
+ * 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 "webrtc/libjingle/xmpp/pubsub_task.h"
+
+#include <map>
+#include <string>
+
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+#include "webrtc/base/common.h"
+
+namespace buzz {
+
+PubsubTask::PubsubTask(XmppTaskParentInterface* parent,
+ const buzz::Jid& pubsub_node_jid)
+ : buzz::XmppTask(parent, buzz::XmppEngine::HL_SENDER),
+ pubsub_node_jid_(pubsub_node_jid) {
+}
+
+PubsubTask::~PubsubTask() {
+}
+
+// Checks for pubsub publish events as well as responses to get IQs.
+bool PubsubTask::HandleStanza(const buzz::XmlElement* stanza) {
+ const buzz::QName& stanza_name(stanza->Name());
+ if (stanza_name == buzz::QN_MESSAGE) {
+ if (MatchStanzaFrom(stanza, pubsub_node_jid_)) {
+ const buzz::XmlElement* pubsub_event_item =
+ stanza->FirstNamed(QN_PUBSUB_EVENT);
+ if (pubsub_event_item != NULL) {
+ QueueStanza(pubsub_event_item);
+ return true;
+ }
+ }
+ } else if (stanza_name == buzz::QN_IQ) {
+ if (MatchResponseIq(stanza, pubsub_node_jid_, task_id())) {
+ const buzz::XmlElement* pubsub_item = stanza->FirstNamed(QN_PUBSUB);
+ if (pubsub_item != NULL) {
+ QueueStanza(pubsub_item);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+int PubsubTask::ProcessResponse() {
+ const buzz::XmlElement* stanza = NextStanza();
+ if (stanza == NULL) {
+ return STATE_BLOCKED;
+ }
+
+ if (stanza->Attr(buzz::QN_TYPE) == buzz::STR_ERROR) {
+ OnPubsubError(stanza->FirstNamed(buzz::QN_ERROR));
+ return STATE_RESPONSE;
+ }
+
+ const buzz::QName& stanza_name(stanza->Name());
+ if (stanza_name == QN_PUBSUB_EVENT) {
+ HandlePubsubEventMessage(stanza);
+ } else if (stanza_name == QN_PUBSUB) {
+ HandlePubsubIqGetResponse(stanza);
+ }
+
+ return STATE_RESPONSE;
+}
+
+// Registers a function pointer to be called when the value of the pubsub
+// node changes.
+// Note that this does not actually change the XMPP pubsub
+// subscription. All publish events are always received by everyone in the
+// MUC. This function just controls whether the handle function will get
+// called when the event is received.
+bool PubsubTask::SubscribeToNode(const std::string& pubsub_node,
+ NodeHandler handler) {
+ subscribed_nodes_[pubsub_node] = handler;
+ rtc::scoped_ptr<buzz::XmlElement> get_iq_request(
+ MakeIq(buzz::STR_GET, pubsub_node_jid_, task_id()));
+ if (!get_iq_request) {
+ return false;
+ }
+ buzz::XmlElement* pubsub_element = new buzz::XmlElement(QN_PUBSUB, true);
+ buzz::XmlElement* items_element = new buzz::XmlElement(QN_PUBSUB_ITEMS, true);
+
+ items_element->AddAttr(buzz::QN_NODE, pubsub_node);
+ pubsub_element->AddElement(items_element);
+ get_iq_request->AddElement(pubsub_element);
+
+ if (SendStanza(get_iq_request.get()) != buzz::XMPP_RETURN_OK) {
+ return false;
+ }
+
+ return true;
+}
+
+void PubsubTask::UnsubscribeFromNode(const std::string& pubsub_node) {
+ subscribed_nodes_.erase(pubsub_node);
+}
+
+void PubsubTask::OnPubsubError(const buzz::XmlElement* error_stanza) {
+}
+
+// Checks for a pubsub event message like the following:
+//
+// <message from="muvc-private-chat-some-id@groupchat.google.com"
+// to="john@site.com/gcomm582B14C9">
+// <event xmlns:"http://jabber.org/protocol/pubsub#event">
+// <items node="node-name">
+// <item id="some-id">
+// <payload/>
+// </item>
+// </items>
+// </event>
+// </message>
+//
+// It also checks for retraction event messages like the following:
+//
+// <message from="muvc-private-chat-some-id@groupchat.google.com"
+// to="john@site.com/gcomm582B14C9">
+// <event xmlns:"http://jabber.org/protocol/pubsub#event">
+// <items node="node-name">
+// <retract id="some-id"/>
+// </items>
+// </event>
+// </message>
+void PubsubTask::HandlePubsubEventMessage(
+ const buzz::XmlElement* pubsub_event) {
+ ASSERT(pubsub_event->Name() == QN_PUBSUB_EVENT);
+ for (const buzz::XmlChild* child = pubsub_event->FirstChild();
+ child != NULL;
+ child = child->NextChild()) {
+ const buzz::XmlElement* child_element = child->AsElement();
+ const buzz::QName& child_name(child_element->Name());
+ if (child_name == QN_PUBSUB_EVENT_ITEMS) {
+ HandlePubsubItems(child_element);
+ }
+ }
+}
+
+// Checks for a response to an pubsub IQ get like the following:
+//
+// <iq from="muvc-private-chat-some-id@groupchat.google.com"
+// to="john@site.com/gcomm582B14C9"
+// type="result">
+// <pubsub xmlns:"http://jabber.org/protocol/pubsub">
+// <items node="node-name">
+// <item id="some-id">
+// <payload/>
+// </item>
+// </items>
+// </event>
+// </message>
+void PubsubTask::HandlePubsubIqGetResponse(
+ const buzz::XmlElement* pubsub_iq_response) {
+ ASSERT(pubsub_iq_response->Name() == QN_PUBSUB);
+ for (const buzz::XmlChild* child = pubsub_iq_response->FirstChild();
+ child != NULL;
+ child = child->NextChild()) {
+ const buzz::XmlElement* child_element = child->AsElement();
+ const buzz::QName& child_name(child_element->Name());
+ if (child_name == QN_PUBSUB_ITEMS) {
+ HandlePubsubItems(child_element);
+ }
+ }
+}
+
+// Calls registered handlers in response to pubsub event or response to
+// IQ pubsub get.
+// 'items' is the child of a pubsub#event:event node or pubsub:pubsub node.
+void PubsubTask::HandlePubsubItems(const buzz::XmlElement* items) {
+ ASSERT(items->HasAttr(QN_NODE));
+ const std::string& node_name(items->Attr(QN_NODE));
+ NodeSubscriptions::iterator iter = subscribed_nodes_.find(node_name);
+ if (iter != subscribed_nodes_.end()) {
+ NodeHandler handler = iter->second;
+ const buzz::XmlElement* item = items->FirstElement();
+ while (item != NULL) {
+ const buzz::QName& item_name(item->Name());
+ if (item_name != QN_PUBSUB_EVENT_ITEM &&
+ item_name != QN_PUBSUB_EVENT_RETRACT &&
+ item_name != QN_PUBSUB_ITEM) {
+ continue;
+ }
+
+ (this->*handler)(item);
+ item = item->NextElement();
+ }
+ return;
+ }
+}
+
+}
diff --git a/libjingle/xmpp/pubsub_task.h b/libjingle/xmpp/pubsub_task.h
new file mode 100644
index 00000000..b1923a0e
--- /dev/null
+++ b/libjingle/xmpp/pubsub_task.h
@@ -0,0 +1,58 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_PUBSUB_TASK_H_
+#define WEBRTC_LIBJINGLE_XMPP_PUBSUB_TASK_H_
+
+#include <map>
+#include <string>
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/jid.h"
+#include "webrtc/libjingle/xmpp/xmpptask.h"
+
+namespace buzz {
+
+// Base class to help write pubsub tasks.
+// In ProcessStart call SubscribeNode with namespaces of interest along with
+// NodeHandlers.
+// When pubsub notifications arrive and matches the namespace, the NodeHandlers
+// will be called back.
+class PubsubTask : public buzz::XmppTask {
+ public:
+ virtual ~PubsubTask();
+
+ protected:
+ typedef void (PubsubTask::*NodeHandler)(const buzz::XmlElement* node);
+
+ PubsubTask(XmppTaskParentInterface* parent, const buzz::Jid& pubsub_node_jid);
+
+ virtual bool HandleStanza(const buzz::XmlElement* stanza);
+ virtual int ProcessResponse();
+
+ bool SubscribeToNode(const std::string& pubsub_node, NodeHandler handler);
+ void UnsubscribeFromNode(const std::string& pubsub_node);
+
+ // Called when there is an error. Derived class can do what it needs to.
+ virtual void OnPubsubError(const buzz::XmlElement* error_stanza);
+
+ private:
+ typedef std::map<std::string, NodeHandler> NodeSubscriptions;
+
+ void HandlePubsubIqGetResponse(const buzz::XmlElement* pubsub_iq_response);
+ void HandlePubsubEventMessage(const buzz::XmlElement* pubsub_event_message);
+ void HandlePubsubItems(const buzz::XmlElement* items);
+
+ buzz::Jid pubsub_node_jid_;
+ NodeSubscriptions subscribed_nodes_;
+};
+
+} // namespace buzz
+
+#endif // WEBRTC_LIBJINGLE_XMPP_PUBSUB_TASK_H_
diff --git a/libjingle/xmpp/pubsubclient.cc b/libjingle/xmpp/pubsubclient.cc
new file mode 100644
index 00000000..41e4e983
--- /dev/null
+++ b/libjingle/xmpp/pubsubclient.cc
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+#include "webrtc/libjingle/xmpp/pubsubclient.h"
+
+#include <string>
+#include <vector>
+
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/jid.h"
+#include "webrtc/libjingle/xmpp/pubsubtasks.h"
+
+namespace buzz {
+
+void PubSubClient::RequestItems() {
+ PubSubRequestTask* request_task =
+ new PubSubRequestTask(parent_, pubsubjid_, node_);
+ request_task->SignalResult.connect(this, &PubSubClient::OnRequestResult);
+ request_task->SignalError.connect(this, &PubSubClient::OnRequestError);
+
+ PubSubReceiveTask* receive_task =
+ new PubSubReceiveTask(parent_, pubsubjid_, node_);
+ receive_task->SignalUpdate.connect(this, &PubSubClient::OnReceiveUpdate);
+
+ receive_task->Start();
+ request_task->Start();
+}
+
+void PubSubClient::PublishItem(
+ const std::string& itemid, XmlElement* payload, std::string* task_id_out) {
+ std::vector<XmlElement*> children;
+ children.push_back(payload);
+ PublishItem(itemid, children, task_id_out);
+}
+
+void PubSubClient::PublishItem(
+ const std::string& itemid, const std::vector<XmlElement*>& children,
+ std::string* task_id_out) {
+ PubSubPublishTask* publish_task =
+ new PubSubPublishTask(parent_, pubsubjid_, node_, itemid, children);
+ publish_task->SignalError.connect(this, &PubSubClient::OnPublishError);
+ publish_task->SignalResult.connect(this, &PubSubClient::OnPublishResult);
+ publish_task->Start();
+ if (task_id_out) {
+ *task_id_out = publish_task->task_id();
+ }
+}
+
+void PubSubClient::RetractItem(
+ const std::string& itemid, std::string* task_id_out) {
+ PubSubRetractTask* retract_task =
+ new PubSubRetractTask(parent_, pubsubjid_, node_, itemid);
+ retract_task->SignalError.connect(this, &PubSubClient::OnRetractError);
+ retract_task->SignalResult.connect(this, &PubSubClient::OnRetractResult);
+ retract_task->Start();
+ if (task_id_out) {
+ *task_id_out = retract_task->task_id();
+ }
+}
+
+void PubSubClient::OnRequestResult(PubSubRequestTask* task,
+ const std::vector<PubSubItem>& items) {
+ SignalItems(this, items);
+}
+
+void PubSubClient::OnRequestError(IqTask* task,
+ const XmlElement* stanza) {
+ SignalRequestError(this, stanza);
+}
+
+void PubSubClient::OnReceiveUpdate(PubSubReceiveTask* task,
+ const std::vector<PubSubItem>& items) {
+ SignalItems(this, items);
+}
+
+const XmlElement* GetItemFromStanza(const XmlElement* stanza) {
+ if (stanza != NULL) {
+ const XmlElement* pubsub = stanza->FirstNamed(QN_PUBSUB);
+ if (pubsub != NULL) {
+ const XmlElement* publish = pubsub->FirstNamed(QN_PUBSUB_PUBLISH);
+ if (publish != NULL) {
+ return publish->FirstNamed(QN_PUBSUB_ITEM);
+ }
+ }
+ }
+ return NULL;
+}
+
+void PubSubClient::OnPublishResult(PubSubPublishTask* task) {
+ const XmlElement* item = GetItemFromStanza(task->stanza());
+ SignalPublishResult(this, task->task_id(), item);
+}
+
+void PubSubClient::OnPublishError(IqTask* task,
+ const XmlElement* error_stanza) {
+ PubSubPublishTask* publish_task =
+ static_cast<PubSubPublishTask*>(task);
+ const XmlElement* item = GetItemFromStanza(publish_task->stanza());
+ SignalPublishError(this, publish_task->task_id(), item, error_stanza);
+}
+
+void PubSubClient::OnRetractResult(PubSubRetractTask* task) {
+ SignalRetractResult(this, task->task_id());
+}
+
+void PubSubClient::OnRetractError(IqTask* task,
+ const XmlElement* stanza) {
+ PubSubRetractTask* retract_task =
+ static_cast<PubSubRetractTask*>(task);
+ SignalRetractError(this, retract_task->task_id(), stanza);
+}
+
+
+const std::string PubSubClient::GetPublisherNickFromPubSubItem(
+ const XmlElement* item_elem) {
+ if (item_elem == NULL) {
+ return "";
+ }
+
+ return Jid(item_elem->Attr(QN_ATTR_PUBLISHER)).resource();
+}
+} // namespace buzz
diff --git a/libjingle/xmpp/pubsubclient.h b/libjingle/xmpp/pubsubclient.h
new file mode 100644
index 00000000..3044b9dc
--- /dev/null
+++ b/libjingle/xmpp/pubsubclient.h
@@ -0,0 +1,111 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_PUBSUBCLIENT_H_
+#define WEBRTC_LIBJINGLE_XMPP_PUBSUBCLIENT_H_
+
+#include <string>
+#include <vector>
+
+#include "webrtc/libjingle/xmpp/jid.h"
+#include "webrtc/libjingle/xmpp/pubsubtasks.h"
+#include "webrtc/base/sigslot.h"
+#include "webrtc/base/sigslotrepeater.h"
+#include "webrtc/base/task.h"
+
+// Easy to use clients built on top of the tasks for XEP-0060
+// (http://xmpp.org/extensions/xep-0060.html).
+
+namespace buzz {
+
+class Jid;
+class XmlElement;
+class XmppTaskParentInterface;
+
+// An easy-to-use pubsub client that handles the three tasks of
+// getting, publishing, and listening for updates. Tied to a specific
+// pubsub jid and node. All you have to do is RequestItems, listen
+// for SignalItems and PublishItems.
+class PubSubClient : public sigslot::has_slots<> {
+ public:
+ PubSubClient(XmppTaskParentInterface* parent,
+ const Jid& pubsubjid,
+ const std::string& node)
+ : parent_(parent),
+ pubsubjid_(pubsubjid),
+ node_(node) {}
+
+ const std::string& node() const { return node_; }
+
+ // Requests the <pubsub><items>, which will be returned via
+ // SignalItems, or SignalRequestError if there is a failure. Should
+ // auto-subscribe.
+ void RequestItems();
+ // Fired when either <pubsub><items> are returned or when
+ // <event><items> are received.
+ sigslot::signal2<PubSubClient*,
+ const std::vector<PubSubItem>&> SignalItems;
+ // Signal (this, error stanza)
+ sigslot::signal2<PubSubClient*,
+ const XmlElement*> SignalRequestError;
+ // Signal (this, task_id, item, error stanza)
+ sigslot::signal4<PubSubClient*,
+ const std::string&,
+ const XmlElement*,
+ const XmlElement*> SignalPublishError;
+ // Signal (this, task_id, item)
+ sigslot::signal3<PubSubClient*,
+ const std::string&,
+ const XmlElement*> SignalPublishResult;
+ // Signal (this, task_id, error stanza)
+ sigslot::signal3<PubSubClient*,
+ const std::string&,
+ const XmlElement*> SignalRetractError;
+ // Signal (this, task_id)
+ sigslot::signal2<PubSubClient*,
+ const std::string&> SignalRetractResult;
+
+ // Publish an item. Takes ownership of payload.
+ void PublishItem(const std::string& itemid,
+ XmlElement* payload,
+ std::string* task_id_out);
+ // Publish an item. Takes ownership of children.
+ void PublishItem(const std::string& itemid,
+ const std::vector<XmlElement*>& children,
+ std::string* task_id_out);
+ // Retract (delete) an item.
+ void RetractItem(const std::string& itemid,
+ std::string* task_id_out);
+
+ // Get the publisher nick if it exists from the pubsub item.
+ const std::string GetPublisherNickFromPubSubItem(const XmlElement* item_elem);
+
+ private:
+ void OnRequestError(IqTask* task,
+ const XmlElement* stanza);
+ void OnRequestResult(PubSubRequestTask* task,
+ const std::vector<PubSubItem>& items);
+ void OnReceiveUpdate(PubSubReceiveTask* task,
+ const std::vector<PubSubItem>& items);
+ void OnPublishResult(PubSubPublishTask* task);
+ void OnPublishError(IqTask* task,
+ const XmlElement* stanza);
+ void OnRetractResult(PubSubRetractTask* task);
+ void OnRetractError(IqTask* task,
+ const XmlElement* stanza);
+
+ XmppTaskParentInterface* parent_;
+ Jid pubsubjid_;
+ std::string node_;
+};
+
+} // namespace buzz
+
+#endif // WEBRTC_LIBJINGLE_XMPP_PUBSUBCLIENT_H_
diff --git a/libjingle/xmpp/pubsubclient_unittest.cc b/libjingle/xmpp/pubsubclient_unittest.cc
new file mode 100644
index 00000000..3815ef8a
--- /dev/null
+++ b/libjingle/xmpp/pubsubclient_unittest.cc
@@ -0,0 +1,278 @@
+/*
+ * 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.
+ */
+
+#include <string>
+
+#include "webrtc/libjingle/xmllite/qname.h"
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/fakexmppclient.h"
+#include "webrtc/libjingle/xmpp/jid.h"
+#include "webrtc/libjingle/xmpp/pubsubclient.h"
+#include "webrtc/base/faketaskrunner.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/sigslot.h"
+
+struct HandledPubSubItem {
+ std::string itemid;
+ std::string payload;
+};
+
+class TestPubSubItemsListener : public sigslot::has_slots<> {
+ public:
+ TestPubSubItemsListener() : error_count(0) {}
+
+ void OnItems(buzz::PubSubClient*,
+ const std::vector<buzz::PubSubItem>& items) {
+ for (std::vector<buzz::PubSubItem>::const_iterator item = items.begin();
+ item != items.end(); ++item) {
+ HandledPubSubItem handled_item;
+ handled_item.itemid = item->itemid;
+ if (item->elem->FirstElement() != NULL) {
+ handled_item.payload = item->elem->FirstElement()->Str();
+ }
+ this->items.push_back(handled_item);
+ }
+ }
+
+ void OnRequestError(buzz::PubSubClient* client,
+ const buzz::XmlElement* stanza) {
+ error_count++;
+ }
+
+ void OnPublishResult(buzz::PubSubClient* client,
+ const std::string& task_id,
+ const buzz::XmlElement* item) {
+ result_task_id = task_id;
+ }
+
+ void OnPublishError(buzz::PubSubClient* client,
+ const std::string& task_id,
+ const buzz::XmlElement* item,
+ const buzz::XmlElement* stanza) {
+ error_count++;
+ error_task_id = task_id;
+ }
+
+ void OnRetractResult(buzz::PubSubClient* client,
+ const std::string& task_id) {
+ result_task_id = task_id;
+ }
+
+ void OnRetractError(buzz::PubSubClient* client,
+ const std::string& task_id,
+ const buzz::XmlElement* stanza) {
+ error_count++;
+ error_task_id = task_id;
+ }
+
+ std::vector<HandledPubSubItem> items;
+ int error_count;
+ std::string error_task_id;
+ std::string result_task_id;
+};
+
+class PubSubClientTest : public testing::Test {
+ public:
+ PubSubClientTest() :
+ pubsubjid("room@domain.com"),
+ node("topic"),
+ itemid("key") {
+ runner.reset(new rtc::FakeTaskRunner());
+ xmpp_client = new buzz::FakeXmppClient(runner.get());
+ client.reset(new buzz::PubSubClient(xmpp_client, pubsubjid, node));
+ listener.reset(new TestPubSubItemsListener());
+ client->SignalItems.connect(
+ listener.get(), &TestPubSubItemsListener::OnItems);
+ client->SignalRequestError.connect(
+ listener.get(), &TestPubSubItemsListener::OnRequestError);
+ client->SignalPublishResult.connect(
+ listener.get(), &TestPubSubItemsListener::OnPublishResult);
+ client->SignalPublishError.connect(
+ listener.get(), &TestPubSubItemsListener::OnPublishError);
+ client->SignalRetractResult.connect(
+ listener.get(), &TestPubSubItemsListener::OnRetractResult);
+ client->SignalRetractError.connect(
+ listener.get(), &TestPubSubItemsListener::OnRetractError);
+ }
+
+ rtc::scoped_ptr<rtc::FakeTaskRunner> runner;
+ // xmpp_client deleted by deleting runner.
+ buzz::FakeXmppClient* xmpp_client;
+ rtc::scoped_ptr<buzz::PubSubClient> client;
+ rtc::scoped_ptr<TestPubSubItemsListener> listener;
+ buzz::Jid pubsubjid;
+ std::string node;
+ std::string itemid;
+};
+
+TEST_F(PubSubClientTest, TestRequest) {
+ client->RequestItems();
+
+ std::string expected_iq =
+ "<cli:iq type=\"get\" to=\"room@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<pub:pubsub xmlns:pub=\"http://jabber.org/protocol/pubsub\">"
+ "<pub:items node=\"topic\"/>"
+ "</pub:pubsub>"
+ "</cli:iq>";
+
+ ASSERT_EQ(1U, xmpp_client->sent_stanzas().size());
+ EXPECT_EQ(expected_iq, xmpp_client->sent_stanzas()[0]->Str());
+
+ std::string result_iq =
+ "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'>"
+ " <pubsub xmlns='http://jabber.org/protocol/pubsub'>"
+ " <items node='topic'>"
+ " <item id='key0'>"
+ " <value0a/>"
+ " </item>"
+ " <item id='key1'>"
+ " <value1a/>"
+ " </item>"
+ " </items>"
+ " </pubsub>"
+ "</iq>";
+
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
+ ASSERT_EQ(2U, listener->items.size());
+ EXPECT_EQ("key0", listener->items[0].itemid);
+ EXPECT_EQ("<pub:value0a xmlns:pub=\"http://jabber.org/protocol/pubsub\"/>",
+ listener->items[0].payload);
+ EXPECT_EQ("key1", listener->items[1].itemid);
+ EXPECT_EQ("<pub:value1a xmlns:pub=\"http://jabber.org/protocol/pubsub\"/>",
+ listener->items[1].payload);
+
+ std::string items_message =
+ "<message xmlns='jabber:client' from='room@domain.com'>"
+ " <event xmlns='http://jabber.org/protocol/pubsub#event'>"
+ " <items node='topic'>"
+ " <item id='key0'>"
+ " <value0b/>"
+ " </item>"
+ " <item id='key1'>"
+ " <value1b/>"
+ " </item>"
+ " </items>"
+ " </event>"
+ "</message>";
+
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(items_message));
+ ASSERT_EQ(4U, listener->items.size());
+ EXPECT_EQ("key0", listener->items[2].itemid);
+ EXPECT_EQ("<eve:value0b"
+ " xmlns:eve=\"http://jabber.org/protocol/pubsub#event\"/>",
+ listener->items[2].payload);
+ EXPECT_EQ("key1", listener->items[3].itemid);
+ EXPECT_EQ("<eve:value1b"
+ " xmlns:eve=\"http://jabber.org/protocol/pubsub#event\"/>",
+ listener->items[3].payload);
+}
+
+TEST_F(PubSubClientTest, TestRequestError) {
+ std::string result_iq =
+ "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'>"
+ " <error type='auth'>"
+ " <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
+ " </error>"
+ "</iq>";
+
+ client->RequestItems();
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
+ EXPECT_EQ(1, listener->error_count);
+}
+
+TEST_F(PubSubClientTest, TestPublish) {
+ buzz::XmlElement* payload =
+ new buzz::XmlElement(buzz::QName(buzz::NS_PUBSUB, "value"));
+
+ std::string task_id;
+ client->PublishItem(itemid, payload, &task_id);
+
+ std::string expected_iq =
+ "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
+ "<publish node=\"topic\">"
+ "<item id=\"key\">"
+ "<value/>"
+ "</item>"
+ "</publish>"
+ "</pubsub>"
+ "</cli:iq>";
+
+ ASSERT_EQ(1U, xmpp_client->sent_stanzas().size());
+ EXPECT_EQ(expected_iq, xmpp_client->sent_stanzas()[0]->Str());
+
+ std::string result_iq =
+ "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'/>";
+
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
+ EXPECT_EQ(task_id, listener->result_task_id);
+}
+
+TEST_F(PubSubClientTest, TestPublishError) {
+ buzz::XmlElement* payload =
+ new buzz::XmlElement(buzz::QName(buzz::NS_PUBSUB, "value"));
+
+ std::string task_id;
+ client->PublishItem(itemid, payload, &task_id);
+
+ std::string result_iq =
+ "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'>"
+ " <error type='auth'>"
+ " <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
+ " </error>"
+ "</iq>";
+
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
+ EXPECT_EQ(1, listener->error_count);
+ EXPECT_EQ(task_id, listener->error_task_id);
+}
+
+TEST_F(PubSubClientTest, TestRetract) {
+ std::string task_id;
+ client->RetractItem(itemid, &task_id);
+
+ std::string expected_iq =
+ "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
+ "<retract node=\"topic\" notify=\"true\">"
+ "<item id=\"key\"/>"
+ "</retract>"
+ "</pubsub>"
+ "</cli:iq>";
+
+ ASSERT_EQ(1U, xmpp_client->sent_stanzas().size());
+ EXPECT_EQ(expected_iq, xmpp_client->sent_stanzas()[0]->Str());
+
+ std::string result_iq =
+ "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'/>";
+
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
+ EXPECT_EQ(task_id, listener->result_task_id);
+}
+
+TEST_F(PubSubClientTest, TestRetractError) {
+ std::string task_id;
+ client->RetractItem(itemid, &task_id);
+
+ std::string result_iq =
+ "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'>"
+ " <error type='auth'>"
+ " <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
+ " </error>"
+ "</iq>";
+
+ xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
+ EXPECT_EQ(1, listener->error_count);
+ EXPECT_EQ(task_id, listener->error_task_id);
+}
diff --git a/libjingle/xmpp/pubsubstateclient.cc b/libjingle/xmpp/pubsubstateclient.cc
new file mode 100644
index 00000000..1fae25df
--- /dev/null
+++ b/libjingle/xmpp/pubsubstateclient.cc
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+#include "webrtc/libjingle/xmpp/pubsubstateclient.h"
+
+namespace buzz {
+
+std::string PublishedNickKeySerializer::GetKey(
+ const std::string& publisher_nick, const std::string& published_nick) {
+ return published_nick;
+}
+
+std::string PublisherAndPublishedNicksKeySerializer::GetKey(
+ const std::string& publisher_nick, const std::string& published_nick) {
+ return publisher_nick + ":" + published_nick;
+}
+
+} // namespace buzz
diff --git a/libjingle/xmpp/pubsubstateclient.h b/libjingle/xmpp/pubsubstateclient.h
new file mode 100644
index 00000000..0c53842a
--- /dev/null
+++ b/libjingle/xmpp/pubsubstateclient.h
@@ -0,0 +1,270 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_PUBSUBSTATECLIENT_H_
+#define WEBRTC_LIBJINGLE_XMPP_PUBSUBSTATECLIENT_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "webrtc/libjingle/xmllite/qname.h"
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/jid.h"
+#include "webrtc/libjingle/xmpp/pubsubclient.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/sigslot.h"
+#include "webrtc/base/sigslotrepeater.h"
+
+namespace buzz {
+
+// To handle retracts correctly, we need to remember certain details
+// about an item. We could just cache the entire XML element, but
+// that would take more memory and require re-parsing.
+struct StateItemInfo {
+ std::string published_nick;
+ std::string publisher_nick;
+};
+
+// Represents a PubSub state change. Usually, the key is the nick,
+// but not always. It's a per-state-type thing. Look below on how keys are
+// computed.
+template <typename C>
+struct PubSubStateChange {
+ // The nick of the user changing the state.
+ std::string publisher_nick;
+ // The nick of the user whose state is changing.
+ std::string published_nick;
+ C old_state;
+ C new_state;
+};
+
+// Knows how to handle specific states and XML.
+template <typename C>
+class PubSubStateSerializer {
+ public:
+ virtual ~PubSubStateSerializer() {}
+ virtual XmlElement* Write(const QName& state_name, const C& state) = 0;
+ virtual void Parse(const XmlElement* state_elem, C* state_out) = 0;
+};
+
+// Knows how to create "keys" for states, which determines their
+// uniqueness. Most states are per-nick, but block is
+// per-blocker-and-blockee. This is independent of itemid, especially
+// in the case of presenter state.
+class PubSubStateKeySerializer {
+ public:
+ virtual ~PubSubStateKeySerializer() {}
+ virtual std::string GetKey(const std::string& publisher_nick,
+ const std::string& published_nick) = 0;
+};
+
+class PublishedNickKeySerializer : public PubSubStateKeySerializer {
+ public:
+ virtual std::string GetKey(const std::string& publisher_nick,
+ const std::string& published_nick);
+};
+
+class PublisherAndPublishedNicksKeySerializer
+ : public PubSubStateKeySerializer {
+ public:
+ virtual std::string GetKey(const std::string& publisher_nick,
+ const std::string& published_nick);
+};
+
+// Adapts PubSubClient to be specifically suited for pub sub call
+// states. Signals state changes and keeps track of keys, which are
+// normally nicks.
+template <typename C>
+class PubSubStateClient : public sigslot::has_slots<> {
+ public:
+ // Gets ownership of the serializers, but not the client.
+ PubSubStateClient(const std::string& publisher_nick,
+ PubSubClient* client,
+ const QName& state_name,
+ C default_state,
+ PubSubStateKeySerializer* key_serializer,
+ PubSubStateSerializer<C>* state_serializer)
+ : publisher_nick_(publisher_nick),
+ client_(client),
+ state_name_(state_name),
+ default_state_(default_state) {
+ key_serializer_.reset(key_serializer);
+ state_serializer_.reset(state_serializer);
+ client_->SignalItems.connect(
+ this, &PubSubStateClient<C>::OnItems);
+ client_->SignalPublishResult.connect(
+ this, &PubSubStateClient<C>::OnPublishResult);
+ client_->SignalPublishError.connect(
+ this, &PubSubStateClient<C>::OnPublishError);
+ client_->SignalRetractResult.connect(
+ this, &PubSubStateClient<C>::OnRetractResult);
+ client_->SignalRetractError.connect(
+ this, &PubSubStateClient<C>::OnRetractError);
+ }
+
+ virtual ~PubSubStateClient() {}
+
+ virtual void Publish(const std::string& published_nick,
+ const C& state,
+ std::string* task_id_out) {
+ std::string key = key_serializer_->GetKey(publisher_nick_, published_nick);
+ std::string itemid = state_name_.LocalPart() + ":" + key;
+ if (StatesEqual(state, default_state_)) {
+ client_->RetractItem(itemid, task_id_out);
+ } else {
+ XmlElement* state_elem = state_serializer_->Write(state_name_, state);
+ state_elem->AddAttr(QN_NICK, published_nick);
+ client_->PublishItem(itemid, state_elem, task_id_out);
+ }
+ }
+
+ sigslot::signal1<const PubSubStateChange<C>&> SignalStateChange;
+ // Signal (task_id, item). item is NULL for retract.
+ sigslot::signal2<const std::string&,
+ const XmlElement*> SignalPublishResult;
+ // Signal (task_id, item, error stanza). item is NULL for retract.
+ sigslot::signal3<const std::string&,
+ const XmlElement*,
+ const XmlElement*> SignalPublishError;
+
+ protected:
+ // return false if retracted item (no info or state given)
+ virtual bool ParseStateItem(const PubSubItem& item,
+ StateItemInfo* info_out,
+ C* state_out) {
+ const XmlElement* state_elem = item.elem->FirstNamed(state_name_);
+ if (state_elem == NULL) {
+ return false;
+ }
+
+ info_out->publisher_nick =
+ client_->GetPublisherNickFromPubSubItem(item.elem);
+ info_out->published_nick = state_elem->Attr(QN_NICK);
+ state_serializer_->Parse(state_elem, state_out);
+ return true;
+ }
+
+ virtual bool StatesEqual(const C& state1, const C& state2) {
+ return state1 == state2;
+ }
+
+ PubSubClient* client() { return client_; }
+ const QName& state_name() { return state_name_; }
+
+ private:
+ void OnItems(PubSubClient* pub_sub_client,
+ const std::vector<PubSubItem>& items) {
+ for (std::vector<PubSubItem>::const_iterator item = items.begin();
+ item != items.end(); ++item) {
+ OnItem(*item);
+ }
+ }
+
+ void OnItem(const PubSubItem& item) {
+ const std::string& itemid = item.itemid;
+ StateItemInfo info;
+ C new_state;
+
+ bool retracted = !ParseStateItem(item, &info, &new_state);
+ if (retracted) {
+ bool known_itemid =
+ (info_by_itemid_.find(itemid) != info_by_itemid_.end());
+ if (!known_itemid) {
+ // Nothing to retract, and nothing to publish.
+ // Probably a different state type.
+ return;
+ } else {
+ info = info_by_itemid_[itemid];
+ info_by_itemid_.erase(itemid);
+ new_state = default_state_;
+ }
+ } else {
+ // TODO: Assert new key matches the known key. It
+ // shouldn't change!
+ info_by_itemid_[itemid] = info;
+ }
+
+ std::string key = key_serializer_->GetKey(
+ info.publisher_nick, info.published_nick);
+ bool has_old_state = (state_by_key_.find(key) != state_by_key_.end());
+ C old_state = has_old_state ? state_by_key_[key] : default_state_;
+ if ((retracted && !has_old_state) || StatesEqual(new_state, old_state)) {
+ // Nothing change, so don't bother signalling.
+ return;
+ }
+
+ if (retracted || StatesEqual(new_state, default_state_)) {
+ // We treat a default state similar to a retract.
+ state_by_key_.erase(key);
+ } else {
+ state_by_key_[key] = new_state;
+ }
+
+ PubSubStateChange<C> change;
+ if (!retracted) {
+ // Retracts do not have publisher information.
+ change.publisher_nick = info.publisher_nick;
+ }
+ change.published_nick = info.published_nick;
+ change.old_state = old_state;
+ change.new_state = new_state;
+ SignalStateChange(change);
+ }
+
+ void OnPublishResult(PubSubClient* pub_sub_client,
+ const std::string& task_id,
+ const XmlElement* item) {
+ SignalPublishResult(task_id, item);
+ }
+
+ void OnPublishError(PubSubClient* pub_sub_client,
+ const std::string& task_id,
+ const buzz::XmlElement* item,
+ const buzz::XmlElement* stanza) {
+ SignalPublishError(task_id, item, stanza);
+ }
+
+ void OnRetractResult(PubSubClient* pub_sub_client,
+ const std::string& task_id) {
+ // There's no point in differentiating between publish and retract
+ // errors, so we simplify by making them both signal a publish
+ // result.
+ const XmlElement* item = NULL;
+ SignalPublishResult(task_id, item);
+ }
+
+ void OnRetractError(PubSubClient* pub_sub_client,
+ const std::string& task_id,
+ const buzz::XmlElement* stanza) {
+ // There's no point in differentiating between publish and retract
+ // errors, so we simplify by making them both signal a publish
+ // error.
+ const XmlElement* item = NULL;
+ SignalPublishError(task_id, item, stanza);
+ }
+
+ std::string publisher_nick_;
+ PubSubClient* client_;
+ const QName state_name_;
+ C default_state_;
+ rtc::scoped_ptr<PubSubStateKeySerializer> key_serializer_;
+ rtc::scoped_ptr<PubSubStateSerializer<C> > state_serializer_;
+ // key => state
+ std::map<std::string, C> state_by_key_;
+ // itemid => StateItemInfo
+ std::map<std::string, StateItemInfo> info_by_itemid_;
+
+ DISALLOW_COPY_AND_ASSIGN(PubSubStateClient);
+};
+} // namespace buzz
+
+#endif // WEBRTC_LIBJINGLE_XMPP_PUBSUBSTATECLIENT_H_
diff --git a/libjingle/xmpp/pubsubtasks.cc b/libjingle/xmpp/pubsubtasks.cc
new file mode 100644
index 00000000..d6532598
--- /dev/null
+++ b/libjingle/xmpp/pubsubtasks.cc
@@ -0,0 +1,204 @@
+/*
+ * 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.
+ */
+
+#include "webrtc/libjingle/xmpp/pubsubtasks.h"
+
+#include <string>
+#include <vector>
+
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/receivetask.h"
+
+// An implementation of the tasks for XEP-0060
+// (http://xmpp.org/extensions/xep-0060.html).
+
+namespace buzz {
+
+namespace {
+
+bool IsPubSubEventItemsElem(const XmlElement* stanza,
+ const std::string& expected_node) {
+ if (stanza->Name() != QN_MESSAGE) {
+ return false;
+ }
+
+ const XmlElement* event_elem = stanza->FirstNamed(QN_PUBSUB_EVENT);
+ if (event_elem == NULL) {
+ return false;
+ }
+
+ const XmlElement* items_elem = event_elem->FirstNamed(QN_PUBSUB_EVENT_ITEMS);
+ if (items_elem == NULL) {
+ return false;
+ }
+
+ const std::string& actual_node = items_elem->Attr(QN_NODE);
+ return (actual_node == expected_node);
+}
+
+
+// Creates <pubsub node="node"><items></pubsub>
+XmlElement* CreatePubSubItemsElem(const std::string& node) {
+ XmlElement* items_elem = new XmlElement(QN_PUBSUB_ITEMS, false);
+ items_elem->AddAttr(QN_NODE, node);
+ XmlElement* pubsub_elem = new XmlElement(QN_PUBSUB, false);
+ pubsub_elem->AddElement(items_elem);
+ return pubsub_elem;
+}
+
+// Creates <pubsub node="node"><publish><item id="itemid">payload</item>...
+// Takes ownership of payload.
+XmlElement* CreatePubSubPublishItemElem(
+ const std::string& node,
+ const std::string& itemid,
+ const std::vector<XmlElement*>& children) {
+ XmlElement* pubsub_elem = new XmlElement(QN_PUBSUB, true);
+ XmlElement* publish_elem = new XmlElement(QN_PUBSUB_PUBLISH, false);
+ publish_elem->AddAttr(QN_NODE, node);
+ XmlElement* item_elem = new XmlElement(QN_PUBSUB_ITEM, false);
+ item_elem->AddAttr(QN_ID, itemid);
+ for (std::vector<XmlElement*>::const_iterator child = children.begin();
+ child != children.end(); ++child) {
+ item_elem->AddElement(*child);
+ }
+ publish_elem->AddElement(item_elem);
+ pubsub_elem->AddElement(publish_elem);
+ return pubsub_elem;
+}
+
+// Creates <pubsub node="node"><publish><item id="itemid">payload</item>...
+// Takes ownership of payload.
+XmlElement* CreatePubSubRetractItemElem(const std::string& node,
+ const std::string& itemid) {
+ XmlElement* pubsub_elem = new XmlElement(QN_PUBSUB, true);
+ XmlElement* retract_elem = new XmlElement(QN_PUBSUB_RETRACT, false);
+ retract_elem->AddAttr(QN_NODE, node);
+ retract_elem->AddAttr(QN_NOTIFY, "true");
+ XmlElement* item_elem = new XmlElement(QN_PUBSUB_ITEM, false);
+ item_elem->AddAttr(QN_ID, itemid);
+ retract_elem->AddElement(item_elem);
+ pubsub_elem->AddElement(retract_elem);
+ return pubsub_elem;
+}
+
+void ParseItem(const XmlElement* item_elem,
+ std::vector<PubSubItem>* items) {
+ PubSubItem item;
+ item.itemid = item_elem->Attr(QN_ID);
+ item.elem = item_elem;
+ items->push_back(item);
+}
+
+// Right now, <retract>s are treated the same as items with empty
+// payloads. We may want to change it in the future, but right now
+// it's sufficient for our needs.
+void ParseRetract(const XmlElement* retract_elem,
+ std::vector<PubSubItem>* items) {
+ ParseItem(retract_elem, items);
+}
+
+void ParseEventItemsElem(const XmlElement* stanza,
+ std::vector<PubSubItem>* items) {
+ const XmlElement* event_elem = stanza->FirstNamed(QN_PUBSUB_EVENT);
+ if (event_elem != NULL) {
+ const XmlElement* items_elem =
+ event_elem->FirstNamed(QN_PUBSUB_EVENT_ITEMS);
+ if (items_elem != NULL) {
+ for (const XmlElement* item_elem =
+ items_elem->FirstNamed(QN_PUBSUB_EVENT_ITEM);
+ item_elem != NULL;
+ item_elem = item_elem->NextNamed(QN_PUBSUB_EVENT_ITEM)) {
+ ParseItem(item_elem, items);
+ }
+ for (const XmlElement* retract_elem =
+ items_elem->FirstNamed(QN_PUBSUB_EVENT_RETRACT);
+ retract_elem != NULL;
+ retract_elem = retract_elem->NextNamed(QN_PUBSUB_EVENT_RETRACT)) {
+ ParseRetract(retract_elem, items);
+ }
+ }
+ }
+}
+
+void ParsePubSubItemsElem(const XmlElement* stanza,
+ std::vector<PubSubItem>* items) {
+ const XmlElement* pubsub_elem = stanza->FirstNamed(QN_PUBSUB);
+ if (pubsub_elem != NULL) {
+ const XmlElement* items_elem = pubsub_elem->FirstNamed(QN_PUBSUB_ITEMS);
+ if (items_elem != NULL) {
+ for (const XmlElement* item_elem = items_elem->FirstNamed(QN_PUBSUB_ITEM);
+ item_elem != NULL;
+ item_elem = item_elem->NextNamed(QN_PUBSUB_ITEM)) {
+ ParseItem(item_elem, items);
+ }
+ }
+ }
+}
+
+} // namespace
+
+PubSubRequestTask::PubSubRequestTask(XmppTaskParentInterface* parent,
+ const Jid& pubsubjid,
+ const std::string& node)
+ : IqTask(parent, STR_GET, pubsubjid, CreatePubSubItemsElem(node)) {
+}
+
+void PubSubRequestTask::HandleResult(const XmlElement* stanza) {
+ std::vector<PubSubItem> items;
+ ParsePubSubItemsElem(stanza, &items);
+ SignalResult(this, items);
+}
+
+int PubSubReceiveTask::ProcessStart() {
+ if (SignalUpdate.is_empty()) {
+ return STATE_DONE;
+ }
+ return ReceiveTask::ProcessStart();
+}
+
+bool PubSubReceiveTask::WantsStanza(const XmlElement* stanza) {
+ return MatchStanzaFrom(stanza, pubsubjid_) &&
+ IsPubSubEventItemsElem(stanza, node_) && !SignalUpdate.is_empty();
+}
+
+void PubSubReceiveTask::ReceiveStanza(const XmlElement* stanza) {
+ std::vector<PubSubItem> items;
+ ParseEventItemsElem(stanza, &items);
+ SignalUpdate(this, items);
+}
+
+PubSubPublishTask::PubSubPublishTask(XmppTaskParentInterface* parent,
+ const Jid& pubsubjid,
+ const std::string& node,
+ const std::string& itemid,
+ const std::vector<XmlElement*>& children)
+ : IqTask(parent, STR_SET, pubsubjid,
+ CreatePubSubPublishItemElem(node, itemid, children)),
+ itemid_(itemid) {
+}
+
+void PubSubPublishTask::HandleResult(const XmlElement* stanza) {
+ SignalResult(this);
+}
+
+PubSubRetractTask::PubSubRetractTask(XmppTaskParentInterface* parent,
+ const Jid& pubsubjid,
+ const std::string& node,
+ const std::string& itemid)
+ : IqTask(parent, STR_SET, pubsubjid,
+ CreatePubSubRetractItemElem(node, itemid)),
+ itemid_(itemid) {
+}
+
+void PubSubRetractTask::HandleResult(const XmlElement* stanza) {
+ SignalResult(this);
+}
+
+} // namespace buzz
diff --git a/libjingle/xmpp/pubsubtasks.h b/libjingle/xmpp/pubsubtasks.h
new file mode 100644
index 00000000..2f56fa87
--- /dev/null
+++ b/libjingle/xmpp/pubsubtasks.h
@@ -0,0 +1,114 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_PUBSUBTASKS_H_
+#define WEBRTC_LIBJINGLE_XMPP_PUBSUBTASKS_H_
+
+#include <vector>
+
+#include "webrtc/libjingle/xmpp/iqtask.h"
+#include "webrtc/libjingle/xmpp/receivetask.h"
+#include "webrtc/base/sigslot.h"
+
+namespace buzz {
+
+// A PubSub itemid + payload. Useful for signaling items.
+struct PubSubItem {
+ std::string itemid;
+ // The entire <item>, owned by the stanza handler. To keep a
+ // reference after handling, make a copy.
+ const XmlElement* elem;
+};
+
+// An IqTask which gets a <pubsub><items> for a particular jid and
+// node, parses the items in the response and signals the items.
+class PubSubRequestTask : public IqTask {
+ public:
+ PubSubRequestTask(XmppTaskParentInterface* parent,
+ const Jid& pubsubjid,
+ const std::string& node);
+
+ sigslot::signal2<PubSubRequestTask*,
+ const std::vector<PubSubItem>&> SignalResult;
+ // SignalError inherited by IqTask.
+ private:
+ virtual void HandleResult(const XmlElement* stanza);
+};
+
+// A ReceiveTask which listens for <event><items> of a particular
+// pubsub JID and node and then signals them items.
+class PubSubReceiveTask : public ReceiveTask {
+ public:
+ PubSubReceiveTask(XmppTaskParentInterface* parent,
+ const Jid& pubsubjid,
+ const std::string& node)
+ : ReceiveTask(parent),
+ pubsubjid_(pubsubjid),
+ node_(node) {
+ }
+
+ virtual int ProcessStart();
+ sigslot::signal2<PubSubReceiveTask*,
+ const std::vector<PubSubItem>&> SignalUpdate;
+
+ protected:
+ virtual bool WantsStanza(const XmlElement* stanza);
+ virtual void ReceiveStanza(const XmlElement* stanza);
+
+ private:
+ Jid pubsubjid_;
+ std::string node_;
+};
+
+// An IqTask which publishes a <pubsub><publish><item> to a particular
+// pubsub jid and node.
+class PubSubPublishTask : public IqTask {
+ public:
+ // Takes ownership of children
+ PubSubPublishTask(XmppTaskParentInterface* parent,
+ const Jid& pubsubjid,
+ const std::string& node,
+ const std::string& itemid,
+ const std::vector<XmlElement*>& children);
+
+ const std::string& itemid() const { return itemid_; }
+
+ sigslot::signal1<PubSubPublishTask*> SignalResult;
+
+ private:
+ // SignalError inherited by IqTask.
+ virtual void HandleResult(const XmlElement* stanza);
+
+ std::string itemid_;
+};
+
+// An IqTask which publishes a <pubsub><publish><retract> to a particular
+// pubsub jid and node.
+class PubSubRetractTask : public IqTask {
+ public:
+ PubSubRetractTask(XmppTaskParentInterface* parent,
+ const Jid& pubsubjid,
+ const std::string& node,
+ const std::string& itemid);
+
+ const std::string& itemid() const { return itemid_; }
+
+ sigslot::signal1<PubSubRetractTask*> SignalResult;
+
+ private:
+ // SignalError inherited by IqTask.
+ virtual void HandleResult(const XmlElement* stanza);
+
+ std::string itemid_;
+};
+
+} // namespace buzz
+
+#endif // WEBRTC_LIBJINGLE_XMPP_PUBSUBTASKS_H_
diff --git a/libjingle/xmpp/pubsubtasks_unittest.cc b/libjingle/xmpp/pubsubtasks_unittest.cc
new file mode 100644
index 00000000..8062e58e
--- /dev/null
+++ b/libjingle/xmpp/pubsubtasks_unittest.cc
@@ -0,0 +1,280 @@
+/*
+ * 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.
+ */
+
+#include <string>
+
+#include "webrtc/libjingle/xmllite/qname.h"
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/fakexmppclient.h"
+#include "webrtc/libjingle/xmpp/iqtask.h"
+#include "webrtc/libjingle/xmpp/jid.h"
+#include "webrtc/libjingle/xmpp/pubsubtasks.h"
+#include "webrtc/base/faketaskrunner.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/sigslot.h"
+
+struct HandledPubSubItem {
+ std::string itemid;
+ std::string payload;
+};
+
+class TestPubSubTasksListener : public sigslot::has_slots<> {
+ public:
+ TestPubSubTasksListener() : result_count(0), error_count(0) {}
+
+ void OnReceiveUpdate(buzz::PubSubReceiveTask* task,
+ const std::vector<buzz::PubSubItem>& items) {
+ OnItems(items);
+ }
+
+ void OnRequestResult(buzz::PubSubRequestTask* task,
+ const std::vector<buzz::PubSubItem>& items) {
+ OnItems(items);
+ }
+
+ void OnItems(const std::vector<buzz::PubSubItem>& items) {
+ for (std::vector<buzz::PubSubItem>::const_iterator item = items.begin();
+ item != items.end(); ++item) {
+ HandledPubSubItem handled_item;
+ handled_item.itemid = item->itemid;
+ if (item->elem->FirstElement() != NULL) {
+ handled_item.payload = item->elem->FirstElement()->Str();
+ }
+ this->items.push_back(handled_item);
+ }
+ }
+
+ void OnPublishResult(buzz::PubSubPublishTask* task) {
+ ++result_count;
+ }
+
+ void OnRetractResult(buzz::PubSubRetractTask* task) {
+ ++result_count;
+ }
+
+ void OnError(buzz::IqTask* task, const buzz::XmlElement* stanza) {
+ ++error_count;
+ }
+
+ std::vector<HandledPubSubItem> items;
+ int result_count;
+ int error_count;
+};
+
+class PubSubTasksTest : public testing::Test {
+ public:
+ PubSubTasksTest() :
+ pubsubjid("room@domain.com"),
+ node("topic"),
+ itemid("key") {
+ runner.reset(new rtc::FakeTaskRunner());
+ client = new buzz::FakeXmppClient(runner.get());
+ listener.reset(new TestPubSubTasksListener());
+ }
+
+ rtc::scoped_ptr<rtc::FakeTaskRunner> runner;
+ // Client deleted by deleting runner.
+ buzz::FakeXmppClient* client;
+ rtc::scoped_ptr<TestPubSubTasksListener> listener;
+ buzz::Jid pubsubjid;
+ std::string node;
+ std::string itemid;
+};
+
+TEST_F(PubSubTasksTest, TestRequest) {
+ buzz::PubSubRequestTask* task =
+ new buzz::PubSubRequestTask(client, pubsubjid, node);
+ task->SignalResult.connect(
+ listener.get(), &TestPubSubTasksListener::OnRequestResult);
+ task->Start();
+
+ std::string expected_iq =
+ "<cli:iq type=\"get\" to=\"room@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<pub:pubsub xmlns:pub=\"http://jabber.org/protocol/pubsub\">"
+ "<pub:items node=\"topic\"/>"
+ "</pub:pubsub>"
+ "</cli:iq>";
+
+ ASSERT_EQ(1U, client->sent_stanzas().size());
+ EXPECT_EQ(expected_iq, client->sent_stanzas()[0]->Str());
+
+ std::string result_iq =
+ "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'>"
+ " <pubsub xmlns='http://jabber.org/protocol/pubsub'>"
+ " <items node='topic'>"
+ " <item id='key0'>"
+ " <value0/>"
+ " </item>"
+ " <item id='key1'>"
+ " <value1/>"
+ " </item>"
+ " </items>"
+ " </pubsub>"
+ "</iq>";
+
+ client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
+
+ ASSERT_EQ(2U, listener->items.size());
+ EXPECT_EQ("key0", listener->items[0].itemid);
+ EXPECT_EQ("<pub:value0 xmlns:pub=\"http://jabber.org/protocol/pubsub\"/>",
+ listener->items[0].payload);
+ EXPECT_EQ("key1", listener->items[1].itemid);
+ EXPECT_EQ("<pub:value1 xmlns:pub=\"http://jabber.org/protocol/pubsub\"/>",
+ listener->items[1].payload);
+}
+
+TEST_F(PubSubTasksTest, TestRequestError) {
+ std::string result_iq =
+ "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'>"
+ " <error type='auth'>"
+ " <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
+ " </error>"
+ "</iq>";
+
+ buzz::PubSubRequestTask* task =
+ new buzz::PubSubRequestTask(client, pubsubjid, node);
+ task->SignalResult.connect(
+ listener.get(), &TestPubSubTasksListener::OnRequestResult);
+ task->SignalError.connect(
+ listener.get(), &TestPubSubTasksListener::OnError);
+ task->Start();
+ client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
+
+ EXPECT_EQ(0, listener->result_count);
+ EXPECT_EQ(1, listener->error_count);
+}
+
+TEST_F(PubSubTasksTest, TestReceive) {
+ std::string items_message =
+ "<message xmlns='jabber:client' from='room@domain.com'>"
+ " <event xmlns='http://jabber.org/protocol/pubsub#event'>"
+ " <items node='topic'>"
+ " <item id='key0'>"
+ " <value0/>"
+ " </item>"
+ " <item id='key1'>"
+ " <value1/>"
+ " </item>"
+ " </items>"
+ " </event>"
+ "</message>";
+
+ buzz::PubSubReceiveTask* task =
+ new buzz::PubSubReceiveTask(client, pubsubjid, node);
+ task->SignalUpdate.connect(
+ listener.get(), &TestPubSubTasksListener::OnReceiveUpdate);
+ task->Start();
+ client->HandleStanza(buzz::XmlElement::ForStr(items_message));
+
+ ASSERT_EQ(2U, listener->items.size());
+ EXPECT_EQ("key0", listener->items[0].itemid);
+ EXPECT_EQ(
+ "<eve:value0 xmlns:eve=\"http://jabber.org/protocol/pubsub#event\"/>",
+ listener->items[0].payload);
+ EXPECT_EQ("key1", listener->items[1].itemid);
+ EXPECT_EQ(
+ "<eve:value1 xmlns:eve=\"http://jabber.org/protocol/pubsub#event\"/>",
+ listener->items[1].payload);
+}
+
+TEST_F(PubSubTasksTest, TestPublish) {
+ buzz::XmlElement* payload =
+ new buzz::XmlElement(buzz::QName(buzz::NS_PUBSUB, "value"));
+ std::string expected_iq =
+ "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
+ "<publish node=\"topic\">"
+ "<item id=\"key\">"
+ "<value/>"
+ "</item>"
+ "</publish>"
+ "</pubsub>"
+ "</cli:iq>";
+
+ std::vector<buzz::XmlElement*> children;
+ children.push_back(payload);
+ buzz::PubSubPublishTask* task =
+ new buzz::PubSubPublishTask(client, pubsubjid, node, itemid, children);
+ task->SignalResult.connect(
+ listener.get(), &TestPubSubTasksListener::OnPublishResult);
+ task->Start();
+
+ ASSERT_EQ(1U, client->sent_stanzas().size());
+ EXPECT_EQ(expected_iq, client->sent_stanzas()[0]->Str());
+
+ std::string result_iq =
+ "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'/>";
+
+ client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
+
+ EXPECT_EQ(1, listener->result_count);
+ EXPECT_EQ(0, listener->error_count);
+}
+
+TEST_F(PubSubTasksTest, TestPublishError) {
+ buzz::XmlElement* payload =
+ new buzz::XmlElement(buzz::QName(buzz::NS_PUBSUB, "value"));
+
+ std::vector<buzz::XmlElement*> children;
+ children.push_back(payload);
+ buzz::PubSubPublishTask* task =
+ new buzz::PubSubPublishTask(client, pubsubjid, node, itemid, children);
+ task->SignalResult.connect(
+ listener.get(), &TestPubSubTasksListener::OnPublishResult);
+ task->SignalError.connect(
+ listener.get(), &TestPubSubTasksListener::OnError);
+ task->Start();
+
+ std::string result_iq =
+ "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'>"
+ " <error type='auth'>"
+ " <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
+ " </error>"
+ "</iq>";
+
+ client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
+
+ EXPECT_EQ(0, listener->result_count);
+ EXPECT_EQ(1, listener->error_count);
+}
+
+TEST_F(PubSubTasksTest, TestRetract) {
+ buzz::PubSubRetractTask* task =
+ new buzz::PubSubRetractTask(client, pubsubjid, node, itemid);
+ task->SignalResult.connect(
+ listener.get(), &TestPubSubTasksListener::OnRetractResult);
+ task->SignalError.connect(
+ listener.get(), &TestPubSubTasksListener::OnError);
+ task->Start();
+
+ std::string expected_iq =
+ "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
+ "<retract node=\"topic\" notify=\"true\">"
+ "<item id=\"key\"/>"
+ "</retract>"
+ "</pubsub>"
+ "</cli:iq>";
+
+ ASSERT_EQ(1U, client->sent_stanzas().size());
+ EXPECT_EQ(expected_iq, client->sent_stanzas()[0]->Str());
+
+ std::string result_iq =
+ "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'/>";
+
+ client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
+
+ EXPECT_EQ(1, listener->result_count);
+ EXPECT_EQ(0, listener->error_count);
+}
diff --git a/libjingle/xmpp/receivetask.cc b/libjingle/xmpp/receivetask.cc
new file mode 100644
index 00000000..9d4687cf
--- /dev/null
+++ b/libjingle/xmpp/receivetask.cc
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/receivetask.h"
+
+namespace buzz {
+
+bool ReceiveTask::HandleStanza(const XmlElement* stanza) {
+ if (WantsStanza(stanza)) {
+ QueueStanza(stanza);
+ return true;
+ }
+
+ return false;
+}
+
+int ReceiveTask::ProcessStart() {
+ const XmlElement* stanza = NextStanza();
+ if (stanza == NULL)
+ return STATE_BLOCKED;
+
+ ReceiveStanza(stanza);
+ return STATE_START;
+}
+
+} // namespace buzz
diff --git a/libjingle/xmpp/receivetask.h b/libjingle/xmpp/receivetask.h
new file mode 100644
index 00000000..b776746b
--- /dev/null
+++ b/libjingle/xmpp/receivetask.h
@@ -0,0 +1,41 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_RECEIVETASK_H_
+#define WEBRTC_LIBJINGLE_XMPP_RECEIVETASK_H_
+
+#include "webrtc/libjingle/xmpp/xmpptask.h"
+
+namespace buzz {
+
+// A base class for receiving stanzas. Override WantsStanza to
+// indicate that a stanza should be received and ReceiveStanza to
+// process it. Once started, ReceiveStanza will be called for all
+// stanzas that return true when passed to WantsStanza. This saves
+// you from having to remember how to setup the queueing and the task
+// states, etc.
+class ReceiveTask : public XmppTask {
+ public:
+ explicit ReceiveTask(XmppTaskParentInterface* parent) :
+ XmppTask(parent, XmppEngine::HL_TYPE) {}
+ virtual int ProcessStart();
+
+ protected:
+ virtual bool HandleStanza(const XmlElement* stanza);
+
+ // Return true if the stanza should be received.
+ virtual bool WantsStanza(const XmlElement* stanza) = 0;
+ // Process the received stanza.
+ virtual void ReceiveStanza(const XmlElement* stanza) = 0;
+};
+
+} // namespace buzz
+
+#endif // WEBRTC_LIBJINGLE_XMPP_RECEIVETASK_H_
diff --git a/libjingle/xmpp/rostermodule.h b/libjingle/xmpp/rostermodule.h
new file mode 100644
index 00000000..85d5d344
--- /dev/null
+++ b/libjingle/xmpp/rostermodule.h
@@ -0,0 +1,331 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_ROSTERMODULE_H_
+#define WEBRTC_LIBJINGLE_XMPP_ROSTERMODULE_H_
+
+#include "webrtc/libjingle/xmpp/module.h"
+
+namespace buzz {
+
+class XmppRosterModule;
+
+// The main way you initialize and use the module would be like this:
+// XmppRosterModule *roster_module = XmppRosterModule::Create();
+// roster_module->RegisterEngine(engine);
+// roster_module->BroadcastPresence();
+// roster_module->RequestRosterUpdate();
+
+//! This enum captures the valid values for the show attribute in a presence
+//! stanza
+enum XmppPresenceShow
+{
+ XMPP_PRESENCE_CHAT = 0,
+ XMPP_PRESENCE_DEFAULT = 1,
+ XMPP_PRESENCE_AWAY = 2,
+ XMPP_PRESENCE_XA = 3,
+ XMPP_PRESENCE_DND = 4,
+};
+
+//! These are the valid subscription states in a roster contact. This
+//! represents the combination of the subscription and ask attributes
+enum XmppSubscriptionState
+{
+ XMPP_SUBSCRIPTION_NONE = 0,
+ XMPP_SUBSCRIPTION_NONE_ASKED = 1,
+ XMPP_SUBSCRIPTION_TO = 2,
+ XMPP_SUBSCRIPTION_FROM = 3,
+ XMPP_SUBSCRIPTION_FROM_ASKED = 4,
+ XMPP_SUBSCRIPTION_BOTH = 5,
+};
+
+//! These represent the valid types of presence stanzas for managing
+//! subscriptions
+enum XmppSubscriptionRequestType
+{
+ XMPP_REQUEST_SUBSCRIBE = 0,
+ XMPP_REQUEST_UNSUBSCRIBE = 1,
+ XMPP_REQUEST_SUBSCRIBED = 2,
+ XMPP_REQUEST_UNSUBSCRIBED = 3,
+};
+
+enum XmppPresenceAvailable {
+ XMPP_PRESENCE_UNAVAILABLE = 0,
+ XMPP_PRESENCE_AVAILABLE = 1,
+ XMPP_PRESENCE_ERROR = 2,
+};
+
+enum XmppPresenceConnectionStatus {
+ XMPP_CONNECTION_STATUS_UNKNOWN = 0,
+ // Status set by the server while the user is being rung.
+ XMPP_CONNECTION_STATUS_CONNECTING = 1,
+ // Status set by the client when the user has accepted the ring but before
+ // the client has joined the call.
+ XMPP_CONNECTION_STATUS_JOINING = 2,
+ // Status set by the client as part of joining the call.
+ XMPP_CONNECTION_STATUS_CONNECTED = 3,
+ XMPP_CONNECTION_STATUS_HANGUP = 4,
+};
+
+//! Presence Information
+//! This class stores both presence information for outgoing presence and is
+//! returned by methods in XmppRosterModule to represent recieved incoming
+//! presence information. When this class is writeable (non-const) then each
+//! update to any property will set the inner xml. Setting the raw_xml will
+//! rederive all of the other properties.
+class XmppPresence {
+public:
+ virtual ~XmppPresence() {}
+
+ //! Create a new Presence
+ //! This is typically only used when sending a directed presence
+ static XmppPresence* Create();
+
+ //! The Jid of for the presence information.
+ //! Typically this will be a full Jid with resource specified.
+ virtual const Jid jid() const = 0;
+
+ //! Is the contact available?
+ virtual XmppPresenceAvailable available() const = 0;
+
+ //! Sets if the user is available or not
+ virtual XmppReturnStatus set_available(XmppPresenceAvailable available) = 0;
+
+ //! The show value of the presence info
+ virtual XmppPresenceShow presence_show() const = 0;
+
+ //! Set the presence show value
+ virtual XmppReturnStatus set_presence_show(XmppPresenceShow show) = 0;
+
+ //! The Priority of the presence info
+ virtual int priority() const = 0;
+
+ //! Set the priority of the presence
+ virtual XmppReturnStatus set_priority(int priority) = 0;
+
+ //! The plain text status of the presence info.
+ //! If there are multiple status because of language, this will either be a
+ //! status that is not tagged for language or the first available
+ virtual const std::string status() const = 0;
+
+ //! Sets the status for the presence info.
+ //! If there is more than one status present already then this will remove
+ //! them all and replace it with one status element we no specified language
+ virtual XmppReturnStatus set_status(const std::string& status) = 0;
+
+ //! The connection status
+ virtual XmppPresenceConnectionStatus connection_status() const = 0;
+
+ //! The focus obfuscated GAIA id
+ virtual const std::string google_user_id() const = 0;
+
+ //! The nickname in the presence
+ virtual const std::string nickname() const = 0;
+
+ //! The raw xml of the presence update
+ virtual const XmlElement* raw_xml() const = 0;
+
+ //! Sets the raw presence stanza for the presence update
+ //! This will cause all other data items in this structure to be rederived
+ virtual XmppReturnStatus set_raw_xml(const XmlElement * xml) = 0;
+};
+
+//! A contact as given by the server
+class XmppRosterContact {
+public:
+ virtual ~XmppRosterContact() {}
+
+ //! Create a new roster contact
+ //! This is typically only used when doing a roster update/add
+ static XmppRosterContact* Create();
+
+ //! The jid for the contact.
+ //! Typically this will be a bare Jid.
+ virtual const Jid jid() const = 0;
+
+ //! Sets the jid for the roster contact update
+ virtual XmppReturnStatus set_jid(const Jid& jid) = 0;
+
+ //! The name (nickname) stored for this contact
+ virtual const std::string name() const = 0;
+
+ //! Sets the name
+ virtual XmppReturnStatus set_name(const std::string& name) = 0;
+
+ //! The Presence subscription state stored on the server for this contact
+ //! This is never settable and will be ignored when generating a roster
+ //! add/update request
+ virtual XmppSubscriptionState subscription_state() const = 0;
+
+ //! The number of Groups applied to this contact
+ virtual size_t GetGroupCount() const = 0;
+
+ //! Gets a Group applied to the contact based on index.
+ //! range
+ virtual const std::string GetGroup(size_t index) const = 0;
+
+ //! Adds a group to this contact.
+ //! This will return a bad argument error if the group is already there.
+ virtual XmppReturnStatus AddGroup(const std::string& group) = 0;
+
+ //! Removes a group from the contact.
+ //! This will return an error if the group cannot be found in the group list.
+ virtual XmppReturnStatus RemoveGroup(const std::string& group) = 0;
+
+ //! The raw xml for this roster contact
+ virtual const XmlElement* raw_xml() const = 0;
+
+ //! Sets the raw presence stanza for the contact update/add
+ //! This will cause all other data items in this structure to be rederived
+ virtual XmppReturnStatus set_raw_xml(const XmlElement * xml) = 0;
+};
+
+//! The XmppRosterHandler is an interface for callbacks from the module
+class XmppRosterHandler {
+public:
+ virtual ~XmppRosterHandler() {}
+
+ //! A request for a subscription has come in.
+ //! Typically, the UI will ask the user if it is okay to let the requester
+ //! get presence notifications for the user. The response is send back
+ //! by calling ApproveSubscriber or CancelSubscriber.
+ virtual void SubscriptionRequest(XmppRosterModule* roster,
+ const Jid& requesting_jid,
+ XmppSubscriptionRequestType type,
+ const XmlElement* raw_xml) = 0;
+
+ //! Some type of presence error has occured
+ virtual void SubscriptionError(XmppRosterModule* roster,
+ const Jid& from,
+ const XmlElement* raw_xml) = 0;
+
+ virtual void RosterError(XmppRosterModule* roster,
+ const XmlElement* raw_xml) = 0;
+
+ //! New presence information has come in
+ //! The user is notified with the presence object directly. This info is also
+ //! added to the store accessable from the engine.
+ virtual void IncomingPresenceChanged(XmppRosterModule* roster,
+ const XmppPresence* presence) = 0;
+
+ //! A contact has changed
+ //! This indicates that the data for a contact may have changed. No
+ //! contacts have been added or removed.
+ virtual void ContactChanged(XmppRosterModule* roster,
+ const XmppRosterContact* old_contact,
+ size_t index) = 0;
+
+ //! A set of contacts have been added
+ //! These contacts may have been added in response to the original roster
+ //! request or due to a "roster push" from the server.
+ virtual void ContactsAdded(XmppRosterModule* roster,
+ size_t index, size_t number) = 0;
+
+ //! A contact has been removed
+ //! This contact has been removed form the list.
+ virtual void ContactRemoved(XmppRosterModule* roster,
+ const XmppRosterContact* removed_contact,
+ size_t index) = 0;
+
+};
+
+//! An XmppModule for handle roster and presence functionality
+class XmppRosterModule : public XmppModule {
+public:
+ //! Creates a new XmppRosterModule
+ static XmppRosterModule * Create();
+ virtual ~XmppRosterModule() {}
+
+ //! Sets the roster handler (callbacks) for the module
+ virtual XmppReturnStatus set_roster_handler(XmppRosterHandler * handler) = 0;
+
+ //! Gets the roster handler for the module
+ virtual XmppRosterHandler* roster_handler() = 0;
+
+ // USER PRESENCE STATE -------------------------------------------------------
+
+ //! Gets the aggregate outgoing presence
+ //! This object is non-const and be edited directly. No update is sent
+ //! to the server until a Broadcast is sent
+ virtual XmppPresence* outgoing_presence() = 0;
+
+ //! Broadcasts that the user is available.
+ //! Nothing with respect to presence is sent until this is called.
+ virtual XmppReturnStatus BroadcastPresence() = 0;
+
+ //! Sends a directed presence to a Jid
+ //! Note that the client doesn't store where directed presence notifications
+ //! have been sent. The server can keep the appropriate state
+ virtual XmppReturnStatus SendDirectedPresence(const XmppPresence* presence,
+ const Jid& to_jid) = 0;
+
+ // INCOMING PRESENCE STATUS --------------------------------------------------
+
+ //! Returns the number of incoming presence data recorded
+ virtual size_t GetIncomingPresenceCount() = 0;
+
+ //! Returns an incoming presence datum based on index
+ virtual const XmppPresence* GetIncomingPresence(size_t index) = 0;
+
+ //! Gets the number of presence data for a bare Jid
+ //! There may be a datum per resource
+ virtual size_t GetIncomingPresenceForJidCount(const Jid& jid) = 0;
+
+ //! Returns a single presence data for a Jid based on index
+ virtual const XmppPresence* GetIncomingPresenceForJid(const Jid& jid,
+ size_t index) = 0;
+
+ // ROSTER MANAGEMENT ---------------------------------------------------------
+
+ //! Requests an update of the roster from the server
+ //! This must be called to initialize the client side cache of the roster
+ //! After this is sent the server should keep this module apprised of any
+ //! changes.
+ virtual XmppReturnStatus RequestRosterUpdate() = 0;
+
+ //! Returns the number of contacts in the roster
+ virtual size_t GetRosterContactCount() = 0;
+
+ //! Returns a contact by index
+ virtual const XmppRosterContact* GetRosterContact(size_t index) = 0;
+
+ //! Finds a contact by Jid
+ virtual const XmppRosterContact* FindRosterContact(const Jid& jid) = 0;
+
+ //! Send a request to the server to add a contact
+ //! Note that the contact won't show up in the roster until the server can
+ //! respond. This happens async when the socket is being serviced
+ virtual XmppReturnStatus RequestRosterChange(
+ const XmppRosterContact* contact) = 0;
+
+ //! Request that the server remove a contact
+ //! The jabber protocol specifies that the server should also cancel any
+ //! subscriptions when this is done. Like adding, this contact won't be
+ //! removed until the server responds.
+ virtual XmppReturnStatus RequestRosterRemove(const Jid& jid) = 0;
+
+ // SUBSCRIPTION MANAGEMENT ---------------------------------------------------
+
+ //! Request a subscription to presence notifications form a Jid
+ virtual XmppReturnStatus RequestSubscription(const Jid& jid) = 0;
+
+ //! Cancel a subscription to presence notifications from a Jid
+ virtual XmppReturnStatus CancelSubscription(const Jid& jid) = 0;
+
+ //! Approve a request to deliver presence notifications to a jid
+ virtual XmppReturnStatus ApproveSubscriber(const Jid& jid) = 0;
+
+ //! Deny or cancel presence notification deliver to a jid
+ virtual XmppReturnStatus CancelSubscriber(const Jid& jid) = 0;
+};
+
+}
+
+#endif // WEBRTC_LIBJINGLE_XMPP_ROSTERMODULE_H_
diff --git a/libjingle/xmpp/rostermodule_unittest.cc b/libjingle/xmpp/rostermodule_unittest.cc
new file mode 100644
index 00000000..1ae6c226
--- /dev/null
+++ b/libjingle/xmpp/rostermodule_unittest.cc
@@ -0,0 +1,832 @@
+/*
+ * 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 <iostream>
+#include <sstream>
+#include <string>
+
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/rostermodule.h"
+#include "webrtc/libjingle/xmpp/util_unittest.h"
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/scoped_ptr.h"
+
+#define TEST_OK(x) EXPECT_EQ((x),XMPP_RETURN_OK)
+#define TEST_BADARGUMENT(x) EXPECT_EQ((x),XMPP_RETURN_BADARGUMENT)
+
+
+namespace buzz {
+
+class RosterModuleTest;
+
+static void
+WriteString(std::ostream& os, const std::string& str) {
+ os<<str;
+}
+
+static void
+WriteSubscriptionState(std::ostream& os, XmppSubscriptionState state)
+{
+ switch (state) {
+ case XMPP_SUBSCRIPTION_NONE:
+ os<<"none";
+ break;
+ case XMPP_SUBSCRIPTION_NONE_ASKED:
+ os<<"none_asked";
+ break;
+ case XMPP_SUBSCRIPTION_TO:
+ os<<"to";
+ break;
+ case XMPP_SUBSCRIPTION_FROM:
+ os<<"from";
+ break;
+ case XMPP_SUBSCRIPTION_FROM_ASKED:
+ os<<"from_asked";
+ break;
+ case XMPP_SUBSCRIPTION_BOTH:
+ os<<"both";
+ break;
+ default:
+ os<<"unknown";
+ break;
+ }
+}
+
+static void
+WriteSubscriptionRequestType(std::ostream& os,
+ XmppSubscriptionRequestType type) {
+ switch(type) {
+ case XMPP_REQUEST_SUBSCRIBE:
+ os<<"subscribe";
+ break;
+ case XMPP_REQUEST_UNSUBSCRIBE:
+ os<<"unsubscribe";
+ break;
+ case XMPP_REQUEST_SUBSCRIBED:
+ os<<"subscribed";
+ break;
+ case XMPP_REQUEST_UNSUBSCRIBED:
+ os<<"unsubscribe";
+ break;
+ default:
+ os<<"unknown";
+ break;
+ }
+}
+
+static void
+WritePresenceShow(std::ostream& os, XmppPresenceShow show) {
+ switch(show) {
+ case XMPP_PRESENCE_AWAY:
+ os<<"away";
+ break;
+ case XMPP_PRESENCE_CHAT:
+ os<<"chat";
+ break;
+ case XMPP_PRESENCE_DND:
+ os<<"dnd";
+ break;
+ case XMPP_PRESENCE_XA:
+ os<<"xa";
+ break;
+ case XMPP_PRESENCE_DEFAULT:
+ os<<"[default]";
+ break;
+ default:
+ os<<"[unknown]";
+ break;
+ }
+}
+
+static void
+WritePresence(std::ostream& os, const XmppPresence* presence) {
+ if (presence == NULL) {
+ os<<"NULL";
+ return;
+ }
+
+ os<<"[Presence jid:";
+ WriteString(os, presence->jid().Str());
+ os<<" available:"<<presence->available();
+ os<<" presence_show:";
+ WritePresenceShow(os, presence->presence_show());
+ os<<" priority:"<<presence->priority();
+ os<<" status:";
+ WriteString(os, presence->status());
+ os<<"]"<<presence->raw_xml()->Str();
+}
+
+static void
+WriteContact(std::ostream& os, const XmppRosterContact* contact) {
+ if (contact == NULL) {
+ os<<"NULL";
+ return;
+ }
+
+ os<<"[Contact jid:";
+ WriteString(os, contact->jid().Str());
+ os<<" name:";
+ WriteString(os, contact->name());
+ os<<" subscription_state:";
+ WriteSubscriptionState(os, contact->subscription_state());
+ os<<" groups:[";
+ for(size_t i=0; i < contact->GetGroupCount(); ++i) {
+ os<<(i==0?"":", ");
+ WriteString(os, contact->GetGroup(i));
+ }
+ os<<"]]"<<contact->raw_xml()->Str();
+}
+
+//! This session handler saves all calls to a string. These are events and
+//! data delivered form the engine to application code.
+class XmppTestRosterHandler : public XmppRosterHandler {
+public:
+ XmppTestRosterHandler() {}
+ virtual ~XmppTestRosterHandler() {}
+
+ virtual void SubscriptionRequest(XmppRosterModule*,
+ const Jid& requesting_jid,
+ XmppSubscriptionRequestType type,
+ const XmlElement* raw_xml) {
+ ss_<<"[SubscriptionRequest Jid:" << requesting_jid.Str()<<" type:";
+ WriteSubscriptionRequestType(ss_, type);
+ ss_<<"]"<<raw_xml->Str();
+ }
+
+ //! Some type of presence error has occured
+ virtual void SubscriptionError(XmppRosterModule*,
+ const Jid& from,
+ const XmlElement* raw_xml) {
+ ss_<<"[SubscriptionError from:"<<from.Str()<<"]"<<raw_xml->Str();
+ }
+
+ virtual void RosterError(XmppRosterModule*,
+ const XmlElement* raw_xml) {
+ ss_<<"[RosterError]"<<raw_xml->Str();
+ }
+
+ //! New presence information has come in
+ //! The user is notified with the presence object directly. This info is also
+ //! added to the store accessable from the engine.
+ virtual void IncomingPresenceChanged(XmppRosterModule*,
+ const XmppPresence* presence) {
+ ss_<<"[IncomingPresenceChanged presence:";
+ WritePresence(ss_, presence);
+ ss_<<"]";
+ }
+
+ //! A contact has changed
+ //! This indicates that the data for a contact may have changed. No
+ //! contacts have been added or removed.
+ virtual void ContactChanged(XmppRosterModule* roster,
+ const XmppRosterContact* old_contact,
+ size_t index) {
+ ss_<<"[ContactChanged old_contact:";
+ WriteContact(ss_, old_contact);
+ ss_<<" index:"<<index<<" new_contact:";
+ WriteContact(ss_, roster->GetRosterContact(index));
+ ss_<<"]";
+ }
+
+ //! A set of contacts have been added
+ //! These contacts may have been added in response to the original roster
+ //! request or due to a "roster push" from the server.
+ virtual void ContactsAdded(XmppRosterModule* roster,
+ size_t index, size_t number) {
+ ss_<<"[ContactsAdded index:"<<index<<" number:"<<number;
+ for (size_t i = 0; i < number; ++i) {
+ ss_<<" "<<(index+i)<<":";
+ WriteContact(ss_, roster->GetRosterContact(index+i));
+ }
+ ss_<<"]";
+ }
+
+ //! A contact has been removed
+ //! This contact has been removed form the list.
+ virtual void ContactRemoved(XmppRosterModule*,
+ const XmppRosterContact* removed_contact,
+ size_t index) {
+ ss_<<"[ContactRemoved old_contact:";
+ WriteContact(ss_, removed_contact);
+ ss_<<" index:"<<index<<"]";
+ }
+
+ std::string Str() {
+ return ss_.str();
+ }
+
+ std::string StrClear() {
+ std::string result = ss_.str();
+ ss_.str("");
+ return result;
+ }
+
+private:
+ std::stringstream ss_;
+};
+
+//! This is the class that holds all of the unit test code for the
+//! roster module
+class RosterModuleTest : public testing::Test {
+public:
+ RosterModuleTest() {}
+ static void RunLogin(RosterModuleTest* obj, XmppEngine* engine,
+ XmppTestHandler* handler) {
+ // Needs to be similar to XmppEngineTest::RunLogin
+ }
+};
+
+TEST_F(RosterModuleTest, TestPresence) {
+ XmlElement* status = new XmlElement(QN_GOOGLE_PSTN_CONFERENCE_STATUS);
+ status->AddAttr(QN_STATUS, STR_PSTN_CONFERENCE_STATUS_CONNECTING);
+ XmlElement presence_xml(QN_PRESENCE);
+ presence_xml.AddElement(status);
+ rtc::scoped_ptr<XmppPresence> presence(XmppPresence::Create());
+ presence->set_raw_xml(&presence_xml);
+ EXPECT_EQ(presence->connection_status(), XMPP_CONNECTION_STATUS_CONNECTING);
+}
+
+TEST_F(RosterModuleTest, TestOutgoingPresence) {
+ std::stringstream dump;
+
+ rtc::scoped_ptr<XmppEngine> engine(XmppEngine::Create());
+ XmppTestHandler handler(engine.get());
+ XmppTestRosterHandler roster_handler;
+
+ rtc::scoped_ptr<XmppRosterModule> roster(XmppRosterModule::Create());
+ roster->set_roster_handler(&roster_handler);
+
+ // Configure the roster module
+ roster->RegisterEngine(engine.get());
+
+ // Set up callbacks
+ engine->SetOutputHandler(&handler);
+ engine->AddStanzaHandler(&handler);
+ engine->SetSessionHandler(&handler);
+
+ // Set up minimal login info
+ engine->SetUser(Jid("david@my-server"));
+ // engine->SetPassword("david");
+
+ // Do the whole login handshake
+ RunLogin(this, engine.get(), &handler);
+ EXPECT_EQ("", handler.OutputActivity());
+
+ // Set some presence and broadcast it
+ TEST_OK(roster->outgoing_presence()->
+ set_available(XMPP_PRESENCE_AVAILABLE));
+ TEST_OK(roster->outgoing_presence()->set_priority(-37));
+ TEST_OK(roster->outgoing_presence()->set_presence_show(XMPP_PRESENCE_DND));
+ TEST_OK(roster->outgoing_presence()->
+ set_status("I'm off to the races!<>&"));
+ TEST_OK(roster->BroadcastPresence());
+
+ EXPECT_EQ(roster_handler.StrClear(), "");
+ EXPECT_EQ(handler.OutputActivity(),
+ "<presence>"
+ "<priority>-37</priority>"
+ "<show>dnd</show>"
+ "<status>I'm off to the races!&lt;&gt;&amp;</status>"
+ "</presence>");
+ EXPECT_EQ(handler.SessionActivity(), "");
+
+ // Try some more
+ TEST_OK(roster->outgoing_presence()->
+ set_available(XMPP_PRESENCE_UNAVAILABLE));
+ TEST_OK(roster->outgoing_presence()->set_priority(0));
+ TEST_OK(roster->outgoing_presence()->set_presence_show(XMPP_PRESENCE_XA));
+ TEST_OK(roster->outgoing_presence()->set_status("Gone fishin'"));
+ TEST_OK(roster->BroadcastPresence());
+
+ EXPECT_EQ(roster_handler.StrClear(), "");
+ EXPECT_EQ(handler.OutputActivity(),
+ "<presence type=\"unavailable\">"
+ "<show>xa</show>"
+ "<status>Gone fishin'</status>"
+ "</presence>");
+ EXPECT_EQ(handler.SessionActivity(), "");
+
+ // Okay -- we are back on
+ TEST_OK(roster->outgoing_presence()->
+ set_available(XMPP_PRESENCE_AVAILABLE));
+ TEST_BADARGUMENT(roster->outgoing_presence()->set_priority(128));
+ TEST_OK(roster->outgoing_presence()->
+ set_presence_show(XMPP_PRESENCE_DEFAULT));
+ TEST_OK(roster->outgoing_presence()->set_status("Cookin' wit gas"));
+ TEST_OK(roster->BroadcastPresence());
+
+ EXPECT_EQ(roster_handler.StrClear(), "");
+ EXPECT_EQ(handler.OutputActivity(),
+ "<presence>"
+ "<status>Cookin' wit gas</status>"
+ "</presence>");
+ EXPECT_EQ(handler.SessionActivity(), "");
+
+ // Set it via XML
+ XmlElement presence_input(QN_PRESENCE);
+ presence_input.AddAttr(QN_TYPE, "unavailable");
+ presence_input.AddElement(new XmlElement(QN_PRIORITY));
+ presence_input.AddText("42", 1);
+ presence_input.AddElement(new XmlElement(QN_STATUS));
+ presence_input.AddAttr(QN_XML_LANG, "es", 1);
+ presence_input.AddText("Hola Amigos!", 1);
+ presence_input.AddElement(new XmlElement(QN_STATUS));
+ presence_input.AddText("Hey there, friend!", 1);
+ TEST_OK(roster->outgoing_presence()->set_raw_xml(&presence_input));
+ TEST_OK(roster->BroadcastPresence());
+
+ WritePresence(dump, roster->outgoing_presence());
+ EXPECT_EQ(dump.str(),
+ "[Presence jid: available:0 presence_show:[default] "
+ "priority:42 status:Hey there, friend!]"
+ "<cli:presence type=\"unavailable\" xmlns:cli=\"jabber:client\">"
+ "<cli:priority>42</cli:priority>"
+ "<cli:status xml:lang=\"es\">Hola Amigos!</cli:status>"
+ "<cli:status>Hey there, friend!</cli:status>"
+ "</cli:presence>");
+ dump.str("");
+ EXPECT_EQ(roster_handler.StrClear(), "");
+ EXPECT_EQ(handler.OutputActivity(),
+ "<presence type=\"unavailable\">"
+ "<priority>42</priority>"
+ "<status xml:lang=\"es\">Hola Amigos!</status>"
+ "<status>Hey there, friend!</status>"
+ "</presence>");
+ EXPECT_EQ(handler.SessionActivity(), "");
+
+ // Construct a directed presence
+ rtc::scoped_ptr<XmppPresence> directed_presence(XmppPresence::Create());
+ TEST_OK(directed_presence->set_available(XMPP_PRESENCE_AVAILABLE));
+ TEST_OK(directed_presence->set_priority(120));
+ TEST_OK(directed_presence->set_status("*very* available"));
+ TEST_OK(roster->SendDirectedPresence(directed_presence.get(),
+ Jid("myhoney@honey.net")));
+
+ EXPECT_EQ(roster_handler.StrClear(), "");
+ EXPECT_EQ(handler.OutputActivity(),
+ "<presence to=\"myhoney@honey.net\">"
+ "<priority>120</priority>"
+ "<status>*very* available</status>"
+ "</presence>");
+ EXPECT_EQ(handler.SessionActivity(), "");
+}
+
+TEST_F(RosterModuleTest, TestIncomingPresence) {
+ rtc::scoped_ptr<XmppEngine> engine(XmppEngine::Create());
+ XmppTestHandler handler(engine.get());
+ XmppTestRosterHandler roster_handler;
+
+ rtc::scoped_ptr<XmppRosterModule> roster(XmppRosterModule::Create());
+ roster->set_roster_handler(&roster_handler);
+
+ // Configure the roster module
+ roster->RegisterEngine(engine.get());
+
+ // Set up callbacks
+ engine->SetOutputHandler(&handler);
+ engine->AddStanzaHandler(&handler);
+ engine->SetSessionHandler(&handler);
+
+ // Set up minimal login info
+ engine->SetUser(Jid("david@my-server"));
+ // engine->SetPassword("david");
+
+ // Do the whole login handshake
+ RunLogin(this, engine.get(), &handler);
+ EXPECT_EQ("", handler.OutputActivity());
+
+ // Load up with a bunch of data
+ std::string input;
+ input = "<presence from='maude@example.net/studio' "
+ "to='david@my-server/test'/>"
+ "<presence from='walter@example.net/home' "
+ "to='david@my-server/test'>"
+ "<priority>-10</priority>"
+ "<show>xa</show>"
+ "<status>Off bowling</status>"
+ "</presence>"
+ "<presence from='walter@example.net/alley' "
+ "to='david@my-server/test'>"
+ "<priority>20</priority>"
+ "<status>Looking for toes...</status>"
+ "</presence>"
+ "<presence from='donny@example.net/alley' "
+ "to='david@my-server/test'>"
+ "<priority>10</priority>"
+ "<status>Throwing rocks</status>"
+ "</presence>";
+ TEST_OK(engine->HandleInput(input.c_str(), input.length()));
+
+ EXPECT_EQ(roster_handler.StrClear(),
+ "[IncomingPresenceChanged "
+ "presence:[Presence jid:maude@example.net/studio available:1 "
+ "presence_show:[default] priority:0 status:]"
+ "<cli:presence from=\"maude@example.net/studio\" "
+ "to=\"david@my-server/test\" "
+ "xmlns:cli=\"jabber:client\"/>]"
+ "[IncomingPresenceChanged "
+ "presence:[Presence jid:walter@example.net/home available:1 "
+ "presence_show:xa priority:-10 status:Off bowling]"
+ "<cli:presence from=\"walter@example.net/home\" "
+ "to=\"david@my-server/test\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<cli:priority>-10</cli:priority>"
+ "<cli:show>xa</cli:show>"
+ "<cli:status>Off bowling</cli:status>"
+ "</cli:presence>]"
+ "[IncomingPresenceChanged "
+ "presence:[Presence jid:walter@example.net/alley available:1 "
+ "presence_show:[default] "
+ "priority:20 status:Looking for toes...]"
+ "<cli:presence from=\"walter@example.net/alley\" "
+ "to=\"david@my-server/test\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<cli:priority>20</cli:priority>"
+ "<cli:status>Looking for toes...</cli:status>"
+ "</cli:presence>]"
+ "[IncomingPresenceChanged "
+ "presence:[Presence jid:donny@example.net/alley available:1 "
+ "presence_show:[default] priority:10 status:Throwing rocks]"
+ "<cli:presence from=\"donny@example.net/alley\" "
+ "to=\"david@my-server/test\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<cli:priority>10</cli:priority>"
+ "<cli:status>Throwing rocks</cli:status>"
+ "</cli:presence>]");
+ EXPECT_EQ(handler.OutputActivity(), "");
+ handler.SessionActivity(); // Ignore the session output
+
+ // Now look at the data structure we've built
+ EXPECT_EQ(roster->GetIncomingPresenceCount(), static_cast<size_t>(4));
+ EXPECT_EQ(roster->GetIncomingPresenceForJidCount(Jid("maude@example.net")),
+ static_cast<size_t>(1));
+ EXPECT_EQ(roster->GetIncomingPresenceForJidCount(Jid("walter@example.net")),
+ static_cast<size_t>(2));
+
+ const XmppPresence * presence;
+ presence = roster->GetIncomingPresenceForJid(Jid("walter@example.net"), 1);
+
+ std::stringstream dump;
+ WritePresence(dump, presence);
+ EXPECT_EQ(dump.str(),
+ "[Presence jid:walter@example.net/alley available:1 "
+ "presence_show:[default] priority:20 status:Looking for toes...]"
+ "<cli:presence from=\"walter@example.net/alley\" "
+ "to=\"david@my-server/test\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<cli:priority>20</cli:priority>"
+ "<cli:status>Looking for toes...</cli:status>"
+ "</cli:presence>");
+ dump.str("");
+
+ // Maude took off...
+ input = "<presence from='maude@example.net/studio' "
+ "to='david@my-server/test' "
+ "type='unavailable'>"
+ "<status>Stealing my rug back</status>"
+ "<priority>-10</priority>"
+ "</presence>";
+ TEST_OK(engine->HandleInput(input.c_str(), input.length()));
+
+ EXPECT_EQ(roster_handler.StrClear(),
+ "[IncomingPresenceChanged "
+ "presence:[Presence jid:maude@example.net/studio available:0 "
+ "presence_show:[default] priority:-10 "
+ "status:Stealing my rug back]"
+ "<cli:presence from=\"maude@example.net/studio\" "
+ "to=\"david@my-server/test\" type=\"unavailable\" "
+ "xmlns:cli=\"jabber:client\">"
+ "<cli:status>Stealing my rug back</cli:status>"
+ "<cli:priority>-10</cli:priority>"
+ "</cli:presence>]");
+ EXPECT_EQ(handler.OutputActivity(), "");
+ handler.SessionActivity(); // Ignore the session output
+}
+
+TEST_F(RosterModuleTest, TestPresenceSubscription) {
+ rtc::scoped_ptr<XmppEngine> engine(XmppEngine::Create());
+ XmppTestHandler handler(engine.get());
+ XmppTestRosterHandler roster_handler;
+
+ rtc::scoped_ptr<XmppRosterModule> roster(XmppRosterModule::Create());
+ roster->set_roster_handler(&roster_handler);
+
+ // Configure the roster module
+ roster->RegisterEngine(engine.get());
+
+ // Set up callbacks
+ engine->SetOutputHandler(&handler);
+ engine->AddStanzaHandler(&handler);
+ engine->SetSessionHandler(&handler);
+
+ // Set up minimal login info
+ engine->SetUser(Jid("david@my-server"));
+ // engine->SetPassword("david");
+
+ // Do the whole login handshake
+ RunLogin(this, engine.get(), &handler);
+ EXPECT_EQ("", handler.OutputActivity());
+
+ // Test incoming requests
+ std::string input;
+ input =
+ "<presence from='maude@example.net' type='subscribe'/>"
+ "<presence from='maude@example.net' type='unsubscribe'/>"
+ "<presence from='maude@example.net' type='subscribed'/>"
+ "<presence from='maude@example.net' type='unsubscribed'/>";
+ TEST_OK(engine->HandleInput(input.c_str(), input.length()));
+
+ EXPECT_EQ(roster_handler.StrClear(),
+ "[SubscriptionRequest Jid:maude@example.net type:subscribe]"
+ "<cli:presence from=\"maude@example.net\" type=\"subscribe\" "
+ "xmlns:cli=\"jabber:client\"/>"
+ "[SubscriptionRequest Jid:maude@example.net type:unsubscribe]"
+ "<cli:presence from=\"maude@example.net\" type=\"unsubscribe\" "
+ "xmlns:cli=\"jabber:client\"/>"
+ "[SubscriptionRequest Jid:maude@example.net type:subscribed]"
+ "<cli:presence from=\"maude@example.net\" type=\"subscribed\" "
+ "xmlns:cli=\"jabber:client\"/>"
+ "[SubscriptionRequest Jid:maude@example.net type:unsubscribe]"
+ "<cli:presence from=\"maude@example.net\" type=\"unsubscribed\" "
+ "xmlns:cli=\"jabber:client\"/>");
+ EXPECT_EQ(handler.OutputActivity(), "");
+ handler.SessionActivity(); // Ignore the session output
+
+ TEST_OK(roster->RequestSubscription(Jid("maude@example.net")));
+ TEST_OK(roster->CancelSubscription(Jid("maude@example.net")));
+ TEST_OK(roster->ApproveSubscriber(Jid("maude@example.net")));
+ TEST_OK(roster->CancelSubscriber(Jid("maude@example.net")));
+
+ EXPECT_EQ(roster_handler.StrClear(), "");
+ EXPECT_EQ(handler.OutputActivity(),
+ "<presence to=\"maude@example.net\" type=\"subscribe\"/>"
+ "<presence to=\"maude@example.net\" type=\"unsubscribe\"/>"
+ "<presence to=\"maude@example.net\" type=\"subscribed\"/>"
+ "<presence to=\"maude@example.net\" type=\"unsubscribed\"/>");
+ EXPECT_EQ(handler.SessionActivity(), "");
+}
+
+TEST_F(RosterModuleTest, TestRosterReceive) {
+ rtc::scoped_ptr<XmppEngine> engine(XmppEngine::Create());
+ XmppTestHandler handler(engine.get());
+ XmppTestRosterHandler roster_handler;
+
+ rtc::scoped_ptr<XmppRosterModule> roster(XmppRosterModule::Create());
+ roster->set_roster_handler(&roster_handler);
+
+ // Configure the roster module
+ roster->RegisterEngine(engine.get());
+
+ // Set up callbacks
+ engine->SetOutputHandler(&handler);
+ engine->AddStanzaHandler(&handler);
+ engine->SetSessionHandler(&handler);
+
+ // Set up minimal login info
+ engine->SetUser(Jid("david@my-server"));
+ // engine->SetPassword("david");
+
+ // Do the whole login handshake
+ RunLogin(this, engine.get(), &handler);
+ EXPECT_EQ("", handler.OutputActivity());
+
+ // Request a roster update
+ TEST_OK(roster->RequestRosterUpdate());
+
+ EXPECT_EQ(roster_handler.StrClear(),"");
+ EXPECT_EQ(handler.OutputActivity(),
+ "<iq type=\"get\" id=\"2\">"
+ "<query xmlns=\"jabber:iq:roster\"/>"
+ "</iq>");
+ EXPECT_EQ(handler.SessionActivity(), "");
+
+ // Prime the roster with a starting set
+ std::string input =
+ "<iq to='david@myserver/test' type='result' id='2'>"
+ "<query xmlns='jabber:iq:roster'>"
+ "<item jid='maude@example.net' "
+ "name='Maude Lebowski' "
+ "subscription='none' "
+ "ask='subscribe'>"
+ "<group>Business Partners</group>"
+ "</item>"
+ "<item jid='walter@example.net' "
+ "name='Walter Sobchak' "
+ "subscription='both'>"
+ "<group>Friends</group>"
+ "<group>Bowling Team</group>"
+ "<group>Bowling League</group>"
+ "</item>"
+ "<item jid='donny@example.net' "
+ "name='Donny' "
+ "subscription='both'>"
+ "<group>Friends</group>"
+ "<group>Bowling Team</group>"
+ "<group>Bowling League</group>"
+ "</item>"
+ "<item jid='jeffrey@example.net' "
+ "name='The Big Lebowski' "
+ "subscription='to'>"
+ "<group>Business Partners</group>"
+ "</item>"
+ "<item jid='jesus@example.net' "
+ "name='Jesus Quintana' "
+ "subscription='from'>"
+ "<group>Bowling League</group>"
+ "</item>"
+ "</query>"
+ "</iq>";
+
+ TEST_OK(engine->HandleInput(input.c_str(), input.length()));
+
+ EXPECT_EQ(roster_handler.StrClear(),
+ "[ContactsAdded index:0 number:5 "
+ "0:[Contact jid:maude@example.net name:Maude Lebowski "
+ "subscription_state:none_asked "
+ "groups:[Business Partners]]"
+ "<ros:item jid=\"maude@example.net\" name=\"Maude Lebowski\" "
+ "subscription=\"none\" ask=\"subscribe\" "
+ "xmlns:ros=\"jabber:iq:roster\">"
+ "<ros:group>Business Partners</ros:group>"
+ "</ros:item> "
+ "1:[Contact jid:walter@example.net name:Walter Sobchak "
+ "subscription_state:both "
+ "groups:[Friends, Bowling Team, Bowling League]]"
+ "<ros:item jid=\"walter@example.net\" name=\"Walter Sobchak\" "
+ "subscription=\"both\" "
+ "xmlns:ros=\"jabber:iq:roster\">"
+ "<ros:group>Friends</ros:group>"
+ "<ros:group>Bowling Team</ros:group>"
+ "<ros:group>Bowling League</ros:group>"
+ "</ros:item> "
+ "2:[Contact jid:donny@example.net name:Donny "
+ "subscription_state:both "
+ "groups:[Friends, Bowling Team, Bowling League]]"
+ "<ros:item jid=\"donny@example.net\" name=\"Donny\" "
+ "subscription=\"both\" "
+ "xmlns:ros=\"jabber:iq:roster\">"
+ "<ros:group>Friends</ros:group>"
+ "<ros:group>Bowling Team</ros:group>"
+ "<ros:group>Bowling League</ros:group>"
+ "</ros:item> "
+ "3:[Contact jid:jeffrey@example.net name:The Big Lebowski "
+ "subscription_state:to "
+ "groups:[Business Partners]]"
+ "<ros:item jid=\"jeffrey@example.net\" name=\"The Big Lebowski\" "
+ "subscription=\"to\" "
+ "xmlns:ros=\"jabber:iq:roster\">"
+ "<ros:group>Business Partners</ros:group>"
+ "</ros:item> "
+ "4:[Contact jid:jesus@example.net name:Jesus Quintana "
+ "subscription_state:from groups:[Bowling League]]"
+ "<ros:item jid=\"jesus@example.net\" name=\"Jesus Quintana\" "
+ "subscription=\"from\" xmlns:ros=\"jabber:iq:roster\">"
+ "<ros:group>Bowling League</ros:group>"
+ "</ros:item>]");
+ EXPECT_EQ(handler.OutputActivity(), "");
+ EXPECT_EQ(handler.SessionActivity(), "");
+
+ // Request that someone be added
+ rtc::scoped_ptr<XmppRosterContact> contact(XmppRosterContact::Create());
+ TEST_OK(contact->set_jid(Jid("brandt@example.net")));
+ TEST_OK(contact->set_name("Brandt"));
+ TEST_OK(contact->AddGroup("Business Partners"));
+ TEST_OK(contact->AddGroup("Watchers"));
+ TEST_OK(contact->AddGroup("Friends"));
+ TEST_OK(contact->RemoveGroup("Friends")); // Maybe not...
+ TEST_OK(roster->RequestRosterChange(contact.get()));
+
+ EXPECT_EQ(roster_handler.StrClear(), "");
+ EXPECT_EQ(handler.OutputActivity(),
+ "<iq type=\"set\" id=\"3\">"
+ "<query xmlns=\"jabber:iq:roster\">"
+ "<item jid=\"brandt@example.net\" "
+ "name=\"Brandt\">"
+ "<group>Business Partners</group>"
+ "<group>Watchers</group>"
+ "</item>"
+ "</query>"
+ "</iq>");
+ EXPECT_EQ(handler.SessionActivity(), "");
+
+ // Get the push from the server
+ input =
+ "<iq type='result' to='david@my-server/test' id='3'/>"
+ "<iq type='set' id='server_1'>"
+ "<query xmlns='jabber:iq:roster'>"
+ "<item jid='brandt@example.net' "
+ "name='Brandt' "
+ "subscription='none'>"
+ "<group>Business Partners</group>"
+ "<group>Watchers</group>"
+ "</item>"
+ "</query>"
+ "</iq>";
+ TEST_OK(engine->HandleInput(input.c_str(), input.length()));
+
+ EXPECT_EQ(roster_handler.StrClear(),
+ "[ContactsAdded index:5 number:1 "
+ "5:[Contact jid:brandt@example.net name:Brandt "
+ "subscription_state:none "
+ "groups:[Business Partners, Watchers]]"
+ "<ros:item jid=\"brandt@example.net\" name=\"Brandt\" "
+ "subscription=\"none\" "
+ "xmlns:ros=\"jabber:iq:roster\">"
+ "<ros:group>Business Partners</ros:group>"
+ "<ros:group>Watchers</ros:group>"
+ "</ros:item>]");
+ EXPECT_EQ(handler.OutputActivity(),
+ "<iq type=\"result\" id=\"server_1\"/>");
+ EXPECT_EQ(handler.SessionActivity(), "");
+
+ // Get a contact update
+ input =
+ "<iq type='set' id='server_2'>"
+ "<query xmlns='jabber:iq:roster'>"
+ "<item jid='walter@example.net' "
+ "name='Walter Sobchak' "
+ "subscription='both'>"
+ "<group>Friends</group>"
+ "<group>Bowling Team</group>"
+ "<group>Bowling League</group>"
+ "<group>Not wrong, just an...</group>"
+ "</item>"
+ "</query>"
+ "</iq>";
+
+ TEST_OK(engine->HandleInput(input.c_str(), input.length()));
+
+ EXPECT_EQ(roster_handler.StrClear(),
+ "[ContactChanged "
+ "old_contact:[Contact jid:walter@example.net name:Walter Sobchak "
+ "subscription_state:both "
+ "groups:[Friends, Bowling Team, Bowling League]]"
+ "<ros:item jid=\"walter@example.net\" name=\"Walter Sobchak\" "
+ "subscription=\"both\" xmlns:ros=\"jabber:iq:roster\">"
+ "<ros:group>Friends</ros:group>"
+ "<ros:group>Bowling Team</ros:group>"
+ "<ros:group>Bowling League</ros:group>"
+ "</ros:item> "
+ "index:1 "
+ "new_contact:[Contact jid:walter@example.net name:Walter Sobchak "
+ "subscription_state:both "
+ "groups:[Friends, Bowling Team, Bowling League, "
+ "Not wrong, just an...]]"
+ "<ros:item jid=\"walter@example.net\" name=\"Walter Sobchak\" "
+ "subscription=\"both\" xmlns:ros=\"jabber:iq:roster\">"
+ "<ros:group>Friends</ros:group>"
+ "<ros:group>Bowling Team</ros:group>"
+ "<ros:group>Bowling League</ros:group>"
+ "<ros:group>Not wrong, just an...</ros:group>"
+ "</ros:item>]");
+ EXPECT_EQ(handler.OutputActivity(),
+ "<iq type=\"result\" id=\"server_2\"/>");
+ EXPECT_EQ(handler.SessionActivity(), "");
+
+ // Remove a contact
+ TEST_OK(roster->RequestRosterRemove(Jid("jesus@example.net")));
+
+ EXPECT_EQ(roster_handler.StrClear(), "");
+ EXPECT_EQ(handler.OutputActivity(),
+ "<iq type=\"set\" id=\"4\">"
+ "<query xmlns=\"jabber:iq:roster\" jid=\"jesus@example.net\" "
+ "subscription=\"remove\"/>"
+ "</iq>");
+ EXPECT_EQ(handler.SessionActivity(), "");
+
+ // Response from the server
+ input =
+ "<iq type='result' to='david@my-server/test' id='4'/>"
+ "<iq type='set' id='server_3'>"
+ "<query xmlns='jabber:iq:roster'>"
+ "<item jid='jesus@example.net' "
+ "subscription='remove'>"
+ "</item>"
+ "</query>"
+ "</iq>";
+ TEST_OK(engine->HandleInput(input.c_str(), input.length()));
+
+ EXPECT_EQ(roster_handler.StrClear(),
+ "[ContactRemoved "
+ "old_contact:[Contact jid:jesus@example.net name:Jesus Quintana "
+ "subscription_state:from groups:[Bowling League]]"
+ "<ros:item jid=\"jesus@example.net\" name=\"Jesus Quintana\" "
+ "subscription=\"from\" "
+ "xmlns:ros=\"jabber:iq:roster\">"
+ "<ros:group>Bowling League</ros:group>"
+ "</ros:item> index:4]");
+ EXPECT_EQ(handler.OutputActivity(),
+ "<iq type=\"result\" id=\"server_3\"/>");
+ EXPECT_EQ(handler.SessionActivity(), "");
+}
+
+}
diff --git a/libjingle/xmpp/rostermoduleimpl.cc b/libjingle/xmpp/rostermoduleimpl.cc
new file mode 100644
index 00000000..b9752896
--- /dev/null
+++ b/libjingle/xmpp/rostermoduleimpl.cc
@@ -0,0 +1,1064 @@
+/*
+ * 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 <algorithm>
+#include <iostream>
+#include <map>
+#include <sstream>
+#include <string>
+#include <vector>
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/rostermoduleimpl.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/stringencode.h"
+
+namespace buzz {
+
+// enum prase and persist helpers ----------------------------------------------
+static bool
+StringToPresenceShow(const std::string& input, XmppPresenceShow* show) {
+ // If this becomes a perf issue we can use a hash or a map here
+ if (STR_SHOW_AWAY == input)
+ *show = XMPP_PRESENCE_AWAY;
+ else if (STR_SHOW_DND == input)
+ *show = XMPP_PRESENCE_DND;
+ else if (STR_SHOW_XA == input)
+ *show = XMPP_PRESENCE_XA;
+ else if (STR_SHOW_CHAT == input)
+ *show = XMPP_PRESENCE_CHAT;
+ else if (STR_EMPTY == input)
+ *show = XMPP_PRESENCE_DEFAULT;
+ else
+ return false;
+
+ return true;
+}
+
+static bool
+PresenceShowToString(XmppPresenceShow show, const char** output) {
+ switch(show) {
+ case XMPP_PRESENCE_AWAY:
+ *output = STR_SHOW_AWAY;
+ return true;
+ case XMPP_PRESENCE_CHAT:
+ *output = STR_SHOW_CHAT;
+ return true;
+ case XMPP_PRESENCE_XA:
+ *output = STR_SHOW_XA;
+ return true;
+ case XMPP_PRESENCE_DND:
+ *output = STR_SHOW_DND;
+ return true;
+ case XMPP_PRESENCE_DEFAULT:
+ *output = STR_EMPTY;
+ return true;
+ }
+
+ *output = STR_EMPTY;
+ return false;
+}
+
+static bool
+StringToSubscriptionState(const std::string& subscription,
+ const std::string& ask,
+ XmppSubscriptionState* state)
+{
+ if (ask == "subscribe")
+ {
+ if (subscription == "none") {
+ *state = XMPP_SUBSCRIPTION_NONE_ASKED;
+ return true;
+ }
+ if (subscription == "from") {
+ *state = XMPP_SUBSCRIPTION_FROM_ASKED;
+ return true;
+ }
+ } else if (ask == STR_EMPTY)
+ {
+ if (subscription == "none") {
+ *state = XMPP_SUBSCRIPTION_NONE;
+ return true;
+ }
+ if (subscription == "from") {
+ *state = XMPP_SUBSCRIPTION_FROM;
+ return true;
+ }
+ if (subscription == "to") {
+ *state = XMPP_SUBSCRIPTION_TO;
+ return true;
+ }
+ if (subscription == "both") {
+ *state = XMPP_SUBSCRIPTION_BOTH;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool
+StringToSubscriptionRequestType(const std::string& string,
+ XmppSubscriptionRequestType* type)
+{
+ if (string == "subscribe")
+ *type = XMPP_REQUEST_SUBSCRIBE;
+ else if (string == "unsubscribe")
+ *type = XMPP_REQUEST_UNSUBSCRIBE;
+ else if (string == "subscribed")
+ *type = XMPP_REQUEST_SUBSCRIBED;
+ else if (string == "unsubscribed")
+ *type = XMPP_REQUEST_UNSUBSCRIBED;
+ else
+ return false;
+ return true;
+}
+
+// XmppPresenceImpl class ------------------------------------------------------
+XmppPresence*
+XmppPresence::Create() {
+ return new XmppPresenceImpl();
+}
+
+XmppPresenceImpl::XmppPresenceImpl() {
+}
+
+const Jid
+XmppPresenceImpl::jid() const {
+ if (!raw_xml_)
+ return Jid();
+
+ return Jid(raw_xml_->Attr(QN_FROM));
+}
+
+XmppPresenceAvailable
+XmppPresenceImpl::available() const {
+ if (!raw_xml_)
+ return XMPP_PRESENCE_UNAVAILABLE;
+
+ if (raw_xml_->Attr(QN_TYPE) == "unavailable")
+ return XMPP_PRESENCE_UNAVAILABLE;
+ else if (raw_xml_->Attr(QN_TYPE) == "error")
+ return XMPP_PRESENCE_ERROR;
+ else
+ return XMPP_PRESENCE_AVAILABLE;
+}
+
+XmppReturnStatus
+XmppPresenceImpl::set_available(XmppPresenceAvailable available) {
+ if (!raw_xml_)
+ CreateRawXmlSkeleton();
+
+ if (available == XMPP_PRESENCE_AVAILABLE)
+ raw_xml_->ClearAttr(QN_TYPE);
+ else if (available == XMPP_PRESENCE_UNAVAILABLE)
+ raw_xml_->SetAttr(QN_TYPE, "unavailable");
+ else if (available == XMPP_PRESENCE_ERROR)
+ raw_xml_->SetAttr(QN_TYPE, "error");
+ return XMPP_RETURN_OK;
+}
+
+XmppPresenceShow
+XmppPresenceImpl::presence_show() const {
+ if (!raw_xml_)
+ return XMPP_PRESENCE_DEFAULT;
+
+ XmppPresenceShow show = XMPP_PRESENCE_DEFAULT;
+ StringToPresenceShow(raw_xml_->TextNamed(QN_SHOW), &show);
+ return show;
+}
+
+XmppReturnStatus
+XmppPresenceImpl::set_presence_show(XmppPresenceShow show) {
+ if (!raw_xml_)
+ CreateRawXmlSkeleton();
+
+ const char* show_string;
+
+ if(!PresenceShowToString(show, &show_string))
+ return XMPP_RETURN_BADARGUMENT;
+
+ raw_xml_->ClearNamedChildren(QN_SHOW);
+
+ if (show!=XMPP_PRESENCE_DEFAULT) {
+ raw_xml_->AddElement(new XmlElement(QN_SHOW));
+ raw_xml_->AddText(show_string, 1);
+ }
+
+ return XMPP_RETURN_OK;
+}
+
+int
+XmppPresenceImpl::priority() const {
+ if (!raw_xml_)
+ return 0;
+
+ int raw_priority = 0;
+ if (!rtc::FromString(raw_xml_->TextNamed(QN_PRIORITY), &raw_priority))
+ raw_priority = 0;
+ if (raw_priority < -128)
+ raw_priority = -128;
+ if (raw_priority > 127)
+ raw_priority = 127;
+
+ return raw_priority;
+}
+
+XmppReturnStatus
+XmppPresenceImpl::set_priority(int priority) {
+ if (!raw_xml_)
+ CreateRawXmlSkeleton();
+
+ if (priority < -128 || priority > 127)
+ return XMPP_RETURN_BADARGUMENT;
+
+ raw_xml_->ClearNamedChildren(QN_PRIORITY);
+ if (0 != priority) {
+ std::string priority_string;
+ if (rtc::ToString(priority, &priority_string)) {
+ raw_xml_->AddElement(new XmlElement(QN_PRIORITY));
+ raw_xml_->AddText(priority_string, 1);
+ }
+ }
+
+ return XMPP_RETURN_OK;
+}
+
+const std::string
+XmppPresenceImpl::status() const {
+ if (!raw_xml_)
+ return STR_EMPTY;
+
+ XmlElement* status_element;
+ XmlElement* element;
+
+ // Search for a status element with no xml:lang attribute on it. if we can't
+ // find that then just return the first status element in the stanza.
+ for (status_element = element = raw_xml_->FirstNamed(QN_STATUS);
+ element;
+ element = element->NextNamed(QN_STATUS)) {
+ if (!element->HasAttr(QN_XML_LANG)) {
+ status_element = element;
+ break;
+ }
+ }
+
+ if (status_element) {
+ return status_element->BodyText();
+ }
+
+ return STR_EMPTY;
+}
+
+XmppReturnStatus
+XmppPresenceImpl::set_status(const std::string& status) {
+ if (!raw_xml_)
+ CreateRawXmlSkeleton();
+
+ raw_xml_->ClearNamedChildren(QN_STATUS);
+
+ if (status != STR_EMPTY) {
+ raw_xml_->AddElement(new XmlElement(QN_STATUS));
+ raw_xml_->AddText(status, 1);
+ }
+
+ return XMPP_RETURN_OK;
+}
+
+XmppPresenceConnectionStatus
+XmppPresenceImpl::connection_status() const {
+ if (!raw_xml_)
+ return XMPP_CONNECTION_STATUS_UNKNOWN;
+
+ XmlElement* con = raw_xml_->FirstNamed(QN_GOOGLE_PSTN_CONFERENCE_STATUS);
+ if (con) {
+ std::string status = con->Attr(QN_ATTR_STATUS);
+ if (status == STR_PSTN_CONFERENCE_STATUS_CONNECTING)
+ return XMPP_CONNECTION_STATUS_CONNECTING;
+ else if (status == STR_PSTN_CONFERENCE_STATUS_CONNECTED)
+ return XMPP_CONNECTION_STATUS_CONNECTED;
+ else if (status == STR_PSTN_CONFERENCE_STATUS_JOINING)
+ return XMPP_CONNECTION_STATUS_JOINING;
+ else if (status == STR_PSTN_CONFERENCE_STATUS_HANGUP)
+ return XMPP_CONNECTION_STATUS_HANGUP;
+ }
+
+ return XMPP_CONNECTION_STATUS_CONNECTED;
+}
+
+const std::string
+XmppPresenceImpl::google_user_id() const {
+ if (!raw_xml_)
+ return std::string();
+
+ XmlElement* muc_user_x = raw_xml_->FirstNamed(QN_MUC_USER_X);
+ if (muc_user_x) {
+ XmlElement* muc_user_item = muc_user_x->FirstNamed(QN_MUC_USER_ITEM);
+ if (muc_user_item) {
+ return muc_user_item->Attr(QN_GOOGLE_USER_ID);
+ }
+ }
+
+ return std::string();
+}
+
+const std::string
+XmppPresenceImpl::nickname() const {
+ if (!raw_xml_)
+ return std::string();
+
+ XmlElement* nickname = raw_xml_->FirstNamed(QN_NICKNAME);
+ if (nickname) {
+ return nickname->BodyText();
+ }
+
+ return std::string();
+}
+
+const XmlElement*
+XmppPresenceImpl::raw_xml() const {
+ if (!raw_xml_)
+ const_cast<XmppPresenceImpl*>(this)->CreateRawXmlSkeleton();
+ return raw_xml_.get();
+}
+
+XmppReturnStatus
+XmppPresenceImpl::set_raw_xml(const XmlElement * xml) {
+ if (!xml ||
+ xml->Name() != QN_PRESENCE)
+ return XMPP_RETURN_BADARGUMENT;
+
+ raw_xml_.reset(new XmlElement(*xml));
+ return XMPP_RETURN_OK;
+}
+
+void
+XmppPresenceImpl::CreateRawXmlSkeleton() {
+ raw_xml_.reset(new XmlElement(QN_PRESENCE));
+}
+
+// XmppRosterContactImpl -------------------------------------------------------
+XmppRosterContact*
+XmppRosterContact::Create() {
+ return new XmppRosterContactImpl();
+}
+
+XmppRosterContactImpl::XmppRosterContactImpl() {
+ ResetGroupCache();
+}
+
+void
+XmppRosterContactImpl::SetXmlFromWire(const XmlElement* xml) {
+ ResetGroupCache();
+ if (xml)
+ raw_xml_.reset(new XmlElement(*xml));
+ else
+ raw_xml_.reset(NULL);
+}
+
+void
+XmppRosterContactImpl::ResetGroupCache() {
+ group_count_ = -1;
+ group_index_returned_ = -1;
+ group_returned_ = NULL;
+}
+
+const Jid
+XmppRosterContactImpl::jid() const {
+ return Jid(raw_xml_->Attr(QN_JID));
+}
+
+XmppReturnStatus
+XmppRosterContactImpl::set_jid(const Jid& jid)
+{
+ if (!raw_xml_)
+ CreateRawXmlSkeleton();
+
+ if (!jid.IsValid())
+ return XMPP_RETURN_BADARGUMENT;
+
+ raw_xml_->SetAttr(QN_JID, jid.Str());
+
+ return XMPP_RETURN_OK;
+}
+
+const std::string
+XmppRosterContactImpl::name() const {
+ return raw_xml_->Attr(QN_NAME);
+}
+
+XmppReturnStatus
+XmppRosterContactImpl::set_name(const std::string& name) {
+ if (!raw_xml_)
+ CreateRawXmlSkeleton();
+
+ if (name == STR_EMPTY)
+ raw_xml_->ClearAttr(QN_NAME);
+ else
+ raw_xml_->SetAttr(QN_NAME, name);
+
+ return XMPP_RETURN_OK;
+}
+
+XmppSubscriptionState
+XmppRosterContactImpl::subscription_state() const {
+ if (!raw_xml_)
+ return XMPP_SUBSCRIPTION_NONE;
+
+ XmppSubscriptionState state = XMPP_SUBSCRIPTION_NONE;
+
+ if (StringToSubscriptionState(raw_xml_->Attr(QN_SUBSCRIPTION),
+ raw_xml_->Attr(QN_ASK),
+ &state))
+ return state;
+
+ return XMPP_SUBSCRIPTION_NONE;
+}
+
+size_t
+XmppRosterContactImpl::GetGroupCount() const {
+ if (!raw_xml_)
+ return 0;
+
+ if (-1 == group_count_) {
+ XmlElement *group_element = raw_xml_->FirstNamed(QN_ROSTER_GROUP);
+ int group_count = 0;
+ while(group_element) {
+ group_count++;
+ group_element = group_element->NextNamed(QN_ROSTER_GROUP);
+ }
+
+ ASSERT(group_count > 0); // protect the cast
+ XmppRosterContactImpl * me = const_cast<XmppRosterContactImpl*>(this);
+ me->group_count_ = group_count;
+ }
+
+ return group_count_;
+}
+
+const std::string
+XmppRosterContactImpl::GetGroup(size_t index) const {
+ if (index >= GetGroupCount())
+ return STR_EMPTY;
+
+ // We cache the last group index and element that we returned. This way
+ // going through the groups in order is order n and not n^2. This could be
+ // enhanced if necessary by starting at the cached value if the index asked
+ // is after the cached one.
+ if (group_index_returned_ >= 0 &&
+ index == static_cast<size_t>(group_index_returned_) + 1)
+ {
+ XmppRosterContactImpl * me = const_cast<XmppRosterContactImpl*>(this);
+ me->group_returned_ = group_returned_->NextNamed(QN_ROSTER_GROUP);
+ ASSERT(group_returned_ != NULL);
+ me->group_index_returned_++;
+ } else if (group_index_returned_ < 0 ||
+ static_cast<size_t>(group_index_returned_) != index) {
+ XmlElement * group_element = raw_xml_->FirstNamed(QN_ROSTER_GROUP);
+ size_t group_index = 0;
+ while(group_index < index) {
+ ASSERT(group_element != NULL);
+ group_index++;
+ group_element = group_element->NextNamed(QN_ROSTER_GROUP);
+ }
+
+ XmppRosterContactImpl * me = const_cast<XmppRosterContactImpl*>(this);
+ me->group_index_returned_ = static_cast<int>(group_index);
+ me->group_returned_ = group_element;
+ }
+
+ return group_returned_->BodyText();
+}
+
+XmppReturnStatus
+XmppRosterContactImpl::AddGroup(const std::string& group) {
+ if (group == STR_EMPTY)
+ return XMPP_RETURN_BADARGUMENT;
+
+ if (!raw_xml_)
+ CreateRawXmlSkeleton();
+
+ if (FindGroup(group, NULL, NULL))
+ return XMPP_RETURN_OK;
+
+ raw_xml_->AddElement(new XmlElement(QN_ROSTER_GROUP));
+ raw_xml_->AddText(group, 1);
+ ++group_count_;
+
+ return XMPP_RETURN_OK;
+}
+
+XmppReturnStatus
+XmppRosterContactImpl::RemoveGroup(const std::string& group) {
+ if (group == STR_EMPTY)
+ return XMPP_RETURN_BADARGUMENT;
+
+ if (!raw_xml_)
+ return XMPP_RETURN_OK;
+
+ XmlChild * child_before;
+ if (FindGroup(group, NULL, &child_before)) {
+ raw_xml_->RemoveChildAfter(child_before);
+ ResetGroupCache();
+ }
+ return XMPP_RETURN_OK;
+}
+
+bool
+XmppRosterContactImpl::FindGroup(const std::string& group,
+ XmlElement** element,
+ XmlChild** child_before) {
+ XmlChild * prev_child = NULL;
+ XmlChild * next_child;
+ XmlChild * child;
+ for (child = raw_xml_->FirstChild(); child; child = next_child) {
+ next_child = child->NextChild();
+ if (!child->IsText() &&
+ child->AsElement()->Name() == QN_ROSTER_GROUP &&
+ child->AsElement()->BodyText() == group) {
+ if (element)
+ *element = child->AsElement();
+ if (child_before)
+ *child_before = prev_child;
+ return true;
+ }
+ prev_child = child;
+ }
+
+ return false;
+}
+
+const XmlElement*
+XmppRosterContactImpl::raw_xml() const {
+ if (!raw_xml_)
+ const_cast<XmppRosterContactImpl*>(this)->CreateRawXmlSkeleton();
+ return raw_xml_.get();
+}
+
+XmppReturnStatus
+XmppRosterContactImpl::set_raw_xml(const XmlElement* xml) {
+ if (!xml ||
+ xml->Name() != QN_ROSTER_ITEM ||
+ xml->HasAttr(QN_SUBSCRIPTION) ||
+ xml->HasAttr(QN_ASK))
+ return XMPP_RETURN_BADARGUMENT;
+
+ ResetGroupCache();
+
+ raw_xml_.reset(new XmlElement(*xml));
+
+ return XMPP_RETURN_OK;
+}
+
+void
+XmppRosterContactImpl::CreateRawXmlSkeleton() {
+ raw_xml_.reset(new XmlElement(QN_ROSTER_ITEM));
+}
+
+// XmppRosterModuleImpl --------------------------------------------------------
+XmppRosterModule *
+XmppRosterModule::Create() {
+ return new XmppRosterModuleImpl();
+}
+
+XmppRosterModuleImpl::XmppRosterModuleImpl() :
+ roster_handler_(NULL),
+ incoming_presence_map_(new JidPresenceVectorMap()),
+ incoming_presence_vector_(new PresenceVector()),
+ contacts_(new ContactVector()) {
+
+}
+
+XmppRosterModuleImpl::~XmppRosterModuleImpl() {
+ DeleteIncomingPresence();
+ DeleteContacts();
+}
+
+XmppReturnStatus
+XmppRosterModuleImpl::set_roster_handler(XmppRosterHandler * handler) {
+ roster_handler_ = handler;
+ return XMPP_RETURN_OK;
+}
+
+XmppRosterHandler*
+XmppRosterModuleImpl::roster_handler() {
+ return roster_handler_;
+}
+
+XmppPresence*
+XmppRosterModuleImpl::outgoing_presence() {
+ return &outgoing_presence_;
+}
+
+XmppReturnStatus
+XmppRosterModuleImpl::BroadcastPresence() {
+ // Scrub the outgoing presence
+ const XmlElement* element = outgoing_presence_.raw_xml();
+
+ ASSERT(!element->HasAttr(QN_TO) &&
+ !element->HasAttr(QN_FROM) &&
+ (element->Attr(QN_TYPE) == STR_EMPTY ||
+ element->Attr(QN_TYPE) == "unavailable"));
+
+ if (!engine())
+ return XMPP_RETURN_BADSTATE;
+
+ return engine()->SendStanza(element);
+}
+
+XmppReturnStatus
+XmppRosterModuleImpl::SendDirectedPresence(const XmppPresence* presence,
+ const Jid& to_jid) {
+ if (!presence)
+ return XMPP_RETURN_BADARGUMENT;
+
+ if (!engine())
+ return XMPP_RETURN_BADSTATE;
+
+ XmlElement element(*(presence->raw_xml()));
+
+ if (element.Name() != QN_PRESENCE ||
+ element.HasAttr(QN_TO) ||
+ element.HasAttr(QN_FROM))
+ return XMPP_RETURN_BADARGUMENT;
+
+ if (element.HasAttr(QN_TYPE)) {
+ if (element.Attr(QN_TYPE) != STR_EMPTY &&
+ element.Attr(QN_TYPE) != "unavailable") {
+ return XMPP_RETURN_BADARGUMENT;
+ }
+ }
+
+ element.SetAttr(QN_TO, to_jid.Str());
+
+ return engine()->SendStanza(&element);
+}
+
+size_t
+XmppRosterModuleImpl::GetIncomingPresenceCount() {
+ return incoming_presence_vector_->size();
+}
+
+const XmppPresence*
+XmppRosterModuleImpl::GetIncomingPresence(size_t index) {
+ if (index >= incoming_presence_vector_->size())
+ return NULL;
+ return (*incoming_presence_vector_)[index];
+}
+
+size_t
+XmppRosterModuleImpl::GetIncomingPresenceForJidCount(const Jid& jid)
+{
+ // find the vector in the map
+ JidPresenceVectorMap::iterator pos;
+ pos = incoming_presence_map_->find(jid);
+ if (pos == incoming_presence_map_->end())
+ return 0;
+
+ ASSERT(pos->second != NULL);
+
+ return pos->second->size();
+}
+
+const XmppPresence*
+XmppRosterModuleImpl::GetIncomingPresenceForJid(const Jid& jid,
+ size_t index) {
+ JidPresenceVectorMap::iterator pos;
+ pos = incoming_presence_map_->find(jid);
+ if (pos == incoming_presence_map_->end())
+ return NULL;
+
+ ASSERT(pos->second != NULL);
+
+ if (index >= pos->second->size())
+ return NULL;
+
+ return (*pos->second)[index];
+}
+
+XmppReturnStatus
+XmppRosterModuleImpl::RequestRosterUpdate() {
+ if (!engine())
+ return XMPP_RETURN_BADSTATE;
+
+ XmlElement roster_get(QN_IQ);
+ roster_get.AddAttr(QN_TYPE, "get");
+ roster_get.AddAttr(QN_ID, engine()->NextId());
+ roster_get.AddElement(new XmlElement(QN_ROSTER_QUERY, true));
+ return engine()->SendIq(&roster_get, this, NULL);
+}
+
+size_t
+XmppRosterModuleImpl::GetRosterContactCount() {
+ return contacts_->size();
+}
+
+const XmppRosterContact*
+XmppRosterModuleImpl::GetRosterContact(size_t index) {
+ if (index >= contacts_->size())
+ return NULL;
+ return (*contacts_)[index];
+}
+
+class RosterPredicate {
+public:
+ explicit RosterPredicate(const Jid& jid) : jid_(jid) {
+ }
+
+ bool operator() (XmppRosterContactImpl *& contact) {
+ return contact->jid() == jid_;
+ }
+
+private:
+ Jid jid_;
+};
+
+const XmppRosterContact*
+XmppRosterModuleImpl::FindRosterContact(const Jid& jid) {
+ ContactVector::iterator pos;
+
+ pos = std::find_if(contacts_->begin(),
+ contacts_->end(),
+ RosterPredicate(jid));
+ if (pos == contacts_->end())
+ return NULL;
+
+ return *pos;
+}
+
+XmppReturnStatus
+XmppRosterModuleImpl::RequestRosterChange(
+ const XmppRosterContact* contact) {
+ if (!contact)
+ return XMPP_RETURN_BADARGUMENT;
+
+ Jid jid = contact->jid();
+
+ if (!jid.IsValid())
+ return XMPP_RETURN_BADARGUMENT;
+
+ if (!engine())
+ return XMPP_RETURN_BADSTATE;
+
+ const XmlElement* contact_xml = contact->raw_xml();
+ if (contact_xml->Name() != QN_ROSTER_ITEM ||
+ contact_xml->HasAttr(QN_SUBSCRIPTION) ||
+ contact_xml->HasAttr(QN_ASK))
+ return XMPP_RETURN_BADARGUMENT;
+
+ XmlElement roster_add(QN_IQ);
+ roster_add.AddAttr(QN_TYPE, "set");
+ roster_add.AddAttr(QN_ID, engine()->NextId());
+ roster_add.AddElement(new XmlElement(QN_ROSTER_QUERY, true));
+ roster_add.AddElement(new XmlElement(*contact_xml), 1);
+
+ return engine()->SendIq(&roster_add, this, NULL);
+}
+
+XmppReturnStatus
+XmppRosterModuleImpl::RequestRosterRemove(const Jid& jid) {
+ if (!jid.IsValid())
+ return XMPP_RETURN_BADARGUMENT;
+
+ if (!engine())
+ return XMPP_RETURN_BADSTATE;
+
+ XmlElement roster_add(QN_IQ);
+ roster_add.AddAttr(QN_TYPE, "set");
+ roster_add.AddAttr(QN_ID, engine()->NextId());
+ roster_add.AddElement(new XmlElement(QN_ROSTER_QUERY, true));
+ roster_add.AddAttr(QN_JID, jid.Str(), 1);
+ roster_add.AddAttr(QN_SUBSCRIPTION, "remove", 1);
+
+ return engine()->SendIq(&roster_add, this, NULL);
+}
+
+XmppReturnStatus
+XmppRosterModuleImpl::RequestSubscription(const Jid& jid) {
+ return SendSubscriptionRequest(jid, "subscribe");
+}
+
+XmppReturnStatus
+XmppRosterModuleImpl::CancelSubscription(const Jid& jid) {
+ return SendSubscriptionRequest(jid, "unsubscribe");
+}
+
+XmppReturnStatus
+XmppRosterModuleImpl::ApproveSubscriber(const Jid& jid) {
+ return SendSubscriptionRequest(jid, "subscribed");
+}
+
+XmppReturnStatus
+XmppRosterModuleImpl::CancelSubscriber(const Jid& jid) {
+ return SendSubscriptionRequest(jid, "unsubscribed");
+}
+
+void
+XmppRosterModuleImpl::IqResponse(XmppIqCookie, const XmlElement * stanza) {
+ // The only real Iq response that we expect to recieve are initial roster
+ // population
+ if (stanza->Attr(QN_TYPE) == "error")
+ {
+ if (roster_handler_)
+ roster_handler_->RosterError(this, stanza);
+
+ return;
+ }
+
+ ASSERT(stanza->Attr(QN_TYPE) == "result");
+
+ InternalRosterItems(stanza);
+}
+
+bool
+XmppRosterModuleImpl::HandleStanza(const XmlElement * stanza)
+{
+ ASSERT(engine() != NULL);
+
+ // There are two types of stanzas that we care about: presence and roster push
+ // Iqs
+ if (stanza->Name() == QN_PRESENCE) {
+ const std::string& jid_string = stanza->Attr(QN_FROM);
+ Jid jid(jid_string);
+
+ if (!jid.IsValid())
+ return false; // if the Jid isn't valid, don't process
+
+ const std::string& type = stanza->Attr(QN_TYPE);
+ XmppSubscriptionRequestType request_type;
+ if (StringToSubscriptionRequestType(type, &request_type))
+ InternalSubscriptionRequest(jid, stanza, request_type);
+ else if (type == "unavailable" || type == STR_EMPTY)
+ InternalIncomingPresence(jid, stanza);
+ else if (type == "error")
+ InternalIncomingPresenceError(jid, stanza);
+ else
+ return false;
+
+ return true;
+ } else if (stanza->Name() == QN_IQ) {
+ const XmlElement * roster_query = stanza->FirstNamed(QN_ROSTER_QUERY);
+ if (!roster_query || stanza->Attr(QN_TYPE) != "set")
+ return false;
+
+ InternalRosterItems(stanza);
+
+ // respond to the IQ
+ XmlElement result(QN_IQ);
+ result.AddAttr(QN_TYPE, "result");
+ result.AddAttr(QN_TO, stanza->Attr(QN_FROM));
+ result.AddAttr(QN_ID, stanza->Attr(QN_ID));
+
+ engine()->SendStanza(&result);
+ return true;
+ }
+
+ return false;
+}
+
+void
+XmppRosterModuleImpl::DeleteIncomingPresence() {
+ // Clear out the vector of all presence notifications
+ {
+ PresenceVector::iterator pos;
+ for (pos = incoming_presence_vector_->begin();
+ pos < incoming_presence_vector_->end();
+ ++pos) {
+ XmppPresenceImpl * presence = *pos;
+ *pos = NULL;
+ delete presence;
+ }
+ incoming_presence_vector_->clear();
+ }
+
+ // Clear out all of the small presence vectors per Jid
+ {
+ JidPresenceVectorMap::iterator pos;
+ for (pos = incoming_presence_map_->begin();
+ pos != incoming_presence_map_->end();
+ ++pos) {
+ PresenceVector* presence_vector = pos->second;
+ pos->second = NULL;
+ delete presence_vector;
+ }
+ incoming_presence_map_->clear();
+ }
+}
+
+void
+XmppRosterModuleImpl::DeleteContacts() {
+ ContactVector::iterator pos;
+ for (pos = contacts_->begin();
+ pos < contacts_->end();
+ ++pos) {
+ XmppRosterContact* contact = *pos;
+ *pos = NULL;
+ delete contact;
+ }
+ contacts_->clear();
+}
+
+XmppReturnStatus
+XmppRosterModuleImpl::SendSubscriptionRequest(const Jid& jid,
+ const std::string& type) {
+ if (!jid.IsValid())
+ return XMPP_RETURN_BADARGUMENT;
+
+ if (!engine())
+ return XMPP_RETURN_BADSTATE;
+
+ XmlElement presence_request(QN_PRESENCE);
+ presence_request.AddAttr(QN_TO, jid.Str());
+ presence_request.AddAttr(QN_TYPE, type);
+
+ return engine()->SendStanza(&presence_request);
+}
+
+
+void
+XmppRosterModuleImpl::InternalSubscriptionRequest(const Jid& jid,
+ const XmlElement* stanza,
+ XmppSubscriptionRequestType
+ request_type) {
+ if (roster_handler_)
+ roster_handler_->SubscriptionRequest(this, jid, request_type, stanza);
+}
+
+class PresencePredicate {
+public:
+ explicit PresencePredicate(const Jid& jid) : jid_(jid) {
+ }
+
+ bool operator() (XmppPresenceImpl *& contact) {
+ return contact->jid() == jid_;
+ }
+
+private:
+ Jid jid_;
+};
+
+void
+XmppRosterModuleImpl::InternalIncomingPresence(const Jid& jid,
+ const XmlElement* stanza) {
+ bool added = false;
+ Jid bare_jid = jid.BareJid();
+
+ // First add the presence to the map
+ JidPresenceVectorMap::iterator pos;
+ pos = incoming_presence_map_->find(jid.BareJid());
+ if (pos == incoming_presence_map_->end()) {
+ // Insert a new entry into the map. Get the position of this new entry
+ pos = (incoming_presence_map_->insert(
+ std::make_pair(bare_jid, new PresenceVector()))).first;
+ }
+
+ PresenceVector * presence_vector = pos->second;
+ ASSERT(presence_vector != NULL);
+
+ // Try to find this jid in the bare jid bucket
+ PresenceVector::iterator presence_pos;
+ XmppPresenceImpl* presence;
+ presence_pos = std::find_if(presence_vector->begin(),
+ presence_vector->end(),
+ PresencePredicate(jid));
+
+ // Update/add it to the bucket
+ if (presence_pos == presence_vector->end()) {
+ presence = new XmppPresenceImpl();
+ if (XMPP_RETURN_OK == presence->set_raw_xml(stanza)) {
+ added = true;
+ presence_vector->push_back(presence);
+ } else {
+ delete presence;
+ presence = NULL;
+ }
+ } else {
+ presence = *presence_pos;
+ presence->set_raw_xml(stanza);
+ }
+
+ // now add to the comprehensive vector
+ if (added)
+ incoming_presence_vector_->push_back(presence);
+
+ // Call back to the user with the changed presence information
+ if (roster_handler_)
+ roster_handler_->IncomingPresenceChanged(this, presence);
+}
+
+
+void
+XmppRosterModuleImpl::InternalIncomingPresenceError(const Jid& jid,
+ const XmlElement* stanza) {
+ if (roster_handler_)
+ roster_handler_->SubscriptionError(this, jid, stanza);
+}
+
+void
+XmppRosterModuleImpl::InternalRosterItems(const XmlElement* stanza) {
+ const XmlElement* result_data = stanza->FirstNamed(QN_ROSTER_QUERY);
+ if (!result_data)
+ return; // unknown stuff in result!
+
+ bool all_new = contacts_->empty();
+
+ for (const XmlElement* roster_item = result_data->FirstNamed(QN_ROSTER_ITEM);
+ roster_item;
+ roster_item = roster_item->NextNamed(QN_ROSTER_ITEM))
+ {
+ const std::string& jid_string = roster_item->Attr(QN_JID);
+ Jid jid(jid_string);
+ if (!jid.IsValid())
+ continue;
+
+ // This algorithm is N^2 on the number of incoming contacts after the
+ // initial load. There is no way to do this faster without allowing
+ // duplicates, introducing more data structures or write a custom data
+ // structure. We'll see if this becomes a perf problem and fix it if it
+ // does.
+ ContactVector::iterator pos = contacts_->end();
+
+ if (!all_new) {
+ pos = std::find_if(contacts_->begin(),
+ contacts_->end(),
+ RosterPredicate(jid));
+ }
+
+ if (pos != contacts_->end()) { // Update/remove a current contact
+ if (roster_item->Attr(QN_SUBSCRIPTION) == "remove") {
+ XmppRosterContact* contact = *pos;
+ contacts_->erase(pos);
+ if (roster_handler_)
+ roster_handler_->ContactRemoved(this, contact,
+ std::distance(contacts_->begin(), pos));
+ delete contact;
+ } else {
+ XmppRosterContact* old_contact = *pos;
+ *pos = new XmppRosterContactImpl();
+ (*pos)->SetXmlFromWire(roster_item);
+ if (roster_handler_)
+ roster_handler_->ContactChanged(this, old_contact,
+ std::distance(contacts_->begin(), pos));
+ delete old_contact;
+ }
+ } else { // Add a new contact
+ XmppRosterContactImpl* contact = new XmppRosterContactImpl();
+ contact->SetXmlFromWire(roster_item);
+ contacts_->push_back(contact);
+ if (roster_handler_ && !all_new)
+ roster_handler_->ContactsAdded(this, contacts_->size() - 1, 1);
+ }
+ }
+
+ // Send a consolidated update if all contacts are new
+ if (roster_handler_ && all_new)
+ roster_handler_->ContactsAdded(this, 0, contacts_->size());
+}
+
+}
diff --git a/libjingle/xmpp/rostermoduleimpl.h b/libjingle/xmpp/rostermoduleimpl.h
new file mode 100644
index 00000000..6e3bd91c
--- /dev/null
+++ b/libjingle/xmpp/rostermoduleimpl.h
@@ -0,0 +1,285 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_XMPPTHREAD_H_
+#define WEBRTC_LIBJINGLE_XMPP_XMPPTHREAD_H_
+
+#include "webrtc/libjingle/xmpp/moduleimpl.h"
+#include "webrtc/libjingle/xmpp/rostermodule.h"
+
+namespace buzz {
+
+//! Presence Information
+//! This class stores both presence information for outgoing presence and is
+//! returned by methods in XmppRosterModule to represent received incoming
+//! presence information. When this class is writeable (non-const) then each
+//! update to any property will set the inner xml. Setting the raw_xml will
+//! rederive all of the other properties.
+class XmppPresenceImpl : public XmppPresence {
+public:
+ virtual ~XmppPresenceImpl() {}
+
+ //! The from Jid of for the presence information.
+ //! Typically this will be a full Jid with resource specified. For outgoing
+ //! presence this should remain JID_NULL and will be scrubbed from the
+ //! stanza when being sent.
+ virtual const Jid jid() const;
+
+ //! Is the contact available?
+ virtual XmppPresenceAvailable available() const;
+
+ //! Sets if the user is available or not
+ virtual XmppReturnStatus set_available(XmppPresenceAvailable available);
+
+ //! The show value of the presence info
+ virtual XmppPresenceShow presence_show() const;
+
+ //! Set the presence show value
+ virtual XmppReturnStatus set_presence_show(XmppPresenceShow show);
+
+ //! The Priority of the presence info
+ virtual int priority() const;
+
+ //! Set the priority of the presence
+ virtual XmppReturnStatus set_priority(int priority);
+
+ //! The plain text status of the presence info.
+ //! If there are multiple status because of language, this will either be a
+ //! status that is not tagged for language or the first available
+ virtual const std::string status() const;
+
+ //! Sets the status for the presence info.
+ //! If there is more than one status present already then this will remove
+ //! them all and replace it with one status element we no specified language
+ virtual XmppReturnStatus set_status(const std::string& status);
+
+ //! The connection status
+ virtual XmppPresenceConnectionStatus connection_status() const;
+
+ //! The focus obfuscated GAIA id
+ virtual const std::string google_user_id() const;
+
+ //! The nickname in the presence
+ virtual const std::string nickname() const;
+
+ //! The raw xml of the presence update
+ virtual const XmlElement* raw_xml() const;
+
+ //! Sets the raw presence stanza for the presence update
+ //! This will cause all other data items in this structure to be rederived
+ virtual XmppReturnStatus set_raw_xml(const XmlElement * xml);
+
+private:
+ XmppPresenceImpl();
+
+ friend class XmppPresence;
+ friend class XmppRosterModuleImpl;
+
+ void CreateRawXmlSkeleton();
+
+ // Store everything in the XML element. If this becomes a perf issue we can
+ // cache the data.
+ rtc::scoped_ptr<XmlElement> raw_xml_;
+};
+
+//! A contact as given by the server
+class XmppRosterContactImpl : public XmppRosterContact {
+public:
+ virtual ~XmppRosterContactImpl() {}
+
+ //! The jid for the contact.
+ //! Typically this will be a bare Jid.
+ virtual const Jid jid() const;
+
+ //! Sets the jid for the roster contact update
+ virtual XmppReturnStatus set_jid(const Jid& jid);
+
+ //! The name (nickname) stored for this contact
+ virtual const std::string name() const;
+
+ //! Sets the name
+ virtual XmppReturnStatus set_name(const std::string& name);
+
+ //! The Presence subscription state stored on the server for this contact
+ //! This is never settable and will be ignored when generating a roster
+ //! add/update request
+ virtual XmppSubscriptionState subscription_state() const;
+
+ //! The number of Groups applied to this contact
+ virtual size_t GetGroupCount() const;
+
+ //! Gets a Group applied to the contact based on index.
+ virtual const std::string GetGroup(size_t index) const;
+
+ //! Adds a group to this contact.
+ //! This will return a no error if the group is already present.
+ virtual XmppReturnStatus AddGroup(const std::string& group);
+
+ //! Removes a group from the contact.
+ //! This will return no error if the group isn't there
+ virtual XmppReturnStatus RemoveGroup(const std::string& group);
+
+ //! The raw xml for this roster contact
+ virtual const XmlElement* raw_xml() const;
+
+ //! Sets the raw presence stanza for the presence update
+ //! This will cause all other data items in this structure to be rederived
+ virtual XmppReturnStatus set_raw_xml(const XmlElement * xml);
+
+private:
+ XmppRosterContactImpl();
+
+ void CreateRawXmlSkeleton();
+ void SetXmlFromWire(const XmlElement * xml);
+ void ResetGroupCache();
+
+ bool FindGroup(const std::string& group,
+ XmlElement** element,
+ XmlChild** child_before);
+
+
+ friend class XmppRosterContact;
+ friend class XmppRosterModuleImpl;
+
+ int group_count_;
+ int group_index_returned_;
+ XmlElement * group_returned_;
+ rtc::scoped_ptr<XmlElement> raw_xml_;
+};
+
+//! An XmppModule for handle roster and presence functionality
+class XmppRosterModuleImpl : public XmppModuleImpl,
+ public XmppRosterModule, public XmppIqHandler {
+public:
+ virtual ~XmppRosterModuleImpl();
+
+ IMPLEMENT_XMPPMODULE
+
+ //! Sets the roster handler (callbacks) for the module
+ virtual XmppReturnStatus set_roster_handler(XmppRosterHandler * handler);
+
+ //! Gets the roster handler for the module
+ virtual XmppRosterHandler* roster_handler();
+
+ // USER PRESENCE STATE -------------------------------------------------------
+
+ //! Gets the aggregate outgoing presence
+ //! This object is non-const and be edited directly. No update is sent
+ //! to the server until a Broadcast is sent
+ virtual XmppPresence* outgoing_presence();
+
+ //! Broadcasts that the user is available.
+ //! Nothing with respect to presence is sent until this is called.
+ virtual XmppReturnStatus BroadcastPresence();
+
+ //! Sends a directed presence to a Jid
+ //! Note that the client doesn't store where directed presence notifications
+ //! have been sent. The server can keep the appropriate state
+ virtual XmppReturnStatus SendDirectedPresence(const XmppPresence* presence,
+ const Jid& to_jid);
+
+ // INCOMING PRESENCE STATUS --------------------------------------------------
+
+ //! Returns the number of incoming presence data recorded
+ virtual size_t GetIncomingPresenceCount();
+
+ //! Returns an incoming presence datum based on index
+ virtual const XmppPresence* GetIncomingPresence(size_t index);
+
+ //! Gets the number of presence data for a bare Jid
+ //! There may be a datum per resource
+ virtual size_t GetIncomingPresenceForJidCount(const Jid& jid);
+
+ //! Returns a single presence data for a Jid based on index
+ virtual const XmppPresence* GetIncomingPresenceForJid(const Jid& jid,
+ size_t index);
+
+ // ROSTER MANAGEMENT ---------------------------------------------------------
+
+ //! Requests an update of the roster from the server
+ //! This must be called to initialize the client side cache of the roster
+ //! After this is sent the server should keep this module apprised of any
+ //! changes.
+ virtual XmppReturnStatus RequestRosterUpdate();
+
+ //! Returns the number of contacts in the roster
+ virtual size_t GetRosterContactCount();
+
+ //! Returns a contact by index
+ virtual const XmppRosterContact* GetRosterContact(size_t index);
+
+ //! Finds a contact by Jid
+ virtual const XmppRosterContact* FindRosterContact(const Jid& jid);
+
+ //! Send a request to the server to add a contact
+ //! Note that the contact won't show up in the roster until the server can
+ //! respond. This happens async when the socket is being serviced
+ virtual XmppReturnStatus RequestRosterChange(
+ const XmppRosterContact* contact);
+
+ //! Request that the server remove a contact
+ //! The jabber protocol specifies that the server should also cancel any
+ //! subscriptions when this is done. Like adding, this contact won't be
+ //! removed until the server responds.
+ virtual XmppReturnStatus RequestRosterRemove(const Jid& jid);
+
+ // SUBSCRIPTION MANAGEMENT ---------------------------------------------------
+
+ //! Request a subscription to presence notifications form a Jid
+ virtual XmppReturnStatus RequestSubscription(const Jid& jid);
+
+ //! Cancel a subscription to presence notifications from a Jid
+ virtual XmppReturnStatus CancelSubscription(const Jid& jid);
+
+ //! Approve a request to deliver presence notifications to a jid
+ virtual XmppReturnStatus ApproveSubscriber(const Jid& jid);
+
+ //! Deny or cancel presence notification deliver to a jid
+ virtual XmppReturnStatus CancelSubscriber(const Jid& jid);
+
+ // XmppIqHandler IMPLEMENTATION ----------------------------------------------
+ virtual void IqResponse(XmppIqCookie cookie, const XmlElement * stanza);
+
+protected:
+ // XmppModuleImpl OVERRIDES --------------------------------------------------
+ virtual bool HandleStanza(const XmlElement *);
+
+ // PRIVATE DATA --------------------------------------------------------------
+private:
+ friend class XmppRosterModule;
+ XmppRosterModuleImpl();
+
+ // Helper functions
+ void DeleteIncomingPresence();
+ void DeleteContacts();
+ XmppReturnStatus SendSubscriptionRequest(const Jid& jid,
+ const std::string& type);
+ void InternalSubscriptionRequest(const Jid& jid, const XmlElement* stanza,
+ XmppSubscriptionRequestType request_type);
+ void InternalIncomingPresence(const Jid& jid, const XmlElement* stanza);
+ void InternalIncomingPresenceError(const Jid& jid, const XmlElement* stanza);
+ void InternalRosterItems(const XmlElement* stanza);
+
+ // Member data
+ XmppPresenceImpl outgoing_presence_;
+ XmppRosterHandler* roster_handler_;
+
+ typedef std::vector<XmppPresenceImpl*> PresenceVector;
+ typedef std::map<Jid, PresenceVector*> JidPresenceVectorMap;
+ rtc::scoped_ptr<JidPresenceVectorMap> incoming_presence_map_;
+ rtc::scoped_ptr<PresenceVector> incoming_presence_vector_;
+
+ typedef std::vector<XmppRosterContactImpl*> ContactVector;
+ rtc::scoped_ptr<ContactVector> contacts_;
+};
+
+}
+
+#endif // WEBRTC_LIBJINGLE_XMPP_XMPPTHREAD_H_
diff --git a/libjingle/xmpp/saslcookiemechanism.h b/libjingle/xmpp/saslcookiemechanism.h
new file mode 100644
index 00000000..7a912466
--- /dev/null
+++ b/libjingle/xmpp/saslcookiemechanism.h
@@ -0,0 +1,69 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_SASLCOOKIEMECHANISM_H_
+#define WEBRTC_LIBJINGLE_XMPP_SASLCOOKIEMECHANISM_H_
+
+#include "webrtc/libjingle/xmllite/qname.h"
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/saslmechanism.h"
+
+namespace buzz {
+
+class SaslCookieMechanism : public SaslMechanism {
+
+public:
+ SaslCookieMechanism(const std::string & mechanism,
+ const std::string & username,
+ const std::string & cookie,
+ const std::string & token_service)
+ : mechanism_(mechanism),
+ username_(username),
+ cookie_(cookie),
+ token_service_(token_service) {}
+
+ SaslCookieMechanism(const std::string & mechanism,
+ const std::string & username,
+ const std::string & cookie)
+ : mechanism_(mechanism),
+ username_(username),
+ cookie_(cookie),
+ token_service_("") {}
+
+ virtual std::string GetMechanismName() { return mechanism_; }
+
+ virtual XmlElement * StartSaslAuth() {
+ // send initial request
+ XmlElement * el = new XmlElement(QN_SASL_AUTH, true);
+ el->AddAttr(QN_MECHANISM, mechanism_);
+ if (!token_service_.empty()) {
+ el->AddAttr(QN_GOOGLE_AUTH_SERVICE, token_service_);
+ }
+
+ std::string credential;
+ credential.append("\0", 1);
+ credential.append(username_);
+ credential.append("\0", 1);
+ credential.append(cookie_);
+ el->AddText(Base64Encode(credential));
+ return el;
+ }
+
+private:
+ std::string mechanism_;
+ std::string username_;
+ std::string cookie_;
+ std::string token_service_;
+};
+
+}
+
+#endif // WEBRTC_LIBJINGLE_XMPP_SASLCOOKIEMECHANISM_H_
diff --git a/libjingle/xmpp/saslhandler.h b/libjingle/xmpp/saslhandler.h
new file mode 100644
index 00000000..f2e38444
--- /dev/null
+++ b/libjingle/xmpp/saslhandler.h
@@ -0,0 +1,42 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_SASLHANDLER_H_
+#define WEBRTC_LIBJINGLE_XMPP_SASLHANDLER_H_
+
+#include <string>
+#include <vector>
+
+namespace buzz {
+
+class XmlElement;
+class SaslMechanism;
+
+// Creates mechanisms to deal with a given mechanism
+class SaslHandler {
+
+public:
+
+ // Intended to be subclassed
+ virtual ~SaslHandler() {}
+
+ // Should pick the best method according to this handler
+ // returns the empty string if none are suitable
+ virtual std::string ChooseBestSaslMechanism(const std::vector<std::string> & mechanisms, bool encrypted) = 0;
+
+ // Creates a SaslMechanism for the given mechanism name (you own it
+ // once you get it).
+ // If not handled, return NULL.
+ virtual SaslMechanism * CreateSaslMechanism(const std::string & mechanism) = 0;
+};
+
+}
+
+#endif // WEBRTC_LIBJINGLE_XMPP_SASLHANDLER_H_
diff --git a/libjingle/xmpp/saslmechanism.cc b/libjingle/xmpp/saslmechanism.cc
new file mode 100644
index 00000000..b4d6e9ba
--- /dev/null
+++ b/libjingle/xmpp/saslmechanism.cc
@@ -0,0 +1,55 @@
+/*
+ * 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 "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/saslmechanism.h"
+#include "webrtc/base/base64.h"
+
+using rtc::Base64;
+
+namespace buzz {
+
+XmlElement *
+SaslMechanism::StartSaslAuth() {
+ return new XmlElement(QN_SASL_AUTH, true);
+}
+
+XmlElement *
+SaslMechanism::HandleSaslChallenge(const XmlElement * challenge) {
+ return new XmlElement(QN_SASL_ABORT, true);
+}
+
+void
+SaslMechanism::HandleSaslSuccess(const XmlElement * success) {
+}
+
+void
+SaslMechanism::HandleSaslFailure(const XmlElement * failure) {
+}
+
+std::string
+SaslMechanism::Base64Encode(const std::string & plain) {
+ return Base64::Encode(plain);
+}
+
+std::string
+SaslMechanism::Base64Decode(const std::string & encoded) {
+ return Base64::Decode(encoded, Base64::DO_LAX);
+}
+
+std::string
+SaslMechanism::Base64EncodeFromArray(const char * plain, size_t length) {
+ std::string result;
+ Base64::EncodeFromArray(plain, length, &result);
+ return result;
+}
+
+}
diff --git a/libjingle/xmpp/saslmechanism.h b/libjingle/xmpp/saslmechanism.h
new file mode 100644
index 00000000..9c392e56
--- /dev/null
+++ b/libjingle/xmpp/saslmechanism.h
@@ -0,0 +1,57 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_SASLMECHANISM_H_
+#define WEBRTC_LIBJINGLE_XMPP_SASLMECHANISM_H_
+
+#include <string>
+
+namespace buzz {
+
+class XmlElement;
+
+
+// Defines a mechnanism to do SASL authentication.
+// Subclass instances should have a self-contained way to present
+// credentials.
+class SaslMechanism {
+
+public:
+
+ // Intended to be subclassed
+ virtual ~SaslMechanism() {}
+
+ // Should return the name of the SASL mechanism, e.g., "PLAIN"
+ virtual std::string GetMechanismName() = 0;
+
+ // Should generate the initial "auth" request. Default is just <auth/>.
+ virtual XmlElement * StartSaslAuth();
+
+ // Should respond to a SASL "<challenge>" request. Default is
+ // to abort (for mechanisms that do not do challenge-response)
+ virtual XmlElement * HandleSaslChallenge(const XmlElement * challenge);
+
+ // Notification of a SASL "<success>". Sometimes information
+ // is passed on success.
+ virtual void HandleSaslSuccess(const XmlElement * success);
+
+ // Notification of a SASL "<failure>". Sometimes information
+ // for the user is passed on failure.
+ virtual void HandleSaslFailure(const XmlElement * failure);
+
+protected:
+ static std::string Base64Encode(const std::string & plain);
+ static std::string Base64Decode(const std::string & encoded);
+ static std::string Base64EncodeFromArray(const char * plain, size_t length);
+};
+
+}
+
+#endif // WEBRTC_LIBJINGLE_XMPP_SASLMECHANISM_H_
diff --git a/libjingle/xmpp/saslplainmechanism.h b/libjingle/xmpp/saslplainmechanism.h
new file mode 100644
index 00000000..8e162e25
--- /dev/null
+++ b/libjingle/xmpp/saslplainmechanism.h
@@ -0,0 +1,48 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_SASLPLAINMECHANISM_H_
+#define WEBRTC_LIBJINGLE_XMPP_SASLPLAINMECHANISM_H_
+
+#include "webrtc/libjingle/xmpp/saslmechanism.h"
+#include "webrtc/base/cryptstring.h"
+
+namespace buzz {
+
+class SaslPlainMechanism : public SaslMechanism {
+
+public:
+ SaslPlainMechanism(const buzz::Jid user_jid, const rtc::CryptString & password) :
+ user_jid_(user_jid), password_(password) {}
+
+ virtual std::string GetMechanismName() { return "PLAIN"; }
+
+ virtual XmlElement * StartSaslAuth() {
+ // send initial request
+ XmlElement * el = new XmlElement(QN_SASL_AUTH, true);
+ el->AddAttr(QN_MECHANISM, "PLAIN");
+
+ rtc::FormatCryptString credential;
+ credential.Append("\0", 1);
+ credential.Append(user_jid_.node());
+ credential.Append("\0", 1);
+ credential.Append(&password_);
+ el->AddText(Base64EncodeFromArray(credential.GetData(), credential.GetLength()));
+ return el;
+ }
+
+private:
+ Jid user_jid_;
+ rtc::CryptString password_;
+};
+
+}
+
+#endif // WEBRTC_LIBJINGLE_XMPP_SASLPLAINMECHANISM_H_
diff --git a/libjingle/xmpp/util_unittest.cc b/libjingle/xmpp/util_unittest.cc
new file mode 100644
index 00000000..330ab48e
--- /dev/null
+++ b/libjingle/xmpp/util_unittest.cc
@@ -0,0 +1,109 @@
+/*
+ * 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 <iostream>
+#include <sstream>
+#include <string>
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/util_unittest.h"
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+#include "webrtc/base/gunit.h"
+
+namespace buzz {
+
+void XmppTestHandler::WriteOutput(const char * bytes, size_t len) {
+ output_ << std::string(bytes, len);
+}
+
+void XmppTestHandler::StartTls(const std::string & cname) {
+ output_ << "[START-TLS " << cname << "]";
+}
+
+void XmppTestHandler::CloseConnection() {
+ output_ << "[CLOSED]";
+}
+
+void XmppTestHandler::OnStateChange(int state) {
+ switch (static_cast<XmppEngine::State>(state)) {
+ case XmppEngine::STATE_START:
+ session_ << "[START]";
+ break;
+ case XmppEngine::STATE_OPENING:
+ session_ << "[OPENING]";
+ break;
+ case XmppEngine::STATE_OPEN:
+ session_ << "[OPEN]";
+ break;
+ case XmppEngine::STATE_CLOSED:
+ session_ << "[CLOSED]";
+ switch (engine_->GetError(NULL)) {
+ case XmppEngine::ERROR_NONE:
+ // do nothing
+ break;
+ case XmppEngine::ERROR_XML:
+ session_ << "[ERROR-XML]";
+ break;
+ case XmppEngine::ERROR_STREAM:
+ session_ << "[ERROR-STREAM]";
+ break;
+ case XmppEngine::ERROR_VERSION:
+ session_ << "[ERROR-VERSION]";
+ break;
+ case XmppEngine::ERROR_UNAUTHORIZED:
+ session_ << "[ERROR-UNAUTHORIZED]";
+ break;
+ case XmppEngine::ERROR_TLS:
+ session_ << "[ERROR-TLS]";
+ break;
+ case XmppEngine::ERROR_AUTH:
+ session_ << "[ERROR-AUTH]";
+ break;
+ case XmppEngine::ERROR_BIND:
+ session_ << "[ERROR-BIND]";
+ break;
+ case XmppEngine::ERROR_CONNECTION_CLOSED:
+ session_ << "[ERROR-CONNECTION-CLOSED]";
+ break;
+ case XmppEngine::ERROR_DOCUMENT_CLOSED:
+ session_ << "[ERROR-DOCUMENT-CLOSED]";
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+bool XmppTestHandler::HandleStanza(const XmlElement * stanza) {
+ stanza_ << stanza->Str();
+ return true;
+}
+
+std::string XmppTestHandler::OutputActivity() {
+ std::string result = output_.str();
+ output_.str("");
+ return result;
+}
+
+std::string XmppTestHandler::SessionActivity() {
+ std::string result = session_.str();
+ session_.str("");
+ return result;
+}
+
+std::string XmppTestHandler::StanzaActivity() {
+ std::string result = stanza_.str();
+ stanza_.str("");
+ return result;
+}
+
+} // namespace buzz
diff --git a/libjingle/xmpp/util_unittest.h b/libjingle/xmpp/util_unittest.h
new file mode 100644
index 00000000..38009fb4
--- /dev/null
+++ b/libjingle/xmpp/util_unittest.h
@@ -0,0 +1,58 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_UTIL_UNITTEST_H_
+#define WEBRTC_LIBJINGLE_XMPP_UTIL_UNITTEST_H_
+
+#include <sstream>
+#include <string>
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+
+namespace buzz {
+
+// This class captures callbacks from engine.
+class XmppTestHandler : public XmppOutputHandler, public XmppSessionHandler,
+ public XmppStanzaHandler {
+ public:
+ explicit XmppTestHandler(XmppEngine* engine) : engine_(engine) {}
+ virtual ~XmppTestHandler() {}
+
+ void SetEngine(XmppEngine* engine);
+
+ // Output handler
+ virtual void WriteOutput(const char * bytes, size_t len);
+ virtual void StartTls(const std::string & cname);
+ virtual void CloseConnection();
+
+ // Session handler
+ virtual void OnStateChange(int state);
+
+ // Stanza handler
+ virtual bool HandleStanza(const XmlElement* stanza);
+
+ std::string OutputActivity();
+ std::string SessionActivity();
+ std::string StanzaActivity();
+
+ private:
+ XmppEngine* engine_;
+ std::stringstream output_;
+ std::stringstream session_;
+ std::stringstream stanza_;
+};
+
+} // namespace buzz
+
+inline std::ostream& operator<<(std::ostream& os, const buzz::Jid& jid) {
+ os << jid.Str();
+ return os;
+}
+
+#endif // WEBRTC_LIBJINGLE_XMPP_UTIL_UNITTEST_H_
diff --git a/libjingle/xmpp/xmpp.gyp b/libjingle/xmpp/xmpp.gyp
new file mode 100644
index 00000000..35755d68
--- /dev/null
+++ b/libjingle/xmpp/xmpp.gyp
@@ -0,0 +1,141 @@
+# 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.
+
+{
+ 'includes': [ '../../build/common.gypi', ],
+ 'targets': [
+ {
+ 'target_name': 'rtc_xmpp',
+ 'type': 'static_library',
+ 'dependencies': [
+ '<(webrtc_root)/base/base.gyp:webrtc_base',
+ '<(webrtc_root)/libjingle/xmllite/xmllite.gyp:rtc_xmllite',
+ '<(DEPTH)/third_party/expat/expat.gyp:expat',
+ ],
+ 'defines': [
+ 'FEATURE_ENABLE_SSL',
+ ],
+ 'cflags_cc!': [
+ '-Wnon-virtual-dtor',
+ ],
+ 'export_dependent_settings': [
+ '<(DEPTH)/third_party/expat/expat.gyp:expat',
+ ],
+ 'sources': [
+ 'asyncsocket.h',
+ 'chatroommodule.h',
+ 'chatroommoduleimpl.cc',
+ 'constants.cc',
+ 'constants.h',
+ 'discoitemsquerytask.cc',
+ 'discoitemsquerytask.h',
+ 'hangoutpubsubclient.cc',
+ 'hangoutpubsubclient.h',
+ 'iqtask.cc',
+ 'iqtask.h',
+ 'jid.cc',
+ 'jid.h',
+ 'module.h',
+ 'moduleimpl.cc',
+ 'moduleimpl.h',
+ 'mucroomconfigtask.cc',
+ 'mucroomconfigtask.h',
+ 'mucroomdiscoverytask.cc',
+ 'mucroomdiscoverytask.h',
+ 'mucroomlookuptask.cc',
+ 'mucroomlookuptask.h',
+ 'mucroomuniquehangoutidtask.cc',
+ 'mucroomuniquehangoutidtask.h',
+ 'pingtask.cc',
+ 'pingtask.h',
+ 'plainsaslhandler.h',
+ 'presenceouttask.cc',
+ 'presenceouttask.h',
+ 'presencereceivetask.cc',
+ 'presencereceivetask.h',
+ 'presencestatus.cc',
+ 'presencestatus.h',
+ 'prexmppauth.h',
+ 'pubsub_task.cc',
+ 'pubsub_task.h',
+ 'pubsubclient.cc',
+ 'pubsubclient.h',
+ 'pubsubstateclient.cc',
+ 'pubsubstateclient.h',
+ 'pubsubtasks.cc',
+ 'pubsubtasks.h',
+ 'receivetask.cc',
+ 'receivetask.h',
+ 'rostermodule.h',
+ 'rostermoduleimpl.cc',
+ 'rostermoduleimpl.h',
+ 'saslcookiemechanism.h',
+ 'saslhandler.h',
+ 'saslmechanism.cc',
+ 'saslmechanism.h',
+ 'saslplainmechanism.h',
+ 'xmppauth.cc',
+ 'xmppauth.h',
+ 'xmppclient.cc',
+ 'xmppclient.h',
+ 'xmppclientsettings.h',
+ 'xmppengine.h',
+ 'xmppengineimpl.cc',
+ 'xmppengineimpl.h',
+ 'xmppengineimpl_iq.cc',
+ 'xmpplogintask.cc',
+ 'xmpplogintask.h',
+ 'xmpppump.cc',
+ 'xmpppump.h',
+ 'xmppsocket.cc',
+ 'xmppsocket.h',
+ 'xmppstanzaparser.cc',
+ 'xmppstanzaparser.h',
+ 'xmpptask.cc',
+ 'xmpptask.h',
+ 'xmppthread.cc',
+ 'xmppthread.h',
+ ],
+ 'direct_dependent_settings': {
+ 'cflags_cc!': [
+ '-Wnon-virtual-dtor',
+ ],
+ 'defines': [
+ 'FEATURE_ENABLE_SSL',
+ 'FEATURE_ENABLE_VOICEMAIL',
+ ],
+ },
+ 'conditions': [
+ ['build_with_chromium==0', {
+ 'defines': [
+ 'FEATURE_ENABLE_VOICEMAIL',
+ 'FEATURE_ENABLE_PSTN',
+ ],
+ }],
+ ['os_posix==1', {
+ 'configurations': {
+ 'Debug_Base': {
+ 'defines': [
+ # Chromium's build/common.gypi defines this for all posix
+ # _except_ for ios & mac. We want it there as well, e.g.
+ # because ASSERT and friends trigger off of it.
+ '_DEBUG',
+ ],
+ },
+ }
+ }],
+ ['OS=="android"', {
+ 'cflags!': [
+ '-Wextra',
+ '-Wall',
+ ],
+ }],
+ ],
+ }],
+}
+
diff --git a/libjingle/xmpp/xmpp_tests.gypi b/libjingle/xmpp/xmpp_tests.gypi
new file mode 100644
index 00000000..f1dec1cd
--- /dev/null
+++ b/libjingle/xmpp/xmpp_tests.gypi
@@ -0,0 +1,37 @@
+# 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.
+
+{
+ 'includes': [ '../../build/common.gypi', ],
+ 'targets': [
+ {
+ 'target_name': 'rtc_xmpp_unittest',
+ 'type': 'none',
+ 'direct_dependent_settings': {
+ 'sources': [
+ 'fakexmppclient.h',
+ 'hangoutpubsubclient_unittest.cc',
+ 'jid_unittest.cc',
+ 'mucroomconfigtask_unittest.cc',
+ 'mucroomdiscoverytask_unittest.cc',
+ 'mucroomlookuptask_unittest.cc',
+ 'mucroomuniquehangoutidtask_unittest.cc',
+ 'pingtask_unittest.cc',
+ 'pubsubclient_unittest.cc',
+ 'pubsubtasks_unittest.cc',
+ 'util_unittest.cc',
+ 'util_unittest.h',
+ 'xmppengine_unittest.cc',
+ 'xmpplogintask_unittest.cc',
+ 'xmppstanzaparser_unittest.cc',
+ ],
+ },
+ },
+ ],
+}
+
diff --git a/libjingle/xmpp/xmppauth.cc b/libjingle/xmpp/xmppauth.cc
new file mode 100644
index 00000000..a3d2f678
--- /dev/null
+++ b/libjingle/xmpp/xmppauth.cc
@@ -0,0 +1,88 @@
+/*
+ * 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 "webrtc/libjingle/xmpp/xmppauth.h"
+
+#include <algorithm>
+
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/saslcookiemechanism.h"
+#include "webrtc/libjingle/xmpp/saslplainmechanism.h"
+
+XmppAuth::XmppAuth() : done_(false) {
+}
+
+XmppAuth::~XmppAuth() {
+}
+
+void XmppAuth::StartPreXmppAuth(const buzz::Jid& jid,
+ const rtc::SocketAddress& server,
+ const rtc::CryptString& pass,
+ const std::string& auth_mechanism,
+ const std::string& auth_token) {
+ jid_ = jid;
+ passwd_ = pass;
+ auth_mechanism_ = auth_mechanism;
+ auth_token_ = auth_token;
+ done_ = true;
+
+ SignalAuthDone();
+}
+
+static bool contains(const std::vector<std::string>& strings,
+ const std::string& string) {
+ return std::find(strings.begin(), strings.end(), string) != strings.end();
+}
+
+std::string XmppAuth::ChooseBestSaslMechanism(
+ const std::vector<std::string>& mechanisms,
+ bool encrypted) {
+ // First try Oauth2.
+ if (GetAuthMechanism() == buzz::AUTH_MECHANISM_OAUTH2 &&
+ contains(mechanisms, buzz::AUTH_MECHANISM_OAUTH2)) {
+ return buzz::AUTH_MECHANISM_OAUTH2;
+ }
+
+ // A token is the weakest auth - 15s, service-limited, so prefer it.
+ if (GetAuthMechanism() == buzz::AUTH_MECHANISM_GOOGLE_TOKEN &&
+ contains(mechanisms, buzz::AUTH_MECHANISM_GOOGLE_TOKEN)) {
+ return buzz::AUTH_MECHANISM_GOOGLE_TOKEN;
+ }
+
+ // A cookie is the next weakest - 14 days.
+ if (GetAuthMechanism() == buzz::AUTH_MECHANISM_GOOGLE_COOKIE &&
+ contains(mechanisms, buzz::AUTH_MECHANISM_GOOGLE_COOKIE)) {
+ return buzz::AUTH_MECHANISM_GOOGLE_COOKIE;
+ }
+
+ // As a last resort, use plain authentication.
+ if (contains(mechanisms, buzz::AUTH_MECHANISM_PLAIN)) {
+ return buzz::AUTH_MECHANISM_PLAIN;
+ }
+
+ // No good mechanism found
+ return "";
+}
+
+buzz::SaslMechanism* XmppAuth::CreateSaslMechanism(
+ const std::string& mechanism) {
+ if (mechanism == buzz::AUTH_MECHANISM_OAUTH2) {
+ return new buzz::SaslCookieMechanism(
+ mechanism, jid_.Str(), auth_token_, "oauth2");
+ } else if (mechanism == buzz::AUTH_MECHANISM_GOOGLE_TOKEN) {
+ return new buzz::SaslCookieMechanism(mechanism, jid_.Str(), auth_token_);
+ // } else if (mechanism == buzz::AUTH_MECHANISM_GOOGLE_COOKIE) {
+ // return new buzz::SaslCookieMechanism(mechanism, jid.Str(), sid_);
+ } else if (mechanism == buzz::AUTH_MECHANISM_PLAIN) {
+ return new buzz::SaslPlainMechanism(jid_, passwd_);
+ } else {
+ return NULL;
+ }
+}
diff --git a/libjingle/xmpp/xmppauth.h b/libjingle/xmpp/xmppauth.h
new file mode 100644
index 00000000..dd363d17
--- /dev/null
+++ b/libjingle/xmpp/xmppauth.h
@@ -0,0 +1,61 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_XMPPAUTH_H_
+#define WEBRTC_LIBJINGLE_XMPP_XMPPAUTH_H_
+
+#include <vector>
+
+#include "webrtc/libjingle/xmpp/jid.h"
+#include "webrtc/libjingle/xmpp/prexmppauth.h"
+#include "webrtc/libjingle/xmpp/saslhandler.h"
+#include "webrtc/base/cryptstring.h"
+#include "webrtc/base/sigslot.h"
+
+class XmppAuth: public buzz::PreXmppAuth {
+public:
+ XmppAuth();
+ virtual ~XmppAuth();
+
+ // TODO: Just have one "secret" that is either pass or
+ // token?
+ virtual void StartPreXmppAuth(const buzz::Jid& jid,
+ const rtc::SocketAddress& server,
+ const rtc::CryptString& pass,
+ const std::string& auth_mechanism,
+ const std::string& auth_token);
+
+ virtual bool IsAuthDone() const { return done_; }
+ virtual bool IsAuthorized() const { return true; }
+ virtual bool HadError() const { return false; }
+ virtual int GetError() const { return 0; }
+ virtual buzz::CaptchaChallenge GetCaptchaChallenge() const {
+ return buzz::CaptchaChallenge();
+ }
+ virtual std::string GetAuthMechanism() const { return auth_mechanism_; }
+ virtual std::string GetAuthToken() const { return auth_token_; }
+
+ virtual std::string ChooseBestSaslMechanism(
+ const std::vector<std::string>& mechanisms,
+ bool encrypted);
+
+ virtual buzz::SaslMechanism * CreateSaslMechanism(
+ const std::string& mechanism);
+
+private:
+ buzz::Jid jid_;
+ rtc::CryptString passwd_;
+ std::string auth_mechanism_;
+ std::string auth_token_;
+ bool done_;
+};
+
+#endif // WEBRTC_LIBJINGLE_XMPP_XMPPAUTH_H_
+
diff --git a/libjingle/xmpp/xmppclient.cc b/libjingle/xmpp/xmppclient.cc
new file mode 100644
index 00000000..7c2a5e69
--- /dev/null
+++ b/libjingle/xmpp/xmppclient.cc
@@ -0,0 +1,424 @@
+/*
+ * 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 "webrtc/libjingle/xmpp/xmppclient.h"
+
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/plainsaslhandler.h"
+#include "webrtc/libjingle/xmpp/prexmppauth.h"
+#include "webrtc/libjingle/xmpp/saslplainmechanism.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/sigslot.h"
+#include "webrtc/base/stringutils.h"
+#include "xmpptask.h"
+
+namespace buzz {
+
+class XmppClient::Private :
+ public sigslot::has_slots<>,
+ public XmppSessionHandler,
+ public XmppOutputHandler {
+public:
+
+ explicit Private(XmppClient* client) :
+ client_(client),
+ socket_(),
+ engine_(),
+ proxy_port_(0),
+ pre_engine_error_(XmppEngine::ERROR_NONE),
+ pre_engine_subcode_(0),
+ signal_closed_(false),
+ allow_plain_(false) {}
+
+ virtual ~Private() {
+ // We need to disconnect from socket_ before engine_ is destructed (by
+ // the auto-generated destructor code).
+ ResetSocket();
+ }
+
+ // the owner
+ XmppClient* const client_;
+
+ // the two main objects
+ rtc::scoped_ptr<AsyncSocket> socket_;
+ rtc::scoped_ptr<XmppEngine> engine_;
+ rtc::scoped_ptr<PreXmppAuth> pre_auth_;
+ rtc::CryptString pass_;
+ std::string auth_mechanism_;
+ std::string auth_token_;
+ rtc::SocketAddress server_;
+ std::string proxy_host_;
+ int proxy_port_;
+ XmppEngine::Error pre_engine_error_;
+ int pre_engine_subcode_;
+ CaptchaChallenge captcha_challenge_;
+ bool signal_closed_;
+ bool allow_plain_;
+
+ void ResetSocket() {
+ if (socket_) {
+ socket_->SignalConnected.disconnect(this);
+ socket_->SignalRead.disconnect(this);
+ socket_->SignalClosed.disconnect(this);
+ socket_.reset(NULL);
+ }
+ }
+
+ // implementations of interfaces
+ void OnStateChange(int state);
+ void WriteOutput(const char* bytes, size_t len);
+ void StartTls(const std::string& domainname);
+ void CloseConnection();
+
+ // slots for socket signals
+ void OnSocketConnected();
+ void OnSocketRead();
+ void OnSocketClosed();
+};
+
+bool IsTestServer(const std::string& server_name,
+ const std::string& test_server_domain) {
+ return (!test_server_domain.empty() &&
+ rtc::ends_with(server_name.c_str(),
+ test_server_domain.c_str()));
+}
+
+XmppReturnStatus XmppClient::Connect(
+ const XmppClientSettings& settings,
+ const std::string& lang, AsyncSocket* socket, PreXmppAuth* pre_auth) {
+ if (socket == NULL)
+ return XMPP_RETURN_BADARGUMENT;
+ if (d_->socket_)
+ return XMPP_RETURN_BADSTATE;
+
+ d_->socket_.reset(socket);
+
+ d_->socket_->SignalConnected.connect(d_.get(), &Private::OnSocketConnected);
+ d_->socket_->SignalRead.connect(d_.get(), &Private::OnSocketRead);
+ d_->socket_->SignalClosed.connect(d_.get(), &Private::OnSocketClosed);
+
+ d_->engine_.reset(XmppEngine::Create());
+ d_->engine_->SetSessionHandler(d_.get());
+ d_->engine_->SetOutputHandler(d_.get());
+ if (!settings.resource().empty()) {
+ d_->engine_->SetRequestedResource(settings.resource());
+ }
+ d_->engine_->SetTls(settings.use_tls());
+
+ // The talk.google.com server returns a certificate with common-name:
+ // CN="gmail.com" for @gmail.com accounts,
+ // CN="googlemail.com" for @googlemail.com accounts,
+ // CN="talk.google.com" for other accounts (such as @example.com),
+ // so we tweak the tls server setting for those other accounts to match the
+ // returned certificate CN of "talk.google.com".
+ // For other servers, we leave the strings empty, which causes the jid's
+ // domain to be used. We do the same for gmail.com and googlemail.com as the
+ // returned CN matches the account domain in those cases.
+ std::string server_name = settings.server().HostAsURIString();
+ if (server_name == buzz::STR_TALK_GOOGLE_COM ||
+ server_name == buzz::STR_TALKX_L_GOOGLE_COM ||
+ server_name == buzz::STR_XMPP_GOOGLE_COM ||
+ server_name == buzz::STR_XMPPX_L_GOOGLE_COM ||
+ IsTestServer(server_name, settings.test_server_domain())) {
+ if (settings.host() != STR_GMAIL_COM &&
+ settings.host() != STR_GOOGLEMAIL_COM) {
+ d_->engine_->SetTlsServer("", STR_TALK_GOOGLE_COM);
+ }
+ }
+
+ // Set language
+ d_->engine_->SetLanguage(lang);
+
+ d_->engine_->SetUser(buzz::Jid(settings.user(), settings.host(), STR_EMPTY));
+
+ d_->pass_ = settings.pass();
+ d_->auth_mechanism_ = settings.auth_mechanism();
+ d_->auth_token_ = settings.auth_token();
+ d_->server_ = settings.server();
+ d_->proxy_host_ = settings.proxy_host();
+ d_->proxy_port_ = settings.proxy_port();
+ d_->allow_plain_ = settings.allow_plain();
+ d_->pre_auth_.reset(pre_auth);
+
+ return XMPP_RETURN_OK;
+}
+
+XmppEngine::State XmppClient::GetState() const {
+ if (!d_->engine_)
+ return XmppEngine::STATE_NONE;
+ return d_->engine_->GetState();
+}
+
+XmppEngine::Error XmppClient::GetError(int* subcode) {
+ if (subcode) {
+ *subcode = 0;
+ }
+ if (!d_->engine_)
+ return XmppEngine::ERROR_NONE;
+ if (d_->pre_engine_error_ != XmppEngine::ERROR_NONE) {
+ if (subcode) {
+ *subcode = d_->pre_engine_subcode_;
+ }
+ return d_->pre_engine_error_;
+ }
+ return d_->engine_->GetError(subcode);
+}
+
+const XmlElement* XmppClient::GetStreamError() {
+ if (!d_->engine_) {
+ return NULL;
+ }
+ return d_->engine_->GetStreamError();
+}
+
+CaptchaChallenge XmppClient::GetCaptchaChallenge() {
+ if (!d_->engine_)
+ return CaptchaChallenge();
+ return d_->captcha_challenge_;
+}
+
+std::string XmppClient::GetAuthMechanism() {
+ if (!d_->engine_)
+ return "";
+ return d_->auth_mechanism_;
+}
+
+std::string XmppClient::GetAuthToken() {
+ if (!d_->engine_)
+ return "";
+ return d_->auth_token_;
+}
+
+int XmppClient::ProcessStart() {
+ // Should not happen, but was observed in crash reports
+ if (!d_->socket_) {
+ LOG(LS_ERROR) << "socket_ already reset";
+ return STATE_DONE;
+ }
+
+ if (d_->pre_auth_) {
+ d_->pre_auth_->SignalAuthDone.connect(this, &XmppClient::OnAuthDone);
+ d_->pre_auth_->StartPreXmppAuth(
+ d_->engine_->GetUser(), d_->server_, d_->pass_,
+ d_->auth_mechanism_, d_->auth_token_);
+ d_->pass_.Clear(); // done with this;
+ return STATE_PRE_XMPP_LOGIN;
+ }
+ else {
+ d_->engine_->SetSaslHandler(new PlainSaslHandler(
+ d_->engine_->GetUser(), d_->pass_, d_->allow_plain_));
+ d_->pass_.Clear(); // done with this;
+ return STATE_START_XMPP_LOGIN;
+ }
+}
+
+void XmppClient::OnAuthDone() {
+ Wake();
+}
+
+int XmppClient::ProcessTokenLogin() {
+ // Should not happen, but was observed in crash reports
+ if (!d_->socket_) {
+ LOG(LS_ERROR) << "socket_ already reset";
+ return STATE_DONE;
+ }
+
+ // Don't know how this could happen, but crash reports show it as NULL
+ if (!d_->pre_auth_) {
+ d_->pre_engine_error_ = XmppEngine::ERROR_AUTH;
+ EnsureClosed();
+ return STATE_ERROR;
+ }
+
+ // Wait until pre authentication is done is done
+ if (!d_->pre_auth_->IsAuthDone())
+ return STATE_BLOCKED;
+
+ if (!d_->pre_auth_->IsAuthorized()) {
+ // maybe split out a case when gaia is down?
+ if (d_->pre_auth_->HadError()) {
+ d_->pre_engine_error_ = XmppEngine::ERROR_AUTH;
+ d_->pre_engine_subcode_ = d_->pre_auth_->GetError();
+ }
+ else {
+ d_->pre_engine_error_ = XmppEngine::ERROR_UNAUTHORIZED;
+ d_->pre_engine_subcode_ = 0;
+ d_->captcha_challenge_ = d_->pre_auth_->GetCaptchaChallenge();
+ }
+ d_->pre_auth_.reset(NULL); // done with this
+ EnsureClosed();
+ return STATE_ERROR;
+ }
+
+ // Save auth token as a result
+
+ d_->auth_mechanism_ = d_->pre_auth_->GetAuthMechanism();
+ d_->auth_token_ = d_->pre_auth_->GetAuthToken();
+
+ // transfer ownership of pre_auth_ to engine
+ d_->engine_->SetSaslHandler(d_->pre_auth_.release());
+ return STATE_START_XMPP_LOGIN;
+}
+
+int XmppClient::ProcessStartXmppLogin() {
+ // Should not happen, but was observed in crash reports
+ if (!d_->socket_) {
+ LOG(LS_ERROR) << "socket_ already reset";
+ return STATE_DONE;
+ }
+
+ // Done with pre-connect tasks - connect!
+ if (!d_->socket_->Connect(d_->server_)) {
+ EnsureClosed();
+ return STATE_ERROR;
+ }
+
+ return STATE_RESPONSE;
+}
+
+int XmppClient::ProcessResponse() {
+ // Hang around while we are connected.
+ if (!delivering_signal_ &&
+ (!d_->engine_ || d_->engine_->GetState() == XmppEngine::STATE_CLOSED))
+ return STATE_DONE;
+ return STATE_BLOCKED;
+}
+
+XmppReturnStatus XmppClient::Disconnect() {
+ if (!d_->socket_)
+ return XMPP_RETURN_BADSTATE;
+ Abort();
+ d_->engine_->Disconnect();
+ d_->ResetSocket();
+ return XMPP_RETURN_OK;
+}
+
+XmppClient::XmppClient(TaskParent* parent)
+ : XmppTaskParentInterface(parent),
+ delivering_signal_(false),
+ valid_(false) {
+ d_.reset(new Private(this));
+ valid_ = true;
+}
+
+XmppClient::~XmppClient() {
+ valid_ = false;
+}
+
+const Jid& XmppClient::jid() const {
+ return d_->engine_->FullJid();
+}
+
+
+std::string XmppClient::NextId() {
+ return d_->engine_->NextId();
+}
+
+XmppReturnStatus XmppClient::SendStanza(const XmlElement* stanza) {
+ return d_->engine_->SendStanza(stanza);
+}
+
+XmppReturnStatus XmppClient::SendStanzaError(
+ const XmlElement* old_stanza, XmppStanzaError xse,
+ const std::string& message) {
+ return d_->engine_->SendStanzaError(old_stanza, xse, message);
+}
+
+XmppReturnStatus XmppClient::SendRaw(const std::string& text) {
+ return d_->engine_->SendRaw(text);
+}
+
+XmppEngine* XmppClient::engine() {
+ return d_->engine_.get();
+}
+
+void XmppClient::Private::OnSocketConnected() {
+ engine_->Connect();
+}
+
+void XmppClient::Private::OnSocketRead() {
+ char bytes[4096];
+ size_t bytes_read;
+ for (;;) {
+ // Should not happen, but was observed in crash reports
+ if (!socket_) {
+ LOG(LS_ERROR) << "socket_ already reset";
+ return;
+ }
+
+ if (!socket_->Read(bytes, sizeof(bytes), &bytes_read)) {
+ // TODO: deal with error information
+ return;
+ }
+
+ if (bytes_read == 0)
+ return;
+
+//#ifdef _DEBUG
+ client_->SignalLogInput(bytes, static_cast<int>(bytes_read));
+//#endif
+
+ engine_->HandleInput(bytes, bytes_read);
+ }
+}
+
+void XmppClient::Private::OnSocketClosed() {
+ int code = socket_->GetError();
+ engine_->ConnectionClosed(code);
+}
+
+void XmppClient::Private::OnStateChange(int state) {
+ if (state == XmppEngine::STATE_CLOSED) {
+ client_->EnsureClosed();
+ }
+ else {
+ client_->SignalStateChange((XmppEngine::State)state);
+ }
+ client_->Wake();
+}
+
+void XmppClient::Private::WriteOutput(const char* bytes, size_t len) {
+//#ifdef _DEBUG
+ client_->SignalLogOutput(bytes, static_cast<int>(len));
+//#endif
+
+ socket_->Write(bytes, len);
+ // TODO: deal with error information
+}
+
+void XmppClient::Private::StartTls(const std::string& domain) {
+#if defined(FEATURE_ENABLE_SSL)
+ socket_->StartTls(domain);
+#endif
+}
+
+void XmppClient::Private::CloseConnection() {
+ socket_->Close();
+}
+
+void XmppClient::AddXmppTask(XmppTask* task, XmppEngine::HandlerLevel level) {
+ d_->engine_->AddStanzaHandler(task, level);
+}
+
+void XmppClient::RemoveXmppTask(XmppTask* task) {
+ d_->engine_->RemoveStanzaHandler(task);
+}
+
+void XmppClient::EnsureClosed() {
+ if (!d_->signal_closed_) {
+ d_->signal_closed_ = true;
+ delivering_signal_ = true;
+ SignalStateChange(XmppEngine::STATE_CLOSED);
+ delivering_signal_ = false;
+ }
+}
+
+} // namespace buzz
diff --git a/libjingle/xmpp/xmppclient.h b/libjingle/xmpp/xmppclient.h
new file mode 100644
index 00000000..7b9eb7ab
--- /dev/null
+++ b/libjingle/xmpp/xmppclient.h
@@ -0,0 +1,148 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_XMPPCLIENT_H_
+#define WEBRTC_LIBJINGLE_XMPP_XMPPCLIENT_H_
+
+#include <string>
+#include "webrtc/libjingle/xmpp/asyncsocket.h"
+#include "webrtc/libjingle/xmpp/xmppclientsettings.h"
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+#include "webrtc/libjingle/xmpp/xmpptask.h"
+#include "webrtc/base/basicdefs.h"
+#include "webrtc/base/sigslot.h"
+#include "webrtc/base/task.h"
+
+namespace buzz {
+
+class PreXmppAuth;
+class CaptchaChallenge;
+
+// Just some non-colliding number. Could have picked "1".
+#define XMPP_CLIENT_TASK_CODE 0x366c1e47
+
+/////////////////////////////////////////////////////////////////////
+//
+// XMPPCLIENT
+//
+/////////////////////////////////////////////////////////////////////
+//
+// See Task first. XmppClient is a parent task for XmppTasks.
+//
+// XmppClient is a task which is designed to be the parent task for
+// all tasks that depend on a single Xmpp connection. If you want to,
+// for example, listen for subscription requests forever, then your
+// listener should be a task that is a child of the XmppClient that owns
+// the connection you are using. XmppClient has all the utility methods
+// that basically drill through to XmppEngine.
+//
+// XmppClient is just a wrapper for XmppEngine, and if I were writing it
+// all over again, I would make XmppClient == XmppEngine. Why?
+// XmppEngine needs tasks too, for example it has an XmppLoginTask which
+// should just be the same kind of Task instead of an XmppEngine specific
+// thing. It would help do certain things like GAIA auth cleaner.
+//
+/////////////////////////////////////////////////////////////////////
+
+class XmppClient : public XmppTaskParentInterface,
+ public XmppClientInterface,
+ public sigslot::has_slots<>
+{
+public:
+ explicit XmppClient(rtc::TaskParent * parent);
+ virtual ~XmppClient();
+
+ XmppReturnStatus Connect(const XmppClientSettings & settings,
+ const std::string & lang,
+ AsyncSocket * socket,
+ PreXmppAuth * preauth);
+
+ virtual int ProcessStart();
+ virtual int ProcessResponse();
+ XmppReturnStatus Disconnect();
+
+ sigslot::signal1<XmppEngine::State> SignalStateChange;
+ XmppEngine::Error GetError(int *subcode);
+
+ // When there is a <stream:error> stanza, return the stanza
+ // so that they can be handled.
+ const XmlElement *GetStreamError();
+
+ // When there is an authentication error, we may have captcha info
+ // that the user can use to unlock their account
+ CaptchaChallenge GetCaptchaChallenge();
+
+ // When authentication is successful, this returns the service token
+ // (if we used GAIA authentication)
+ std::string GetAuthMechanism();
+ std::string GetAuthToken();
+
+ XmppReturnStatus SendRaw(const std::string & text);
+
+ XmppEngine* engine();
+
+ sigslot::signal2<const char *, int> SignalLogInput;
+ sigslot::signal2<const char *, int> SignalLogOutput;
+
+ // As XmppTaskParentIntreface
+ virtual XmppClientInterface* GetClient() { return this; }
+
+ // As XmppClientInterface
+ virtual XmppEngine::State GetState() const;
+ virtual const Jid& jid() const;
+ virtual std::string NextId();
+ virtual XmppReturnStatus SendStanza(const XmlElement *stanza);
+ virtual XmppReturnStatus SendStanzaError(const XmlElement * pelOriginal,
+ XmppStanzaError code,
+ const std::string & text);
+ virtual void AddXmppTask(XmppTask *, XmppEngine::HandlerLevel);
+ virtual void RemoveXmppTask(XmppTask *);
+
+ private:
+ friend class XmppTask;
+
+ void OnAuthDone();
+
+ // Internal state management
+ enum {
+ STATE_PRE_XMPP_LOGIN = STATE_NEXT,
+ STATE_START_XMPP_LOGIN = STATE_NEXT + 1,
+ };
+ int Process(int state) {
+ switch (state) {
+ case STATE_PRE_XMPP_LOGIN: return ProcessTokenLogin();
+ case STATE_START_XMPP_LOGIN: return ProcessStartXmppLogin();
+ default: return Task::Process(state);
+ }
+ }
+
+ std::string GetStateName(int state) const {
+ switch (state) {
+ case STATE_PRE_XMPP_LOGIN: return "PRE_XMPP_LOGIN";
+ case STATE_START_XMPP_LOGIN: return "START_XMPP_LOGIN";
+ default: return Task::GetStateName(state);
+ }
+ }
+
+ int ProcessTokenLogin();
+ int ProcessStartXmppLogin();
+ void EnsureClosed();
+
+ class Private;
+ friend class Private;
+ rtc::scoped_ptr<Private> d_;
+
+ bool delivering_signal_;
+ bool valid_;
+};
+
+}
+
+#endif // WEBRTC_LIBJINGLE_XMPP_XMPPCLIENT_H_
diff --git a/libjingle/xmpp/xmppclientsettings.h b/libjingle/xmpp/xmppclientsettings.h
new file mode 100644
index 00000000..5b7572aa
--- /dev/null
+++ b/libjingle/xmpp/xmppclientsettings.h
@@ -0,0 +1,111 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_XMPPCLIENTSETTINGS_H_
+#define WEBRTC_LIBJINGLE_XMPP_XMPPCLIENTSETTINGS_H_
+
+#include "webrtc/p2p/base/port.h"
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+#include "webrtc/base/cryptstring.h"
+
+namespace buzz {
+
+class XmppUserSettings {
+ public:
+ XmppUserSettings()
+ : use_tls_(buzz::TLS_DISABLED),
+ allow_plain_(false) {
+ }
+
+ void set_user(const std::string& user) { user_ = user; }
+ void set_host(const std::string& host) { host_ = host; }
+ void set_pass(const rtc::CryptString& pass) { pass_ = pass; }
+ void set_auth_token(const std::string& mechanism,
+ const std::string& token) {
+ auth_mechanism_ = mechanism;
+ auth_token_ = token;
+ }
+ void set_resource(const std::string& resource) { resource_ = resource; }
+ void set_use_tls(const TlsOptions use_tls) { use_tls_ = use_tls; }
+ void set_allow_plain(bool f) { allow_plain_ = f; }
+ void set_test_server_domain(const std::string& test_server_domain) {
+ test_server_domain_ = test_server_domain;
+ }
+ void set_token_service(const std::string& token_service) {
+ token_service_ = token_service;
+ }
+
+ const std::string& user() const { return user_; }
+ const std::string& host() const { return host_; }
+ const rtc::CryptString& pass() const { return pass_; }
+ const std::string& auth_mechanism() const { return auth_mechanism_; }
+ const std::string& auth_token() const { return auth_token_; }
+ const std::string& resource() const { return resource_; }
+ TlsOptions use_tls() const { return use_tls_; }
+ bool allow_plain() const { return allow_plain_; }
+ const std::string& test_server_domain() const { return test_server_domain_; }
+ const std::string& token_service() const { return token_service_; }
+
+ private:
+ std::string user_;
+ std::string host_;
+ rtc::CryptString pass_;
+ std::string auth_mechanism_;
+ std::string auth_token_;
+ std::string resource_;
+ TlsOptions use_tls_;
+ bool allow_plain_;
+ std::string test_server_domain_;
+ std::string token_service_;
+};
+
+class XmppClientSettings : public XmppUserSettings {
+ public:
+ XmppClientSettings()
+ : protocol_(cricket::PROTO_TCP),
+ proxy_(rtc::PROXY_NONE),
+ proxy_port_(80),
+ use_proxy_auth_(false) {
+ }
+
+ void set_server(const rtc::SocketAddress& server) {
+ server_ = server;
+ }
+ void set_protocol(cricket::ProtocolType protocol) { protocol_ = protocol; }
+ void set_proxy(rtc::ProxyType f) { proxy_ = f; }
+ void set_proxy_host(const std::string& host) { proxy_host_ = host; }
+ void set_proxy_port(int port) { proxy_port_ = port; };
+ void set_use_proxy_auth(bool f) { use_proxy_auth_ = f; }
+ void set_proxy_user(const std::string& user) { proxy_user_ = user; }
+ void set_proxy_pass(const rtc::CryptString& pass) { proxy_pass_ = pass; }
+
+ const rtc::SocketAddress& server() const { return server_; }
+ cricket::ProtocolType protocol() const { return protocol_; }
+ rtc::ProxyType proxy() const { return proxy_; }
+ const std::string& proxy_host() const { return proxy_host_; }
+ int proxy_port() const { return proxy_port_; }
+ bool use_proxy_auth() const { return use_proxy_auth_; }
+ const std::string& proxy_user() const { return proxy_user_; }
+ const rtc::CryptString& proxy_pass() const { return proxy_pass_; }
+
+ private:
+ rtc::SocketAddress server_;
+ cricket::ProtocolType protocol_;
+ rtc::ProxyType proxy_;
+ std::string proxy_host_;
+ int proxy_port_;
+ bool use_proxy_auth_;
+ std::string proxy_user_;
+ rtc::CryptString proxy_pass_;
+};
+
+}
+
+#endif // WEBRTC_LIBJINGLE_XMPP_XMPPCLIENT_H_
diff --git a/libjingle/xmpp/xmppengine.h b/libjingle/xmpp/xmppengine.h
new file mode 100644
index 00000000..2bc2453c
--- /dev/null
+++ b/libjingle/xmpp/xmppengine.h
@@ -0,0 +1,332 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_XMPPENGINE_H_
+#define WEBRTC_LIBJINGLE_XMPP_XMPPENGINE_H_
+
+// also part of the API
+#include "webrtc/libjingle/xmllite/qname.h"
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/jid.h"
+
+
+namespace buzz {
+
+class XmppEngine;
+class SaslHandler;
+typedef void * XmppIqCookie;
+
+//! XMPP stanza error codes.
+//! Used in XmppEngine.SendStanzaError().
+enum XmppStanzaError {
+ XSE_BAD_REQUEST,
+ XSE_CONFLICT,
+ XSE_FEATURE_NOT_IMPLEMENTED,
+ XSE_FORBIDDEN,
+ XSE_GONE,
+ XSE_INTERNAL_SERVER_ERROR,
+ XSE_ITEM_NOT_FOUND,
+ XSE_JID_MALFORMED,
+ XSE_NOT_ACCEPTABLE,
+ XSE_NOT_ALLOWED,
+ XSE_PAYMENT_REQUIRED,
+ XSE_RECIPIENT_UNAVAILABLE,
+ XSE_REDIRECT,
+ XSE_REGISTRATION_REQUIRED,
+ XSE_SERVER_NOT_FOUND,
+ XSE_SERVER_TIMEOUT,
+ XSE_RESOURCE_CONSTRAINT,
+ XSE_SERVICE_UNAVAILABLE,
+ XSE_SUBSCRIPTION_REQUIRED,
+ XSE_UNDEFINED_CONDITION,
+ XSE_UNEXPECTED_REQUEST,
+};
+
+// XmppReturnStatus
+// This is used by API functions to synchronously return status.
+enum XmppReturnStatus {
+ XMPP_RETURN_OK,
+ XMPP_RETURN_BADARGUMENT,
+ XMPP_RETURN_BADSTATE,
+ XMPP_RETURN_PENDING,
+ XMPP_RETURN_UNEXPECTED,
+ XMPP_RETURN_NOTYETIMPLEMENTED,
+};
+
+// TlsOptions
+// This is used by API to identify TLS setting.
+enum TlsOptions {
+ TLS_DISABLED,
+ TLS_ENABLED,
+ TLS_REQUIRED
+};
+
+//! Callback for socket output for an XmppEngine connection.
+//! Register via XmppEngine.SetOutputHandler. An XmppEngine
+//! can call back to this handler while it is processing
+//! Connect, SendStanza, SendIq, Disconnect, or HandleInput.
+class XmppOutputHandler {
+public:
+ virtual ~XmppOutputHandler() {}
+
+ //! Deliver the specified bytes to the XMPP socket.
+ virtual void WriteOutput(const char * bytes, size_t len) = 0;
+
+ //! Initiate TLS encryption on the socket.
+ //! The implementation must verify that the SSL
+ //! certificate matches the given domainname.
+ virtual void StartTls(const std::string & domainname) = 0;
+
+ //! Called when engine wants the connecton closed.
+ virtual void CloseConnection() = 0;
+};
+
+//! Callback to deliver engine state change notifications
+//! to the object managing the engine.
+class XmppSessionHandler {
+public:
+ virtual ~XmppSessionHandler() {}
+ //! Called when engine changes state. Argument is new state.
+ virtual void OnStateChange(int state) = 0;
+};
+
+//! Callback to deliver stanzas to an Xmpp application module.
+//! Register via XmppEngine.SetDefaultSessionHandler or via
+//! XmppEngine.AddSessionHAndler.
+class XmppStanzaHandler {
+public:
+ virtual ~XmppStanzaHandler() {}
+ //! Process the given stanza.
+ //! The handler must return true if it has handled the stanza.
+ //! A false return value causes the stanza to be passed on to
+ //! the next registered handler.
+ virtual bool HandleStanza(const XmlElement * stanza) = 0;
+};
+
+//! Callback to deliver iq responses (results and errors).
+//! Register while sending an iq via XmppEngine.SendIq.
+//! Iq responses are routed to matching XmppIqHandlers in preference
+//! to sending to any registered SessionHandlers.
+class XmppIqHandler {
+public:
+ virtual ~XmppIqHandler() {}
+ //! Called to handle the iq response.
+ //! The response may be either a result or an error, and will have
+ //! an 'id' that matches the request and a 'from' that matches the
+ //! 'to' of the request. Called no more than once; once this is
+ //! called, the handler is automatically unregistered.
+ virtual void IqResponse(XmppIqCookie cookie, const XmlElement * pelStanza) = 0;
+};
+
+//! The XMPP connection engine.
+//! This engine implements the client side of the 'core' XMPP protocol.
+//! To use it, register an XmppOutputHandler to handle socket output
+//! and pass socket input to HandleInput. Then application code can
+//! set up the connection with a user, password, and other settings,
+//! and then call Connect() to initiate the connection.
+//! An application can listen for events and receive stanzas by
+//! registering an XmppStanzaHandler via AddStanzaHandler().
+class XmppEngine {
+public:
+ static XmppEngine * Create();
+ virtual ~XmppEngine() {}
+
+ //! Error codes. See GetError().
+ enum Error {
+ ERROR_NONE = 0, //!< No error
+ ERROR_XML, //!< Malformed XML or encoding error
+ ERROR_STREAM, //!< XMPP stream error - see GetStreamError()
+ ERROR_VERSION, //!< XMPP version error
+ ERROR_UNAUTHORIZED, //!< User is not authorized (rejected credentials)
+ ERROR_TLS, //!< TLS could not be negotiated
+ ERROR_AUTH, //!< Authentication could not be negotiated
+ ERROR_BIND, //!< Resource or session binding could not be negotiated
+ ERROR_CONNECTION_CLOSED,//!< Connection closed by output handler.
+ ERROR_DOCUMENT_CLOSED, //!< Closed by </stream:stream>
+ ERROR_SOCKET, //!< Socket error
+ ERROR_NETWORK_TIMEOUT, //!< Some sort of timeout (eg., we never got the roster)
+ ERROR_MISSING_USERNAME //!< User has a Google Account but no nickname
+ };
+
+ //! States. See GetState().
+ enum State {
+ STATE_NONE = 0, //!< Nonexistent state
+ STATE_START, //!< Initial state.
+ STATE_OPENING, //!< Exchanging stream headers, authenticating and so on.
+ STATE_OPEN, //!< Authenticated and bound.
+ STATE_CLOSED, //!< Session closed, possibly due to error.
+ };
+
+ // SOCKET INPUT AND OUTPUT ------------------------------------------------
+
+ //! Registers the handler for socket output
+ virtual XmppReturnStatus SetOutputHandler(XmppOutputHandler *pxoh) = 0;
+
+ //! Provides socket input to the engine
+ virtual XmppReturnStatus HandleInput(const char * bytes, size_t len) = 0;
+
+ //! Advises the engine that the socket has closed
+ virtual XmppReturnStatus ConnectionClosed(int subcode) = 0;
+
+ // SESSION SETUP ---------------------------------------------------------
+
+ //! Indicates the (bare) JID for the user to use.
+ virtual XmppReturnStatus SetUser(const Jid & jid)= 0;
+
+ //! Get the login (bare) JID.
+ virtual const Jid & GetUser() = 0;
+
+ //! Provides different methods for credentials for login.
+ //! Takes ownership of this object; deletes when login is done
+ virtual XmppReturnStatus SetSaslHandler(SaslHandler * h) = 0;
+
+ //! Sets whether TLS will be used within the connection (default true).
+ virtual XmppReturnStatus SetTls(TlsOptions useTls) = 0;
+
+ //! Sets an alternate domain from which we allows TLS certificates.
+ //! This is for use in the case where a we want to allow a proxy to
+ //! serve up its own certificate rather than one owned by the underlying
+ //! domain.
+ virtual XmppReturnStatus SetTlsServer(const std::string & proxy_hostname,
+ const std::string & proxy_domain) = 0;
+
+ //! Gets whether TLS will be used within the connection.
+ virtual TlsOptions GetTls() = 0;
+
+ //! Sets the request resource name, if any (optional).
+ //! Note that the resource name may be overridden by the server; after
+ //! binding, the actual resource name is available as part of FullJid().
+ virtual XmppReturnStatus SetRequestedResource(const std::string& resource) = 0;
+
+ //! Gets the request resource name.
+ virtual const std::string & GetRequestedResource() = 0;
+
+ //! Sets language
+ virtual void SetLanguage(const std::string & lang) = 0;
+
+ // SESSION MANAGEMENT ---------------------------------------------------
+
+ //! Set callback for state changes.
+ virtual XmppReturnStatus SetSessionHandler(XmppSessionHandler* handler) = 0;
+
+ //! Initiates the XMPP connection.
+ //! After supplying connection settings, call this once to initiate,
+ //! (optionally) encrypt, authenticate, and bind the connection.
+ virtual XmppReturnStatus Connect() = 0;
+
+ //! The current engine state.
+ virtual State GetState() = 0;
+
+ //! Returns true if the connection is encrypted (under TLS)
+ virtual bool IsEncrypted() = 0;
+
+ //! The error code.
+ //! Consult this after XmppOutputHandler.OnClose().
+ virtual Error GetError(int *subcode) = 0;
+
+ //! The stream:error stanza, when the error is XmppEngine::ERROR_STREAM.
+ //! Notice the stanza returned is owned by the XmppEngine and
+ //! is deleted when the engine is destroyed.
+ virtual const XmlElement * GetStreamError() = 0;
+
+ //! Closes down the connection.
+ //! Sends CloseConnection to output, and disconnects and registered
+ //! session handlers. After Disconnect completes, it is guaranteed
+ //! that no further callbacks will be made.
+ virtual XmppReturnStatus Disconnect() = 0;
+
+ // APPLICATION USE -------------------------------------------------------
+
+ enum HandlerLevel {
+ HL_NONE = 0,
+ HL_PEEK, //!< Sees messages before all other processing; cannot abort
+ HL_SINGLE, //!< Watches for a single message, e.g., by id and sender
+ HL_SENDER, //!< Watches for a type of message from a specific sender
+ HL_TYPE, //!< Watches a type of message, e.g., all groupchat msgs
+ HL_ALL, //!< Watches all messages - gets last shot
+ HL_COUNT, //!< Count of handler levels
+ };
+
+ //! Adds a listener for session events.
+ //! Stanza delivery is chained to session handlers; the first to
+ //! return 'true' is the last to get each stanza.
+ virtual XmppReturnStatus AddStanzaHandler(XmppStanzaHandler* handler, HandlerLevel level = HL_PEEK) = 0;
+
+ //! Removes a listener for session events.
+ virtual XmppReturnStatus RemoveStanzaHandler(XmppStanzaHandler* handler) = 0;
+
+ //! Sends a stanza to the server.
+ virtual XmppReturnStatus SendStanza(const XmlElement * pelStanza) = 0;
+
+ //! Sends raw text to the server
+ virtual XmppReturnStatus SendRaw(const std::string & text) = 0;
+
+ //! Sends an iq to the server, and registers a callback for the result.
+ //! Returns the cookie passed to the result handler.
+ virtual XmppReturnStatus SendIq(const XmlElement* pelStanza,
+ XmppIqHandler* iq_handler,
+ XmppIqCookie* cookie) = 0;
+
+ //! Unregisters an iq callback handler given its cookie.
+ //! No callback will come to this handler after it's unregistered.
+ virtual XmppReturnStatus RemoveIqHandler(XmppIqCookie cookie,
+ XmppIqHandler** iq_handler) = 0;
+
+
+ //! Forms and sends an error in response to the given stanza.
+ //! Swaps to and from, sets type to "error", and adds error information
+ //! based on the passed code. Text is optional and may be STR_EMPTY.
+ virtual XmppReturnStatus SendStanzaError(const XmlElement * pelOriginal,
+ XmppStanzaError code,
+ const std::string & text) = 0;
+
+ //! The fullly bound JID.
+ //! This JID is only valid after binding has succeeded. If the value
+ //! is JID_NULL, the binding has not succeeded.
+ virtual const Jid & FullJid() = 0;
+
+ //! The next unused iq id for this connection.
+ //! Call this when building iq stanzas, to ensure that each iq
+ //! gets its own unique id.
+ virtual std::string NextId() = 0;
+
+};
+
+}
+
+
+// Move these to a better location
+
+#define XMPP_FAILED(x) \
+ ( (x) == buzz::XMPP_RETURN_OK ? false : true) \
+
+
+#define XMPP_SUCCEEDED(x) \
+ ( (x) == buzz::XMPP_RETURN_OK ? true : false) \
+
+#define IFR(x) \
+ do { \
+ xmpp_status = (x); \
+ if (XMPP_FAILED(xmpp_status)) { \
+ return xmpp_status; \
+ } \
+ } while (false) \
+
+
+#define IFC(x) \
+ do { \
+ xmpp_status = (x); \
+ if (XMPP_FAILED(xmpp_status)) { \
+ goto Cleanup; \
+ } \
+ } while (false) \
+
+
+#endif // WEBRTC_LIBJINGLE_XMPP_XMPPENGINE_H_
diff --git a/libjingle/xmpp/xmppengine_unittest.cc b/libjingle/xmpp/xmppengine_unittest.cc
new file mode 100644
index 00000000..7af151ba
--- /dev/null
+++ b/libjingle/xmpp/xmppengine_unittest.cc
@@ -0,0 +1,325 @@
+/*
+ * 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 <iostream>
+#include <sstream>
+#include <string>
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/plainsaslhandler.h"
+#include "webrtc/libjingle/xmpp/saslplainmechanism.h"
+#include "webrtc/libjingle/xmpp/util_unittest.h"
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/gunit.h"
+
+using buzz::Jid;
+using buzz::QName;
+using buzz::XmlElement;
+using buzz::XmppEngine;
+using buzz::XmppIqCookie;
+using buzz::XmppIqHandler;
+using buzz::XmppTestHandler;
+using buzz::QN_ID;
+using buzz::QN_IQ;
+using buzz::QN_TYPE;
+using buzz::QN_ROSTER_QUERY;
+using buzz::XMPP_RETURN_OK;
+using buzz::XMPP_RETURN_BADARGUMENT;
+
+// XmppEngineTestIqHandler
+// This class grabs the response to an IQ stanza and stores it in a string.
+class XmppEngineTestIqHandler : public XmppIqHandler {
+ public:
+ virtual void IqResponse(XmppIqCookie, const XmlElement * stanza) {
+ ss_ << stanza->Str();
+ }
+
+ std::string IqResponseActivity() {
+ std::string result = ss_.str();
+ ss_.str("");
+ return result;
+ }
+
+ private:
+ std::stringstream ss_;
+};
+
+class XmppEngineTest : public testing::Test {
+ public:
+ XmppEngine* engine() { return engine_.get(); }
+ XmppTestHandler* handler() { return handler_.get(); }
+ virtual void SetUp() {
+ engine_.reset(XmppEngine::Create());
+ handler_.reset(new XmppTestHandler(engine_.get()));
+
+ Jid jid("david@my-server");
+ rtc::InsecureCryptStringImpl pass;
+ pass.password() = "david";
+ engine_->SetSessionHandler(handler_.get());
+ engine_->SetOutputHandler(handler_.get());
+ engine_->AddStanzaHandler(handler_.get());
+ engine_->SetUser(jid);
+ engine_->SetSaslHandler(
+ new buzz::PlainSaslHandler(jid, rtc::CryptString(pass), true));
+ }
+ virtual void TearDown() {
+ handler_.reset();
+ engine_.reset();
+ }
+ void RunLogin();
+
+ private:
+ rtc::scoped_ptr<XmppEngine> engine_;
+ rtc::scoped_ptr<XmppTestHandler> handler_;
+};
+
+void XmppEngineTest::RunLogin() {
+ // Connect
+ EXPECT_EQ(XmppEngine::STATE_START, engine()->GetState());
+ engine()->Connect();
+ EXPECT_EQ(XmppEngine::STATE_OPENING, engine()->GetState());
+
+ EXPECT_EQ("[OPENING]", handler_->SessionActivity());
+
+ EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" version=\"1.0\" "
+ "xmlns:stream=\"http://etherx.jabber.org/streams\" "
+ "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
+
+ std::string input =
+ "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" "
+ "xmlns:stream=\"http://etherx.jabber.org/streams\" "
+ "xmlns=\"jabber:client\">";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ input =
+ "<stream:features>"
+ "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>"
+ "<required/>"
+ "</starttls>"
+ "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
+ "<mechanism>DIGEST-MD5</mechanism>"
+ "<mechanism>PLAIN</mechanism>"
+ "</mechanisms>"
+ "</stream:features>";
+ engine()->HandleInput(input.c_str(), input.length());
+ EXPECT_EQ("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>",
+ handler_->OutputActivity());
+
+ EXPECT_EQ("", handler_->SessionActivity());
+ EXPECT_EQ("", handler_->StanzaActivity());
+
+ input = "<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>";
+ engine()->HandleInput(input.c_str(), input.length());
+ EXPECT_EQ("[START-TLS my-server]"
+ "<stream:stream to=\"my-server\" xml:lang=\"*\" "
+ "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" "
+ "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
+
+ EXPECT_EQ("", handler_->SessionActivity());
+ EXPECT_EQ("", handler_->StanzaActivity());
+
+ input = "<stream:stream id=\"01234567\" version=\"1.0\" "
+ "xmlns:stream=\"http://etherx.jabber.org/streams\" "
+ "xmlns=\"jabber:client\">";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ input =
+ "<stream:features>"
+ "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
+ "<mechanism>DIGEST-MD5</mechanism>"
+ "<mechanism>PLAIN</mechanism>"
+ "</mechanisms>"
+ "</stream:features>";
+ engine()->HandleInput(input.c_str(), input.length());
+ EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
+ "mechanism=\"PLAIN\" "
+ "auth:allow-non-google-login=\"true\" "
+ "auth:client-uses-full-bind-result=\"true\" "
+ "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
+ ">AGRhdmlkAGRhdmlk</auth>",
+ handler_->OutputActivity());
+
+ EXPECT_EQ("", handler_->SessionActivity());
+ EXPECT_EQ("", handler_->StanzaActivity());
+
+ input = "<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>";
+ engine()->HandleInput(input.c_str(), input.length());
+ EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" version=\"1.0\" "
+ "xmlns:stream=\"http://etherx.jabber.org/streams\" "
+ "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
+
+ EXPECT_EQ("", handler_->SessionActivity());
+ EXPECT_EQ("", handler_->StanzaActivity());
+
+ input = "<stream:stream id=\"01234567\" version=\"1.0\" "
+ "xmlns:stream=\"http://etherx.jabber.org/streams\" "
+ "xmlns=\"jabber:client\">";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ input = "<stream:features>"
+ "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>"
+ "<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>"
+ "</stream:features>";
+ engine()->HandleInput(input.c_str(), input.length());
+ EXPECT_EQ("<iq type=\"set\" id=\"0\">"
+ "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"/></iq>",
+ handler_->OutputActivity());
+
+ EXPECT_EQ("", handler_->SessionActivity());
+ EXPECT_EQ("", handler_->StanzaActivity());
+
+ input = "<iq type='result' id='0'>"
+ "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><jid>"
+ "david@my-server/test</jid></bind></iq>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("<iq type=\"set\" id=\"1\">"
+ "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/></iq>",
+ handler_->OutputActivity());
+
+ EXPECT_EQ("", handler_->SessionActivity());
+ EXPECT_EQ("", handler_->StanzaActivity());
+
+ input = "<iq type='result' id='1'/>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("[OPEN]", handler_->SessionActivity());
+ EXPECT_EQ("", handler_->StanzaActivity());
+ EXPECT_EQ(Jid("david@my-server/test"), engine()->FullJid());
+}
+
+// TestSuccessfulLogin()
+// This function simply tests to see if a login works. This includes
+// encryption and authentication
+TEST_F(XmppEngineTest, TestSuccessfulLoginAndDisconnect) {
+ RunLogin();
+ engine()->Disconnect();
+ EXPECT_EQ("</stream:stream>[CLOSED]", handler()->OutputActivity());
+ EXPECT_EQ("[CLOSED]", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+
+TEST_F(XmppEngineTest, TestSuccessfulLoginAndConnectionClosed) {
+ RunLogin();
+ engine()->ConnectionClosed(0);
+ EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
+ EXPECT_EQ("[CLOSED][ERROR-CONNECTION-CLOSED]", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+
+
+// TestNotXmpp()
+// This tests the error case when connecting to a non XMPP service
+TEST_F(XmppEngineTest, TestNotXmpp) {
+ // Connect
+ engine()->Connect();
+ EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" version=\"1.0\" "
+ "xmlns:stream=\"http://etherx.jabber.org/streams\" "
+ "xmlns=\"jabber:client\">\r\n", handler()->OutputActivity());
+
+ // Send garbage response (courtesy of apache)
+ std::string input = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
+ EXPECT_EQ("[OPENING][CLOSED][ERROR-XML]", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+
+// TestPassthrough()
+// This tests that arbitrary stanzas can be passed to the server through
+// the engine.
+TEST_F(XmppEngineTest, TestPassthrough) {
+ // Queue up an app stanza
+ XmlElement application_stanza(QName("test", "app-stanza"));
+ application_stanza.AddText("this-is-a-test");
+ engine()->SendStanza(&application_stanza);
+
+ // Do the whole login handshake
+ RunLogin();
+
+ EXPECT_EQ("<test:app-stanza xmlns:test=\"test\">this-is-a-test"
+ "</test:app-stanza>", handler()->OutputActivity());
+
+ // do another stanza
+ XmlElement roster_get(QN_IQ);
+ roster_get.AddAttr(QN_TYPE, "get");
+ roster_get.AddAttr(QN_ID, engine()->NextId());
+ roster_get.AddElement(new XmlElement(QN_ROSTER_QUERY, true));
+ engine()->SendStanza(&roster_get);
+ EXPECT_EQ("<iq type=\"get\" id=\"2\"><query xmlns=\"jabber:iq:roster\"/>"
+ "</iq>", handler()->OutputActivity());
+
+ // now say the server ends the stream
+ engine()->HandleInput("</stream:stream>", 16);
+ EXPECT_EQ("[CLOSED][ERROR-DOCUMENT-CLOSED]", handler()->SessionActivity());
+ EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+
+// TestIqCallback()
+// This tests the routing of Iq stanzas and responses.
+TEST_F(XmppEngineTest, TestIqCallback) {
+ XmppEngineTestIqHandler iq_response;
+ XmppIqCookie cookie;
+
+ // Do the whole login handshake
+ RunLogin();
+
+ // Build an iq request
+ XmlElement roster_get(QN_IQ);
+ roster_get.AddAttr(QN_TYPE, "get");
+ roster_get.AddAttr(QN_ID, engine()->NextId());
+ roster_get.AddElement(new XmlElement(QN_ROSTER_QUERY, true));
+ engine()->SendIq(&roster_get, &iq_response, &cookie);
+ EXPECT_EQ("<iq type=\"get\" id=\"2\"><query xmlns=\"jabber:iq:roster\"/>"
+ "</iq>", handler()->OutputActivity());
+ EXPECT_EQ("", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+ EXPECT_EQ("", iq_response.IqResponseActivity());
+
+ // now say the server responds to the iq
+ std::string input = "<iq type='result' id='2'>"
+ "<query xmlns='jabber:iq:roster'><item>foo</item>"
+ "</query></iq>";
+ engine()->HandleInput(input.c_str(), input.length());
+ EXPECT_EQ("", handler()->OutputActivity());
+ EXPECT_EQ("", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+ EXPECT_EQ("<cli:iq type=\"result\" id=\"2\" xmlns:cli=\"jabber:client\">"
+ "<query xmlns=\"jabber:iq:roster\"><item>foo</item></query>"
+ "</cli:iq>", iq_response.IqResponseActivity());
+
+ EXPECT_EQ(XMPP_RETURN_BADARGUMENT, engine()->RemoveIqHandler(cookie, NULL));
+
+ // Do it again with another id to test cancel
+ roster_get.SetAttr(QN_ID, engine()->NextId());
+ engine()->SendIq(&roster_get, &iq_response, &cookie);
+ EXPECT_EQ("<iq type=\"get\" id=\"3\"><query xmlns=\"jabber:iq:roster\"/>"
+ "</iq>", handler()->OutputActivity());
+ EXPECT_EQ("", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+ EXPECT_EQ("", iq_response.IqResponseActivity());
+
+ // cancel the handler this time
+ EXPECT_EQ(XMPP_RETURN_OK, engine()->RemoveIqHandler(cookie, NULL));
+
+ // now say the server responds to the iq: the iq handler should not get it.
+ input = "<iq type='result' id='3'><query xmlns='jabber:iq:roster'><item>bar"
+ "</item></query></iq>";
+ engine()->HandleInput(input.c_str(), input.length());
+ EXPECT_EQ("<cli:iq type=\"result\" id=\"3\" xmlns:cli=\"jabber:client\">"
+ "<query xmlns=\"jabber:iq:roster\"><item>bar</item></query>"
+ "</cli:iq>", handler()->StanzaActivity());
+ EXPECT_EQ("", iq_response.IqResponseActivity());
+ EXPECT_EQ("", handler()->OutputActivity());
+ EXPECT_EQ("", handler()->SessionActivity());
+}
diff --git a/libjingle/xmpp/xmppengineimpl.cc b/libjingle/xmpp/xmppengineimpl.cc
new file mode 100644
index 00000000..e77a1d93
--- /dev/null
+++ b/libjingle/xmpp/xmppengineimpl.cc
@@ -0,0 +1,446 @@
+/*
+ * 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 "webrtc/libjingle/xmpp/xmppengineimpl.h"
+
+#include <algorithm>
+#include <sstream>
+#include <vector>
+
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmllite/xmlprinter.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/saslhandler.h"
+#include "webrtc/libjingle/xmpp/xmpplogintask.h"
+#include "webrtc/base/common.h"
+
+namespace buzz {
+
+XmppEngine* XmppEngine::Create() {
+ return new XmppEngineImpl();
+}
+
+
+XmppEngineImpl::XmppEngineImpl()
+ : stanza_parse_handler_(this),
+ stanza_parser_(&stanza_parse_handler_),
+ engine_entered_(0),
+ password_(),
+ requested_resource_(STR_EMPTY),
+ tls_option_(buzz::TLS_REQUIRED),
+ login_task_(new XmppLoginTask(this)),
+ next_id_(0),
+ state_(STATE_START),
+ encrypted_(false),
+ error_code_(ERROR_NONE),
+ subcode_(0),
+ stream_error_(),
+ raised_reset_(false),
+ output_handler_(NULL),
+ session_handler_(NULL),
+ iq_entries_(new IqEntryVector()),
+ sasl_handler_(),
+ output_(new std::stringstream()) {
+ for (int i = 0; i < HL_COUNT; i+= 1) {
+ stanza_handlers_[i].reset(new StanzaHandlerVector());
+ }
+
+ // Add XMPP namespaces to XML namespaces stack.
+ xmlns_stack_.AddXmlns("stream", "http://etherx.jabber.org/streams");
+ xmlns_stack_.AddXmlns("", "jabber:client");
+}
+
+XmppEngineImpl::~XmppEngineImpl() {
+ DeleteIqCookies();
+}
+
+XmppReturnStatus XmppEngineImpl::SetOutputHandler(
+ XmppOutputHandler* output_handler) {
+ if (state_ != STATE_START)
+ return XMPP_RETURN_BADSTATE;
+
+ output_handler_ = output_handler;
+
+ return XMPP_RETURN_OK;
+}
+
+XmppReturnStatus XmppEngineImpl::SetSessionHandler(
+ XmppSessionHandler* session_handler) {
+ if (state_ != STATE_START)
+ return XMPP_RETURN_BADSTATE;
+
+ session_handler_ = session_handler;
+
+ return XMPP_RETURN_OK;
+}
+
+XmppReturnStatus XmppEngineImpl::HandleInput(
+ const char* bytes, size_t len) {
+ if (state_ < STATE_OPENING || state_ > STATE_OPEN)
+ return XMPP_RETURN_BADSTATE;
+
+ EnterExit ee(this);
+
+ // TODO: The return value of the xml parser is not checked.
+ stanza_parser_.Parse(bytes, len, false);
+
+ return XMPP_RETURN_OK;
+}
+
+XmppReturnStatus XmppEngineImpl::ConnectionClosed(int subcode) {
+ if (state_ != STATE_CLOSED) {
+ EnterExit ee(this);
+ // If told that connection closed and not already closed,
+ // then connection was unpexectedly dropped.
+ if (subcode) {
+ SignalError(ERROR_SOCKET, subcode);
+ } else {
+ SignalError(ERROR_CONNECTION_CLOSED, 0); // no subcode
+ }
+ }
+ return XMPP_RETURN_OK;
+}
+
+XmppReturnStatus XmppEngineImpl::SetTls(TlsOptions use_tls) {
+ if (state_ != STATE_START)
+ return XMPP_RETURN_BADSTATE;
+ tls_option_ = use_tls;
+ return XMPP_RETURN_OK;
+}
+
+XmppReturnStatus XmppEngineImpl::SetTlsServer(
+ const std::string& tls_server_hostname,
+ const std::string& tls_server_domain) {
+ if (state_ != STATE_START)
+ return XMPP_RETURN_BADSTATE;
+
+ tls_server_hostname_ = tls_server_hostname;
+ tls_server_domain_= tls_server_domain;
+
+ return XMPP_RETURN_OK;
+}
+
+TlsOptions XmppEngineImpl::GetTls() {
+ return tls_option_;
+}
+
+XmppReturnStatus XmppEngineImpl::SetUser(const Jid& jid) {
+ if (state_ != STATE_START)
+ return XMPP_RETURN_BADSTATE;
+
+ user_jid_ = jid;
+
+ return XMPP_RETURN_OK;
+}
+
+const Jid& XmppEngineImpl::GetUser() {
+ return user_jid_;
+}
+
+XmppReturnStatus XmppEngineImpl::SetSaslHandler(SaslHandler* sasl_handler) {
+ if (state_ != STATE_START)
+ return XMPP_RETURN_BADSTATE;
+
+ sasl_handler_.reset(sasl_handler);
+ return XMPP_RETURN_OK;
+}
+
+XmppReturnStatus XmppEngineImpl::SetRequestedResource(
+ const std::string& resource) {
+ if (state_ != STATE_START)
+ return XMPP_RETURN_BADSTATE;
+
+ requested_resource_ = resource;
+
+ return XMPP_RETURN_OK;
+}
+
+const std::string& XmppEngineImpl::GetRequestedResource() {
+ return requested_resource_;
+}
+
+XmppReturnStatus XmppEngineImpl::AddStanzaHandler(
+ XmppStanzaHandler* stanza_handler,
+ XmppEngine::HandlerLevel level) {
+ if (state_ == STATE_CLOSED)
+ return XMPP_RETURN_BADSTATE;
+
+ stanza_handlers_[level]->push_back(stanza_handler);
+
+ return XMPP_RETURN_OK;
+}
+
+XmppReturnStatus XmppEngineImpl::RemoveStanzaHandler(
+ XmppStanzaHandler* stanza_handler) {
+ bool found = false;
+
+ for (int level = 0; level < HL_COUNT; level += 1) {
+ StanzaHandlerVector::iterator new_end =
+ std::remove(stanza_handlers_[level]->begin(),
+ stanza_handlers_[level]->end(),
+ stanza_handler);
+
+ if (new_end != stanza_handlers_[level]->end()) {
+ stanza_handlers_[level]->erase(new_end, stanza_handlers_[level]->end());
+ found = true;
+ }
+ }
+
+ if (!found)
+ return XMPP_RETURN_BADARGUMENT;
+
+ return XMPP_RETURN_OK;
+}
+
+XmppReturnStatus XmppEngineImpl::Connect() {
+ if (state_ != STATE_START)
+ return XMPP_RETURN_BADSTATE;
+
+ EnterExit ee(this);
+
+ // get the login task started
+ state_ = STATE_OPENING;
+ if (login_task_) {
+ login_task_->IncomingStanza(NULL, false);
+ if (login_task_->IsDone())
+ login_task_.reset();
+ }
+
+ return XMPP_RETURN_OK;
+}
+
+XmppReturnStatus XmppEngineImpl::SendStanza(const XmlElement* element) {
+ if (state_ == STATE_CLOSED)
+ return XMPP_RETURN_BADSTATE;
+
+ EnterExit ee(this);
+
+ if (login_task_) {
+ // still handshaking - then outbound stanzas are queued
+ login_task_->OutgoingStanza(element);
+ } else {
+ // handshake done - send straight through
+ InternalSendStanza(element);
+ }
+
+ return XMPP_RETURN_OK;
+}
+
+XmppReturnStatus XmppEngineImpl::SendRaw(const std::string& text) {
+ if (state_ == STATE_CLOSED || login_task_)
+ return XMPP_RETURN_BADSTATE;
+
+ EnterExit ee(this);
+
+ (*output_) << text;
+
+ return XMPP_RETURN_OK;
+}
+
+std::string XmppEngineImpl::NextId() {
+ std::stringstream ss;
+ ss << next_id_++;
+ return ss.str();
+}
+
+XmppReturnStatus XmppEngineImpl::Disconnect() {
+ if (state_ != STATE_CLOSED) {
+ EnterExit ee(this);
+ if (state_ == STATE_OPEN)
+ *output_ << "</stream:stream>";
+ state_ = STATE_CLOSED;
+ }
+
+ return XMPP_RETURN_OK;
+}
+
+void XmppEngineImpl::IncomingStart(const XmlElement* start) {
+ if (HasError() || raised_reset_)
+ return;
+
+ if (login_task_) {
+ // start-stream should go to login task
+ login_task_->IncomingStanza(start, true);
+ if (login_task_->IsDone())
+ login_task_.reset();
+ }
+ else {
+ // if not logging in, it's an error to see a start
+ SignalError(ERROR_XML, 0);
+ }
+}
+
+void XmppEngineImpl::IncomingStanza(const XmlElement* stanza) {
+ if (HasError() || raised_reset_)
+ return;
+
+ if (stanza->Name() == QN_STREAM_ERROR) {
+ // Explicit XMPP stream error
+ SignalStreamError(stanza);
+ } else if (login_task_) {
+ // Handle login handshake
+ login_task_->IncomingStanza(stanza, false);
+ if (login_task_->IsDone())
+ login_task_.reset();
+ } else if (HandleIqResponse(stanza)) {
+ // iq is handled by above call
+ } else {
+ // give every "peek" handler a shot at all stanzas
+ for (size_t i = 0; i < stanza_handlers_[HL_PEEK]->size(); i += 1) {
+ (*stanza_handlers_[HL_PEEK])[i]->HandleStanza(stanza);
+ }
+
+ // give other handlers a shot in precedence order, stopping after handled
+ for (int level = HL_SINGLE; level <= HL_ALL; level += 1) {
+ for (size_t i = 0; i < stanza_handlers_[level]->size(); i += 1) {
+ if ((*stanza_handlers_[level])[i]->HandleStanza(stanza))
+ return;
+ }
+ }
+
+ // If nobody wants to handle a stanza then send back an error.
+ // Only do this for IQ stanzas as messages should probably just be dropped
+ // and presence stanzas should certainly be dropped.
+ std::string type = stanza->Attr(QN_TYPE);
+ if (stanza->Name() == QN_IQ &&
+ !(type == "error" || type == "result")) {
+ SendStanzaError(stanza, XSE_FEATURE_NOT_IMPLEMENTED, STR_EMPTY);
+ }
+ }
+}
+
+void XmppEngineImpl::IncomingEnd(bool isError) {
+ if (HasError() || raised_reset_)
+ return;
+
+ SignalError(isError ? ERROR_XML : ERROR_DOCUMENT_CLOSED, 0);
+}
+
+void XmppEngineImpl::InternalSendStart(const std::string& to) {
+ std::string hostname = tls_server_hostname_;
+ if (hostname.empty())
+ hostname = to;
+
+ // If not language is specified, the spec says use *
+ std::string lang = lang_;
+ if (lang.length() == 0)
+ lang = "*";
+
+ // send stream-beginning
+ // note, we put a \r\n at tne end fo the first line to cause non-XMPP
+ // line-oriented servers (e.g., Apache) to reveal themselves more quickly.
+ *output_ << "<stream:stream to=\"" << hostname << "\" "
+ << "xml:lang=\"" << lang << "\" "
+ << "version=\"1.0\" "
+ << "xmlns:stream=\"http://etherx.jabber.org/streams\" "
+ << "xmlns=\"jabber:client\">\r\n";
+}
+
+void XmppEngineImpl::InternalSendStanza(const XmlElement* element) {
+ // It should really never be necessary to set a FROM attribute on a stanza.
+ // It is implied by the bind on the stream and if you get it wrong
+ // (by flipping from/to on a message?) the server will close the stream.
+ ASSERT(!element->HasAttr(QN_FROM));
+
+ XmlPrinter::PrintXml(output_.get(), element, &xmlns_stack_);
+}
+
+std::string XmppEngineImpl::ChooseBestSaslMechanism(
+ const std::vector<std::string>& mechanisms, bool encrypted) {
+ return sasl_handler_->ChooseBestSaslMechanism(mechanisms, encrypted);
+}
+
+SaslMechanism* XmppEngineImpl::GetSaslMechanism(const std::string& name) {
+ return sasl_handler_->CreateSaslMechanism(name);
+}
+
+void XmppEngineImpl::SignalBound(const Jid& fullJid) {
+ if (state_ == STATE_OPENING) {
+ bound_jid_ = fullJid;
+ state_ = STATE_OPEN;
+ }
+}
+
+void XmppEngineImpl::SignalStreamError(const XmlElement* stream_error) {
+ if (state_ != STATE_CLOSED) {
+ stream_error_.reset(new XmlElement(*stream_error));
+ SignalError(ERROR_STREAM, 0);
+ }
+}
+
+void XmppEngineImpl::SignalError(Error error_code, int sub_code) {
+ if (state_ != STATE_CLOSED) {
+ error_code_ = error_code;
+ subcode_ = sub_code;
+ state_ = STATE_CLOSED;
+ }
+}
+
+bool XmppEngineImpl::HasError() {
+ return error_code_ != ERROR_NONE;
+}
+
+void XmppEngineImpl::StartTls(const std::string& domain) {
+ if (output_handler_) {
+ // As substitute for the real (login jid's) domain, we permit
+ // verifying a tls_server_domain_ instead, if one was passed.
+ // This allows us to avoid running a proxy that needs to handle
+ // valuable certificates.
+ output_handler_->StartTls(
+ tls_server_domain_.empty() ? domain : tls_server_domain_);
+ encrypted_ = true;
+ }
+}
+
+XmppEngineImpl::EnterExit::EnterExit(XmppEngineImpl* engine)
+ : engine_(engine),
+ state_(engine->state_) {
+ engine->engine_entered_ += 1;
+}
+
+XmppEngineImpl::EnterExit::~EnterExit() {
+ XmppEngineImpl* engine = engine_;
+
+ engine->engine_entered_ -= 1;
+
+ bool closing = (engine->state_ != state_ &&
+ engine->state_ == STATE_CLOSED);
+ bool flushing = closing || (engine->engine_entered_ == 0);
+
+ if (engine->output_handler_ && flushing) {
+ std::string output = engine->output_->str();
+ if (output.length() > 0)
+ engine->output_handler_->WriteOutput(output.c_str(), output.length());
+ engine->output_->str("");
+
+ if (closing) {
+ engine->output_handler_->CloseConnection();
+ engine->output_handler_ = 0;
+ }
+ }
+
+ if (engine->engine_entered_)
+ return;
+
+ if (engine->raised_reset_) {
+ engine->stanza_parser_.Reset();
+ engine->raised_reset_ = false;
+ }
+
+ if (engine->session_handler_) {
+ if (engine->state_ != state_)
+ engine->session_handler_->OnStateChange(engine->state_);
+ // Note: Handling of OnStateChange(CLOSED) should allow for the
+ // deletion of the engine, so no members should be accessed
+ // after this line.
+ }
+}
+
+} // namespace buzz
diff --git a/libjingle/xmpp/xmppengineimpl.h b/libjingle/xmpp/xmppengineimpl.h
new file mode 100644
index 00000000..c322596c
--- /dev/null
+++ b/libjingle/xmpp/xmppengineimpl.h
@@ -0,0 +1,265 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_XMPPENGINEIMPL_H_
+#define WEBRTC_LIBJINGLE_XMPP_XMPPENGINEIMPL_H_
+
+#include <sstream>
+#include <vector>
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+#include "webrtc/libjingle/xmpp/xmppstanzaparser.h"
+
+namespace buzz {
+
+class XmppLoginTask;
+class XmppEngine;
+class XmppIqEntry;
+class SaslHandler;
+class SaslMechanism;
+
+//! The XMPP connection engine.
+//! This engine implements the client side of the 'core' XMPP protocol.
+//! To use it, register an XmppOutputHandler to handle socket output
+//! and pass socket input to HandleInput. Then application code can
+//! set up the connection with a user, password, and other settings,
+//! and then call Connect() to initiate the connection.
+//! An application can listen for events and receive stanzas by
+//! registering an XmppStanzaHandler via AddStanzaHandler().
+class XmppEngineImpl : public XmppEngine {
+ public:
+ XmppEngineImpl();
+ virtual ~XmppEngineImpl();
+
+ // SOCKET INPUT AND OUTPUT ------------------------------------------------
+
+ //! Registers the handler for socket output
+ virtual XmppReturnStatus SetOutputHandler(XmppOutputHandler *pxoh);
+
+ //! Provides socket input to the engine
+ virtual XmppReturnStatus HandleInput(const char* bytes, size_t len);
+
+ //! Advises the engine that the socket has closed
+ virtual XmppReturnStatus ConnectionClosed(int subcode);
+
+ // SESSION SETUP ---------------------------------------------------------
+
+ //! Indicates the (bare) JID for the user to use.
+ virtual XmppReturnStatus SetUser(const Jid& jid);
+
+ //! Get the login (bare) JID.
+ virtual const Jid& GetUser();
+
+ //! Indicates the autentication to use. Takes ownership of the object.
+ virtual XmppReturnStatus SetSaslHandler(SaslHandler* sasl_handler);
+
+ //! Sets whether TLS will be used within the connection (default true).
+ virtual XmppReturnStatus SetTls(TlsOptions use_tls);
+
+ //! Sets an alternate domain from which we allows TLS certificates.
+ //! This is for use in the case where a we want to allow a proxy to
+ //! serve up its own certificate rather than one owned by the underlying
+ //! domain.
+ virtual XmppReturnStatus SetTlsServer(const std::string& proxy_hostname,
+ const std::string& proxy_domain);
+
+ //! Gets whether TLS will be used within the connection.
+ virtual TlsOptions GetTls();
+
+ //! Sets the request resource name, if any (optional).
+ //! Note that the resource name may be overridden by the server; after
+ //! binding, the actual resource name is available as part of FullJid().
+ virtual XmppReturnStatus SetRequestedResource(const std::string& resource);
+
+ //! Gets the request resource name.
+ virtual const std::string& GetRequestedResource();
+
+ //! Sets language
+ virtual void SetLanguage(const std::string& lang) {
+ lang_ = lang;
+ }
+
+ // SESSION MANAGEMENT ---------------------------------------------------
+
+ //! Set callback for state changes.
+ virtual XmppReturnStatus SetSessionHandler(XmppSessionHandler* handler);
+
+ //! Initiates the XMPP connection.
+ //! After supplying connection settings, call this once to initiate,
+ //! (optionally) encrypt, authenticate, and bind the connection.
+ virtual XmppReturnStatus Connect();
+
+ //! The current engine state.
+ virtual State GetState() { return state_; }
+
+ //! Returns true if the connection is encrypted (under TLS)
+ virtual bool IsEncrypted() { return encrypted_; }
+
+ //! The error code.
+ //! Consult this after XmppOutputHandler.OnClose().
+ virtual Error GetError(int *subcode) {
+ if (subcode) {
+ *subcode = subcode_;
+ }
+ return error_code_;
+ }
+
+ //! The stream:error stanza, when the error is XmppEngine::ERROR_STREAM.
+ //! Notice the stanza returned is owned by the XmppEngine and
+ //! is deleted when the engine is destroyed.
+ virtual const XmlElement* GetStreamError() { return stream_error_.get(); }
+
+ //! Closes down the connection.
+ //! Sends CloseConnection to output, and disconnects and registered
+ //! session handlers. After Disconnect completes, it is guaranteed
+ //! that no further callbacks will be made.
+ virtual XmppReturnStatus Disconnect();
+
+ // APPLICATION USE -------------------------------------------------------
+
+ //! Adds a listener for session events.
+ //! Stanza delivery is chained to session handlers; the first to
+ //! return 'true' is the last to get each stanza.
+ virtual XmppReturnStatus AddStanzaHandler(XmppStanzaHandler* handler,
+ XmppEngine::HandlerLevel level);
+
+ //! Removes a listener for session events.
+ virtual XmppReturnStatus RemoveStanzaHandler(XmppStanzaHandler* handler);
+
+ //! Sends a stanza to the server.
+ virtual XmppReturnStatus SendStanza(const XmlElement* stanza);
+
+ //! Sends raw text to the server
+ virtual XmppReturnStatus SendRaw(const std::string& text);
+
+ //! Sends an iq to the server, and registers a callback for the result.
+ //! Returns the cookie passed to the result handler.
+ virtual XmppReturnStatus SendIq(const XmlElement* stanza,
+ XmppIqHandler* iq_handler,
+ XmppIqCookie* cookie);
+
+ //! Unregisters an iq callback handler given its cookie.
+ //! No callback will come to this handler after it's unregistered.
+ virtual XmppReturnStatus RemoveIqHandler(XmppIqCookie cookie,
+ XmppIqHandler** iq_handler);
+
+ //! Forms and sends an error in response to the given stanza.
+ //! Swaps to and from, sets type to "error", and adds error information
+ //! based on the passed code. Text is optional and may be STR_EMPTY.
+ virtual XmppReturnStatus SendStanzaError(const XmlElement* pelOriginal,
+ XmppStanzaError code,
+ const std::string& text);
+
+ //! The fullly bound JID.
+ //! This JID is only valid after binding has succeeded. If the value
+ //! is JID_NULL, the binding has not succeeded.
+ virtual const Jid& FullJid() { return bound_jid_; }
+
+ //! The next unused iq id for this connection.
+ //! Call this when building iq stanzas, to ensure that each iq
+ //! gets its own unique id.
+ virtual std::string NextId();
+
+ private:
+ friend class XmppLoginTask;
+ friend class XmppIqEntry;
+
+ void IncomingStanza(const XmlElement *stanza);
+ void IncomingStart(const XmlElement *stanza);
+ void IncomingEnd(bool isError);
+
+ void InternalSendStart(const std::string& domainName);
+ void InternalSendStanza(const XmlElement* stanza);
+ std::string ChooseBestSaslMechanism(
+ const std::vector<std::string>& mechanisms, bool encrypted);
+ SaslMechanism* GetSaslMechanism(const std::string& name);
+ void SignalBound(const Jid& fullJid);
+ void SignalStreamError(const XmlElement* streamError);
+ void SignalError(Error errorCode, int subCode);
+ bool HasError();
+ void DeleteIqCookies();
+ bool HandleIqResponse(const XmlElement* element);
+ void StartTls(const std::string& domain);
+ void RaiseReset() { raised_reset_ = true; }
+
+ class StanzaParseHandler : public XmppStanzaParseHandler {
+ public:
+ StanzaParseHandler(XmppEngineImpl* outer) : outer_(outer) {}
+ virtual ~StanzaParseHandler() {}
+
+ virtual void StartStream(const XmlElement* stream) {
+ outer_->IncomingStart(stream);
+ }
+ virtual void Stanza(const XmlElement* stanza) {
+ outer_->IncomingStanza(stanza);
+ }
+ virtual void EndStream() {
+ outer_->IncomingEnd(false);
+ }
+ virtual void XmlError() {
+ outer_->IncomingEnd(true);
+ }
+
+ private:
+ XmppEngineImpl* const outer_;
+ };
+
+ class EnterExit {
+ public:
+ EnterExit(XmppEngineImpl* engine);
+ ~EnterExit();
+ private:
+ XmppEngineImpl* engine_;
+ State state_;
+ };
+
+ friend class StanzaParseHandler;
+ friend class EnterExit;
+
+ StanzaParseHandler stanza_parse_handler_;
+ XmppStanzaParser stanza_parser_;
+
+ // state
+ int engine_entered_;
+ Jid user_jid_;
+ std::string password_;
+ std::string requested_resource_;
+ TlsOptions tls_option_;
+ std::string tls_server_hostname_;
+ std::string tls_server_domain_;
+ rtc::scoped_ptr<XmppLoginTask> login_task_;
+ std::string lang_;
+
+ int next_id_;
+ Jid bound_jid_;
+ State state_;
+ bool encrypted_;
+ Error error_code_;
+ int subcode_;
+ rtc::scoped_ptr<XmlElement> stream_error_;
+ bool raised_reset_;
+ XmppOutputHandler* output_handler_;
+ XmppSessionHandler* session_handler_;
+
+ XmlnsStack xmlns_stack_;
+
+ typedef std::vector<XmppStanzaHandler*> StanzaHandlerVector;
+ rtc::scoped_ptr<StanzaHandlerVector> stanza_handlers_[HL_COUNT];
+
+ typedef std::vector<XmppIqEntry*> IqEntryVector;
+ rtc::scoped_ptr<IqEntryVector> iq_entries_;
+
+ rtc::scoped_ptr<SaslHandler> sasl_handler_;
+
+ rtc::scoped_ptr<std::stringstream> output_;
+};
+
+} // namespace buzz
+
+#endif // WEBRTC_LIBJINGLE_XMPP_XMPPENGINEIMPL_H_
diff --git a/libjingle/xmpp/xmppengineimpl_iq.cc b/libjingle/xmpp/xmppengineimpl_iq.cc
new file mode 100644
index 00000000..23b9fc43
--- /dev/null
+++ b/libjingle/xmpp/xmppengineimpl_iq.cc
@@ -0,0 +1,260 @@
+/*
+ * 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 <algorithm>
+#include <vector>
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/xmppengineimpl.h"
+#include "webrtc/base/common.h"
+
+namespace buzz {
+
+class XmppIqEntry {
+ XmppIqEntry(const std::string & id, const std::string & to,
+ XmppEngine * pxce, XmppIqHandler * iq_handler) :
+ id_(id),
+ to_(to),
+ engine_(pxce),
+ iq_handler_(iq_handler) {
+ }
+
+private:
+ friend class XmppEngineImpl;
+
+ const std::string id_;
+ const std::string to_;
+ XmppEngine * const engine_;
+ XmppIqHandler * const iq_handler_;
+};
+
+
+XmppReturnStatus
+XmppEngineImpl::SendIq(const XmlElement * element, XmppIqHandler * iq_handler,
+ XmppIqCookie* cookie) {
+ if (state_ == STATE_CLOSED)
+ return XMPP_RETURN_BADSTATE;
+ if (NULL == iq_handler)
+ return XMPP_RETURN_BADARGUMENT;
+ if (!element || element->Name() != QN_IQ)
+ return XMPP_RETURN_BADARGUMENT;
+
+ const std::string& type = element->Attr(QN_TYPE);
+ if (type != "get" && type != "set")
+ return XMPP_RETURN_BADARGUMENT;
+
+ if (!element->HasAttr(QN_ID))
+ return XMPP_RETURN_BADARGUMENT;
+ const std::string& id = element->Attr(QN_ID);
+
+ XmppIqEntry * iq_entry = new XmppIqEntry(id,
+ element->Attr(QN_TO),
+ this, iq_handler);
+ iq_entries_->push_back(iq_entry);
+ SendStanza(element);
+
+ if (cookie)
+ *cookie = iq_entry;
+
+ return XMPP_RETURN_OK;
+}
+
+
+XmppReturnStatus
+XmppEngineImpl::RemoveIqHandler(XmppIqCookie cookie,
+ XmppIqHandler ** iq_handler) {
+
+ std::vector<XmppIqEntry*, std::allocator<XmppIqEntry*> >::iterator pos;
+
+ pos = std::find(iq_entries_->begin(),
+ iq_entries_->end(),
+ reinterpret_cast<XmppIqEntry*>(cookie));
+
+ if (pos == iq_entries_->end())
+ return XMPP_RETURN_BADARGUMENT;
+
+ XmppIqEntry* entry = *pos;
+ iq_entries_->erase(pos);
+ if (iq_handler)
+ *iq_handler = entry->iq_handler_;
+ delete entry;
+
+ return XMPP_RETURN_OK;
+}
+
+void
+XmppEngineImpl::DeleteIqCookies() {
+ for (size_t i = 0; i < iq_entries_->size(); i += 1) {
+ XmppIqEntry * iq_entry_ = (*iq_entries_)[i];
+ (*iq_entries_)[i] = NULL;
+ delete iq_entry_;
+ }
+ iq_entries_->clear();
+}
+
+static void
+AecImpl(XmlElement * error_element, const QName & name,
+ const char * type, const char * code) {
+ error_element->AddElement(new XmlElement(QN_ERROR));
+ error_element->AddAttr(QN_CODE, code, 1);
+ error_element->AddAttr(QN_TYPE, type, 1);
+ error_element->AddElement(new XmlElement(name, true), 1);
+}
+
+
+static void
+AddErrorCode(XmlElement * error_element, XmppStanzaError code) {
+ switch (code) {
+ case XSE_BAD_REQUEST:
+ AecImpl(error_element, QN_STANZA_BAD_REQUEST, "modify", "400");
+ break;
+ case XSE_CONFLICT:
+ AecImpl(error_element, QN_STANZA_CONFLICT, "cancel", "409");
+ break;
+ case XSE_FEATURE_NOT_IMPLEMENTED:
+ AecImpl(error_element, QN_STANZA_FEATURE_NOT_IMPLEMENTED,
+ "cancel", "501");
+ break;
+ case XSE_FORBIDDEN:
+ AecImpl(error_element, QN_STANZA_FORBIDDEN, "auth", "403");
+ break;
+ case XSE_GONE:
+ AecImpl(error_element, QN_STANZA_GONE, "modify", "302");
+ break;
+ case XSE_INTERNAL_SERVER_ERROR:
+ AecImpl(error_element, QN_STANZA_INTERNAL_SERVER_ERROR, "wait", "500");
+ break;
+ case XSE_ITEM_NOT_FOUND:
+ AecImpl(error_element, QN_STANZA_ITEM_NOT_FOUND, "cancel", "404");
+ break;
+ case XSE_JID_MALFORMED:
+ AecImpl(error_element, QN_STANZA_JID_MALFORMED, "modify", "400");
+ break;
+ case XSE_NOT_ACCEPTABLE:
+ AecImpl(error_element, QN_STANZA_NOT_ACCEPTABLE, "cancel", "406");
+ break;
+ case XSE_NOT_ALLOWED:
+ AecImpl(error_element, QN_STANZA_NOT_ALLOWED, "cancel", "405");
+ break;
+ case XSE_PAYMENT_REQUIRED:
+ AecImpl(error_element, QN_STANZA_PAYMENT_REQUIRED, "auth", "402");
+ break;
+ case XSE_RECIPIENT_UNAVAILABLE:
+ AecImpl(error_element, QN_STANZA_RECIPIENT_UNAVAILABLE, "wait", "404");
+ break;
+ case XSE_REDIRECT:
+ AecImpl(error_element, QN_STANZA_REDIRECT, "modify", "302");
+ break;
+ case XSE_REGISTRATION_REQUIRED:
+ AecImpl(error_element, QN_STANZA_REGISTRATION_REQUIRED, "auth", "407");
+ break;
+ case XSE_SERVER_NOT_FOUND:
+ AecImpl(error_element, QN_STANZA_REMOTE_SERVER_NOT_FOUND,
+ "cancel", "404");
+ break;
+ case XSE_SERVER_TIMEOUT:
+ AecImpl(error_element, QN_STANZA_REMOTE_SERVER_TIMEOUT, "wait", "502");
+ break;
+ case XSE_RESOURCE_CONSTRAINT:
+ AecImpl(error_element, QN_STANZA_RESOURCE_CONSTRAINT, "wait", "500");
+ break;
+ case XSE_SERVICE_UNAVAILABLE:
+ AecImpl(error_element, QN_STANZA_SERVICE_UNAVAILABLE, "cancel", "503");
+ break;
+ case XSE_SUBSCRIPTION_REQUIRED:
+ AecImpl(error_element, QN_STANZA_SUBSCRIPTION_REQUIRED, "auth", "407");
+ break;
+ case XSE_UNDEFINED_CONDITION:
+ AecImpl(error_element, QN_STANZA_UNDEFINED_CONDITION, "wait", "500");
+ break;
+ case XSE_UNEXPECTED_REQUEST:
+ AecImpl(error_element, QN_STANZA_UNEXPECTED_REQUEST, "wait", "400");
+ break;
+ }
+}
+
+
+XmppReturnStatus
+XmppEngineImpl::SendStanzaError(const XmlElement * element_original,
+ XmppStanzaError code,
+ const std::string & text) {
+
+ if (state_ == STATE_CLOSED)
+ return XMPP_RETURN_BADSTATE;
+
+ XmlElement error_element(element_original->Name());
+ error_element.AddAttr(QN_TYPE, "error");
+
+ // copy attrs, copy 'from' to 'to' and strip 'from'
+ for (const XmlAttr * attribute = element_original->FirstAttr();
+ attribute; attribute = attribute->NextAttr()) {
+ QName name = attribute->Name();
+ if (name == QN_TO)
+ continue; // no need to put a from attr. Server will stamp stanza
+ else if (name == QN_FROM)
+ name = QN_TO;
+ else if (name == QN_TYPE)
+ continue;
+ error_element.AddAttr(name, attribute->Value());
+ }
+
+ // copy children
+ for (const XmlChild * child = element_original->FirstChild();
+ child;
+ child = child->NextChild()) {
+ if (child->IsText()) {
+ error_element.AddText(child->AsText()->Text());
+ } else {
+ error_element.AddElement(new XmlElement(*(child->AsElement())));
+ }
+ }
+
+ // add error information
+ AddErrorCode(&error_element, code);
+ if (text != STR_EMPTY) {
+ XmlElement * text_element = new XmlElement(QN_STANZA_TEXT, true);
+ text_element->AddText(text);
+ error_element.AddElement(text_element);
+ }
+
+ SendStanza(&error_element);
+
+ return XMPP_RETURN_OK;
+}
+
+
+bool
+XmppEngineImpl::HandleIqResponse(const XmlElement * element) {
+ if (iq_entries_->empty())
+ return false;
+ if (element->Name() != QN_IQ)
+ return false;
+ std::string type = element->Attr(QN_TYPE);
+ if (type != "result" && type != "error")
+ return false;
+ if (!element->HasAttr(QN_ID))
+ return false;
+ std::string id = element->Attr(QN_ID);
+ std::string from = element->Attr(QN_FROM);
+
+ for (std::vector<XmppIqEntry *>::iterator it = iq_entries_->begin();
+ it != iq_entries_->end(); it += 1) {
+ XmppIqEntry * iq_entry = *it;
+ if (iq_entry->id_ == id && iq_entry->to_ == from) {
+ iq_entries_->erase(it);
+ iq_entry->iq_handler_->IqResponse(iq_entry, element);
+ delete iq_entry;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+}
diff --git a/libjingle/xmpp/xmpplogintask.cc b/libjingle/xmpp/xmpplogintask.cc
new file mode 100644
index 00000000..f5745cd9
--- /dev/null
+++ b/libjingle/xmpp/xmpplogintask.cc
@@ -0,0 +1,380 @@
+/*
+ * 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 "webrtc/libjingle/xmpp/xmpplogintask.h"
+
+#include <string>
+#include <vector>
+
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/jid.h"
+#include "webrtc/libjingle/xmpp/saslmechanism.h"
+#include "webrtc/libjingle/xmpp/xmppengineimpl.h"
+#include "webrtc/base/base64.h"
+#include "webrtc/base/common.h"
+
+using rtc::ConstantLabel;
+
+namespace buzz {
+
+#ifdef _DEBUG
+const ConstantLabel XmppLoginTask::LOGINTASK_STATES[] = {
+ KLABEL(LOGINSTATE_INIT),
+ KLABEL(LOGINSTATE_STREAMSTART_SENT),
+ KLABEL(LOGINSTATE_STARTED_XMPP),
+ KLABEL(LOGINSTATE_TLS_INIT),
+ KLABEL(LOGINSTATE_AUTH_INIT),
+ KLABEL(LOGINSTATE_BIND_INIT),
+ KLABEL(LOGINSTATE_TLS_REQUESTED),
+ KLABEL(LOGINSTATE_SASL_RUNNING),
+ KLABEL(LOGINSTATE_BIND_REQUESTED),
+ KLABEL(LOGINSTATE_SESSION_REQUESTED),
+ KLABEL(LOGINSTATE_DONE),
+ LASTLABEL
+};
+#endif // _DEBUG
+XmppLoginTask::XmppLoginTask(XmppEngineImpl * pctx) :
+ pctx_(pctx),
+ authNeeded_(true),
+ allowNonGoogleLogin_(true),
+ state_(LOGINSTATE_INIT),
+ pelStanza_(NULL),
+ isStart_(false),
+ iqId_(STR_EMPTY),
+ pelFeatures_(),
+ fullJid_(STR_EMPTY),
+ streamId_(STR_EMPTY),
+ pvecQueuedStanzas_(new std::vector<XmlElement *>()),
+ sasl_mech_() {
+}
+
+XmppLoginTask::~XmppLoginTask() {
+ for (size_t i = 0; i < pvecQueuedStanzas_->size(); i += 1)
+ delete (*pvecQueuedStanzas_)[i];
+}
+
+void
+XmppLoginTask::IncomingStanza(const XmlElement *element, bool isStart) {
+ pelStanza_ = element;
+ isStart_ = isStart;
+ Advance();
+ pelStanza_ = NULL;
+ isStart_ = false;
+}
+
+const XmlElement *
+XmppLoginTask::NextStanza() {
+ const XmlElement * result = pelStanza_;
+ pelStanza_ = NULL;
+ return result;
+}
+
+bool
+XmppLoginTask::Advance() {
+
+ for (;;) {
+
+ const XmlElement * element = NULL;
+
+#if _DEBUG
+ LOG(LS_VERBOSE) << "XmppLoginTask::Advance - "
+ << rtc::ErrorName(state_, LOGINTASK_STATES);
+#endif // _DEBUG
+
+ switch (state_) {
+
+ case LOGINSTATE_INIT: {
+ pctx_->RaiseReset();
+ pelFeatures_.reset(NULL);
+
+ // The proper domain to verify against is the real underlying
+ // domain - i.e., the domain that owns the JID. Our XmppEngineImpl
+ // also allows matching against a proxy domain instead, if it is told
+ // to do so - see the implementation of XmppEngineImpl::StartTls and
+ // XmppEngine::SetTlsServerDomain to see how you can use that feature
+ pctx_->InternalSendStart(pctx_->user_jid_.domain());
+ state_ = LOGINSTATE_STREAMSTART_SENT;
+ break;
+ }
+
+ case LOGINSTATE_STREAMSTART_SENT: {
+ if (NULL == (element = NextStanza()))
+ return true;
+
+ if (!isStart_ || !HandleStartStream(element))
+ return Failure(XmppEngine::ERROR_VERSION);
+
+ state_ = LOGINSTATE_STARTED_XMPP;
+ return true;
+ }
+
+ case LOGINSTATE_STARTED_XMPP: {
+ if (NULL == (element = NextStanza()))
+ return true;
+
+ if (!HandleFeatures(element))
+ return Failure(XmppEngine::ERROR_VERSION);
+
+ bool tls_present = (GetFeature(QN_TLS_STARTTLS) != NULL);
+ // Error if TLS required but not present.
+ if (pctx_->tls_option_ == buzz::TLS_REQUIRED && !tls_present) {
+ return Failure(XmppEngine::ERROR_TLS);
+ }
+ // Use TLS if required or enabled, and also available
+ if ((pctx_->tls_option_ == buzz::TLS_REQUIRED ||
+ pctx_->tls_option_ == buzz::TLS_ENABLED) && tls_present) {
+ state_ = LOGINSTATE_TLS_INIT;
+ continue;
+ }
+
+ if (authNeeded_) {
+ state_ = LOGINSTATE_AUTH_INIT;
+ continue;
+ }
+
+ state_ = LOGINSTATE_BIND_INIT;
+ continue;
+ }
+
+ case LOGINSTATE_TLS_INIT: {
+ const XmlElement * pelTls = GetFeature(QN_TLS_STARTTLS);
+ if (!pelTls)
+ return Failure(XmppEngine::ERROR_TLS);
+
+ XmlElement el(QN_TLS_STARTTLS, true);
+ pctx_->InternalSendStanza(&el);
+ state_ = LOGINSTATE_TLS_REQUESTED;
+ continue;
+ }
+
+ case LOGINSTATE_TLS_REQUESTED: {
+ if (NULL == (element = NextStanza()))
+ return true;
+ if (element->Name() != QN_TLS_PROCEED)
+ return Failure(XmppEngine::ERROR_TLS);
+
+ // The proper domain to verify against is the real underlying
+ // domain - i.e., the domain that owns the JID. Our XmppEngineImpl
+ // also allows matching against a proxy domain instead, if it is told
+ // to do so - see the implementation of XmppEngineImpl::StartTls and
+ // XmppEngine::SetTlsServerDomain to see how you can use that feature
+ pctx_->StartTls(pctx_->user_jid_.domain());
+ pctx_->tls_option_ = buzz::TLS_ENABLED;
+ state_ = LOGINSTATE_INIT;
+ continue;
+ }
+
+ case LOGINSTATE_AUTH_INIT: {
+ const XmlElement * pelSaslAuth = GetFeature(QN_SASL_MECHANISMS);
+ if (!pelSaslAuth) {
+ return Failure(XmppEngine::ERROR_AUTH);
+ }
+
+ // Collect together the SASL auth mechanisms presented by the server
+ std::vector<std::string> mechanisms;
+ for (const XmlElement * pelMech =
+ pelSaslAuth->FirstNamed(QN_SASL_MECHANISM);
+ pelMech;
+ pelMech = pelMech->NextNamed(QN_SASL_MECHANISM)) {
+
+ mechanisms.push_back(pelMech->BodyText());
+ }
+
+ // Given all the mechanisms, choose the best
+ std::string choice(pctx_->ChooseBestSaslMechanism(mechanisms, pctx_->IsEncrypted()));
+ if (choice.empty()) {
+ return Failure(XmppEngine::ERROR_AUTH);
+ }
+
+ // No recognized auth mechanism - that's an error
+ sasl_mech_.reset(pctx_->GetSaslMechanism(choice));
+ if (!sasl_mech_) {
+ return Failure(XmppEngine::ERROR_AUTH);
+ }
+
+ // OK, let's start it.
+ XmlElement * auth = sasl_mech_->StartSaslAuth();
+ if (auth == NULL) {
+ return Failure(XmppEngine::ERROR_AUTH);
+ }
+ if (allowNonGoogleLogin_) {
+ // Setting the following two attributes is required to support
+ // non-google ids.
+
+ // Allow login with non-google id accounts.
+ auth->SetAttr(QN_GOOGLE_ALLOW_NON_GOOGLE_ID_XMPP_LOGIN, "true");
+
+ // Allow login with either the non-google id or the friendly email.
+ auth->SetAttr(QN_GOOGLE_AUTH_CLIENT_USES_FULL_BIND_RESULT, "true");
+ }
+
+ pctx_->InternalSendStanza(auth);
+ delete auth;
+ state_ = LOGINSTATE_SASL_RUNNING;
+ continue;
+ }
+
+ case LOGINSTATE_SASL_RUNNING: {
+ if (NULL == (element = NextStanza()))
+ return true;
+ if (element->Name().Namespace() != NS_SASL)
+ return Failure(XmppEngine::ERROR_AUTH);
+ if (element->Name() == QN_SASL_CHALLENGE) {
+ XmlElement * response = sasl_mech_->HandleSaslChallenge(element);
+ if (response == NULL) {
+ return Failure(XmppEngine::ERROR_AUTH);
+ }
+ pctx_->InternalSendStanza(response);
+ delete response;
+ state_ = LOGINSTATE_SASL_RUNNING;
+ continue;
+ }
+ if (element->Name() != QN_SASL_SUCCESS) {
+ return Failure(XmppEngine::ERROR_UNAUTHORIZED);
+ }
+
+ // Authenticated!
+ authNeeded_ = false;
+ state_ = LOGINSTATE_INIT;
+ continue;
+ }
+
+ case LOGINSTATE_BIND_INIT: {
+ const XmlElement * pelBindFeature = GetFeature(QN_BIND_BIND);
+ const XmlElement * pelSessionFeature = GetFeature(QN_SESSION_SESSION);
+ if (!pelBindFeature || !pelSessionFeature)
+ return Failure(XmppEngine::ERROR_BIND);
+
+ XmlElement iq(QN_IQ);
+ iq.AddAttr(QN_TYPE, "set");
+
+ iqId_ = pctx_->NextId();
+ iq.AddAttr(QN_ID, iqId_);
+ iq.AddElement(new XmlElement(QN_BIND_BIND, true));
+
+ if (pctx_->requested_resource_ != STR_EMPTY) {
+ iq.AddElement(new XmlElement(QN_BIND_RESOURCE), 1);
+ iq.AddText(pctx_->requested_resource_, 2);
+ }
+ pctx_->InternalSendStanza(&iq);
+ state_ = LOGINSTATE_BIND_REQUESTED;
+ continue;
+ }
+
+ case LOGINSTATE_BIND_REQUESTED: {
+ if (NULL == (element = NextStanza()))
+ return true;
+
+ if (element->Name() != QN_IQ || element->Attr(QN_ID) != iqId_ ||
+ element->Attr(QN_TYPE) == "get" || element->Attr(QN_TYPE) == "set")
+ return true;
+
+ if (element->Attr(QN_TYPE) != "result" || element->FirstElement() == NULL ||
+ element->FirstElement()->Name() != QN_BIND_BIND)
+ return Failure(XmppEngine::ERROR_BIND);
+
+ fullJid_ = Jid(element->FirstElement()->TextNamed(QN_BIND_JID));
+ if (!fullJid_.IsFull()) {
+ return Failure(XmppEngine::ERROR_BIND);
+ }
+
+ // now request session
+ XmlElement iq(QN_IQ);
+ iq.AddAttr(QN_TYPE, "set");
+
+ iqId_ = pctx_->NextId();
+ iq.AddAttr(QN_ID, iqId_);
+ iq.AddElement(new XmlElement(QN_SESSION_SESSION, true));
+ pctx_->InternalSendStanza(&iq);
+
+ state_ = LOGINSTATE_SESSION_REQUESTED;
+ continue;
+ }
+
+ case LOGINSTATE_SESSION_REQUESTED: {
+ if (NULL == (element = NextStanza()))
+ return true;
+ if (element->Name() != QN_IQ || element->Attr(QN_ID) != iqId_ ||
+ element->Attr(QN_TYPE) == "get" || element->Attr(QN_TYPE) == "set")
+ return false;
+
+ if (element->Attr(QN_TYPE) != "result")
+ return Failure(XmppEngine::ERROR_BIND);
+
+ pctx_->SignalBound(fullJid_);
+ FlushQueuedStanzas();
+ state_ = LOGINSTATE_DONE;
+ return true;
+ }
+
+ case LOGINSTATE_DONE:
+ return false;
+ }
+ }
+}
+
+bool
+XmppLoginTask::HandleStartStream(const XmlElement *element) {
+
+ if (element->Name() != QN_STREAM_STREAM)
+ return false;
+
+ if (element->Attr(QN_XMLNS) != "jabber:client")
+ return false;
+
+ if (element->Attr(QN_VERSION) != "1.0")
+ return false;
+
+ if (!element->HasAttr(QN_ID))
+ return false;
+
+ streamId_ = element->Attr(QN_ID);
+
+ return true;
+}
+
+bool
+XmppLoginTask::HandleFeatures(const XmlElement *element) {
+ if (element->Name() != QN_STREAM_FEATURES)
+ return false;
+
+ pelFeatures_.reset(new XmlElement(*element));
+ return true;
+}
+
+const XmlElement *
+XmppLoginTask::GetFeature(const QName & name) {
+ return pelFeatures_->FirstNamed(name);
+}
+
+bool
+XmppLoginTask::Failure(XmppEngine::Error reason) {
+ state_ = LOGINSTATE_DONE;
+ pctx_->SignalError(reason, 0);
+ return false;
+}
+
+void
+XmppLoginTask::OutgoingStanza(const XmlElement * element) {
+ XmlElement * pelCopy = new XmlElement(*element);
+ pvecQueuedStanzas_->push_back(pelCopy);
+}
+
+void
+XmppLoginTask::FlushQueuedStanzas() {
+ for (size_t i = 0; i < pvecQueuedStanzas_->size(); i += 1) {
+ pctx_->InternalSendStanza((*pvecQueuedStanzas_)[i]);
+ delete (*pvecQueuedStanzas_)[i];
+ }
+ pvecQueuedStanzas_->clear();
+}
+
+}
diff --git a/libjingle/xmpp/xmpplogintask.h b/libjingle/xmpp/xmpplogintask.h
new file mode 100644
index 00000000..58e0a2f3
--- /dev/null
+++ b/libjingle/xmpp/xmpplogintask.h
@@ -0,0 +1,87 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_LOGINTASK_H_
+#define WEBRTC_LIBJINGLE_XMPP_LOGINTASK_H_
+
+#include <string>
+#include <vector>
+
+#include "webrtc/libjingle/xmpp/jid.h"
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/scoped_ptr.h"
+
+namespace buzz {
+
+class XmlElement;
+class XmppEngineImpl;
+class SaslMechanism;
+
+
+// TODO: Rename to LoginTask.
+class XmppLoginTask {
+
+public:
+ XmppLoginTask(XmppEngineImpl *pctx);
+ ~XmppLoginTask();
+
+ bool IsDone()
+ { return state_ == LOGINSTATE_DONE; }
+ void IncomingStanza(const XmlElement * element, bool isStart);
+ void OutgoingStanza(const XmlElement *element);
+ void set_allow_non_google_login(bool b)
+ { allowNonGoogleLogin_ = b; }
+
+private:
+ enum LoginTaskState {
+ LOGINSTATE_INIT = 0,
+ LOGINSTATE_STREAMSTART_SENT,
+ LOGINSTATE_STARTED_XMPP,
+ LOGINSTATE_TLS_INIT,
+ LOGINSTATE_AUTH_INIT,
+ LOGINSTATE_BIND_INIT,
+ LOGINSTATE_TLS_REQUESTED,
+ LOGINSTATE_SASL_RUNNING,
+ LOGINSTATE_BIND_REQUESTED,
+ LOGINSTATE_SESSION_REQUESTED,
+ LOGINSTATE_DONE,
+ };
+
+ const XmlElement * NextStanza();
+ bool Advance();
+ bool HandleStartStream(const XmlElement * element);
+ bool HandleFeatures(const XmlElement * element);
+ const XmlElement * GetFeature(const QName & name);
+ bool Failure(XmppEngine::Error reason);
+ void FlushQueuedStanzas();
+
+ XmppEngineImpl * pctx_;
+ bool authNeeded_;
+ bool allowNonGoogleLogin_;
+ LoginTaskState state_;
+ const XmlElement * pelStanza_;
+ bool isStart_;
+ std::string iqId_;
+ rtc::scoped_ptr<XmlElement> pelFeatures_;
+ Jid fullJid_;
+ std::string streamId_;
+ rtc::scoped_ptr<std::vector<XmlElement *> > pvecQueuedStanzas_;
+
+ rtc::scoped_ptr<SaslMechanism> sasl_mech_;
+
+#ifdef _DEBUG
+ static const rtc::ConstantLabel LOGINTASK_STATES[];
+#endif // _DEBUG
+};
+
+}
+
+#endif // WEBRTC_LIBJINGLE_XMPP_LOGINTASK_H_
diff --git a/libjingle/xmpp/xmpplogintask_unittest.cc b/libjingle/xmpp/xmpplogintask_unittest.cc
new file mode 100644
index 00000000..035275fe
--- /dev/null
+++ b/libjingle/xmpp/xmpplogintask_unittest.cc
@@ -0,0 +1,621 @@
+/*
+ * 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 <iostream>
+#include <sstream>
+#include <string>
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/plainsaslhandler.h"
+#include "webrtc/libjingle/xmpp/saslplainmechanism.h"
+#include "webrtc/libjingle/xmpp/util_unittest.h"
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/cryptstring.h"
+#include "webrtc/base/gunit.h"
+
+using buzz::Jid;
+using buzz::QName;
+using buzz::XmlElement;
+using buzz::XmppEngine;
+using buzz::XmppTestHandler;
+
+enum XlttStage {
+ XLTT_STAGE_CONNECT = 0,
+ XLTT_STAGE_STREAMSTART,
+ XLTT_STAGE_TLS_FEATURES,
+ XLTT_STAGE_TLS_PROCEED,
+ XLTT_STAGE_ENCRYPTED_START,
+ XLTT_STAGE_AUTH_FEATURES,
+ XLTT_STAGE_AUTH_SUCCESS,
+ XLTT_STAGE_AUTHENTICATED_START,
+ XLTT_STAGE_BIND_FEATURES,
+ XLTT_STAGE_BIND_SUCCESS,
+ XLTT_STAGE_SESSION_SUCCESS,
+};
+
+class XmppLoginTaskTest : public testing::Test {
+ public:
+ XmppEngine* engine() { return engine_.get(); }
+ XmppTestHandler* handler() { return handler_.get(); }
+ virtual void SetUp() {
+ engine_.reset(XmppEngine::Create());
+ handler_.reset(new XmppTestHandler(engine_.get()));
+
+ Jid jid("david@my-server");
+ rtc::InsecureCryptStringImpl pass;
+ pass.password() = "david";
+ engine_->SetSessionHandler(handler_.get());
+ engine_->SetOutputHandler(handler_.get());
+ engine_->AddStanzaHandler(handler_.get());
+ engine_->SetUser(jid);
+ engine_->SetSaslHandler(
+ new buzz::PlainSaslHandler(jid, rtc::CryptString(pass), true));
+ }
+ virtual void TearDown() {
+ handler_.reset();
+ engine_.reset();
+ }
+ void RunPartialLogin(XlttStage startstage, XlttStage endstage);
+ void SetTlsOptions(buzz::TlsOptions option);
+
+ private:
+ rtc::scoped_ptr<XmppEngine> engine_;
+ rtc::scoped_ptr<XmppTestHandler> handler_;
+};
+
+void XmppLoginTaskTest::SetTlsOptions(buzz::TlsOptions option) {
+ engine_->SetTls(option);
+}
+void XmppLoginTaskTest::RunPartialLogin(XlttStage startstage,
+ XlttStage endstage) {
+ std::string input;
+
+ switch (startstage) {
+ case XLTT_STAGE_CONNECT: {
+ engine_->Connect();
+ XmlElement appStanza(QName("test", "app-stanza"));
+ appStanza.AddText("this-is-a-test");
+ engine_->SendStanza(&appStanza);
+
+ EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" "
+ "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" "
+ "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
+ EXPECT_EQ("[OPENING]", handler_->SessionActivity());
+ EXPECT_EQ("", handler_->StanzaActivity());
+ if (endstage == XLTT_STAGE_CONNECT)
+ return;
+ }
+
+ case XLTT_STAGE_STREAMSTART: {
+ input = "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" "
+ "xmlns:stream=\"http://etherx.jabber.org/streams\" "
+ "xmlns=\"jabber:client\">";
+ engine_->HandleInput(input.c_str(), input.length());
+ EXPECT_EQ("", handler_->StanzaActivity());
+ EXPECT_EQ("", handler_->SessionActivity());
+ EXPECT_EQ("", handler_->OutputActivity());
+ if (endstage == XLTT_STAGE_STREAMSTART)
+ return;
+ }
+
+ case XLTT_STAGE_TLS_FEATURES: {
+ input = "<stream:features>"
+ "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>"
+ "</stream:features>";
+ engine_->HandleInput(input.c_str(), input.length());
+ EXPECT_EQ("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>",
+ handler_->OutputActivity());
+ EXPECT_EQ("", handler_->StanzaActivity());
+ EXPECT_EQ("", handler_->SessionActivity());
+ if (endstage == XLTT_STAGE_TLS_FEATURES)
+ return;
+ }
+
+ case XLTT_STAGE_TLS_PROCEED: {
+ input = std::string("<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
+ engine_->HandleInput(input.c_str(), input.length());
+ EXPECT_EQ("[START-TLS my-server]"
+ "<stream:stream to=\"my-server\" xml:lang=\"*\" "
+ "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" "
+ "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
+ EXPECT_EQ("", handler_->StanzaActivity());
+ EXPECT_EQ("", handler_->SessionActivity());
+ if (endstage == XLTT_STAGE_TLS_PROCEED)
+ return;
+ }
+
+ case XLTT_STAGE_ENCRYPTED_START: {
+ input = std::string("<stream:stream id=\"01234567\" version=\"1.0\" "
+ "xmlns:stream=\"http://etherx.jabber.org/streams\" "
+ "xmlns=\"jabber:client\">");
+ engine_->HandleInput(input.c_str(), input.length());
+ EXPECT_EQ("", handler_->StanzaActivity());
+ EXPECT_EQ("", handler_->SessionActivity());
+ EXPECT_EQ("", handler_->OutputActivity());
+ if (endstage == XLTT_STAGE_ENCRYPTED_START)
+ return;
+ }
+
+ case XLTT_STAGE_AUTH_FEATURES: {
+ input = "<stream:features>"
+ "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
+ "<mechanism>DIGEST-MD5</mechanism>"
+ "<mechanism>PLAIN</mechanism>"
+ "</mechanisms>"
+ "</stream:features>";
+ engine_->HandleInput(input.c_str(), input.length());
+ EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
+ "mechanism=\"PLAIN\" "
+ "auth:allow-non-google-login=\"true\" "
+ "auth:client-uses-full-bind-result=\"true\" "
+ "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
+ ">AGRhdmlkAGRhdmlk</auth>",
+ handler_->OutputActivity());
+ EXPECT_EQ("", handler_->StanzaActivity());
+ EXPECT_EQ("", handler_->SessionActivity());
+ if (endstage == XLTT_STAGE_AUTH_FEATURES)
+ return;
+ }
+
+ case XLTT_STAGE_AUTH_SUCCESS: {
+ input = "<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>";
+ engine_->HandleInput(input.c_str(), input.length());
+ EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" "
+ "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" "
+ "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
+ EXPECT_EQ("", handler_->StanzaActivity());
+ EXPECT_EQ("", handler_->SessionActivity());
+ if (endstage == XLTT_STAGE_AUTH_SUCCESS)
+ return;
+ }
+
+ case XLTT_STAGE_AUTHENTICATED_START: {
+ input = std::string("<stream:stream id=\"01234567\" version=\"1.0\" "
+ "xmlns:stream=\"http://etherx.jabber.org/streams\" "
+ "xmlns=\"jabber:client\">");
+ engine_->HandleInput(input.c_str(), input.length());
+ EXPECT_EQ("", handler_->StanzaActivity());
+ EXPECT_EQ("", handler_->SessionActivity());
+ EXPECT_EQ("", handler_->OutputActivity());
+ if (endstage == XLTT_STAGE_AUTHENTICATED_START)
+ return;
+ }
+
+ case XLTT_STAGE_BIND_FEATURES: {
+ input = "<stream:features>"
+ "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>"
+ "<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>"
+ "</stream:features>";
+ engine_->HandleInput(input.c_str(), input.length());
+ EXPECT_EQ("<iq type=\"set\" id=\"0\">"
+ "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"/></iq>",
+ handler_->OutputActivity());
+ EXPECT_EQ("", handler_->StanzaActivity());
+ EXPECT_EQ("", handler_->SessionActivity());
+ if (endstage == XLTT_STAGE_BIND_FEATURES)
+ return;
+ }
+
+ case XLTT_STAGE_BIND_SUCCESS: {
+ input = "<iq type='result' id='0'>"
+ "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>"
+ "<jid>david@my-server/test</jid></bind></iq>";
+ engine_->HandleInput(input.c_str(), input.length());
+ EXPECT_EQ("<iq type=\"set\" id=\"1\">"
+ "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/></iq>",
+ handler_->OutputActivity());
+ EXPECT_EQ("", handler_->StanzaActivity());
+ EXPECT_EQ("", handler_->SessionActivity());
+ if (endstage == XLTT_STAGE_BIND_SUCCESS)
+ return;
+ }
+
+ case XLTT_STAGE_SESSION_SUCCESS: {
+ input = "<iq type='result' id='1'/>";
+ engine_->HandleInput(input.c_str(), input.length());
+ EXPECT_EQ("<test:app-stanza xmlns:test=\"test\">this-is-a-test"
+ "</test:app-stanza>", handler_->OutputActivity());
+ EXPECT_EQ("[OPEN]", handler_->SessionActivity());
+ EXPECT_EQ("", handler_->StanzaActivity());
+ if (endstage == XLTT_STAGE_SESSION_SUCCESS)
+ return;
+ }
+ }
+}
+
+TEST_F(XmppLoginTaskTest, TestUtf8Good) {
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_CONNECT);
+
+ std::string input = "<?xml version='1.0' encoding='UTF-8'?>"
+ "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" "
+ "xmlns:stream=\"http://etherx.jabber.org/streams\" "
+ "xmlns=\"jabber:client\">";
+ engine()->HandleInput(input.c_str(), input.length());
+ EXPECT_EQ("", handler()->OutputActivity());
+ EXPECT_EQ("", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+
+TEST_F(XmppLoginTaskTest, TestNonUtf8Bad) {
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_CONNECT);
+
+ std::string input = "<?xml version='1.0' encoding='ISO-8859-1'?>"
+ "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" "
+ "xmlns:stream=\"http://etherx.jabber.org/streams\" "
+ "xmlns=\"jabber:client\">";
+ engine()->HandleInput(input.c_str(), input.length());
+ EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
+ EXPECT_EQ("[CLOSED][ERROR-XML]", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+
+TEST_F(XmppLoginTaskTest, TestNoFeatures) {
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
+
+ std::string input = "<iq type='get' id='1'/>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
+ EXPECT_EQ("[CLOSED][ERROR-VERSION]", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+
+TEST_F(XmppLoginTaskTest, TestTlsRequiredNotPresent) {
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
+
+ std::string input = "<stream:features>"
+ "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
+ "<mechanism>DIGEST-MD5</mechanism>"
+ "<mechanism>PLAIN</mechanism>"
+ "</mechanisms>"
+ "</stream:features>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
+ EXPECT_EQ("[CLOSED][ERROR-TLS]", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+
+TEST_F(XmppLoginTaskTest, TestTlsRequeiredAndPresent) {
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
+
+ std::string input = "<stream:features>"
+ "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>"
+ "<required/>"
+ "</starttls>"
+ "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
+ "<mechanism>X-GOOGLE-TOKEN</mechanism>"
+ "<mechanism>PLAIN</mechanism>"
+ "<mechanism>X-OAUTH2</mechanism>"
+ "</mechanisms>"
+ "</stream:features>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>",
+ handler()->OutputActivity());
+ EXPECT_EQ("", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+
+TEST_F(XmppLoginTaskTest, TestTlsEnabledNotPresent) {
+ SetTlsOptions(buzz::TLS_ENABLED);
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
+
+ std::string input = "<stream:features>"
+ "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
+ "<mechanism>DIGEST-MD5</mechanism>"
+ "<mechanism>PLAIN</mechanism>"
+ "</mechanisms>"
+ "</stream:features>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
+ "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" "
+ "auth:client-uses-full-bind-result=\"true\" "
+ "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
+ ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity());
+ EXPECT_EQ("", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+
+TEST_F(XmppLoginTaskTest, TestTlsEnabledAndPresent) {
+ SetTlsOptions(buzz::TLS_ENABLED);
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
+
+ std::string input = "<stream:features>"
+ "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
+ "<mechanism>X-GOOGLE-TOKEN</mechanism>"
+ "<mechanism>PLAIN</mechanism>"
+ "<mechanism>X-OAUTH2</mechanism>"
+ "</mechanisms>"
+ "</stream:features>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
+ "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" "
+ "auth:client-uses-full-bind-result=\"true\" "
+ "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
+ ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity());
+ EXPECT_EQ("", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+
+TEST_F(XmppLoginTaskTest, TestTlsDisabledNotPresent) {
+ SetTlsOptions(buzz::TLS_DISABLED);
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
+
+ std::string input = "<stream:features>"
+ "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
+ "<mechanism>DIGEST-MD5</mechanism>"
+ "<mechanism>PLAIN</mechanism>"
+ "</mechanisms>"
+ "</stream:features>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
+ "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" "
+ "auth:client-uses-full-bind-result=\"true\" "
+ "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
+ ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity());
+ EXPECT_EQ("", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+
+TEST_F(XmppLoginTaskTest, TestTlsDisabledAndPresent) {
+ SetTlsOptions(buzz::TLS_DISABLED);
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
+
+ std::string input = "<stream:features>"
+ "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
+ "<mechanism>X-GOOGLE-TOKEN</mechanism>"
+ "<mechanism>PLAIN</mechanism>"
+ "<mechanism>X-OAUTH2</mechanism>"
+ "</mechanisms>"
+ "</stream:features>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
+ "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" "
+ "auth:client-uses-full-bind-result=\"true\" "
+ "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
+ ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity());
+ EXPECT_EQ("", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+
+TEST_F(XmppLoginTaskTest, TestTlsFailure) {
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_TLS_FEATURES);
+
+ std::string input = "<failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
+ EXPECT_EQ("[CLOSED][ERROR-TLS]", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+
+TEST_F(XmppLoginTaskTest, TestTlsBadStream) {
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_TLS_PROCEED);
+
+ std::string input = "<wrongtag>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
+ EXPECT_EQ("[CLOSED][ERROR-VERSION]", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+
+TEST_F(XmppLoginTaskTest, TestMissingSaslPlain) {
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_ENCRYPTED_START);
+
+ std::string input = "<stream:features>"
+ "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
+ "<mechanism>DIGEST-MD5</mechanism>"
+ "</mechanisms>"
+ "</stream:features>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
+ EXPECT_EQ("[CLOSED][ERROR-AUTH]", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+
+TEST_F(XmppLoginTaskTest, TestWrongPassword) {
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTH_FEATURES);
+
+ std::string input = "<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
+ EXPECT_EQ("[CLOSED][ERROR-UNAUTHORIZED]", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+
+TEST_F(XmppLoginTaskTest, TestAuthBadStream) {
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTH_SUCCESS);
+
+ std::string input = "<wrongtag>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
+ EXPECT_EQ("[CLOSED][ERROR-VERSION]", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+
+TEST_F(XmppLoginTaskTest, TestMissingBindFeature) {
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTHENTICATED_START);
+
+ std::string input = "<stream:features>"
+ "<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>"
+ "</stream:features>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
+ EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
+}
+
+TEST_F(XmppLoginTaskTest, TestMissingSessionFeature) {
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTHENTICATED_START);
+
+ std::string input = "<stream:features>"
+ "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>"
+ "</stream:features>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
+ EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+
+/* TODO: Handle this case properly inside XmppLoginTask.
+TEST_F(XmppLoginTaskTest, TestBindFailure1) {
+ // check wrong JID
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES);
+
+ std::string input = "<iq type='result' id='0'>"
+ "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>"
+ "<jid>davey@my-server/test</jid></bind></iq>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
+ EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+*/
+
+TEST_F(XmppLoginTaskTest, TestBindFailure2) {
+ // check missing JID
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES);
+
+ std::string input = "<iq type='result' id='0'>"
+ "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/></iq>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
+ EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+
+TEST_F(XmppLoginTaskTest, TestBindFailure3) {
+ // check plain failure
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES);
+
+ std::string input = "<iq type='error' id='0'/>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
+ EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
+ EXPECT_EQ("", handler()->StanzaActivity());
+}
+
+TEST_F(XmppLoginTaskTest, TestBindFailure4) {
+ // check wrong id to ignore
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES);
+
+ std::string input = "<iq type='error' id='1'/>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ // continue after an ignored iq
+ RunPartialLogin(XLTT_STAGE_BIND_SUCCESS, XLTT_STAGE_SESSION_SUCCESS);
+}
+
+TEST_F(XmppLoginTaskTest, TestSessionFailurePlain1) {
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_SUCCESS);
+
+ std::string input = "<iq type='error' id='1'/>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
+ EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
+}
+
+TEST_F(XmppLoginTaskTest, TestSessionFailurePlain2) {
+ RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_SUCCESS);
+
+ // check reverse iq to ignore
+ // TODO: consider queueing or passing through?
+ std::string input = "<iq type='get' id='1'/>";
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("", handler()->OutputActivity());
+ EXPECT_EQ("", handler()->SessionActivity());
+
+ // continue after an ignored iq
+ RunPartialLogin(XLTT_STAGE_SESSION_SUCCESS, XLTT_STAGE_SESSION_SUCCESS);
+}
+
+TEST_F(XmppLoginTaskTest, TestBadXml) {
+ int errorKind = 0;
+ for (XlttStage stage = XLTT_STAGE_CONNECT;
+ stage <= XLTT_STAGE_SESSION_SUCCESS;
+ stage = static_cast<XlttStage>(stage + 1)) {
+ RunPartialLogin(XLTT_STAGE_CONNECT, stage);
+
+ std::string input;
+ switch (errorKind++ % 5) {
+ case 0: input = "&syntax;"; break;
+ case 1: input = "<nons:iq/>"; break;
+ case 2: input = "<iq a='b' a='dupe'/>"; break;
+ case 3: input = "<>"; break;
+ case 4: input = "<iq a='<wrong>'>"; break;
+ }
+
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
+ EXPECT_EQ("[CLOSED][ERROR-XML]", handler()->SessionActivity());
+
+ TearDown();
+ SetUp();
+ }
+}
+
+TEST_F(XmppLoginTaskTest, TestStreamError) {
+ for (XlttStage stage = XLTT_STAGE_CONNECT;
+ stage <= XLTT_STAGE_SESSION_SUCCESS;
+ stage = static_cast<XlttStage>(stage + 1)) {
+ switch (stage) {
+ case XLTT_STAGE_CONNECT:
+ case XLTT_STAGE_TLS_PROCEED:
+ case XLTT_STAGE_AUTH_SUCCESS:
+ continue;
+ default:
+ break;
+ }
+
+ RunPartialLogin(XLTT_STAGE_CONNECT, stage);
+
+ std::string input = "<stream:error>"
+ "<xml-not-well-formed xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>"
+ "<text xml:lang='en' xmlns='urn:ietf:params:xml:ns:xmpp-streams'>"
+ "Some special application diagnostic information!"
+ "</text>"
+ "<escape-your-data xmlns='application-ns'/>"
+ "</stream:error>";
+
+ engine()->HandleInput(input.c_str(), input.length());
+
+ EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
+ EXPECT_EQ("[CLOSED][ERROR-STREAM]", handler()->SessionActivity());
+
+ EXPECT_EQ("<str:error xmlns:str=\"http://etherx.jabber.org/streams\">"
+ "<xml-not-well-formed xmlns=\"urn:ietf:params:xml:ns:xmpp-streams\"/>"
+ "<text xml:lang=\"en\" xmlns=\"urn:ietf:params:xml:ns:xmpp-streams\">"
+ "Some special application diagnostic information!"
+ "</text>"
+ "<escape-your-data xmlns=\"application-ns\"/>"
+ "</str:error>", engine()->GetStreamError()->Str());
+
+ TearDown();
+ SetUp();
+ }
+}
+
diff --git a/libjingle/xmpp/xmpppump.cc b/libjingle/xmpp/xmpppump.cc
new file mode 100644
index 00000000..45259b12
--- /dev/null
+++ b/libjingle/xmpp/xmpppump.cc
@@ -0,0 +1,67 @@
+/*
+ * 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 "webrtc/libjingle/xmpp/xmpppump.h"
+
+#include "webrtc/libjingle/xmpp/xmppauth.h"
+
+namespace buzz {
+
+XmppPump::XmppPump(XmppPumpNotify * notify) {
+ state_ = buzz::XmppEngine::STATE_NONE;
+ notify_ = notify;
+ client_ = new buzz::XmppClient(this); // NOTE: deleted by TaskRunner
+}
+
+void XmppPump::DoLogin(const buzz::XmppClientSettings & xcs,
+ buzz::AsyncSocket* socket,
+ buzz::PreXmppAuth* auth) {
+ OnStateChange(buzz::XmppEngine::STATE_START);
+ if (!AllChildrenDone()) {
+ client_->SignalStateChange.connect(this, &XmppPump::OnStateChange);
+ client_->Connect(xcs, "", socket, auth);
+ client_->Start();
+ }
+}
+
+void XmppPump::DoDisconnect() {
+ if (!AllChildrenDone())
+ client_->Disconnect();
+ OnStateChange(buzz::XmppEngine::STATE_CLOSED);
+}
+
+void XmppPump::OnStateChange(buzz::XmppEngine::State state) {
+ if (state_ == state)
+ return;
+ state_ = state;
+ if (notify_ != NULL)
+ notify_->OnStateChange(state);
+}
+
+void XmppPump::WakeTasks() {
+ rtc::Thread::Current()->Post(this);
+}
+
+int64 XmppPump::CurrentTime() {
+ return (int64)rtc::Time();
+}
+
+void XmppPump::OnMessage(rtc::Message *pmsg) {
+ RunTasks();
+}
+
+buzz::XmppReturnStatus XmppPump::SendStanza(const buzz::XmlElement *stanza) {
+ if (!AllChildrenDone())
+ return client_->SendStanza(stanza);
+ return buzz::XMPP_RETURN_BADSTATE;
+}
+
+} // namespace buzz
+
diff --git a/libjingle/xmpp/xmpppump.h b/libjingle/xmpp/xmpppump.h
new file mode 100644
index 00000000..81632987
--- /dev/null
+++ b/libjingle/xmpp/xmpppump.h
@@ -0,0 +1,62 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_XMPPPUMP_H_
+#define WEBRTC_LIBJINGLE_XMPP_XMPPPUMP_H_
+
+#include "webrtc/libjingle/xmpp/xmppclient.h"
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+#include "webrtc/libjingle/xmpp/xmpptask.h"
+#include "webrtc/base/messagequeue.h"
+#include "webrtc/base/taskrunner.h"
+#include "webrtc/base/thread.h"
+#include "webrtc/base/timeutils.h"
+
+namespace buzz {
+
+// Simple xmpp pump
+
+class XmppPumpNotify {
+public:
+ virtual ~XmppPumpNotify() {}
+ virtual void OnStateChange(buzz::XmppEngine::State state) = 0;
+};
+
+class XmppPump : public rtc::MessageHandler, public rtc::TaskRunner {
+public:
+ XmppPump(buzz::XmppPumpNotify * notify = NULL);
+
+ buzz::XmppClient *client() { return client_; }
+
+ void DoLogin(const buzz::XmppClientSettings & xcs,
+ buzz::AsyncSocket* socket,
+ buzz::PreXmppAuth* auth);
+ void DoDisconnect();
+
+ void OnStateChange(buzz::XmppEngine::State state);
+
+ void WakeTasks();
+
+ int64 CurrentTime();
+
+ void OnMessage(rtc::Message *pmsg);
+
+ buzz::XmppReturnStatus SendStanza(const buzz::XmlElement *stanza);
+
+private:
+ buzz::XmppClient *client_;
+ buzz::XmppEngine::State state_;
+ buzz::XmppPumpNotify *notify_;
+};
+
+} // namespace buzz
+
+#endif // WEBRTC_LIBJINGLE_XMPP_XMPPPUMP_H_
+
diff --git a/libjingle/xmpp/xmppsocket.cc b/libjingle/xmpp/xmppsocket.cc
new file mode 100644
index 00000000..d67a71fe
--- /dev/null
+++ b/libjingle/xmpp/xmppsocket.cc
@@ -0,0 +1,245 @@
+/*
+ * 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 "xmppsocket.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include "webrtc/base/basicdefs.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/thread.h"
+#ifdef FEATURE_ENABLE_SSL
+#include "webrtc/base/ssladapter.h"
+#endif
+
+#ifdef USE_SSLSTREAM
+#include "webrtc/base/socketstream.h"
+#ifdef FEATURE_ENABLE_SSL
+#include "webrtc/base/sslstreamadapter.h"
+#endif // FEATURE_ENABLE_SSL
+#endif // USE_SSLSTREAM
+
+namespace buzz {
+
+XmppSocket::XmppSocket(buzz::TlsOptions tls) : cricket_socket_(NULL),
+ tls_(tls) {
+ state_ = buzz::AsyncSocket::STATE_CLOSED;
+}
+
+void XmppSocket::CreateCricketSocket(int family) {
+ rtc::Thread* pth = rtc::Thread::Current();
+ if (family == AF_UNSPEC) {
+ family = AF_INET;
+ }
+ rtc::AsyncSocket* socket =
+ pth->socketserver()->CreateAsyncSocket(family, SOCK_STREAM);
+#ifndef USE_SSLSTREAM
+#ifdef FEATURE_ENABLE_SSL
+ if (tls_ != buzz::TLS_DISABLED) {
+ socket = rtc::SSLAdapter::Create(socket);
+ }
+#endif // FEATURE_ENABLE_SSL
+ cricket_socket_ = socket;
+ cricket_socket_->SignalReadEvent.connect(this, &XmppSocket::OnReadEvent);
+ cricket_socket_->SignalWriteEvent.connect(this, &XmppSocket::OnWriteEvent);
+ cricket_socket_->SignalConnectEvent.connect(this,
+ &XmppSocket::OnConnectEvent);
+ cricket_socket_->SignalCloseEvent.connect(this, &XmppSocket::OnCloseEvent);
+#else // USE_SSLSTREAM
+ cricket_socket_ = socket;
+ stream_ = new rtc::SocketStream(cricket_socket_);
+#ifdef FEATURE_ENABLE_SSL
+ if (tls_ != buzz::TLS_DISABLED)
+ stream_ = rtc::SSLStreamAdapter::Create(stream_);
+#endif // FEATURE_ENABLE_SSL
+ stream_->SignalEvent.connect(this, &XmppSocket::OnEvent);
+#endif // USE_SSLSTREAM
+}
+
+XmppSocket::~XmppSocket() {
+ Close();
+#ifndef USE_SSLSTREAM
+ delete cricket_socket_;
+#else // USE_SSLSTREAM
+ delete stream_;
+#endif // USE_SSLSTREAM
+}
+
+#ifndef USE_SSLSTREAM
+void XmppSocket::OnReadEvent(rtc::AsyncSocket * socket) {
+ SignalRead();
+}
+
+void XmppSocket::OnWriteEvent(rtc::AsyncSocket * socket) {
+ // Write bytes if there are any
+ while (buffer_.Length() != 0) {
+ int written = cricket_socket_->Send(buffer_.Data(), buffer_.Length());
+ if (written > 0) {
+ buffer_.Consume(written);
+ continue;
+ }
+ if (!cricket_socket_->IsBlocking())
+ LOG(LS_ERROR) << "Send error: " << cricket_socket_->GetError();
+ return;
+ }
+}
+
+void XmppSocket::OnConnectEvent(rtc::AsyncSocket * socket) {
+#if defined(FEATURE_ENABLE_SSL)
+ if (state_ == buzz::AsyncSocket::STATE_TLS_CONNECTING) {
+ state_ = buzz::AsyncSocket::STATE_TLS_OPEN;
+ SignalSSLConnected();
+ OnWriteEvent(cricket_socket_);
+ return;
+ }
+#endif // !defined(FEATURE_ENABLE_SSL)
+ state_ = buzz::AsyncSocket::STATE_OPEN;
+ SignalConnected();
+}
+
+void XmppSocket::OnCloseEvent(rtc::AsyncSocket * socket, int error) {
+ SignalCloseEvent(error);
+}
+
+#else // USE_SSLSTREAM
+
+void XmppSocket::OnEvent(rtc::StreamInterface* stream,
+ int events, int err) {
+ if ((events & rtc::SE_OPEN)) {
+#if defined(FEATURE_ENABLE_SSL)
+ if (state_ == buzz::AsyncSocket::STATE_TLS_CONNECTING) {
+ state_ = buzz::AsyncSocket::STATE_TLS_OPEN;
+ SignalSSLConnected();
+ events |= rtc::SE_WRITE;
+ } else
+#endif
+ {
+ state_ = buzz::AsyncSocket::STATE_OPEN;
+ SignalConnected();
+ }
+ }
+ if ((events & rtc::SE_READ))
+ SignalRead();
+ if ((events & rtc::SE_WRITE)) {
+ // Write bytes if there are any
+ while (buffer_.Length() != 0) {
+ rtc::StreamResult result;
+ size_t written;
+ int error;
+ result = stream_->Write(buffer_.Data(), buffer_.Length(),
+ &written, &error);
+ if (result == rtc::SR_ERROR) {
+ LOG(LS_ERROR) << "Send error: " << error;
+ return;
+ }
+ if (result == rtc::SR_BLOCK)
+ return;
+ ASSERT(result == rtc::SR_SUCCESS);
+ ASSERT(written > 0);
+ buffer_.Shift(written);
+ }
+ }
+ if ((events & rtc::SE_CLOSE))
+ SignalCloseEvent(err);
+}
+#endif // USE_SSLSTREAM
+
+buzz::AsyncSocket::State XmppSocket::state() {
+ return state_;
+}
+
+buzz::AsyncSocket::Error XmppSocket::error() {
+ return buzz::AsyncSocket::ERROR_NONE;
+}
+
+int XmppSocket::GetError() {
+ return 0;
+}
+
+bool XmppSocket::Connect(const rtc::SocketAddress& addr) {
+ if (cricket_socket_ == NULL) {
+ CreateCricketSocket(addr.family());
+ }
+ if (cricket_socket_->Connect(addr) < 0) {
+ return cricket_socket_->IsBlocking();
+ }
+ return true;
+}
+
+bool XmppSocket::Read(char * data, size_t len, size_t* len_read) {
+#ifndef USE_SSLSTREAM
+ int read = cricket_socket_->Recv(data, len);
+ if (read > 0) {
+ *len_read = (size_t)read;
+ return true;
+ }
+#else // USE_SSLSTREAM
+ rtc::StreamResult result = stream_->Read(data, len, len_read, NULL);
+ if (result == rtc::SR_SUCCESS)
+ return true;
+#endif // USE_SSLSTREAM
+ return false;
+}
+
+bool XmppSocket::Write(const char * data, size_t len) {
+ buffer_.WriteBytes(data, len);
+#ifndef USE_SSLSTREAM
+ OnWriteEvent(cricket_socket_);
+#else // USE_SSLSTREAM
+ OnEvent(stream_, rtc::SE_WRITE, 0);
+#endif // USE_SSLSTREAM
+ return true;
+}
+
+bool XmppSocket::Close() {
+ if (state_ != buzz::AsyncSocket::STATE_OPEN)
+ return false;
+#ifndef USE_SSLSTREAM
+ if (cricket_socket_->Close() == 0) {
+ state_ = buzz::AsyncSocket::STATE_CLOSED;
+ SignalClosed();
+ return true;
+ }
+ return false;
+#else // USE_SSLSTREAM
+ state_ = buzz::AsyncSocket::STATE_CLOSED;
+ stream_->Close();
+ SignalClosed();
+ return true;
+#endif // USE_SSLSTREAM
+}
+
+bool XmppSocket::StartTls(const std::string & domainname) {
+#if defined(FEATURE_ENABLE_SSL)
+ if (tls_ == buzz::TLS_DISABLED)
+ return false;
+#ifndef USE_SSLSTREAM
+ rtc::SSLAdapter* ssl_adapter =
+ static_cast<rtc::SSLAdapter *>(cricket_socket_);
+ if (ssl_adapter->StartSSL(domainname.c_str(), false) != 0)
+ return false;
+#else // USE_SSLSTREAM
+ rtc::SSLStreamAdapter* ssl_stream =
+ static_cast<rtc::SSLStreamAdapter *>(stream_);
+ if (ssl_stream->StartSSLWithServer(domainname.c_str()) != 0)
+ return false;
+#endif // USE_SSLSTREAM
+ state_ = buzz::AsyncSocket::STATE_TLS_CONNECTING;
+ return true;
+#else // !defined(FEATURE_ENABLE_SSL)
+ return false;
+#endif // !defined(FEATURE_ENABLE_SSL)
+}
+
+} // namespace buzz
+
diff --git a/libjingle/xmpp/xmppsocket.h b/libjingle/xmpp/xmppsocket.h
new file mode 100644
index 00000000..527b23a5
--- /dev/null
+++ b/libjingle/xmpp/xmppsocket.h
@@ -0,0 +1,72 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_XMPPSOCKET_H_
+#define WEBRTC_LIBJINGLE_XMPP_XMPPSOCKET_H_
+
+#include "webrtc/libjingle/xmpp/asyncsocket.h"
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+#include "webrtc/base/asyncsocket.h"
+#include "webrtc/base/bytebuffer.h"
+#include "webrtc/base/sigslot.h"
+
+// The below define selects the SSLStreamAdapter implementation for
+// SSL, as opposed to the SSLAdapter socket adapter.
+// #define USE_SSLSTREAM
+
+namespace rtc {
+ class StreamInterface;
+ class SocketAddress;
+};
+extern rtc::AsyncSocket* cricket_socket_;
+
+namespace buzz {
+
+class XmppSocket : public buzz::AsyncSocket, public sigslot::has_slots<> {
+public:
+ XmppSocket(buzz::TlsOptions tls);
+ ~XmppSocket();
+
+ virtual buzz::AsyncSocket::State state();
+ virtual buzz::AsyncSocket::Error error();
+ virtual int GetError();
+
+ virtual bool Connect(const rtc::SocketAddress& addr);
+ virtual bool Read(char * data, size_t len, size_t* len_read);
+ virtual bool Write(const char * data, size_t len);
+ virtual bool Close();
+ virtual bool StartTls(const std::string & domainname);
+
+ sigslot::signal1<int> SignalCloseEvent;
+
+private:
+ void CreateCricketSocket(int family);
+#ifndef USE_SSLSTREAM
+ void OnReadEvent(rtc::AsyncSocket * socket);
+ void OnWriteEvent(rtc::AsyncSocket * socket);
+ void OnConnectEvent(rtc::AsyncSocket * socket);
+ void OnCloseEvent(rtc::AsyncSocket * socket, int error);
+#else // USE_SSLSTREAM
+ void OnEvent(rtc::StreamInterface* stream, int events, int err);
+#endif // USE_SSLSTREAM
+
+ rtc::AsyncSocket * cricket_socket_;
+#ifdef USE_SSLSTREAM
+ rtc::StreamInterface *stream_;
+#endif // USE_SSLSTREAM
+ buzz::AsyncSocket::State state_;
+ rtc::ByteBuffer buffer_;
+ buzz::TlsOptions tls_;
+};
+
+} // namespace buzz
+
+#endif // WEBRTC_LIBJINGLE_XMPP_XMPPSOCKET_H_
+
diff --git a/libjingle/xmpp/xmppstanzaparser.cc b/libjingle/xmpp/xmppstanzaparser.cc
new file mode 100644
index 00000000..035bb0b6
--- /dev/null
+++ b/libjingle/xmpp/xmppstanzaparser.cc
@@ -0,0 +1,89 @@
+/*
+ * 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 "webrtc/libjingle/xmpp/xmppstanzaparser.h"
+
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/base/common.h"
+#ifdef EXPAT_RELATIVE_PATH
+#include "expat.h"
+#else
+#include "third_party/expat/v2_0_1/Source/lib/expat.h"
+#endif
+
+namespace buzz {
+
+XmppStanzaParser::XmppStanzaParser(XmppStanzaParseHandler *psph) :
+ psph_(psph),
+ innerHandler_(this),
+ parser_(&innerHandler_),
+ depth_(0),
+ builder_() {
+}
+
+void
+XmppStanzaParser::Reset() {
+ parser_.Reset();
+ depth_ = 0;
+ builder_.Reset();
+}
+
+void
+XmppStanzaParser::IncomingStartElement(
+ XmlParseContext * pctx, const char * name, const char ** atts) {
+ if (depth_++ == 0) {
+ XmlElement * pelStream = XmlBuilder::BuildElement(pctx, name, atts);
+ if (pelStream == NULL) {
+ pctx->RaiseError(XML_ERROR_SYNTAX);
+ return;
+ }
+ psph_->StartStream(pelStream);
+ delete pelStream;
+ return;
+ }
+
+ builder_.StartElement(pctx, name, atts);
+}
+
+void
+XmppStanzaParser::IncomingCharacterData(
+ XmlParseContext * pctx, const char * text, int len) {
+ if (depth_ > 1) {
+ builder_.CharacterData(pctx, text, len);
+ }
+}
+
+void
+XmppStanzaParser::IncomingEndElement(
+ XmlParseContext * pctx, const char * name) {
+ if (--depth_ == 0) {
+ psph_->EndStream();
+ return;
+ }
+
+ builder_.EndElement(pctx, name);
+
+ if (depth_ == 1) {
+ XmlElement *element = builder_.CreateElement();
+ psph_->Stanza(element);
+ delete element;
+ }
+}
+
+void
+XmppStanzaParser::IncomingError(
+ XmlParseContext * pctx, XML_Error errCode) {
+ RTC_UNUSED(pctx);
+ RTC_UNUSED(errCode);
+ psph_->XmlError();
+}
+
+}
diff --git a/libjingle/xmpp/xmppstanzaparser.h b/libjingle/xmpp/xmppstanzaparser.h
new file mode 100644
index 00000000..3ad052e4
--- /dev/null
+++ b/libjingle/xmpp/xmppstanzaparser.h
@@ -0,0 +1,80 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_XMPPSTANZAPARSER_H_
+#define WEBRTC_LIBJINGLE_XMPP_XMPPSTANZAPARSER_H_
+
+#include "webrtc/libjingle/xmllite/xmlbuilder.h"
+#include "webrtc/libjingle/xmllite/xmlparser.h"
+
+
+namespace buzz {
+
+class XmlElement;
+
+class XmppStanzaParseHandler {
+public:
+ virtual ~XmppStanzaParseHandler() {}
+ virtual void StartStream(const XmlElement * pelStream) = 0;
+ virtual void Stanza(const XmlElement * pelStanza) = 0;
+ virtual void EndStream() = 0;
+ virtual void XmlError() = 0;
+};
+
+class XmppStanzaParser {
+public:
+ XmppStanzaParser(XmppStanzaParseHandler *psph);
+ bool Parse(const char * data, size_t len, bool isFinal)
+ { return parser_.Parse(data, len, isFinal); }
+ void Reset();
+
+private:
+ class ParseHandler : public XmlParseHandler {
+ public:
+ ParseHandler(XmppStanzaParser * outer) : outer_(outer) {}
+ virtual void StartElement(XmlParseContext * pctx,
+ const char * name, const char ** atts)
+ { outer_->IncomingStartElement(pctx, name, atts); }
+ virtual void EndElement(XmlParseContext * pctx,
+ const char * name)
+ { outer_->IncomingEndElement(pctx, name); }
+ virtual void CharacterData(XmlParseContext * pctx,
+ const char * text, int len)
+ { outer_->IncomingCharacterData(pctx, text, len); }
+ virtual void Error(XmlParseContext * pctx,
+ XML_Error errCode)
+ { outer_->IncomingError(pctx, errCode); }
+ private:
+ XmppStanzaParser * const outer_;
+ };
+
+ friend class ParseHandler;
+
+ void IncomingStartElement(XmlParseContext * pctx,
+ const char * name, const char ** atts);
+ void IncomingEndElement(XmlParseContext * pctx,
+ const char * name);
+ void IncomingCharacterData(XmlParseContext * pctx,
+ const char * text, int len);
+ void IncomingError(XmlParseContext * pctx,
+ XML_Error errCode);
+
+ XmppStanzaParseHandler * psph_;
+ ParseHandler innerHandler_;
+ XmlParser parser_;
+ int depth_;
+ XmlBuilder builder_;
+
+ };
+
+
+}
+
+#endif // WEBRTC_LIBJINGLE_XMPP_XMPPSTANZAPARSER_H_
diff --git a/libjingle/xmpp/xmppstanzaparser_unittest.cc b/libjingle/xmpp/xmppstanzaparser_unittest.cc
new file mode 100644
index 00000000..65fcac9d
--- /dev/null
+++ b/libjingle/xmpp/xmppstanzaparser_unittest.cc
@@ -0,0 +1,175 @@
+/*
+ * 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 <iostream>
+#include <sstream>
+#include <string>
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/xmppstanzaparser.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/gunit.h"
+
+using buzz::QName;
+using buzz::XmlElement;
+using buzz::XmppStanzaParser;
+using buzz::XmppStanzaParseHandler;
+
+class XmppStanzaParserTestHandler : public XmppStanzaParseHandler {
+ public:
+ virtual void StartStream(const XmlElement * element) {
+ ss_ << "START" << element->Str();
+ }
+ virtual void Stanza(const XmlElement * element) {
+ ss_ << "STANZA" << element->Str();
+ }
+ virtual void EndStream() {
+ ss_ << "END";
+ }
+ virtual void XmlError() {
+ ss_ << "ERROR";
+ }
+
+ std::string Str() {
+ return ss_.str();
+ }
+
+ std::string StrClear() {
+ std::string result = ss_.str();
+ ss_.str("");
+ return result;
+ }
+
+ private:
+ std::stringstream ss_;
+};
+
+
+TEST(XmppStanzaParserTest, TestTrivial) {
+ XmppStanzaParserTestHandler handler;
+ XmppStanzaParser parser(&handler);
+ std::string fragment;
+
+ fragment = "<trivial/>";
+ parser.Parse(fragment.c_str(), fragment.length(), false);
+ EXPECT_EQ("START<trivial/>END", handler.StrClear());
+}
+
+TEST(XmppStanzaParserTest, TestStanzaAtATime) {
+ XmppStanzaParserTestHandler handler;
+ XmppStanzaParser parser(&handler);
+ std::string fragment;
+
+ fragment = "<stream:stream id='abc' xmlns='j:c' xmlns:stream='str'>";
+ parser.Parse(fragment.c_str(), fragment.length(), false);
+ EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" "
+ "xmlns:stream=\"str\"/>", handler.StrClear());
+
+ fragment = "<message type='foo'><body>hello</body></message>";
+ parser.Parse(fragment.c_str(), fragment.length(), false);
+ EXPECT_EQ("STANZA<c:message type=\"foo\" xmlns:c=\"j:c\">"
+ "<c:body>hello</c:body></c:message>", handler.StrClear());
+
+ fragment = " SOME TEXT TO IGNORE ";
+ parser.Parse(fragment.c_str(), fragment.length(), false);
+ EXPECT_EQ("", handler.StrClear());
+
+ fragment = "<iq type='set' id='123'><abc xmlns='def'/></iq>";
+ parser.Parse(fragment.c_str(), fragment.length(), false);
+ EXPECT_EQ("STANZA<c:iq type=\"set\" id=\"123\" xmlns:c=\"j:c\">"
+ "<abc xmlns=\"def\"/></c:iq>", handler.StrClear());
+
+ fragment = "</stream:stream>";
+ parser.Parse(fragment.c_str(), fragment.length(), false);
+ EXPECT_EQ("END", handler.StrClear());
+}
+
+TEST(XmppStanzaParserTest, TestFragmentedStanzas) {
+ XmppStanzaParserTestHandler handler;
+ XmppStanzaParser parser(&handler);
+ std::string fragment;
+
+ fragment = "<stream:stream id='abc' xmlns='j:c' xml";
+ parser.Parse(fragment.c_str(), fragment.length(), false);
+ EXPECT_EQ("", handler.StrClear());
+
+ fragment = "ns:stream='str'><message type='foo'><body>hel";
+ parser.Parse(fragment.c_str(), fragment.length(), false);
+ EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" "
+ "xmlns:stream=\"str\"/>", handler.StrClear());
+
+ fragment = "lo</body></message> IGNORE ME <iq type='set' id='123'>"
+ "<abc xmlns='def'/></iq></st";
+ parser.Parse(fragment.c_str(), fragment.length(), false);
+ EXPECT_EQ("STANZA<c:message type=\"foo\" xmlns:c=\"j:c\">"
+ "<c:body>hello</c:body></c:message>STANZA<c:iq type=\"set\" id=\"123\" "
+ "xmlns:c=\"j:c\"><abc xmlns=\"def\"/></c:iq>", handler.StrClear());
+
+ fragment = "ream:stream>";
+ parser.Parse(fragment.c_str(), fragment.length(), false);
+ EXPECT_EQ("END", handler.StrClear());
+}
+
+TEST(XmppStanzaParserTest, TestReset) {
+ XmppStanzaParserTestHandler handler;
+ XmppStanzaParser parser(&handler);
+ std::string fragment;
+
+ fragment = "<stream:stream id='abc' xmlns='j:c' xml";
+ parser.Parse(fragment.c_str(), fragment.length(), false);
+ EXPECT_EQ("", handler.StrClear());
+
+ parser.Reset();
+ fragment = "<stream:stream id='abc' xmlns='j:c' xml";
+ parser.Parse(fragment.c_str(), fragment.length(), false);
+ EXPECT_EQ("", handler.StrClear());
+
+ fragment = "ns:stream='str'><message type='foo'><body>hel";
+ parser.Parse(fragment.c_str(), fragment.length(), false);
+ EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" "
+ "xmlns:stream=\"str\"/>", handler.StrClear());
+ parser.Reset();
+
+ fragment = "<stream:stream id='abc' xmlns='j:c' xmlns:stream='str'>";
+ parser.Parse(fragment.c_str(), fragment.length(), false);
+ EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" "
+ "xmlns:stream=\"str\"/>", handler.StrClear());
+
+ fragment = "<message type='foo'><body>hello</body></message>";
+ parser.Parse(fragment.c_str(), fragment.length(), false);
+ EXPECT_EQ("STANZA<c:message type=\"foo\" xmlns:c=\"j:c\">"
+ "<c:body>hello</c:body></c:message>", handler.StrClear());
+}
+
+TEST(XmppStanzaParserTest, TestError) {
+ XmppStanzaParserTestHandler handler;
+ XmppStanzaParser parser(&handler);
+ std::string fragment;
+
+ fragment = "<-foobar/>";
+ parser.Parse(fragment.c_str(), fragment.length(), false);
+ EXPECT_EQ("ERROR", handler.StrClear());
+
+ parser.Reset();
+ fragment = "<stream:stream/>";
+ parser.Parse(fragment.c_str(), fragment.length(), false);
+ EXPECT_EQ("ERROR", handler.StrClear());
+ parser.Reset();
+
+ fragment = "ns:stream='str'><message type='foo'><body>hel";
+ parser.Parse(fragment.c_str(), fragment.length(), false);
+ EXPECT_EQ("ERROR", handler.StrClear());
+ parser.Reset();
+
+ fragment = "<stream:stream xmlns:stream='st' xmlns='jc'>"
+ "<foo/><bar><st:foobar/></bar>";
+ parser.Parse(fragment.c_str(), fragment.length(), false);
+ EXPECT_EQ("START<stream:stream xmlns:stream=\"st\" xmlns=\"jc\"/>STANZA"
+ "<jc:foo xmlns:jc=\"jc\"/>ERROR", handler.StrClear());
+}
diff --git a/libjingle/xmpp/xmpptask.cc b/libjingle/xmpp/xmpptask.cc
new file mode 100644
index 00000000..09067058
--- /dev/null
+++ b/libjingle/xmpp/xmpptask.cc
@@ -0,0 +1,158 @@
+/*
+ * 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 "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/xmppclient.h"
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+#include "webrtc/libjingle/xmpp/xmpptask.h"
+
+namespace buzz {
+
+XmppClientInterface::XmppClientInterface() {
+}
+
+XmppClientInterface::~XmppClientInterface() {
+}
+
+XmppTask::XmppTask(XmppTaskParentInterface* parent,
+ XmppEngine::HandlerLevel level)
+ : XmppTaskBase(parent), stopped_(false) {
+#ifdef _DEBUG
+ debug_force_timeout_ = false;
+#endif
+
+ id_ = GetClient()->NextId();
+ GetClient()->AddXmppTask(this, level);
+ GetClient()->SignalDisconnected.connect(this, &XmppTask::OnDisconnect);
+}
+
+XmppTask::~XmppTask() {
+ StopImpl();
+}
+
+void XmppTask::StopImpl() {
+ while (NextStanza() != NULL) {}
+ if (!stopped_) {
+ GetClient()->RemoveXmppTask(this);
+ GetClient()->SignalDisconnected.disconnect(this);
+ stopped_ = true;
+ }
+}
+
+XmppReturnStatus XmppTask::SendStanza(const XmlElement* stanza) {
+ if (stopped_)
+ return XMPP_RETURN_BADSTATE;
+ return GetClient()->SendStanza(stanza);
+}
+
+XmppReturnStatus XmppTask::SendStanzaError(const XmlElement* element_original,
+ XmppStanzaError code,
+ const std::string& text) {
+ if (stopped_)
+ return XMPP_RETURN_BADSTATE;
+ return GetClient()->SendStanzaError(element_original, code, text);
+}
+
+void XmppTask::Stop() {
+ StopImpl();
+ Task::Stop();
+}
+
+void XmppTask::OnDisconnect() {
+ Error();
+}
+
+void XmppTask::QueueStanza(const XmlElement* stanza) {
+#ifdef _DEBUG
+ if (debug_force_timeout_)
+ return;
+#endif
+
+ stanza_queue_.push_back(new XmlElement(*stanza));
+ Wake();
+}
+
+const XmlElement* XmppTask::NextStanza() {
+ XmlElement* result = NULL;
+ if (!stanza_queue_.empty()) {
+ result = stanza_queue_.front();
+ stanza_queue_.pop_front();
+ }
+ next_stanza_.reset(result);
+ return result;
+}
+
+XmlElement* XmppTask::MakeIq(const std::string& type,
+ const buzz::Jid& to,
+ const std::string& id) {
+ XmlElement* result = new XmlElement(QN_IQ);
+ if (!type.empty())
+ result->AddAttr(QN_TYPE, type);
+ if (!to.IsEmpty())
+ result->AddAttr(QN_TO, to.Str());
+ if (!id.empty())
+ result->AddAttr(QN_ID, id);
+ return result;
+}
+
+XmlElement* XmppTask::MakeIqResult(const XmlElement * query) {
+ XmlElement* result = new XmlElement(QN_IQ);
+ result->AddAttr(QN_TYPE, STR_RESULT);
+ if (query->HasAttr(QN_FROM)) {
+ result->AddAttr(QN_TO, query->Attr(QN_FROM));
+ }
+ result->AddAttr(QN_ID, query->Attr(QN_ID));
+ return result;
+}
+
+bool XmppTask::MatchResponseIq(const XmlElement* stanza,
+ const Jid& to,
+ const std::string& id) {
+ if (stanza->Name() != QN_IQ)
+ return false;
+
+ if (stanza->Attr(QN_ID) != id)
+ return false;
+
+ return MatchStanzaFrom(stanza, to);
+}
+
+bool XmppTask::MatchStanzaFrom(const XmlElement* stanza,
+ const Jid& to) {
+ Jid from(stanza->Attr(QN_FROM));
+ if (from == to)
+ return true;
+
+ // We address the server as "", check if we are doing so here.
+ if (!to.IsEmpty())
+ return false;
+
+ // It is legal for the server to identify itself with "domain" or
+ // "myself@domain"
+ Jid me = GetClient()->jid();
+ return (from == Jid(me.domain())) || (from == me.BareJid());
+}
+
+bool XmppTask::MatchRequestIq(const XmlElement* stanza,
+ const std::string& type,
+ const QName& qn) {
+ if (stanza->Name() != QN_IQ)
+ return false;
+
+ if (stanza->Attr(QN_TYPE) != type)
+ return false;
+
+ if (stanza->FirstNamed(qn) == NULL)
+ return false;
+
+ return true;
+}
+
+}
diff --git a/libjingle/xmpp/xmpptask.h b/libjingle/xmpp/xmpptask.h
new file mode 100644
index 00000000..e27b265c
--- /dev/null
+++ b/libjingle/xmpp/xmpptask.h
@@ -0,0 +1,172 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_XMPPTASK_H_
+#define WEBRTC_LIBJINGLE_XMPP_XMPPTASK_H_
+
+#include <deque>
+#include <string>
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+#include "webrtc/base/sigslot.h"
+#include "webrtc/base/task.h"
+#include "webrtc/base/taskparent.h"
+
+namespace buzz {
+
+/////////////////////////////////////////////////////////////////////
+//
+// XMPPTASK
+//
+/////////////////////////////////////////////////////////////////////
+//
+// See Task and XmppClient first.
+//
+// XmppTask is a task that is designed to go underneath XmppClient and be
+// useful there. It has a way of finding its XmppClient parent so you
+// can have it nested arbitrarily deep under an XmppClient and it can
+// still find the XMPP services.
+//
+// Tasks register themselves to listen to particular kinds of stanzas
+// that are sent out by the client. Rather than processing stanzas
+// right away, they should decide if they own the sent stanza,
+// and if so, queue it and Wake() the task, or if a stanza does not belong
+// to you, return false right away so the next XmppTask can take a crack.
+// This technique (synchronous recognize, but asynchronous processing)
+// allows you to have arbitrary logic for recognizing stanzas yet still,
+// for example, disconnect a client while processing a stanza -
+// without reentrancy problems.
+//
+/////////////////////////////////////////////////////////////////////
+
+class XmppTask;
+
+// XmppClientInterface is an abstract interface for sending and
+// handling stanzas. It can be implemented for unit tests or
+// different network environments. It will usually be implemented by
+// XmppClient.
+class XmppClientInterface {
+ public:
+ XmppClientInterface();
+ virtual ~XmppClientInterface();
+
+ virtual XmppEngine::State GetState() const = 0;
+ virtual const Jid& jid() const = 0;
+ virtual std::string NextId() = 0;
+ virtual XmppReturnStatus SendStanza(const XmlElement* stanza) = 0;
+ virtual XmppReturnStatus SendStanzaError(const XmlElement* original_stanza,
+ XmppStanzaError error_code,
+ const std::string& message) = 0;
+ virtual void AddXmppTask(XmppTask* task, XmppEngine::HandlerLevel level) = 0;
+ virtual void RemoveXmppTask(XmppTask* task) = 0;
+ sigslot::signal0<> SignalDisconnected;
+
+ DISALLOW_EVIL_CONSTRUCTORS(XmppClientInterface);
+};
+
+// XmppTaskParentInterface is the interface require for any parent of
+// an XmppTask. It needs, for example, a way to get an
+// XmppClientInterface.
+
+// We really ought to inherit from a TaskParentInterface, but we tried
+// that and it's way too complicated to change
+// Task/TaskParent/TaskRunner. For now, this works.
+class XmppTaskParentInterface : public rtc::Task {
+ public:
+ explicit XmppTaskParentInterface(rtc::TaskParent* parent)
+ : Task(parent) {
+ }
+ virtual ~XmppTaskParentInterface() {}
+
+ virtual XmppClientInterface* GetClient() = 0;
+
+ DISALLOW_EVIL_CONSTRUCTORS(XmppTaskParentInterface);
+};
+
+class XmppTaskBase : public XmppTaskParentInterface {
+ public:
+ explicit XmppTaskBase(XmppTaskParentInterface* parent)
+ : XmppTaskParentInterface(parent),
+ parent_(parent) {
+ }
+ virtual ~XmppTaskBase() {}
+
+ virtual XmppClientInterface* GetClient() {
+ return parent_->GetClient();
+ }
+
+ protected:
+ XmppTaskParentInterface* parent_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(XmppTaskBase);
+};
+
+class XmppTask : public XmppTaskBase,
+ public XmppStanzaHandler,
+ public sigslot::has_slots<>
+{
+ public:
+ XmppTask(XmppTaskParentInterface* parent,
+ XmppEngine::HandlerLevel level = XmppEngine::HL_NONE);
+ virtual ~XmppTask();
+
+ std::string task_id() const { return id_; }
+ void set_task_id(std::string id) { id_ = id; }
+
+#ifdef _DEBUG
+ void set_debug_force_timeout(const bool f) { debug_force_timeout_ = f; }
+#endif
+
+ virtual bool HandleStanza(const XmlElement* stanza) { return false; }
+
+ protected:
+ XmppReturnStatus SendStanza(const XmlElement* stanza);
+ XmppReturnStatus SetResult(const std::string& code);
+ XmppReturnStatus SendStanzaError(const XmlElement* element_original,
+ XmppStanzaError code,
+ const std::string& text);
+
+ virtual void Stop();
+ virtual void OnDisconnect();
+
+ virtual void QueueStanza(const XmlElement* stanza);
+ const XmlElement* NextStanza();
+
+ bool MatchStanzaFrom(const XmlElement* stanza, const Jid& match_jid);
+
+ bool MatchResponseIq(const XmlElement* stanza, const Jid& to,
+ const std::string& task_id);
+
+ static bool MatchRequestIq(const XmlElement* stanza, const std::string& type,
+ const QName& qn);
+ static XmlElement *MakeIqResult(const XmlElement* query);
+ static XmlElement *MakeIq(const std::string& type,
+ const Jid& to, const std::string& task_id);
+
+ // Returns true if the task is under the specified rate limit and updates the
+ // rate limit accordingly
+ bool VerifyTaskRateLimit(const std::string task_name, int max_count,
+ int per_x_seconds);
+
+private:
+ void StopImpl();
+
+ bool stopped_;
+ std::deque<XmlElement*> stanza_queue_;
+ rtc::scoped_ptr<XmlElement> next_stanza_;
+ std::string id_;
+
+#ifdef _DEBUG
+ bool debug_force_timeout_;
+#endif
+};
+
+} // namespace buzz
+
+#endif // WEBRTC_LIBJINGLE_XMPP_XMPPTASK_H_
diff --git a/libjingle/xmpp/xmppthread.cc b/libjingle/xmpp/xmppthread.cc
new file mode 100644
index 00000000..faf21642
--- /dev/null
+++ b/libjingle/xmpp/xmppthread.cc
@@ -0,0 +1,69 @@
+/*
+ * 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 "webrtc/libjingle/xmpp/xmppthread.h"
+
+#include "webrtc/libjingle/xmpp/xmppauth.h"
+#include "webrtc/libjingle/xmpp/xmppclientsettings.h"
+
+namespace buzz {
+namespace {
+
+const uint32 MSG_LOGIN = 1;
+const uint32 MSG_DISCONNECT = 2;
+
+struct LoginData: public rtc::MessageData {
+ LoginData(const buzz::XmppClientSettings& s) : xcs(s) {}
+ virtual ~LoginData() {}
+
+ buzz::XmppClientSettings xcs;
+};
+
+} // namespace
+
+XmppThread::XmppThread() {
+ pump_ = new buzz::XmppPump(this);
+}
+
+XmppThread::~XmppThread() {
+ Stop();
+ delete pump_;
+}
+
+void XmppThread::ProcessMessages(int cms) {
+ rtc::Thread::ProcessMessages(cms);
+}
+
+void XmppThread::Login(const buzz::XmppClientSettings& xcs) {
+ Post(this, MSG_LOGIN, new LoginData(xcs));
+}
+
+void XmppThread::Disconnect() {
+ Post(this, MSG_DISCONNECT);
+}
+
+void XmppThread::OnStateChange(buzz::XmppEngine::State state) {
+}
+
+void XmppThread::OnMessage(rtc::Message* pmsg) {
+ if (pmsg->message_id == MSG_LOGIN) {
+ ASSERT(pmsg->pdata != NULL);
+ LoginData* data = reinterpret_cast<LoginData*>(pmsg->pdata);
+ pump_->DoLogin(data->xcs, new XmppSocket(buzz::TLS_DISABLED),
+ new XmppAuth());
+ delete data;
+ } else if (pmsg->message_id == MSG_DISCONNECT) {
+ pump_->DoDisconnect();
+ } else {
+ ASSERT(false);
+ }
+}
+
+} // namespace buzz
diff --git a/libjingle/xmpp/xmppthread.h b/libjingle/xmpp/xmppthread.h
new file mode 100644
index 00000000..80179250
--- /dev/null
+++ b/libjingle/xmpp/xmppthread.h
@@ -0,0 +1,45 @@
+/*
+ * 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 WEBRTC_LIBJINGLE_XMPP_XMPPTHREAD_H_
+#define WEBRTC_LIBJINGLE_XMPP_XMPPTHREAD_H_
+
+#include "webrtc/libjingle/xmpp/xmppclientsettings.h"
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+#include "webrtc/libjingle/xmpp/xmpppump.h"
+#include "webrtc/libjingle/xmpp/xmppsocket.h"
+#include "webrtc/base/thread.h"
+
+namespace buzz {
+
+class XmppThread:
+ public rtc::Thread, buzz::XmppPumpNotify, rtc::MessageHandler {
+public:
+ XmppThread();
+ ~XmppThread();
+
+ buzz::XmppClient* client() { return pump_->client(); }
+
+ void ProcessMessages(int cms);
+
+ void Login(const buzz::XmppClientSettings & xcs);
+ void Disconnect();
+
+private:
+ buzz::XmppPump* pump_;
+
+ void OnStateChange(buzz::XmppEngine::State state);
+ void OnMessage(rtc::Message* pmsg);
+};
+
+} // namespace buzz
+
+#endif // WEBRTC_LIBJINGLE_XMPP_XMPPTHREAD_H_
+
diff --git a/modules/CNG.target.darwin-arm.mk b/modules/CNG.target.darwin-arm.mk
index 8aa231f0..325b032b 100644
--- a/modules/CNG.target.darwin-arm.mk
+++ b/modules/CNG.target.darwin-arm.mk
@@ -87,11 +87,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +109,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -208,11 +211,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -228,6 +233,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/CNG.target.darwin-arm64.mk b/modules/CNG.target.darwin-arm64.mk
index ef2a7223..a294979b 100644
--- a/modules/CNG.target.darwin-arm64.mk
+++ b/modules/CNG.target.darwin-arm64.mk
@@ -76,11 +76,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -89,10 +91,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -182,11 +186,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -195,10 +201,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/CNG.target.darwin-mips.mk b/modules/CNG.target.darwin-mips.mk
index c74926f1..28d99305 100644
--- a/modules/CNG.target.darwin-mips.mk
+++ b/modules/CNG.target.darwin-mips.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -195,11 +198,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -214,6 +219,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/CNG.target.darwin-mips64.mk b/modules/CNG.target.darwin-mips64.mk
new file mode 100644
index 00000000..d8277d9a
--- /dev/null
+++ b/modules/CNG.target.darwin-mips64.mk
@@ -0,0 +1,275 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_CNG_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/cng/webrtc_cng.c \
+ third_party/webrtc/modules/audio_coding/codecs/cng/cng_helpfuns.c
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/cng/include \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/cng/include \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_CNG_gyp
+
+# Alias gyp target name.
+.PHONY: CNG
+CNG: third_party_webrtc_modules_CNG_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/CNG.target.darwin-x86.mk b/modules/CNG.target.darwin-x86.mk
index 0701555f..a23265d3 100644
--- a/modules/CNG.target.darwin-x86.mk
+++ b/modules/CNG.target.darwin-x86.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -194,11 +197,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -211,6 +216,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/CNG.target.darwin-x86_64.mk b/modules/CNG.target.darwin-x86_64.mk
index 49f0ee1c..f7d133ff 100644
--- a/modules/CNG.target.darwin-x86_64.mk
+++ b/modules/CNG.target.darwin-x86_64.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,6 +100,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -192,11 +195,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -209,6 +214,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/CNG.target.linux-arm.mk b/modules/CNG.target.linux-arm.mk
index 8aa231f0..325b032b 100644
--- a/modules/CNG.target.linux-arm.mk
+++ b/modules/CNG.target.linux-arm.mk
@@ -87,11 +87,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +109,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -208,11 +211,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -228,6 +233,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/CNG.target.linux-arm64.mk b/modules/CNG.target.linux-arm64.mk
index ef2a7223..a294979b 100644
--- a/modules/CNG.target.linux-arm64.mk
+++ b/modules/CNG.target.linux-arm64.mk
@@ -76,11 +76,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -89,10 +91,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -182,11 +186,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -195,10 +201,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/CNG.target.linux-mips.mk b/modules/CNG.target.linux-mips.mk
index c74926f1..28d99305 100644
--- a/modules/CNG.target.linux-mips.mk
+++ b/modules/CNG.target.linux-mips.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -195,11 +198,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -214,6 +219,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/CNG.target.linux-mips64.mk b/modules/CNG.target.linux-mips64.mk
new file mode 100644
index 00000000..d8277d9a
--- /dev/null
+++ b/modules/CNG.target.linux-mips64.mk
@@ -0,0 +1,275 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_CNG_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/cng/webrtc_cng.c \
+ third_party/webrtc/modules/audio_coding/codecs/cng/cng_helpfuns.c
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/cng/include \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/cng/include \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_CNG_gyp
+
+# Alias gyp target name.
+.PHONY: CNG
+CNG: third_party_webrtc_modules_CNG_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/CNG.target.linux-x86.mk b/modules/CNG.target.linux-x86.mk
index 0701555f..a23265d3 100644
--- a/modules/CNG.target.linux-x86.mk
+++ b/modules/CNG.target.linux-x86.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -194,11 +197,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -211,6 +216,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/CNG.target.linux-x86_64.mk b/modules/CNG.target.linux-x86_64.mk
index 49f0ee1c..f7d133ff 100644
--- a/modules/CNG.target.linux-x86_64.mk
+++ b/modules/CNG.target.linux-x86_64.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,6 +100,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -192,11 +195,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -209,6 +214,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/G711.target.darwin-arm.mk b/modules/G711.target.darwin-arm.mk
index 9e5001b0..b8317a4c 100644
--- a/modules/G711.target.darwin-arm.mk
+++ b/modules/G711.target.darwin-arm.mk
@@ -18,13 +18,15 @@ GYP_GENERATED_OUTPUTS :=
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+LOCAL_CPP_EXTENSION := .cc
LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
third_party/webrtc/modules/audio_coding/codecs/g711/g711_interface.c \
- third_party/webrtc/modules/audio_coding/codecs/g711/g711.c
+ third_party/webrtc/modules/audio_coding/codecs/g711/g711.c \
+ third_party/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
# Flags passed to both C and C++ files.
@@ -87,11 +89,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +111,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -205,11 +210,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -225,6 +232,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/G711.target.darwin-arm64.mk b/modules/G711.target.darwin-arm64.mk
index 03914704..5985ed55 100644
--- a/modules/G711.target.darwin-arm64.mk
+++ b/modules/G711.target.darwin-arm64.mk
@@ -18,13 +18,15 @@ GYP_GENERATED_OUTPUTS :=
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+LOCAL_CPP_EXTENSION := .cc
LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
third_party/webrtc/modules/audio_coding/codecs/g711/g711_interface.c \
- third_party/webrtc/modules/audio_coding/codecs/g711/g711.c
+ third_party/webrtc/modules/audio_coding/codecs/g711/g711.c \
+ third_party/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
# Flags passed to both C and C++ files.
@@ -76,11 +78,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -89,10 +93,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -179,11 +185,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -192,10 +200,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/G711.target.darwin-mips.mk b/modules/G711.target.darwin-mips.mk
index 2b57aeae..cfa44379 100644
--- a/modules/G711.target.darwin-mips.mk
+++ b/modules/G711.target.darwin-mips.mk
@@ -18,13 +18,15 @@ GYP_GENERATED_OUTPUTS :=
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+LOCAL_CPP_EXTENSION := .cc
LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
third_party/webrtc/modules/audio_coding/codecs/g711/g711_interface.c \
- third_party/webrtc/modules/audio_coding/codecs/g711/g711.c
+ third_party/webrtc/modules/audio_coding/codecs/g711/g711.c \
+ third_party/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
# Flags passed to both C and C++ files.
@@ -81,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +104,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -192,11 +197,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -211,6 +218,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/G711.target.darwin-mips64.mk b/modules/G711.target.darwin-mips64.mk
new file mode 100644
index 00000000..dd204ad6
--- /dev/null
+++ b/modules/G711.target.darwin-mips64.mk
@@ -0,0 +1,271 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_G711_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/g711/g711_interface.c \
+ third_party/webrtc/modules/audio_coding/codecs/g711/g711.c \
+ third_party/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g711/include \
+ $(LOCAL_PATH)/third_party/webrtc
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g711/include \
+ $(LOCAL_PATH)/third_party/webrtc
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_G711_gyp
+
+# Alias gyp target name.
+.PHONY: G711
+G711: third_party_webrtc_modules_G711_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/G711.target.darwin-x86.mk b/modules/G711.target.darwin-x86.mk
index 6bbab2ab..ac39ccbc 100644
--- a/modules/G711.target.darwin-x86.mk
+++ b/modules/G711.target.darwin-x86.mk
@@ -18,13 +18,15 @@ GYP_GENERATED_OUTPUTS :=
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+LOCAL_CPP_EXTENSION := .cc
LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
third_party/webrtc/modules/audio_coding/codecs/g711/g711_interface.c \
- third_party/webrtc/modules/audio_coding/codecs/g711/g711.c
+ third_party/webrtc/modules/audio_coding/codecs/g711/g711.c \
+ third_party/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
# Flags passed to both C and C++ files.
@@ -82,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +196,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -208,6 +215,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/G711.target.darwin-x86_64.mk b/modules/G711.target.darwin-x86_64.mk
index e0278810..33f38bec 100644
--- a/modules/G711.target.darwin-x86_64.mk
+++ b/modules/G711.target.darwin-x86_64.mk
@@ -18,13 +18,15 @@ GYP_GENERATED_OUTPUTS :=
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+LOCAL_CPP_EXTENSION := .cc
LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
third_party/webrtc/modules/audio_coding/codecs/g711/g711_interface.c \
- third_party/webrtc/modules/audio_coding/codecs/g711/g711.c
+ third_party/webrtc/modules/audio_coding/codecs/g711/g711.c \
+ third_party/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
# Flags passed to both C and C++ files.
@@ -81,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -189,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -206,6 +213,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/G711.target.linux-arm.mk b/modules/G711.target.linux-arm.mk
index 9e5001b0..b8317a4c 100644
--- a/modules/G711.target.linux-arm.mk
+++ b/modules/G711.target.linux-arm.mk
@@ -18,13 +18,15 @@ GYP_GENERATED_OUTPUTS :=
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+LOCAL_CPP_EXTENSION := .cc
LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
third_party/webrtc/modules/audio_coding/codecs/g711/g711_interface.c \
- third_party/webrtc/modules/audio_coding/codecs/g711/g711.c
+ third_party/webrtc/modules/audio_coding/codecs/g711/g711.c \
+ third_party/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
# Flags passed to both C and C++ files.
@@ -87,11 +89,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +111,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -205,11 +210,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -225,6 +232,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/G711.target.linux-arm64.mk b/modules/G711.target.linux-arm64.mk
index 03914704..5985ed55 100644
--- a/modules/G711.target.linux-arm64.mk
+++ b/modules/G711.target.linux-arm64.mk
@@ -18,13 +18,15 @@ GYP_GENERATED_OUTPUTS :=
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+LOCAL_CPP_EXTENSION := .cc
LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
third_party/webrtc/modules/audio_coding/codecs/g711/g711_interface.c \
- third_party/webrtc/modules/audio_coding/codecs/g711/g711.c
+ third_party/webrtc/modules/audio_coding/codecs/g711/g711.c \
+ third_party/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
# Flags passed to both C and C++ files.
@@ -76,11 +78,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -89,10 +93,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -179,11 +185,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -192,10 +200,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/G711.target.linux-mips.mk b/modules/G711.target.linux-mips.mk
index 2b57aeae..cfa44379 100644
--- a/modules/G711.target.linux-mips.mk
+++ b/modules/G711.target.linux-mips.mk
@@ -18,13 +18,15 @@ GYP_GENERATED_OUTPUTS :=
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+LOCAL_CPP_EXTENSION := .cc
LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
third_party/webrtc/modules/audio_coding/codecs/g711/g711_interface.c \
- third_party/webrtc/modules/audio_coding/codecs/g711/g711.c
+ third_party/webrtc/modules/audio_coding/codecs/g711/g711.c \
+ third_party/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
# Flags passed to both C and C++ files.
@@ -81,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +104,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -192,11 +197,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -211,6 +218,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/G711.target.linux-mips64.mk b/modules/G711.target.linux-mips64.mk
new file mode 100644
index 00000000..dd204ad6
--- /dev/null
+++ b/modules/G711.target.linux-mips64.mk
@@ -0,0 +1,271 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_G711_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/g711/g711_interface.c \
+ third_party/webrtc/modules/audio_coding/codecs/g711/g711.c \
+ third_party/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g711/include \
+ $(LOCAL_PATH)/third_party/webrtc
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g711/include \
+ $(LOCAL_PATH)/third_party/webrtc
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_G711_gyp
+
+# Alias gyp target name.
+.PHONY: G711
+G711: third_party_webrtc_modules_G711_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/G711.target.linux-x86.mk b/modules/G711.target.linux-x86.mk
index 6bbab2ab..ac39ccbc 100644
--- a/modules/G711.target.linux-x86.mk
+++ b/modules/G711.target.linux-x86.mk
@@ -18,13 +18,15 @@ GYP_GENERATED_OUTPUTS :=
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+LOCAL_CPP_EXTENSION := .cc
LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
third_party/webrtc/modules/audio_coding/codecs/g711/g711_interface.c \
- third_party/webrtc/modules/audio_coding/codecs/g711/g711.c
+ third_party/webrtc/modules/audio_coding/codecs/g711/g711.c \
+ third_party/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
# Flags passed to both C and C++ files.
@@ -82,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +196,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -208,6 +215,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/G711.target.linux-x86_64.mk b/modules/G711.target.linux-x86_64.mk
index e0278810..33f38bec 100644
--- a/modules/G711.target.linux-x86_64.mk
+++ b/modules/G711.target.linux-x86_64.mk
@@ -18,13 +18,15 @@ GYP_GENERATED_OUTPUTS :=
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+LOCAL_CPP_EXTENSION := .cc
LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
third_party/webrtc/modules/audio_coding/codecs/g711/g711_interface.c \
- third_party/webrtc/modules/audio_coding/codecs/g711/g711.c
+ third_party/webrtc/modules/audio_coding/codecs/g711/g711.c \
+ third_party/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
# Flags passed to both C and C++ files.
@@ -81,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -189,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -206,6 +213,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/G722.target.darwin-arm.mk b/modules/G722.target.darwin-arm.mk
index ec53ae52..30b1a068 100644
--- a/modules/G722.target.darwin-arm.mk
+++ b/modules/G722.target.darwin-arm.mk
@@ -88,11 +88,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -108,6 +110,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -206,11 +209,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -226,6 +231,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/G722.target.darwin-arm64.mk b/modules/G722.target.darwin-arm64.mk
index bab6cb8b..5b94da1f 100644
--- a/modules/G722.target.darwin-arm64.mk
+++ b/modules/G722.target.darwin-arm64.mk
@@ -77,11 +77,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -90,10 +92,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -180,11 +184,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -193,10 +199,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/G722.target.darwin-mips.mk b/modules/G722.target.darwin-mips.mk
index ff5f97be..a8ea043a 100644
--- a/modules/G722.target.darwin-mips.mk
+++ b/modules/G722.target.darwin-mips.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -193,11 +196,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -212,6 +217,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/G722.target.darwin-mips64.mk b/modules/G722.target.darwin-mips64.mk
new file mode 100644
index 00000000..e6985ee2
--- /dev/null
+++ b/modules/G722.target.darwin-mips64.mk
@@ -0,0 +1,270 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_G722_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/g722/g722_interface.c \
+ third_party/webrtc/modules/audio_coding/codecs/g722/g722_encode.c \
+ third_party/webrtc/modules/audio_coding/codecs/g722/g722_decode.c
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g722/include \
+ $(LOCAL_PATH)/third_party/webrtc
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g722/include \
+ $(LOCAL_PATH)/third_party/webrtc
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_G722_gyp
+
+# Alias gyp target name.
+.PHONY: G722
+G722: third_party_webrtc_modules_G722_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/G722.target.darwin-x86.mk b/modules/G722.target.darwin-x86.mk
index 7a276d6d..94c4bb7c 100644
--- a/modules/G722.target.darwin-x86.mk
+++ b/modules/G722.target.darwin-x86.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -192,11 +195,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -209,6 +214,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/G722.target.darwin-x86_64.mk b/modules/G722.target.darwin-x86_64.mk
index 589efac1..118ec039 100644
--- a/modules/G722.target.darwin-x86_64.mk
+++ b/modules/G722.target.darwin-x86_64.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -190,11 +193,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -207,6 +212,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/G722.target.linux-arm.mk b/modules/G722.target.linux-arm.mk
index ec53ae52..30b1a068 100644
--- a/modules/G722.target.linux-arm.mk
+++ b/modules/G722.target.linux-arm.mk
@@ -88,11 +88,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -108,6 +110,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -206,11 +209,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -226,6 +231,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/G722.target.linux-arm64.mk b/modules/G722.target.linux-arm64.mk
index bab6cb8b..5b94da1f 100644
--- a/modules/G722.target.linux-arm64.mk
+++ b/modules/G722.target.linux-arm64.mk
@@ -77,11 +77,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -90,10 +92,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -180,11 +184,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -193,10 +199,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/G722.target.linux-mips.mk b/modules/G722.target.linux-mips.mk
index ff5f97be..a8ea043a 100644
--- a/modules/G722.target.linux-mips.mk
+++ b/modules/G722.target.linux-mips.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -193,11 +196,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -212,6 +217,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/G722.target.linux-mips64.mk b/modules/G722.target.linux-mips64.mk
new file mode 100644
index 00000000..e6985ee2
--- /dev/null
+++ b/modules/G722.target.linux-mips64.mk
@@ -0,0 +1,270 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_G722_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/g722/g722_interface.c \
+ third_party/webrtc/modules/audio_coding/codecs/g722/g722_encode.c \
+ third_party/webrtc/modules/audio_coding/codecs/g722/g722_decode.c
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g722/include \
+ $(LOCAL_PATH)/third_party/webrtc
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g722/include \
+ $(LOCAL_PATH)/third_party/webrtc
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_G722_gyp
+
+# Alias gyp target name.
+.PHONY: G722
+G722: third_party_webrtc_modules_G722_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/G722.target.linux-x86.mk b/modules/G722.target.linux-x86.mk
index 7a276d6d..94c4bb7c 100644
--- a/modules/G722.target.linux-x86.mk
+++ b/modules/G722.target.linux-x86.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -192,11 +195,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -209,6 +214,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/G722.target.linux-x86_64.mk b/modules/G722.target.linux-x86_64.mk
index 589efac1..118ec039 100644
--- a/modules/G722.target.linux-x86_64.mk
+++ b/modules/G722.target.linux-x86_64.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -190,11 +193,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -207,6 +212,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/PCM16B.target.darwin-arm.mk b/modules/PCM16B.target.darwin-arm.mk
index e4b94cd7..404a4890 100644
--- a/modules/PCM16B.target.darwin-arm.mk
+++ b/modules/PCM16B.target.darwin-arm.mk
@@ -86,11 +86,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -106,6 +108,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -204,11 +207,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -224,6 +229,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/PCM16B.target.darwin-arm64.mk b/modules/PCM16B.target.darwin-arm64.mk
index dc883bce..6db1b5ea 100644
--- a/modules/PCM16B.target.darwin-arm64.mk
+++ b/modules/PCM16B.target.darwin-arm64.mk
@@ -75,11 +75,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -88,10 +90,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -178,11 +182,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -191,10 +197,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/PCM16B.target.darwin-mips.mk b/modules/PCM16B.target.darwin-mips.mk
index b4a9f923..5aac0613 100644
--- a/modules/PCM16B.target.darwin-mips.mk
+++ b/modules/PCM16B.target.darwin-mips.mk
@@ -80,11 +80,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -210,6 +215,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/PCM16B.target.darwin-mips64.mk b/modules/PCM16B.target.darwin-mips64.mk
new file mode 100644
index 00000000..7a37a0c1
--- /dev/null
+++ b/modules/PCM16B.target.darwin-mips64.mk
@@ -0,0 +1,268 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_PCM16B_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.c
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/pcm16b/include \
+ $(LOCAL_PATH)/third_party/webrtc
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/pcm16b/include \
+ $(LOCAL_PATH)/third_party/webrtc
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_PCM16B_gyp
+
+# Alias gyp target name.
+.PHONY: PCM16B
+PCM16B: third_party_webrtc_modules_PCM16B_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/PCM16B.target.darwin-x86.mk b/modules/PCM16B.target.darwin-x86.mk
index 31cae404..2345cbbe 100644
--- a/modules/PCM16B.target.darwin-x86.mk
+++ b/modules/PCM16B.target.darwin-x86.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,6 +100,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -190,11 +193,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -207,6 +212,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/PCM16B.target.darwin-x86_64.mk b/modules/PCM16B.target.darwin-x86_64.mk
index fd77326f..21ab87f0 100644
--- a/modules/PCM16B.target.darwin-x86_64.mk
+++ b/modules/PCM16B.target.darwin-x86_64.mk
@@ -80,11 +80,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -97,6 +99,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -188,11 +191,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -205,6 +210,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/PCM16B.target.linux-arm.mk b/modules/PCM16B.target.linux-arm.mk
index e4b94cd7..404a4890 100644
--- a/modules/PCM16B.target.linux-arm.mk
+++ b/modules/PCM16B.target.linux-arm.mk
@@ -86,11 +86,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -106,6 +108,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -204,11 +207,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -224,6 +229,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/PCM16B.target.linux-arm64.mk b/modules/PCM16B.target.linux-arm64.mk
index dc883bce..6db1b5ea 100644
--- a/modules/PCM16B.target.linux-arm64.mk
+++ b/modules/PCM16B.target.linux-arm64.mk
@@ -75,11 +75,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -88,10 +90,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -178,11 +182,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -191,10 +197,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/PCM16B.target.linux-mips.mk b/modules/PCM16B.target.linux-mips.mk
index b4a9f923..5aac0613 100644
--- a/modules/PCM16B.target.linux-mips.mk
+++ b/modules/PCM16B.target.linux-mips.mk
@@ -80,11 +80,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -210,6 +215,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/PCM16B.target.linux-mips64.mk b/modules/PCM16B.target.linux-mips64.mk
new file mode 100644
index 00000000..7a37a0c1
--- /dev/null
+++ b/modules/PCM16B.target.linux-mips64.mk
@@ -0,0 +1,268 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_PCM16B_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.c
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/pcm16b/include \
+ $(LOCAL_PATH)/third_party/webrtc
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/pcm16b/include \
+ $(LOCAL_PATH)/third_party/webrtc
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_PCM16B_gyp
+
+# Alias gyp target name.
+.PHONY: PCM16B
+PCM16B: third_party_webrtc_modules_PCM16B_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/PCM16B.target.linux-x86.mk b/modules/PCM16B.target.linux-x86.mk
index 31cae404..2345cbbe 100644
--- a/modules/PCM16B.target.linux-x86.mk
+++ b/modules/PCM16B.target.linux-x86.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,6 +100,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -190,11 +193,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -207,6 +212,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/PCM16B.target.linux-x86_64.mk b/modules/PCM16B.target.linux-x86_64.mk
index fd77326f..21ab87f0 100644
--- a/modules/PCM16B.target.linux-x86_64.mk
+++ b/modules/PCM16B.target.linux-x86_64.mk
@@ -80,11 +80,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -97,6 +99,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -188,11 +191,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -205,6 +210,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn
index d6cdf0e8..547f15f0 100644
--- a/modules/audio_coding/BUILD.gn
+++ b/modules/audio_coding/BUILD.gn
@@ -147,7 +147,9 @@ config("g711_config") {
source_set("g711") {
sources = [
+ "codecs/g711/include/audio_encoder_pcm.h",
"codecs/g711/include/g711_interface.h",
+ "codecs/g711/audio_encoder_pcm.cc",
"codecs/g711/g711_interface.c",
"codecs/g711/g711.c",
"codecs/g711/g711.h",
@@ -606,6 +608,8 @@ config("opus_config") {
source_set("webrtc_opus") {
sources = [
+ "codecs/opus/audio_encoder_opus.cc",
+ "codecs/opus/interface/audio_encoder_opus.h",
"codecs/opus/interface/opus_interface.h",
"codecs/opus/opus_inst.h",
"codecs/opus/opus_interface.c",
diff --git a/modules/audio_coding/codecs/audio_encoder.h b/modules/audio_coding/codecs/audio_encoder.h
index 1569cafb..45c0a855 100644
--- a/modules/audio_coding/codecs/audio_encoder.h
+++ b/modules/audio_coding/codecs/audio_encoder.h
@@ -12,7 +12,6 @@
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_AUDIO_ENCODER_H_
#include <algorithm>
-#include <limits>
#include "webrtc/base/checks.h"
#include "webrtc/typedefs.h"
@@ -28,39 +27,48 @@ class AudioEncoder {
// Accepts one 10 ms block of input audio (i.e., sample_rate_hz() / 100 *
// num_channels() samples). Multi-channel audio must be sample-interleaved.
// If successful, the encoder produces zero or more bytes of output in
- // |encoded|, and returns the number of bytes. In case of error, -1 is
- // returned. It is an error for the encoder to attempt to produce more than
- // |max_encoded_bytes| bytes of output.
- ssize_t Encode(uint32_t timestamp,
- const int16_t* audio,
- size_t num_samples,
- size_t max_encoded_bytes,
- uint8_t* encoded,
- uint32_t* encoded_timestamp) {
- CHECK_EQ(num_samples,
- static_cast<size_t>(sample_rate_hz() / 100 * num_channels()));
- ssize_t num_bytes =
- Encode(timestamp, audio, max_encoded_bytes, encoded, encoded_timestamp);
- CHECK_LE(num_bytes,
- static_cast<ssize_t>(std::min(
- max_encoded_bytes,
- static_cast<size_t>(std::numeric_limits<ssize_t>::max()))));
- return num_bytes;
+ // |encoded|, and provides the number of encoded bytes in |encoded_bytes|.
+ // In case of error, false is returned, otherwise true. It is an error for the
+ // encoder to attempt to produce more than |max_encoded_bytes| bytes of
+ // output.
+ bool Encode(uint32_t timestamp,
+ const int16_t* audio,
+ size_t num_samples_per_channel,
+ size_t max_encoded_bytes,
+ uint8_t* encoded,
+ size_t* encoded_bytes,
+ uint32_t* encoded_timestamp) {
+ CHECK_EQ(num_samples_per_channel,
+ static_cast<size_t>(sample_rate_hz() / 100));
+ bool ret = Encode(timestamp,
+ audio,
+ max_encoded_bytes,
+ encoded,
+ encoded_bytes,
+ encoded_timestamp);
+ CHECK_LE(*encoded_bytes, max_encoded_bytes);
+ return ret;
}
- // Returns the input sample rate in Hz, the number of input channels, and the
- // number of 10 ms frames the encoder puts in one output packet. These are
- // constants set at instantiation time.
+ // Return the input sample rate in Hz and the number of input channels.
+ // These are constants set at instantiation time.
virtual int sample_rate_hz() const = 0;
virtual int num_channels() const = 0;
- virtual int num_10ms_frames_per_packet() const = 0;
+
+ // 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 int Num10MsFramesInNextPacket() const = 0;
protected:
- virtual ssize_t Encode(uint32_t timestamp,
- const int16_t* audio,
- size_t max_encoded_bytes,
- uint8_t* encoded,
- uint32_t* encoded_timestamp) = 0;
+ virtual bool Encode(uint32_t timestamp,
+ const int16_t* audio,
+ size_t max_encoded_bytes,
+ uint8_t* encoded,
+ size_t* encoded_bytes,
+ uint32_t* encoded_timestamp) = 0;
};
} // namespace webrtc
diff --git a/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc b/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
new file mode 100644
index 00000000..6454e93c
--- /dev/null
+++ b/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc
@@ -0,0 +1,98 @@
+/*
+ * 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 "webrtc/modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h"
+
+#include <limits>
+
+#include "webrtc/modules/audio_coding/codecs/g711/include/g711_interface.h"
+
+namespace webrtc {
+
+namespace {
+int16_t NumSamplesPerFrame(int num_channels,
+ int frame_size_ms,
+ int sample_rate_hz) {
+ int samples_per_frame = num_channels * frame_size_ms * sample_rate_hz / 1000;
+ CHECK_LE(samples_per_frame, std::numeric_limits<int16_t>::max())
+ << "Frame size too large.";
+ return static_cast<int16_t>(samples_per_frame);
+}
+} // namespace
+
+AudioEncoderPcm::AudioEncoderPcm(const Config& config)
+ : num_channels_(config.num_channels),
+ num_10ms_frames_per_packet_(config.frame_size_ms / 10),
+ full_frame_samples_(NumSamplesPerFrame(num_channels_,
+ config.frame_size_ms,
+ kSampleRateHz)),
+ first_timestamp_in_buffer_(0) {
+ CHECK_EQ(config.frame_size_ms % 10, 0)
+ << "Frame size must be an integer multiple of 10 ms.";
+ speech_buffer_.reserve(full_frame_samples_);
+}
+
+AudioEncoderPcm::~AudioEncoderPcm() {
+}
+
+int AudioEncoderPcm::sample_rate_hz() const {
+ return kSampleRateHz;
+}
+int AudioEncoderPcm::num_channels() const {
+ return num_channels_;
+}
+int AudioEncoderPcm::Num10MsFramesInNextPacket() const {
+ return num_10ms_frames_per_packet_;
+}
+
+bool AudioEncoderPcm::Encode(uint32_t timestamp,
+ const int16_t* audio,
+ size_t max_encoded_bytes,
+ uint8_t* encoded,
+ size_t* encoded_bytes,
+ uint32_t* encoded_timestamp) {
+ const int num_samples = sample_rate_hz() / 100 * num_channels();
+ if (speech_buffer_.empty()) {
+ first_timestamp_in_buffer_ = timestamp;
+ }
+ for (int i = 0; i < num_samples; ++i) {
+ speech_buffer_.push_back(audio[i]);
+ }
+ if (speech_buffer_.size() < static_cast<size_t>(full_frame_samples_)) {
+ *encoded_bytes = 0;
+ return true;
+ }
+ CHECK_EQ(speech_buffer_.size(), static_cast<size_t>(full_frame_samples_));
+ int16_t ret = EncodeCall(&speech_buffer_[0], full_frame_samples_, encoded);
+ speech_buffer_.clear();
+ *encoded_timestamp = first_timestamp_in_buffer_;
+ if (ret < 0)
+ return false;
+ *encoded_bytes = static_cast<size_t>(ret);
+ return true;
+}
+
+int16_t AudioEncoderPcmA::EncodeCall(const int16_t* audio,
+ size_t input_len,
+ uint8_t* encoded) {
+ return WebRtcG711_EncodeA(const_cast<int16_t*>(audio),
+ static_cast<int16_t>(input_len),
+ reinterpret_cast<int16_t*>(encoded));
+}
+
+int16_t AudioEncoderPcmU::EncodeCall(const int16_t* audio,
+ size_t input_len,
+ uint8_t* encoded) {
+ return WebRtcG711_EncodeU(const_cast<int16_t*>(audio),
+ static_cast<int16_t>(input_len),
+ reinterpret_cast<int16_t*>(encoded));
+}
+
+} // namespace webrtc
diff --git a/modules/audio_coding/codecs/g711/g711.gypi b/modules/audio_coding/codecs/g711/g711.gypi
index c39b4af1..2b637cf9 100644
--- a/modules/audio_coding/codecs/g711/g711.gypi
+++ b/modules/audio_coding/codecs/g711/g711.gypi
@@ -23,9 +23,11 @@
},
'sources': [
'include/g711_interface.h',
+ 'include/audio_encoder_pcm.h',
'g711_interface.c',
'g711.c',
'g711.h',
+ 'audio_encoder_pcm.cc',
],
},
], # targets
diff --git a/modules/audio_coding/codecs/g711/g711_interface.c b/modules/audio_coding/codecs/g711/g711_interface.c
index 134c1e4e..ec726c51 100644
--- a/modules/audio_coding/codecs/g711/g711_interface.c
+++ b/modules/audio_coding/codecs/g711/g711_interface.c
@@ -12,16 +12,12 @@
#include "g711_interface.h"
#include "webrtc/typedefs.h"
-int16_t WebRtcG711_EncodeA(void* state,
- int16_t* speechIn,
+int16_t WebRtcG711_EncodeA(int16_t* speechIn,
int16_t len,
int16_t* encoded) {
int n;
uint16_t tempVal, tempVal2;
- // Set and discard to avoid getting warnings
- (void)(state = NULL);
-
// Sanity check of input length
if (len < 0) {
return (-1);
@@ -50,16 +46,12 @@ int16_t WebRtcG711_EncodeA(void* state,
return (len);
}
-int16_t WebRtcG711_EncodeU(void* state,
- int16_t* speechIn,
+int16_t WebRtcG711_EncodeU(int16_t* speechIn,
int16_t len,
int16_t* encoded) {
int n;
uint16_t tempVal;
- // Set and discard to avoid getting warnings
- (void)(state = NULL);
-
// Sanity check of input length
if (len < 0) {
return (-1);
@@ -86,17 +78,13 @@ int16_t WebRtcG711_EncodeU(void* state,
return (len);
}
-int16_t WebRtcG711_DecodeA(void* state,
- int16_t* encoded,
+int16_t WebRtcG711_DecodeA(int16_t* encoded,
int16_t len,
int16_t* decoded,
int16_t* speechType) {
int n;
uint16_t tempVal;
- // Set and discard to avoid getting warnings
- (void)(state = NULL);
-
// Sanity check of input length
if (len < 0) {
return (-1);
@@ -123,17 +111,13 @@ int16_t WebRtcG711_DecodeA(void* state,
return (len);
}
-int16_t WebRtcG711_DecodeU(void* state,
- int16_t* encoded,
+int16_t WebRtcG711_DecodeU(int16_t* encoded,
int16_t len,
int16_t* decoded,
int16_t* speechType) {
int n;
uint16_t tempVal;
- // Set and discard to avoid getting warnings
- (void)(state = NULL);
-
// Sanity check of input length
if (len < 0) {
return (-1);
@@ -160,10 +144,8 @@ int16_t WebRtcG711_DecodeU(void* state,
return (len);
}
-int WebRtcG711_DurationEst(void* state,
- const uint8_t* payload,
+int WebRtcG711_DurationEst(const uint8_t* payload,
int payload_length_bytes) {
- (void) state;
(void) payload;
/* G.711 is one byte per sample, so we can just return the number of bytes. */
return payload_length_bytes;
diff --git a/modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h b/modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h
new file mode 100644
index 00000000..f6682969
--- /dev/null
+++ b/modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h
@@ -0,0 +1,79 @@
+/*
+ * 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 WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_INCLUDE_AUDIO_ENCODER_PCM_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_INCLUDE_AUDIO_ENCODER_PCM_H_
+
+#include <vector>
+
+#include "webrtc/modules/audio_coding/codecs/audio_encoder.h"
+
+namespace webrtc {
+
+class AudioEncoderPcm : public AudioEncoder {
+ public:
+ struct Config {
+ Config() : frame_size_ms(20), num_channels(1) {}
+
+ int frame_size_ms;
+ int num_channels;
+ };
+
+ explicit AudioEncoderPcm(const Config& config);
+
+ virtual ~AudioEncoderPcm();
+
+ virtual int sample_rate_hz() const OVERRIDE;
+ virtual int num_channels() const OVERRIDE;
+ virtual int Num10MsFramesInNextPacket() const OVERRIDE;
+
+ protected:
+ virtual bool Encode(uint32_t timestamp,
+ const int16_t* audio,
+ size_t max_encoded_bytes,
+ uint8_t* encoded,
+ size_t* encoded_bytes,
+ uint32_t* encoded_timestamp) OVERRIDE;
+
+ virtual int16_t EncodeCall(const int16_t* audio,
+ size_t input_len,
+ uint8_t* encoded) = 0;
+
+ private:
+ static const int kSampleRateHz = 8000;
+ const int num_channels_;
+ const int num_10ms_frames_per_packet_;
+ const int16_t full_frame_samples_;
+ std::vector<int16_t> speech_buffer_;
+ uint32_t first_timestamp_in_buffer_;
+};
+
+class AudioEncoderPcmA : public AudioEncoderPcm {
+ public:
+ explicit AudioEncoderPcmA(const Config& config) : AudioEncoderPcm(config) {}
+
+ protected:
+ virtual int16_t EncodeCall(const int16_t* audio,
+ size_t input_len,
+ uint8_t* encoded) OVERRIDE;
+};
+
+class AudioEncoderPcmU : public AudioEncoderPcm {
+ public:
+ explicit AudioEncoderPcmU(const Config& config) : AudioEncoderPcm(config) {}
+
+ protected:
+ virtual int16_t EncodeCall(const int16_t* audio,
+ size_t input_len,
+ uint8_t* encoded) OVERRIDE;
+};
+
+} // namespace webrtc
+#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_INCLUDE_AUDIO_ENCODER_PCM_H_
diff --git a/modules/audio_coding/codecs/g711/include/g711_interface.h b/modules/audio_coding/codecs/g711/include/g711_interface.h
index 83357e47..545ca3e8 100644
--- a/modules/audio_coding/codecs/g711/include/g711_interface.h
+++ b/modules/audio_coding/codecs/g711/include/g711_interface.h
@@ -28,8 +28,6 @@ extern "C" {
* Input speech length has be of any length.
*
* Input:
- * - state : Dummy state to make this codec look more like
- * other codecs
* - speechIn : Input speech vector
* - len : Samples in speechIn
*
@@ -40,8 +38,7 @@ extern "C" {
* -1 - Error
*/
-int16_t WebRtcG711_EncodeA(void* state,
- int16_t* speechIn,
+int16_t WebRtcG711_EncodeA(int16_t* speechIn,
int16_t len,
int16_t* encoded);
@@ -52,8 +49,6 @@ int16_t WebRtcG711_EncodeA(void* state,
* Input speech length has be of any length.
*
* Input:
- * - state : Dummy state to make this codec look more like
- * other codecs
* - speechIn : Input speech vector
* - len : Samples in speechIn
*
@@ -64,8 +59,7 @@ int16_t WebRtcG711_EncodeA(void* state,
* -1 - Error
*/
-int16_t WebRtcG711_EncodeU(void* state,
- int16_t* speechIn,
+int16_t WebRtcG711_EncodeU(int16_t* speechIn,
int16_t len,
int16_t* encoded);
@@ -75,8 +69,6 @@ int16_t WebRtcG711_EncodeU(void* state,
* This function decodes a packet G711 A-law frame.
*
* Input:
- * - state : Dummy state to make this codec look more like
- * other codecs
* - encoded : Encoded data
* - len : Bytes in encoded vector
*
@@ -90,8 +82,7 @@ int16_t WebRtcG711_EncodeU(void* state,
* -1 - Error
*/
-int16_t WebRtcG711_DecodeA(void* state,
- int16_t* encoded,
+int16_t WebRtcG711_DecodeA(int16_t* encoded,
int16_t len,
int16_t* decoded,
int16_t* speechType);
@@ -102,8 +93,6 @@ int16_t WebRtcG711_DecodeA(void* state,
* This function decodes a packet G711 U-law frame.
*
* Input:
- * - state : Dummy state to make this codec look more like
- * other codecs
* - encoded : Encoded data
* - len : Bytes in encoded vector
*
@@ -117,8 +106,7 @@ int16_t WebRtcG711_DecodeA(void* state,
* -1 - Error
*/
-int16_t WebRtcG711_DecodeU(void* state,
- int16_t* encoded,
+int16_t WebRtcG711_DecodeU(int16_t* encoded,
int16_t len,
int16_t* decoded,
int16_t* speechType);
@@ -129,8 +117,6 @@ int16_t WebRtcG711_DecodeU(void* state,
* This function estimates the duration of a G711 packet in samples.
*
* Input:
- * - state : Dummy state to make this codec look more like
- * other codecs
* - payload : Encoded data
* - payloadLengthBytes : Bytes in encoded vector
*
@@ -139,8 +125,7 @@ int16_t WebRtcG711_DecodeU(void* state,
* byte per sample.
*/
-int WebRtcG711_DurationEst(void* state,
- const uint8_t* payload,
+int WebRtcG711_DurationEst(const uint8_t* payload,
int payload_length_bytes);
/**********************************************************************
diff --git a/modules/audio_coding/codecs/g711/test/testG711.cc b/modules/audio_coding/codecs/g711/test/testG711.cc
index 95a02469..76950fa3 100644
--- a/modules/audio_coding/codecs/g711/test/testG711.cc
+++ b/modules/audio_coding/codecs/g711/test/testG711.cc
@@ -127,7 +127,7 @@ int main(int argc, char* argv[]) {
/* G.711 encoding */
if (!strcmp(law, "A")) {
/* A-law encoding */
- stream_len = WebRtcG711_EncodeA(NULL, shortdata, framelength, streamdata);
+ stream_len = WebRtcG711_EncodeA(shortdata, framelength, streamdata);
if (argc == 6) {
/* Write bits to file */
if (fwrite(streamdata, sizeof(unsigned char), stream_len, bitp) !=
@@ -135,11 +135,11 @@ int main(int argc, char* argv[]) {
return -1;
}
}
- err = WebRtcG711_DecodeA(NULL, streamdata, stream_len, decoded,
+ err = WebRtcG711_DecodeA(streamdata, stream_len, decoded,
speechType);
} else if (!strcmp(law, "u")) {
/* u-law encoding */
- stream_len = WebRtcG711_EncodeU(NULL, shortdata, framelength, streamdata);
+ stream_len = WebRtcG711_EncodeU(shortdata, framelength, streamdata);
if (argc == 6) {
/* Write bits to file */
if (fwrite(streamdata, sizeof(unsigned char), stream_len, bitp) !=
@@ -147,8 +147,7 @@ int main(int argc, char* argv[]) {
return -1;
}
}
- err = WebRtcG711_DecodeU(NULL, streamdata, stream_len, decoded,
- speechType);
+ err = WebRtcG711_DecodeU(streamdata, stream_len, decoded, speechType);
} else {
printf("Wrong law mode\n");
exit(1);
diff --git a/modules/audio_coding/codecs/ilbc/cb_construct.c b/modules/audio_coding/codecs/ilbc/cb_construct.c
index 808451f3..04a59e1d 100644
--- a/modules/audio_coding/codecs/ilbc/cb_construct.c
+++ b/modules/audio_coding/codecs/ilbc/cb_construct.c
@@ -60,7 +60,7 @@ void WebRtcIlbcfix_CbConstruct(
a32 += WEBRTC_SPL_MUL_16_16(*gainPtr++, cbvec1[j]);
a32 += WEBRTC_SPL_MUL_16_16(*gainPtr, cbvec2[j]);
gainPtr -= 2;
- decvector[j] = (int16_t) WEBRTC_SPL_RSHIFT_W32(a32 + 8192, 14);
+ decvector[j] = (int16_t)((a32 + 8192) >> 14);
}
return;
diff --git a/modules/audio_coding/codecs/ilbc/cb_mem_energy.c b/modules/audio_coding/codecs/ilbc/cb_mem_energy.c
index f883287d..50ad0ad3 100644
--- a/modules/audio_coding/codecs/ilbc/cb_mem_energy.c
+++ b/modules/audio_coding/codecs/ilbc/cb_mem_energy.c
@@ -54,7 +54,7 @@ void WebRtcIlbcfix_CbMemEnergy(
/* Normalize the energy and store the number of shifts */
energyShifts[0] = (int16_t)WebRtcSpl_NormW32(energy);
tmp32 = WEBRTC_SPL_LSHIFT_W32(energy, energyShifts[0]);
- energyW16[0] = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp32, 16);
+ energyW16[0] = (int16_t)(tmp32 >> 16);
/* Compute the energy of the rest of the cb memory
* by step wise adding and subtracting the next
@@ -70,7 +70,7 @@ void WebRtcIlbcfix_CbMemEnergy(
/* Normalize the energy and store the number of shifts */
energyShifts[base_size] = (int16_t)WebRtcSpl_NormW32(energy);
tmp32 = WEBRTC_SPL_LSHIFT_W32(energy, energyShifts[base_size]);
- energyW16[base_size] = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp32, 16);
+ energyW16[base_size] = (int16_t)(tmp32 >> 16);
ppi = filteredCB + lMem - 1 - lTarget;
ppo = filteredCB + lMem - 1;
diff --git a/modules/audio_coding/codecs/ilbc/cb_mem_energy_augmentation.c b/modules/audio_coding/codecs/ilbc/cb_mem_energy_augmentation.c
index 29f499f2..e5fb81c5 100644
--- a/modules/audio_coding/codecs/ilbc/cb_mem_energy_augmentation.c
+++ b/modules/audio_coding/codecs/ilbc/cb_mem_energy_augmentation.c
@@ -60,7 +60,7 @@ void WebRtcIlbcfix_CbMemEnergyAugmentation(
/* Normalize the energy and store the number of shifts */
(*enShPtr) = (int16_t)WebRtcSpl_NormW32(energy);
tmp32 = WEBRTC_SPL_LSHIFT_W32(energy, (*enShPtr));
- (*enPtr) = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp32, 16);
+ *enPtr = (int16_t)(tmp32 >> 16);
enShPtr++;
enPtr++;
}
diff --git a/modules/audio_coding/codecs/ilbc/cb_mem_energy_calc.c b/modules/audio_coding/codecs/ilbc/cb_mem_energy_calc.c
index a2bc9b88..4c7332a2 100644
--- a/modules/audio_coding/codecs/ilbc/cb_mem_energy_calc.c
+++ b/modules/audio_coding/codecs/ilbc/cb_mem_energy_calc.c
@@ -47,7 +47,7 @@ void WebRtcIlbcfix_CbMemEnergyCalc(
operation on the edge samples */
tmp = WEBRTC_SPL_MUL_16_16(*ppi, *ppi);
tmp -= WEBRTC_SPL_MUL_16_16(*ppo, *ppo);
- energy += WEBRTC_SPL_RSHIFT_W32(tmp, scale);
+ energy += tmp >> scale;
energy = WEBRTC_SPL_MAX(energy, 0);
ppi--;
@@ -60,6 +60,6 @@ void WebRtcIlbcfix_CbMemEnergyCalc(
*eSh_ptr++ = shft;
tmp = WEBRTC_SPL_LSHIFT_W32(energy, shft);
- *eW16_ptr++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp, 16);
+ *eW16_ptr++ = (int16_t)(tmp >> 16);
}
}
diff --git a/modules/audio_coding/codecs/ilbc/cb_search_core.c b/modules/audio_coding/codecs/ilbc/cb_search_core.c
index c2299d53..a5114224 100644
--- a/modules/audio_coding/codecs/ilbc/cb_search_core.c
+++ b/modules/audio_coding/codecs/ilbc/cb_search_core.c
@@ -66,7 +66,7 @@ void WebRtcIlbcfix_CbSearchCore(
for (i=0;i<range;i++) {
/* Calculate cDot*cDot and put the result in a int16_t */
tmp32 = WEBRTC_SPL_LSHIFT_W32(*cDotPtr,sh);
- tmp16 = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp32,16);
+ tmp16 = (int16_t)(tmp32 >> 16);
cDotSqW16 = (int16_t)(((int32_t)(tmp16)*(tmp16))>>16);
/* Calculate the criteria (cDot*cDot/energy) */
diff --git a/modules/audio_coding/codecs/ilbc/cb_update_best_index.c b/modules/audio_coding/codecs/ilbc/cb_update_best_index.c
index 88ea1997..9e32437f 100644
--- a/modules/audio_coding/codecs/ilbc/cb_update_best_index.c
+++ b/modules/audio_coding/codecs/ilbc/cb_update_best_index.c
@@ -51,8 +51,7 @@ void WebRtcIlbcfix_CbUpdateBestIndex(
calculate the gain and store this index as the new best one
*/
- if (WEBRTC_SPL_RSHIFT_W32(CritNew, shNew)>
- WEBRTC_SPL_RSHIFT_W32((*CritMax),shOld)) {
+ if ((CritNew >> shNew) > (*CritMax >> shOld)) {
tmp16 = (int16_t)WebRtcSpl_NormW32(cDotNew);
tmp16 = 16 - tmp16;
diff --git a/modules/audio_coding/codecs/ilbc/chebyshev.c b/modules/audio_coding/codecs/ilbc/chebyshev.c
index b49dd799..6174c9dd 100644
--- a/modules/audio_coding/codecs/ilbc/chebyshev.c
+++ b/modules/audio_coding/codecs/ilbc/chebyshev.c
@@ -46,8 +46,8 @@ int16_t WebRtcIlbcfix_Chebyshev(
tmp2W32 = tmp1W32;
/* Split b1 (in tmp1W32) into a high and low part */
- b1_high = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp1W32, 16);
- b1_low = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp1W32-WEBRTC_SPL_LSHIFT_W32(((int32_t)b1_high),16), 1);
+ b1_high = (int16_t)(tmp1W32 >> 16);
+ b1_low = (int16_t)((tmp1W32 - ((int32_t)b1_high << 16)) >> 1);
/* Calculate 2*x*b1-b2+f[i] */
tmp1W32 = WEBRTC_SPL_LSHIFT_W32( (WEBRTC_SPL_MUL_16_16(b1_high, x) +
@@ -61,8 +61,8 @@ int16_t WebRtcIlbcfix_Chebyshev(
}
/* Split b1 (in tmp1W32) into a high and low part */
- b1_high = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp1W32, 16);
- b1_low = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp1W32-WEBRTC_SPL_LSHIFT_W32(((int32_t)b1_high),16), 1);
+ b1_high = (int16_t)(tmp1W32 >> 16);
+ b1_low = (int16_t)((tmp1W32 - ((int32_t)b1_high << 16)) >> 1);
/* tmp1W32 = x*b1 - b2 + f[i]/2 */
tmp1W32 = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(b1_high, x), 1) +
@@ -77,6 +77,6 @@ int16_t WebRtcIlbcfix_Chebyshev(
} else if (tmp1W32<((int32_t)-33554432)) {
return(WEBRTC_SPL_WORD16_MIN);
} else {
- return((int16_t)WEBRTC_SPL_RSHIFT_W32(tmp1W32, 10));
+ return (int16_t)(tmp1W32 >> 10);
}
}
diff --git a/modules/audio_coding/codecs/ilbc/do_plc.c b/modules/audio_coding/codecs/ilbc/do_plc.c
index c0f53684..4d233e39 100644
--- a/modules/audio_coding/codecs/ilbc/do_plc.c
+++ b/modules/audio_coding/codecs/ilbc/do_plc.c
@@ -262,11 +262,11 @@ void WebRtcIlbcfix_DoThePlc(
/* mix noise and pitch repeatition */
- PLCresidual[i] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(tot_gain,
- (int16_t)WEBRTC_SPL_RSHIFT_W32( (WEBRTC_SPL_MUL_16_16(pitchfact, PLCresidual[i]) +
- WEBRTC_SPL_MUL_16_16((32767-pitchfact), randvec[i]) + 16384),
- 15),
- 15);
+ PLCresidual[i] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(
+ tot_gain,
+ (pitchfact * PLCresidual[i] + (32767 - pitchfact) * randvec[i] +
+ 16384) >> 15,
+ 15);
/* Shifting down the result one step extra to ensure that no overflow
will occur */
diff --git a/modules/audio_coding/codecs/ilbc/get_lsp_poly.c b/modules/audio_coding/codecs/ilbc/get_lsp_poly.c
index d44380f2..2b0fe2bb 100644
--- a/modules/audio_coding/codecs/ilbc/get_lsp_poly.c
+++ b/modules/audio_coding/codecs/ilbc/get_lsp_poly.c
@@ -64,8 +64,8 @@ void WebRtcIlbcfix_GetLspPoly(
for(j=i; j>1; j--)
{
/* Compute f[j] = f[j] + tmp*f[j-1] + f[j-2]; */
- high = (int16_t)WEBRTC_SPL_RSHIFT_W32(fPtr[-1], 16);
- low = (int16_t)WEBRTC_SPL_RSHIFT_W32(fPtr[-1]-WEBRTC_SPL_LSHIFT_W32(((int32_t)high),16), 1);
+ high = (int16_t)(fPtr[-1] >> 16);
+ low = (int16_t)((fPtr[-1] - ((int32_t)high << 16)) >> 1);
tmpW32 = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(high, (*lspPtr)), 2) +
WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16_RSFT(low, (*lspPtr), 15), 2);
diff --git a/modules/audio_coding/codecs/ilbc/hp_input.c b/modules/audio_coding/codecs/ilbc/hp_input.c
index 48bd7c4e..40c35eb3 100644
--- a/modules/audio_coding/codecs/ilbc/hp_input.c
+++ b/modules/audio_coding/codecs/ilbc/hp_input.c
@@ -65,7 +65,7 @@ void WebRtcIlbcfix_HpInput(
tmpW32b = WEBRTC_SPL_SAT((int32_t)268435455, tmpW32b, (int32_t)-268435456);
/* Convert back to Q0 and multiply with 0.5 */
- signal[i] = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmpW32b, 13);
+ signal[i] = (int16_t)(tmpW32b >> 13);
/* Update state (filtered part) */
y[2] = y[0];
diff --git a/modules/audio_coding/codecs/ilbc/hp_output.c b/modules/audio_coding/codecs/ilbc/hp_output.c
index 432fdee2..e1de8292 100644
--- a/modules/audio_coding/codecs/ilbc/hp_output.c
+++ b/modules/audio_coding/codecs/ilbc/hp_output.c
@@ -65,7 +65,7 @@ void WebRtcIlbcfix_HpOutput(
tmpW32b = WEBRTC_SPL_SAT((int32_t)67108863, tmpW32b, (int32_t)-67108864);
/* Convert back to Q0 and multiply with 2 */
- signal[i] = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmpW32b, 11);
+ signal[i] = (int16_t)(tmpW32b >> 11);
/* Update state (filtered part) */
y[2] = y[0];
diff --git a/modules/audio_coding/codecs/ilbc/interpolate.c b/modules/audio_coding/codecs/ilbc/interpolate.c
index b6ea201f..d0869a5d 100644
--- a/modules/audio_coding/codecs/ilbc/interpolate.c
+++ b/modules/audio_coding/codecs/ilbc/interpolate.c
@@ -39,9 +39,7 @@ void WebRtcIlbcfix_Interpolate(
invcoef = 16384 - coef; /* 16384 = 1.0 (Q14)*/
for (i = 0; i < length; i++) {
- out[i] = (int16_t) WEBRTC_SPL_RSHIFT_W32(
- (WEBRTC_SPL_MUL_16_16(coef, in1[i]) + WEBRTC_SPL_MUL_16_16(invcoef, in2[i]))+8192,
- 14);
+ out[i] = (int16_t)((coef * in1[i] + invcoef * in2[i] + 8192) >> 14);
}
return;
diff --git a/modules/audio_coding/codecs/ilbc/lsf_to_lsp.c b/modules/audio_coding/codecs/ilbc/lsf_to_lsp.c
index 579fdcf7..078a0fc0 100644
--- a/modules/audio_coding/codecs/ilbc/lsf_to_lsp.c
+++ b/modules/audio_coding/codecs/ilbc/lsf_to_lsp.c
@@ -54,7 +54,7 @@ void WebRtcIlbcfix_Lsf2Lsp(
/* Calculate linear approximation */
tmpW32 = WEBRTC_SPL_MUL_16_16(WebRtcIlbcfix_kCosDerivative[k], diff);
- lsp[i] = WebRtcIlbcfix_kCos[k]+(int16_t)(WEBRTC_SPL_RSHIFT_W32(tmpW32, 12));
+ lsp[i] = WebRtcIlbcfix_kCos[k] + (int16_t)(tmpW32 >> 12);
}
return;
diff --git a/modules/audio_coding/codecs/ilbc/lsf_to_poly.c b/modules/audio_coding/codecs/ilbc/lsf_to_poly.c
index acc5ac83..c3a34cab 100644
--- a/modules/audio_coding/codecs/ilbc/lsf_to_poly.c
+++ b/modules/audio_coding/codecs/ilbc/lsf_to_poly.c
@@ -71,10 +71,10 @@ void WebRtcIlbcfix_Lsf2Poly(
for (i=5; i>0; i--)
{
tmpW32 = (*f1ptr) + (*f2ptr);
- (*a1ptr) = (int16_t)WEBRTC_SPL_RSHIFT_W32((tmpW32+4096),13);
+ *a1ptr = (int16_t)((tmpW32 + 4096) >> 13);
tmpW32 = (*f1ptr) - (*f2ptr);
- (*a2ptr) = (int16_t)WEBRTC_SPL_RSHIFT_W32((tmpW32+4096),13);
+ *a2ptr = (int16_t)((tmpW32 + 4096) >> 13);
a1ptr++;
a2ptr--;
diff --git a/modules/audio_coding/codecs/ilbc/poly_to_lsp.c b/modules/audio_coding/codecs/ilbc/poly_to_lsp.c
index e194e8fd..74bb1b7d 100644
--- a/modules/audio_coding/codecs/ilbc/poly_to_lsp.c
+++ b/modules/audio_coding/codecs/ilbc/poly_to_lsp.c
@@ -56,8 +56,10 @@ void WebRtcIlbcfix_Poly2Lsp(
(*f1ptr) = 1024; /* 1.0 in Q10 */
(*f2ptr) = 1024; /* 1.0 in Q10 */
for (i = 0; i < 5; i++) {
- (*(f1ptr+1)) = (int16_t)(WEBRTC_SPL_RSHIFT_W32(((int32_t)(*a_i_ptr)+(*a_10mi_ptr)), 2) - (*f1ptr));
- (*(f2ptr+1)) = (int16_t)(WEBRTC_SPL_RSHIFT_W32(((int32_t)(*a_i_ptr)-(*a_10mi_ptr)), 2) + (*f2ptr));
+ *(f1ptr + 1) =
+ (int16_t)((((int32_t)(*a_i_ptr) + *a_10mi_ptr) >> 2) - *f1ptr);
+ *(f2ptr + 1) =
+ (int16_t)((((int32_t)(*a_i_ptr) - *a_10mi_ptr) >> 2) + *f2ptr);
a_i_ptr++;
a_10mi_ptr--;
f1ptr++;
diff --git a/modules/audio_coding/codecs/ilbc/refiner.c b/modules/audio_coding/codecs/ilbc/refiner.c
index fed33948..e96ae269 100644
--- a/modules/audio_coding/codecs/ilbc/refiner.c
+++ b/modules/audio_coding/codecs/ilbc/refiner.c
@@ -81,7 +81,7 @@ void WebRtcIlbcfix_Refiner(
if (scalefact>0) {
for (i=0;i<corrdim;i++) {
- corrVec[i]=(int16_t)WEBRTC_SPL_RSHIFT_W32(corrVecTemp[i], scalefact);
+ corrVec[i] = (int16_t)(corrVecTemp[i] >> scalefact);
}
} else {
for (i=0;i<corrdim;i++) {
diff --git a/modules/audio_coding/codecs/ilbc/smooth.c b/modules/audio_coding/codecs/ilbc/smooth.c
index c975098d..3d59c521 100644
--- a/modules/audio_coding/codecs/ilbc/smooth.c
+++ b/modules/audio_coding/codecs/ilbc/smooth.c
@@ -101,7 +101,7 @@ void WebRtcIlbcfix_Smooth(
} else {
/* crit = 0.05 * w00 (Result in Q-6) */
crit = WEBRTC_SPL_SHIFT_W32(
- WEBRTC_SPL_MUL(ENH_A0, WEBRTC_SPL_RSHIFT_W32(w00prim, 14)),
+ WEBRTC_SPL_MUL(ENH_A0, w00prim >> 14),
-(6-scale+scale1));
}
@@ -139,7 +139,7 @@ void WebRtcIlbcfix_Smooth(
endiff = (w11w00-w10w10);
endiff = WEBRTC_SPL_MAX(0, endiff);
/* denom is in Q16 */
- denom = WebRtcSpl_DivW32W16(endiff, (int16_t)WEBRTC_SPL_RSHIFT_W32(w00w00, 16));
+ denom = WebRtcSpl_DivW32W16(endiff, (int16_t)(w00w00 >> 16));
} else {
denom = 65536;
}
@@ -151,10 +151,10 @@ void WebRtcIlbcfix_Smooth(
if (scale>0) {
/* denomW16 is in Q(16+scale) */
- denomW16=(int16_t)WEBRTC_SPL_RSHIFT_W32(denom, scale);
+ denomW16 = (int16_t)(denom >> scale);
/* num in Q(34-scale) */
- num=WEBRTC_SPL_RSHIFT_W32(ENH_A0_MINUS_A0A0DIV4, scale);
+ num = ENH_A0_MINUS_A0A0DIV4 >> scale;
} else {
/* denomW16 is in Q16 */
denomW16=(int16_t)denom;
@@ -174,8 +174,8 @@ void WebRtcIlbcfix_Smooth(
scale = bitsw00-scale2-15;
if (scale>0) {
- w10prim=WEBRTC_SPL_RSHIFT_W32(w10prim, scale);
- w00prim=WEBRTC_SPL_RSHIFT_W32(w00prim, scale);
+ w10prim >>= scale;
+ w00prim >>= scale;
}
if ((w00prim>0)&&(w10prim>0)) {
@@ -187,7 +187,7 @@ void WebRtcIlbcfix_Smooth(
B_W32 = (int32_t)1073741824 - (int32_t)ENH_A0DIV2 -
WEBRTC_SPL_MUL(A, w11_div_w00);
}
- B = (int16_t)WEBRTC_SPL_RSHIFT_W32(B_W32, 16); /* B in Q14 */
+ B = (int16_t)(B_W32 >> 16); /* B in Q14. */
} else {
/* No smoothing */
A = 0;
diff --git a/modules/audio_coding/codecs/ilbc/smooth_out_data.c b/modules/audio_coding/codecs/ilbc/smooth_out_data.c
index cf3b30ae..622af7bb 100644
--- a/modules/audio_coding/codecs/ilbc/smooth_out_data.c
+++ b/modules/audio_coding/codecs/ilbc/smooth_out_data.c
@@ -31,8 +31,7 @@ int32_t WebRtcIlbcfix_Smooth_odata(
int32_t errs;
for(i=0;i<80;i++) {
- odata[i]= (int16_t)WEBRTC_SPL_RSHIFT_W32(
- (WEBRTC_SPL_MUL_16_16(C, surround[i])+1024), 11);
+ odata[i]= (int16_t)((C * surround[i] + 1024) >> 11);
}
errs=0;
diff --git a/modules/audio_coding/codecs/ilbc/sort_sq.c b/modules/audio_coding/codecs/ilbc/sort_sq.c
index dcfd8bdf..c51bf6dc 100644
--- a/modules/audio_coding/codecs/ilbc/sort_sq.c
+++ b/modules/audio_coding/codecs/ilbc/sort_sq.c
@@ -40,7 +40,7 @@ void WebRtcIlbcfix_SortSq(
i++;
}
- if (x > WEBRTC_SPL_RSHIFT_W32(( (int32_t)cb[i] + cb[i - 1] + 1),1)) {
+ if (x > (((int32_t)cb[i] + cb[i - 1] + 1) >> 1)) {
*index = i;
*xq = cb[i];
} else {
diff --git a/modules/audio_coding/codecs/ilbc/window32_w32.c b/modules/audio_coding/codecs/ilbc/window32_w32.c
index 9ff1be39..ef5357e4 100644
--- a/modules/audio_coding/codecs/ilbc/window32_w32.c
+++ b/modules/audio_coding/codecs/ilbc/window32_w32.c
@@ -42,15 +42,15 @@ void WebRtcIlbcfix_Window32W32(
*/
for (i = 0; i < N; i++) {
/* Extract higher bytes */
- x_hi = (int16_t) WEBRTC_SPL_RSHIFT_W32(x[i], 16);
- y_hi = (int16_t) WEBRTC_SPL_RSHIFT_W32(y[i], 16);
+ x_hi = (int16_t)(x[i] >> 16);
+ y_hi = (int16_t)(y[i] >> 16);
/* Extract lower bytes, defined as (w32 - hi<<16)>>1 */
temp = WEBRTC_SPL_LSHIFT_W32((int32_t)x_hi, 16);
- x_low = (int16_t) WEBRTC_SPL_RSHIFT_W32((x[i] - temp), 1);
+ x_low = (int16_t)((x[i] - temp) >> 1);
temp = WEBRTC_SPL_LSHIFT_W32((int32_t)y_hi, 16);
- y_low = (int16_t) WEBRTC_SPL_RSHIFT_W32((y[i] - temp), 1);
+ y_low = (int16_t)((y[i] - temp) >> 1);
/* Calculate z by a 32 bit multiplication using both low and high from x and y */
temp = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(x_hi, y_hi), 1);
diff --git a/modules/audio_coding/codecs/ilbc/xcorr_coef.c b/modules/audio_coding/codecs/ilbc/xcorr_coef.c
index eb7f828f..38af71f8 100644
--- a/modules/audio_coding/codecs/ilbc/xcorr_coef.c
+++ b/modules/audio_coding/codecs/ilbc/xcorr_coef.c
@@ -131,9 +131,7 @@ int WebRtcIlbcfix_XcorrCoef(
pos+=step;
/* Do a +/- to get the next energy */
- Energy += step*(WEBRTC_SPL_RSHIFT_W32(
- ((int32_t)(*rp_end)*(*rp_end)) - ((int32_t)(*rp_beg)*(*rp_beg)),
- shifts));
+ Energy += step * ((*rp_end * *rp_end - *rp_beg * *rp_beg) >> shifts);
rp_beg+=step;
rp_end+=step;
}
diff --git a/modules/audio_coding/codecs/isac/fix/source/arith_routines.c b/modules/audio_coding/codecs/isac/fix/source/arith_routines.c
index 38eecb79..5925d68e 100644
--- a/modules/audio_coding/codecs/isac/fix/source/arith_routines.c
+++ b/modules/audio_coding/codecs/isac/fix/source/arith_routines.c
@@ -72,11 +72,10 @@ int16_t WebRtcIsacfix_EncTerminate(Bitstr_enc *streamData)
}
/* write remaining data to bitstream, if "full == 0" first byte has data */
if (streamData->full == 0) {
- *streamPtr++ += (uint16_t) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24);
+ *streamPtr++ += (uint16_t)(streamData->streamval >> 24);
streamData->full = 1;
} else {
- *streamPtr = (uint16_t) WEBRTC_SPL_LSHIFT_W32(
- WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24), 8);
+ *streamPtr = (uint16_t)((streamData->streamval >> 24) << 8);
streamData->full = 0;
}
}
@@ -111,11 +110,10 @@ int16_t WebRtcIsacfix_EncTerminate(Bitstr_enc *streamData)
}
/* write remaining data (2 bytes) to bitstream */
if (streamData->full) {
- *streamPtr++ = (uint16_t) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 16);
+ *streamPtr++ = (uint16_t)(streamData->streamval >> 16);
} else {
- *streamPtr++ |= (uint16_t) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24);
- *streamPtr = (uint16_t) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 8)
- & 0xFF00;
+ *streamPtr++ |= (uint16_t)(streamData->streamval >> 24);
+ *streamPtr = (uint16_t)(streamData->streamval >> 8) & 0xFF00;
}
}
diff --git a/modules/audio_coding/codecs/isac/fix/source/arith_routines_hist.c b/modules/audio_coding/codecs/isac/fix/source/arith_routines_hist.c
index b88bc1f2..83f36fef 100644
--- a/modules/audio_coding/codecs/isac/fix/source/arith_routines_hist.c
+++ b/modules/audio_coding/codecs/isac/fix/source/arith_routines_hist.c
@@ -65,7 +65,7 @@ int WebRtcIsacfix_EncHistMulti(Bitstr_enc *streamData,
/* update interval */
W_upper_LSB = W_upper & 0x0000FFFF;
- W_upper_MSB = WEBRTC_SPL_RSHIFT_W32(W_upper, 16);
+ W_upper_MSB = W_upper >> 16;
W_lower = WEBRTC_SPL_UMUL(W_upper_MSB, cdfLo);
W_lower += ((W_upper_LSB * cdfLo) >> 16);
W_upper = WEBRTC_SPL_UMUL(W_upper_MSB, cdfHi);
@@ -103,11 +103,10 @@ int WebRtcIsacfix_EncHistMulti(Bitstr_enc *streamData,
{
W_upper = WEBRTC_SPL_LSHIFT_W32(W_upper, 8);
if (streamData->full == 0) {
- *streamPtr++ += (uint16_t) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24);
+ *streamPtr++ += (uint16_t)(streamData->streamval >> 24);
streamData->full = 1;
} else {
- *streamPtr = (uint16_t) WEBRTC_SPL_LSHIFT_W32(
- WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24), 8);
+ *streamPtr = (uint16_t)((streamData->streamval >> 24) << 8);
streamData->full = 0;
}
@@ -185,7 +184,7 @@ int16_t WebRtcIsacfix_DecHistBisectMulti(int16_t *data,
{
/* find the integer *data for which streamval lies in [W_lower+1, W_upper] */
W_upper_LSB = W_upper & 0x0000FFFF;
- W_upper_MSB = WEBRTC_SPL_RSHIFT_W32(W_upper, 16);
+ W_upper_MSB = W_upper >> 16;
/* start halfway the cdf range */
sizeTmp = *cdfSize++ / 2;
diff --git a/modules/audio_coding/codecs/isac/fix/source/arith_routines_logist.c b/modules/audio_coding/codecs/isac/fix/source/arith_routines_logist.c
index 27f582a2..5c7df478 100644
--- a/modules/audio_coding/codecs/isac/fix/source/arith_routines_logist.c
+++ b/modules/audio_coding/codecs/isac/fix/source/arith_routines_logist.c
@@ -71,7 +71,7 @@ static __inline uint16_t WebRtcIsacfix_Piecewise(int32_t xinQ15) {
/* Find index for x-value */
qtmp1 = WEBRTC_SPL_SAT(kHistEdges[50],xinQ15,kHistEdges[0]);
ind = WEBRTC_SPL_MUL(5, qtmp1 - kHistEdges[0]);
- ind = WEBRTC_SPL_RSHIFT_W32(ind, 16);
+ ind >>= 16;
/* Calculate corresponding y-value ans return*/
qtmp1 = qtmp1 - kHistEdges[ind];
@@ -300,7 +300,7 @@ int16_t WebRtcIsacfix_DecLogisticMulti2(int16_t *dataQ7,
candQ7 = - *dataQ7 + 64;
cdfTmp = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8));
- W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB);
+ W_tmp = (uint32_t)cdfTmp * W_upper_MSB;
W_tmp += ((uint32_t)cdfTmp * (uint32_t)W_upper_LSB) >> 16;
if (streamVal > W_tmp)
@@ -309,7 +309,7 @@ int16_t WebRtcIsacfix_DecLogisticMulti2(int16_t *dataQ7,
candQ7 += 128;
cdfTmp = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8));
- W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB);
+ W_tmp = (uint32_t)cdfTmp * W_upper_MSB;
W_tmp += ((uint32_t)cdfTmp * (uint32_t)W_upper_LSB) >> 16;
while (streamVal > W_tmp)
@@ -319,7 +319,7 @@ int16_t WebRtcIsacfix_DecLogisticMulti2(int16_t *dataQ7,
cdfTmp = WebRtcIsacfix_Piecewise(
WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8));
- W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB);
+ W_tmp = (uint32_t)cdfTmp * W_upper_MSB;
W_tmp += ((uint32_t)cdfTmp * (uint32_t)W_upper_LSB) >> 16;
/* error check */
@@ -338,7 +338,7 @@ int16_t WebRtcIsacfix_DecLogisticMulti2(int16_t *dataQ7,
candQ7 -= 128;
cdfTmp = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8));
- W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB);
+ W_tmp = (uint32_t)cdfTmp * W_upper_MSB;
W_tmp += ((uint32_t)cdfTmp * (uint32_t)W_upper_LSB) >> 16;
while ( !(streamVal > W_tmp) )
@@ -348,7 +348,7 @@ int16_t WebRtcIsacfix_DecLogisticMulti2(int16_t *dataQ7,
cdfTmp = WebRtcIsacfix_Piecewise(
WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8));
- W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB);
+ W_tmp = (uint32_t)cdfTmp * W_upper_MSB;
W_tmp += ((uint32_t)cdfTmp * (uint32_t)W_upper_LSB) >> 16;
/* error check */
diff --git a/modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.c b/modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.c
index 7012e8d6..63797d2d 100644
--- a/modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.c
+++ b/modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.c
@@ -200,8 +200,8 @@ int32_t WebRtcIsacfix_UpdateUplinkBwImpl(BwEstimatorstr *bweStr,
}
/* kBitsByteSec is in Q15 */
- recRtpRate = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(kBitsByteSec,
- (int32_t)pksize), 15) + bweStr->recHeaderRate;
+ recRtpRate = (int16_t)((kBitsByteSec * pksize) >> 15) +
+ bweStr->recHeaderRate;
} else {
/* If frameSize changed since last call, from 60 to 30, recalculate some values */
@@ -215,8 +215,8 @@ int32_t WebRtcIsacfix_UpdateUplinkBwImpl(BwEstimatorstr *bweStr,
}
/* kBitsByteSec is in Q14 */
- recRtpRate = (uint16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(kBitsByteSec,
- (int32_t)pksize), 14) + bweStr->recHeaderRate;
+ recRtpRate = (uint16_t)((kBitsByteSec * pksize) >> 14) +
+ bweStr->recHeaderRate;
}
@@ -293,7 +293,7 @@ int32_t WebRtcIsacfix_UpdateUplinkBwImpl(BwEstimatorstr *bweStr,
if ( reductionFactor != 0 ) {
bweStr->recBwInv = WEBRTC_SPL_MUL((int32_t)bweStr->recBwInv, (int32_t)reductionFactor);
- bweStr->recBwInv = WEBRTC_SPL_RSHIFT_W32((int32_t)bweStr->recBwInv, 13);
+ bweStr->recBwInv = (int32_t)bweStr->recBwInv >> 13;
} else {
static const uint32_t kInitRate = INIT_BN_EST + INIT_HDR_RATE;
@@ -345,8 +345,8 @@ int32_t WebRtcIsacfix_UpdateUplinkBwImpl(BwEstimatorstr *bweStr,
}
}
- if ((bweStr->prevRtpRate > WEBRTC_SPL_RSHIFT_W32((int32_t) bweStr->recBwAvg, 5)) &&
- (recRtpRate > WEBRTC_SPL_RSHIFT_W32((int32_t)bweStr->recBwAvg, 5)) &&
+ if ((bweStr->prevRtpRate > (int32_t)bweStr->recBwAvg >> 5) &&
+ (recRtpRate > (int32_t)bweStr->recBwAvg >> 5) &&
!bweStr->inWaitPeriod) {
/* test if still in initiation period and increment counter */
@@ -356,7 +356,7 @@ int32_t WebRtcIsacfix_UpdateUplinkBwImpl(BwEstimatorstr *bweStr,
} else {
/* weight decreases with number of updates, 1/countUpdates in Q13 */
weight = (uint16_t) WebRtcSpl_DivW32W16(
- (int32_t)(8192 + WEBRTC_SPL_RSHIFT_W32((int32_t) bweStr->countUpdates, 1)),
+ 8192 + (bweStr->countUpdates >> 1),
(int16_t)bweStr->countUpdates);
}
@@ -374,8 +374,8 @@ int32_t WebRtcIsacfix_UpdateUplinkBwImpl(BwEstimatorstr *bweStr,
/* compute inverse receiving rate for last packet, in Q19 */
numBytesInv = (uint16_t) WebRtcSpl_DivW32W16(
- (int32_t)(524288 + WEBRTC_SPL_RSHIFT_W32(((int32_t)pksize + HEADER_SIZE), 1)),
- (int16_t)(pksize + HEADER_SIZE));
+ 524288 + ((pksize + HEADER_SIZE) >> 1),
+ pksize + HEADER_SIZE);
/* 8389 is ~ 1/128000 in Q30 */
byteSecondsPerBit = WEBRTC_SPL_MUL_16_16(arrTimeDiff, 8389);
@@ -445,12 +445,12 @@ int32_t WebRtcIsacfix_UpdateUplinkBwImpl(BwEstimatorstr *bweStr,
arrTimeNoiseAbs = arrTimeNoise;
/* long term averaged absolute jitter, Q15 */
- weight = WEBRTC_SPL_RSHIFT_W32(weight, 3);
+ weight >>= 3;
bweStr->recJitter = WEBRTC_SPL_MUL(weight, WEBRTC_SPL_LSHIFT_W32(arrTimeNoiseAbs, 5))
+ WEBRTC_SPL_MUL(1024 - weight, bweStr->recJitter);
/* remove the fractional portion */
- bweStr->recJitter = WEBRTC_SPL_RSHIFT_W32(bweStr->recJitter, 10);
+ bweStr->recJitter >>= 10;
/* Maximum jitter is 10 msec in Q15 */
if (bweStr->recJitter > (int32_t)327680) {
@@ -461,7 +461,7 @@ int32_t WebRtcIsacfix_UpdateUplinkBwImpl(BwEstimatorstr *bweStr,
/* Calculation in Q13 products in Q23 */
bweStr->recJitterShortTermAbs = WEBRTC_SPL_MUL(51, WEBRTC_SPL_LSHIFT_W32(arrTimeNoiseAbs, 3)) +
WEBRTC_SPL_MUL(973, bweStr->recJitterShortTermAbs);
- bweStr->recJitterShortTermAbs = WEBRTC_SPL_RSHIFT_W32(bweStr->recJitterShortTermAbs , 10);
+ bweStr->recJitterShortTermAbs >>= 10;
/* short term averaged jitter */
/* Calculation in Q13 products in Q23 */
@@ -470,10 +470,10 @@ int32_t WebRtcIsacfix_UpdateUplinkBwImpl(BwEstimatorstr *bweStr,
if (bweStr->recJitterShortTerm < 0) {
temp = -bweStr->recJitterShortTerm;
- temp = WEBRTC_SPL_RSHIFT_W32(temp, 12);
+ temp >>= 12;
bweStr->recJitterShortTerm = -temp;
} else {
- bweStr->recJitterShortTerm = WEBRTC_SPL_RSHIFT_W32(bweStr->recJitterShortTerm, 12);
+ bweStr->recJitterShortTerm >>= 12;
}
}
}
@@ -558,7 +558,7 @@ int16_t WebRtcIsacfix_UpdateUplinkBwRec(BwEstimatorstr *bweStr,
/* sendMaxDelayAvg = 0.9 * sendMaxDelayAvg + 0.1 * MAX_ISAC_MD */
bweStr->sendMaxDelayAvg = WEBRTC_SPL_MUL(461, bweStr->sendMaxDelayAvg) +
WEBRTC_SPL_MUL(51, WEBRTC_SPL_LSHIFT_W32((int32_t)MAX_ISAC_MD, 9));
- bweStr->sendMaxDelayAvg = WEBRTC_SPL_RSHIFT_W32(bweStr->sendMaxDelayAvg, 9);
+ bweStr->sendMaxDelayAvg >>= 9;
} else {
RateInd = Index;
@@ -566,7 +566,7 @@ int16_t WebRtcIsacfix_UpdateUplinkBwRec(BwEstimatorstr *bweStr,
/* sendMaxDelayAvg = 0.9 * sendMaxDelayAvg + 0.1 * MIN_ISAC_MD */
bweStr->sendMaxDelayAvg = WEBRTC_SPL_MUL(461, bweStr->sendMaxDelayAvg) +
WEBRTC_SPL_MUL(51, WEBRTC_SPL_LSHIFT_W32((int32_t)MIN_ISAC_MD,9));
- bweStr->sendMaxDelayAvg = WEBRTC_SPL_RSHIFT_W32(bweStr->sendMaxDelayAvg, 9);
+ bweStr->sendMaxDelayAvg >>= 9;
}
@@ -644,7 +644,7 @@ uint16_t WebRtcIsacfix_GetDownlinkBwIndexImpl(BwEstimatorstr *bweStr)
/* 0.9 times recBwAvgQ in Q16 */
/* 461/512 - 25/65536 =0.900009 */
tempTerm1 = WEBRTC_SPL_MUL(bweStr->recBwAvgQ, 25);
- tempTerm1 = WEBRTC_SPL_RSHIFT_W32(tempTerm1, 7);
+ tempTerm1 >>= 7;
tempTermX = WEBRTC_SPL_UMUL(461, bweStr->recBwAvgQ) - tempTerm1;
/* rate in Q16 */
@@ -667,7 +667,7 @@ uint16_t WebRtcIsacfix_GetDownlinkBwIndexImpl(BwEstimatorstr *bweStr)
tempTermX += KQRate01[rateInd];
/* Shift back to Q7 */
- bweStr->recBwAvgQ = WEBRTC_SPL_RSHIFT_W32(tempTermX, 9);
+ bweStr->recBwAvgQ = tempTermX >> 9;
/* Count consecutive received bandwidth above 28000 kbps (28000 in Q7 = 3584000) */
/* If 66 high estimates in a row, set highSpeedRec to one */
@@ -700,13 +700,13 @@ uint16_t WebRtcIsacfix_GetDownlinkBwIndexImpl(BwEstimatorstr *bweStr)
tempTerm1 = tempTermX + tempMin;
/* update quantized average, shift back to Q9 */
- bweStr->recMaxDelayAvgQ = WEBRTC_SPL_RSHIFT_W32(tempTerm1, 9);
+ bweStr->recMaxDelayAvgQ = tempTerm1 >> 9;
} else {
maxDelayBit = 12;
tempTerm1 = tempTermX + tempMax;
/* update quantized average, shift back to Q9 */
- bweStr->recMaxDelayAvgQ = WEBRTC_SPL_RSHIFT_W32(tempTerm1, 9);
+ bweStr->recMaxDelayAvgQ = tempTerm1 >> 9;
}
/* Return bandwitdh and jitter index (0..23) */
@@ -727,39 +727,41 @@ uint16_t WebRtcIsacfix_GetDownlinkBandwidth(const BwEstimatorstr *bweStr)
rec_jitter_short_term_abs_inv = 0x80000000u / bweStr->recJitterShortTermAbs;
/* Q27 = 9 + 18 */
- jitter_sign = WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(bweStr->recJitterShortTerm, 4), (int32_t)rec_jitter_short_term_abs_inv);
+ jitter_sign = (bweStr->recJitterShortTerm >> 4) *
+ rec_jitter_short_term_abs_inv;
if (jitter_sign < 0) {
temp = -jitter_sign;
- temp = WEBRTC_SPL_RSHIFT_W32(temp, 19);
+ temp >>= 19;
jitter_sign = -temp;
} else {
- jitter_sign = WEBRTC_SPL_RSHIFT_W32(jitter_sign, 19);
+ jitter_sign >>= 19;
}
/* adjust bw proportionally to negative average jitter sign */
//bw_adjust = 1.0f - jitter_sign * (0.15f + 0.15f * jitter_sign * jitter_sign);
//Q8 -> Q16 .15 +.15 * jitter^2 first term is .15 in Q16 latter term is Q8*Q8*Q8
//38 in Q8 ~.15 9830 in Q16 ~.15
- temp = 9830 + WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL(38, WEBRTC_SPL_MUL(jitter_sign, jitter_sign))), 8);
+ temp = 9830 + ((38 * jitter_sign * jitter_sign) >> 8);
if (jitter_sign < 0) {
temp = WEBRTC_SPL_MUL(jitter_sign, temp);
temp = -temp;
- temp = WEBRTC_SPL_RSHIFT_W32(temp, 8);
+ temp >>= 8;
bw_adjust = (uint32_t)65536 + temp; /* (1 << 16) + temp; */
} else {
- bw_adjust = (uint32_t)65536 - WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(jitter_sign, temp), 8);/* (1 << 16) - ((jitter_sign * temp) >> 8); */
+ /* (1 << 16) - ((jitter_sign * temp) >> 8); */
+ bw_adjust = 65536 - ((jitter_sign * temp) >> 8);
}
//make sure following multiplication won't overflow
//bw adjust now Q14
- bw_adjust = WEBRTC_SPL_RSHIFT_W32(bw_adjust, 2);//see if good resolution is maintained
+ bw_adjust >>= 2; // See if good resolution is maintained.
/* adjust Rate if jitter sign is mostly constant */
recBw = WEBRTC_SPL_UMUL(bweStr->recBw, bw_adjust);
- recBw = WEBRTC_SPL_RSHIFT_W32(recBw, 14);
+ recBw >>= 14;
/* limit range of bottle neck rate */
if (recBw < MIN_ISAC_BW) {
@@ -774,9 +776,7 @@ uint16_t WebRtcIsacfix_GetDownlinkBandwidth(const BwEstimatorstr *bweStr)
/* Returns the mmax delay (in ms) */
int16_t WebRtcIsacfix_GetDownlinkMaxDelay(const BwEstimatorstr *bweStr)
{
- int16_t recMaxDelay;
-
- recMaxDelay = (int16_t) WEBRTC_SPL_RSHIFT_W32(bweStr->recMaxDelay, 15);
+ int16_t recMaxDelay = (int16_t)(bweStr->recMaxDelay >> 15);
/* limit range of jitter estimate */
if (recMaxDelay < MIN_ISAC_MD) {
@@ -810,9 +810,7 @@ int16_t WebRtcIsacfix_GetUplinkBandwidth(const BwEstimatorstr *bweStr)
/* Returns the max delay value from the other side in ms */
int16_t WebRtcIsacfix_GetUplinkMaxDelay(const BwEstimatorstr *bweStr)
{
- int16_t send_max_delay;
-
- send_max_delay = (int16_t) WEBRTC_SPL_RSHIFT_W32(bweStr->sendMaxDelayAvg, 9);
+ int16_t send_max_delay = (int16_t)(bweStr->sendMaxDelayAvg >> 9);
/* limit range of jitter estimate */
if (send_max_delay < MIN_ISAC_MD) {
@@ -858,17 +856,19 @@ uint16_t WebRtcIsacfix_GetMinBytes(RateModel *State,
(((512 - 512 / BURST_LEN) * DelayBuildUp) >> 9)) {
/* max bps derived from BottleNeck and DelayBuildUp values */
inv_Q12 = 4096 / (BURST_LEN * FrameSamples);
- MinRate = WEBRTC_SPL_MUL(512 + WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(DelayBuildUp, inv_Q12), 3)), BottleNeck);
+ MinRate = (512 + SAMPLES_PER_MSEC * ((DelayBuildUp * inv_Q12) >> 3)) *
+ BottleNeck;
} else {
/* max bps derived from StillBuffered and DelayBuildUp values */
inv_Q12 = 4096 / FrameSamples;
if (DelayBuildUp > State->StillBuffered) {
- MinRate = WEBRTC_SPL_MUL(512 + WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(DelayBuildUp - State->StillBuffered, inv_Q12), 3)), BottleNeck);
+ MinRate = (512 + SAMPLES_PER_MSEC * (((DelayBuildUp -
+ State->StillBuffered) * inv_Q12) >> 3)) * BottleNeck;
} else if ((den = WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, (State->StillBuffered - DelayBuildUp))) >= FrameSamples) {
/* MinRate will be negative here */
MinRate = 0;
} else {
- MinRate = WEBRTC_SPL_MUL((512 - WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(den, inv_Q12), 3)), BottleNeck);
+ MinRate = (512 - ((den * inv_Q12) >> 3)) * BottleNeck;
}
//if (MinRate < 1.04 * BottleNeck)
// MinRate = 1.04 * BottleNeck;
@@ -886,7 +886,7 @@ uint16_t WebRtcIsacfix_GetMinBytes(RateModel *State,
/* convert rate from bits/second to bytes/packet */
//round and shift before conversion
MinRate += 256;
- MinRate = WEBRTC_SPL_RSHIFT_W32(MinRate, 9);
+ MinRate >>= 9;
MinBytes = MinRate * FrameSamples / FS8;
/* StreamSize will be adjusted if less than MinBytes */
diff --git a/modules/audio_coding/codecs/isac/fix/source/decode.c b/modules/audio_coding/codecs/isac/fix/source/decode.c
index 263f88a4..fb9c7be9 100644
--- a/modules/audio_coding/codecs/isac/fix/source/decode.c
+++ b/modules/audio_coding/codecs/isac/fix/source/decode.c
@@ -54,7 +54,7 @@ int16_t WebRtcIsacfix_DecodeImpl(int16_t *signal_out16,
int16_t AvgPitchGain_Q12;
int16_t tmp_1, tmp_2;
- int32_t tmp32a, tmp32b;
+ int32_t tmp32a;
int16_t gainQ13;
@@ -113,7 +113,8 @@ int16_t WebRtcIsacfix_DecodeImpl(int16_t *signal_out16,
WebRtcIsacfix_Spec2Time(Vector_Word16_1, Vector_Word16_2, Vector_Word32_1, Vector_Word32_2);
for (k=0; k<FRAMESAMPLES/2; k++) {
- Vector_Word16_1[k] = (int16_t)WEBRTC_SPL_RSHIFT_W32(Vector_Word32_1[k]+64, 7); //Q16 -> Q9
+ // Q16 -> Q9.
+ Vector_Word16_1[k] = (int16_t)((Vector_Word32_1[k] + 64) >> 7);
}
/* ---- If this is recovery frame ---- */
@@ -176,8 +177,7 @@ int16_t WebRtcIsacfix_DecodeImpl(int16_t *signal_out16,
/* reduce gain to compensate for pitch enhancer */
/* gain = 1.0f - 0.45f * AvgPitchGain; */
tmp32a = WEBRTC_SPL_MUL_16_16_RSFT(AvgPitchGain_Q12, 29, 0); // Q18
- tmp32b = 262144 - tmp32a; // Q18
- gainQ13 = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); // Q13
+ gainQ13 = (int16_t)((262144 - tmp32a) >> 5); // Q18 -> Q13.
for (k = 0; k < FRAMESAMPLES/2; k++)
{
diff --git a/modules/audio_coding/codecs/isac/fix/source/decode_plc.c b/modules/audio_coding/codecs/isac/fix/source/decode_plc.c
index 2099dc48..51344c2a 100644
--- a/modules/audio_coding/codecs/isac/fix/source/decode_plc.c
+++ b/modules/audio_coding/codecs/isac/fix/source/decode_plc.c
@@ -71,7 +71,7 @@ static int16_t plc_filterma_Fast(
o = WEBRTC_SPL_SAT((int32_t)lim, o, (int32_t)-lim);
/* o should be in the range of int16_t */
- o = WEBRTC_SPL_RSHIFT_W32( o, rshift );
+ o >>= rshift;
/* decay the output signal; this is specific to plc */
*Out++ = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT( (int16_t)o, decay, 15); // ((o + (int32_t)2048) >> 12);
@@ -97,7 +97,7 @@ static __inline int32_t log2_Q8_T( uint32_t x ) {
int16_t frac;
zeros=WebRtcSpl_NormU32(x);
- frac=(int16_t)WEBRTC_SPL_RSHIFT_W32(((uint32_t)WEBRTC_SPL_LSHIFT_W32(x, zeros)&0x7FFFFFFF), 23);
+ frac = (int16_t)(((x << zeros) & 0x7FFFFFFF) >> 23);
/* log2(magn(i)) */
return ((31 - zeros) << 8) + frac;
@@ -145,7 +145,7 @@ static void MemshipValQ15( int16_t in, int16_t *A, int16_t *B )
WEBRTC_SPL_MUL_16_16_RSFT( in, 983, 12) );
/* b = x^2 / 2 {in Q15} so a shift of 16 is required to
be in correct domain and one more for the division by 2 */
- *B = (int16_t)WEBRTC_SPL_RSHIFT_W32( WEBRTC_SPL_MUL_16_16( x, x ) + 0x00010000, 17 );
+ *B = (int16_t)((x * x + 0x00010000) >> 17);
*A = WEBRTC_SPL_WORD16_MAX - *B;
}
else
@@ -164,7 +164,7 @@ static void MemshipValQ15( int16_t in, int16_t *A, int16_t *B )
WEBRTC_SPL_MUL_16_16_RSFT( in, 983, 12) );
/* b = x^2 / 2 {in Q15} so a shift of 16 is required to
be in correct domain and one more for the division by 2 */
- *A = (int16_t)WEBRTC_SPL_RSHIFT_W32( WEBRTC_SPL_MUL_16_16( x, x ) + 0x00010000, 17 );
+ *A = (int16_t)((x * x + 0x00010000) >> 17);
*B = WEBRTC_SPL_WORD16_MAX - *A;
}
@@ -501,14 +501,13 @@ int16_t WebRtcIsacfix_DecodePlcImpl(int16_t *signal_out16,
rshift = 0;
while( maxCoeff > WEBRTC_SPL_WORD16_MAX )
{
- maxCoeff = WEBRTC_SPL_RSHIFT_W32(maxCoeff, 1);
+ maxCoeff >>= 1;
rshift++;
}
for( i = 0; i < NOISE_FILTER_LEN; i++ ) {
- Vector_Word16_1[ FRAMESAMPLES_HALF - NOISE_FILTER_LEN + i] =
- (int16_t)WEBRTC_SPL_RSHIFT_W32(
- (ISACdec_obj->plcstr_obj).prevHP[
- PITCH_MAX_LAG + 10 - NOISE_FILTER_LEN + i], rshift);
+ Vector_Word16_1[FRAMESAMPLES_HALF - NOISE_FILTER_LEN + i] =(int16_t)(
+ ISACdec_obj->plcstr_obj.prevHP[PITCH_MAX_LAG + 10 - NOISE_FILTER_LEN +
+ i] >> rshift);
}
(ISACdec_obj->plcstr_obj).decayCoeffNoise = plc_filterma_Fast(
Vector_Word16_2,
diff --git a/modules/audio_coding/codecs/isac/fix/source/encode.c b/modules/audio_coding/codecs/isac/fix/source/encode.c
index 0998545a..2c63c027 100644
--- a/modules/audio_coding/codecs/isac/fix/source/encode.c
+++ b/modules/audio_coding/codecs/isac/fix/source/encode.c
@@ -194,7 +194,8 @@ int WebRtcIsacfix_EncodeImpl(int16_t *in,
}
return status;
}
- AvgPitchGain_Q12 = WEBRTC_SPL_RSHIFT_W32(PitchGains_Q12[0] + PitchGains_Q12[1] + PitchGains_Q12[2] + PitchGains_Q12[3], 2);
+ AvgPitchGain_Q12 = (PitchGains_Q12[0] + PitchGains_Q12[1] +
+ PitchGains_Q12[2] + PitchGains_Q12[3]) >> 2;
/* find coefficients for perceptual pre-filters */
WebRtcIsacfix_GetLpcCoef(LPandHP, HP16a+QLOOKAHEAD, &ISACenc_obj->maskfiltstr_obj,
diff --git a/modules/audio_coding/codecs/isac/fix/source/entropy_coding.c b/modules/audio_coding/codecs/isac/fix/source/entropy_coding.c
index c1b4abb7..869db75d 100644
--- a/modules/audio_coding/codecs/isac/fix/source/entropy_coding.c
+++ b/modules/audio_coding/codecs/isac/fix/source/entropy_coding.c
@@ -72,13 +72,7 @@ enum matrixprod_init_case {
*/
static __inline int32_t CalcLrIntQ(int32_t fixVal, int16_t qDomain) {
- int32_t intgr;
- int32_t roundVal;
-
- roundVal = WEBRTC_SPL_LSHIFT_W32((int32_t)1, qDomain-1);
- intgr = WEBRTC_SPL_RSHIFT_W32(fixVal+roundVal, qDomain);
-
- return intgr;
+ return (fixVal + (1 << (qDomain - 1))) >> qDomain;
}
/*
@@ -154,10 +148,10 @@ static int32_t CalcExpN(int16_t x) {
ax = -ax;
axINT = 1 + (ax >> 8); //Q0
axFRAC = 0x00FF - (ax&0x00FF);
- exp16 = (int16_t) WEBRTC_SPL_RSHIFT_W32(32768, axINT); //Q15
+ exp16 = (int16_t)(32768 >> axINT); // Q15
axFRAC = axFRAC+256; //Q8
exp = WEBRTC_SPL_MUL_16_16(exp16, axFRAC); // Q15*Q8 = Q23
- exp = WEBRTC_SPL_RSHIFT_W32(exp, 6); //Q17
+ exp >>= 6; // Q17
}
return exp;
@@ -173,8 +167,8 @@ static void CalcCorrelation(int32_t *PSpecQ12, int32_t *CorrQ7)
int k, n;
for (k = 0; k < FRAMESAMPLES/8; k++) {
- summ[k] = WEBRTC_SPL_RSHIFT_W32(PSpecQ12[k] + PSpecQ12[FRAMESAMPLES/4-1 - k] + 16, 5);
- diff[k] = WEBRTC_SPL_RSHIFT_W32(PSpecQ12[k] - PSpecQ12[FRAMESAMPLES/4-1 - k] + 16, 5);
+ summ[k] = (PSpecQ12[k] + PSpecQ12[FRAMESAMPLES / 4 - 1 - k] + 16) >> 5;
+ diff[k] = (PSpecQ12[k] - PSpecQ12[FRAMESAMPLES / 4 - 1 - k] + 16) >> 5;
}
sum = 2;
@@ -185,14 +179,14 @@ static void CalcCorrelation(int32_t *PSpecQ12, int32_t *CorrQ7)
for (k = 0; k < AR_ORDER; k += 2) {
sum = 0;
for (n = 0; n < FRAMESAMPLES/8; n++)
- sum += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WebRtcIsacfix_kCos[k][n], diff[n]) + 256, 9);
+ sum += (WebRtcIsacfix_kCos[k][n] * diff[n] + 256) >> 9;
CorrQ7[k+1] = sum;
}
for (k=1; k<AR_ORDER; k+=2) {
sum = 0;
for (n = 0; n < FRAMESAMPLES/8; n++)
- sum += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WebRtcIsacfix_kCos[k][n], summ[n]) + 256, 9);
+ sum += (WebRtcIsacfix_kCos[k][n] * summ[n] + 256) >> 9;
CorrQ7[k+1] = sum;
}
}
@@ -213,12 +207,12 @@ static void CalcInvArSpec(const int16_t *ARCoefQ12,
sum = 0;
for (n = 0; n < AR_ORDER+1; n++)
sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]); /* Q24 */
- sum = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(sum, 6), 65) + 32768, 16); /* result in Q8 */
- CorrQ11[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, gainQ10) + 256, 9);
+ sum = ((sum >> 6) * 65 + 32768) >> 16; /* Result in Q8. */
+ CorrQ11[0] = (sum * gainQ10 + 256) >> 9;
/* To avoid overflow, we shift down gainQ10 if it is large. We will not lose any precision */
if(gainQ10>400000){
- tmpGain = WEBRTC_SPL_RSHIFT_W32(gainQ10, 3);
+ tmpGain = gainQ10 >> 3;
round = 32;
shftVal = 6;
} else {
@@ -231,8 +225,8 @@ static void CalcInvArSpec(const int16_t *ARCoefQ12,
sum = 16384;
for (n = k; n < AR_ORDER+1; n++)
sum += WEBRTC_SPL_MUL(ARCoefQ12[n-k], ARCoefQ12[n]); /* Q24 */
- sum = WEBRTC_SPL_RSHIFT_W32(sum, 15);
- CorrQ11[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, tmpGain) + round, shftVal);
+ sum >>= 15;
+ CorrQ11[k] = (sum * tmpGain + round) >> shftVal;
}
sum = WEBRTC_SPL_LSHIFT_W32(CorrQ11[0], 7);
for (n = 0; n < FRAMESAMPLES/8; n++)
@@ -240,7 +234,7 @@ static void CalcInvArSpec(const int16_t *ARCoefQ12,
for (k = 1; k < AR_ORDER; k += 2) {
for (n = 0; n < FRAMESAMPLES/8; n++)
- CurveQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WebRtcIsacfix_kCos[k][n], CorrQ11[k+1]) + 2, 2);
+ CurveQ16[n] += (WebRtcIsacfix_kCos[k][n] * CorrQ11[k + 1] + 2) >> 2;
}
CS_ptrQ9 = WebRtcIsacfix_kCos[0];
@@ -256,11 +250,11 @@ static void CalcInvArSpec(const int16_t *ARCoefQ12,
shftVal = 0;
for (n = 0; n < FRAMESAMPLES/8; n++)
- diffQ16[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[1], shftVal)) + 2, 2);
+ diffQ16[n] = (CS_ptrQ9[n] * (CorrQ11[1] >> shftVal) + 2) >> 2;
for (k = 2; k < AR_ORDER; k += 2) {
CS_ptrQ9 = WebRtcIsacfix_kCos[k];
for (n = 0; n < FRAMESAMPLES/8; n++)
- diffQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[k+1], shftVal)) + 2, 2);
+ diffQ16[n] += (CS_ptrQ9[n] * (CorrQ11[k + 1] >> shftVal) + 2) >> 2;
}
for (k=0; k<FRAMESAMPLES/8; k++) {
@@ -286,12 +280,12 @@ static void CalcRootInvArSpec(const int16_t *ARCoefQ12,
sum = 0;
for (n = 0; n < AR_ORDER+1; n++)
sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]); /* Q24 */
- sum = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(sum, 6), 65) + 32768, 16); /* result in Q8 */
- CorrQ11[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, gainQ10) + 256, 9);
+ sum = ((sum >> 6) * 65 + 32768) >> 16; /* Result in Q8. */
+ CorrQ11[0] = (sum * gainQ10 + 256) >> 9;
/* To avoid overflow, we shift down gainQ10 if it is large. We will not lose any precision */
if(gainQ10>400000){
- tmpGain = WEBRTC_SPL_RSHIFT_W32(gainQ10, 3);
+ tmpGain = gainQ10 >> 3;
round = 32;
shftVal = 6;
} else {
@@ -304,8 +298,8 @@ static void CalcRootInvArSpec(const int16_t *ARCoefQ12,
sum = 16384;
for (n = k; n < AR_ORDER+1; n++)
sum += WEBRTC_SPL_MUL(ARCoefQ12[n-k], ARCoefQ12[n]); /* Q24 */
- sum = WEBRTC_SPL_RSHIFT_W32(sum, 15);
- CorrQ11[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, tmpGain) + round, shftVal);
+ sum >>= 15;
+ CorrQ11[k] = (sum * tmpGain + round) >> shftVal;
}
sum = WEBRTC_SPL_LSHIFT_W32(CorrQ11[0], 7);
for (n = 0; n < FRAMESAMPLES/8; n++)
@@ -329,11 +323,11 @@ static void CalcRootInvArSpec(const int16_t *ARCoefQ12,
shftVal = 0;
for (n = 0; n < FRAMESAMPLES/8; n++)
- diffQ16[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[1], shftVal)) + 2, 2);
+ diffQ16[n] = (CS_ptrQ9[n] * (CorrQ11[1] >> shftVal) + 2) >> 2;
for (k = 2; k < AR_ORDER; k += 2) {
CS_ptrQ9 = WebRtcIsacfix_kCos[k];
for (n = 0; n < FRAMESAMPLES/8; n++)
- diffQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[k+1], shftVal)) + 2, 2);
+ diffQ16[n] += (CS_ptrQ9[n] * (CorrQ11[k + 1] >> shftVal) + 2) >> 2;
}
in_sqrt = summQ16[0] + WEBRTC_SPL_LSHIFT_W32(diffQ16[0], shftVal);
@@ -399,13 +393,13 @@ static void GenerateDitherQ7(int16_t *bufQ7,
seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515;
/* fixed-point dither sample between -64 and 64 (Q7) */
- dither1_Q7 = (int16_t)WEBRTC_SPL_RSHIFT_W32((int32_t)seed + 16777216, 25); // * 128/4294967295
+ dither1_Q7 = (int16_t)(((int32_t)seed + 16777216) >> 25);
/* new random unsigned int32_t */
seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515;
/* fixed-point dither sample between -64 and 64 */
- dither2_Q7 = (int16_t)WEBRTC_SPL_RSHIFT_W32(seed + 16777216, 25);
+ dither2_Q7 = (int16_t)((seed + 16777216) >> 25);
shft = (int16_t)(WEBRTC_SPL_RSHIFT_U32(seed, 25) & 15);
if (shft < 5)
@@ -439,12 +433,12 @@ static void GenerateDitherQ7(int16_t *bufQ7,
seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515;
/* fixed-point dither sample between -64 and 64 */
- dither1_Q7 = (int16_t)WEBRTC_SPL_RSHIFT_W32((int32_t)seed + 16777216, 25);
+ dither1_Q7 = (int16_t)(((int32_t)seed + 16777216) >> 25);
/* dither sample is placed in either even or odd index */
shft = (int16_t)(WEBRTC_SPL_RSHIFT_U32(seed, 25) & 1); /* either 0 or 1 */
- bufQ7[k + shft] = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(dither_gain_Q14, dither1_Q7) + 8192, 14);
+ bufQ7[k + shft] = (int16_t)((dither_gain_Q14 * dither1_Q7 + 8192) >> 14);
bufQ7[k + 1 - shft] = 0;
}
}
@@ -501,10 +495,10 @@ int16_t WebRtcIsacfix_DecodeSpec(Bitstr_dec *streamdata,
{
gainQ10 = WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_LSHIFT_W32((int32_t)30, 10),
(int16_t)WEBRTC_SPL_RSHIFT_U32(invARSpec2_Q16[k>>2] + (uint32_t)2195456, 16));
- *frQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[ k ], gainQ10) + 512, 10);
- *fiQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+1], gainQ10) + 512, 10);
- *frQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+2], gainQ10) + 512, 10);
- *fiQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+3], gainQ10) + 512, 10);
+ *frQ7++ = (int16_t)((data[k] * gainQ10 + 512) >> 10);
+ *fiQ7++ = (int16_t)((data[k + 1] * gainQ10 + 512) >> 10);
+ *frQ7++ = (int16_t)((data[k + 2] * gainQ10 + 512) >> 10);
+ *fiQ7++ = (int16_t)((data[k + 3] * gainQ10 + 512) >> 10);
}
}
else
@@ -513,10 +507,10 @@ int16_t WebRtcIsacfix_DecodeSpec(Bitstr_dec *streamdata,
{
gainQ10 = WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_LSHIFT_W32((int32_t)36, 10),
(int16_t)WEBRTC_SPL_RSHIFT_U32(invARSpec2_Q16[k>>2] + (uint32_t)2654208, 16));
- *frQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[ k ], gainQ10) + 512, 10);
- *fiQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+1], gainQ10) + 512, 10);
- *frQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+2], gainQ10) + 512, 10);
- *fiQ7++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+3], gainQ10) + 512, 10);
+ *frQ7++ = (int16_t)((data[k] * gainQ10 + 512) >> 10);
+ *fiQ7++ = (int16_t)((data[k + 1] * gainQ10 + 512) >> 10);
+ *frQ7++ = (int16_t)((data[k + 2] * gainQ10 + 512) >> 10);
+ *fiQ7++ = (int16_t)((data[k + 3] * gainQ10 + 512) >> 10);
}
}
@@ -584,7 +578,7 @@ int WebRtcIsacfix_EncodeSpec(const int16_t *fr,
CorrQ7_norm[k] = WEBRTC_SPL_LSHIFT_W32(CorrQ7[k], lft_shft);
} else {
for (k=0; k<AR_ORDER+1; k++)
- CorrQ7_norm[k] = WEBRTC_SPL_RSHIFT_W32(CorrQ7[k], -lft_shft);
+ CorrQ7_norm[k] = CorrQ7[k] >> -lft_shft;
}
/* find RC coefficients */
@@ -603,20 +597,22 @@ int WebRtcIsacfix_EncodeSpec(const int16_t *fr,
nrg = 0;
for (j = 0; j <= AR_ORDER; j++) {
for (n = 0; n <= j; n++)
- nrg += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(ARCoefQ12[j], WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CorrQ7_norm[j-n], ARCoefQ12[n]) + 256, 9)) + 4, 3);
+ nrg += (ARCoefQ12[j] * ((CorrQ7_norm[j - n] * ARCoefQ12[n] + 256) >> 9) +
+ 4) >> 3;
for (n = j+1; n <= AR_ORDER; n++)
- nrg += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(ARCoefQ12[j], WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CorrQ7_norm[n-j], ARCoefQ12[n]) + 256, 9)) + 4, 3);
+ nrg += (ARCoefQ12[j] * ((CorrQ7_norm[n - j] * ARCoefQ12[n] + 256) >> 9) +
+ 4) >> 3;
}
if (lft_shft > 0)
- nrg = WEBRTC_SPL_RSHIFT_W32(nrg, lft_shft);
+ nrg >>= lft_shft;
else
nrg = WEBRTC_SPL_LSHIFT_W32(nrg, -lft_shft);
if(nrg>131072)
gain2_Q10 = WebRtcSpl_DivResultInQ31(FRAMESAMPLES >> 2, nrg); /* also shifts 31 bits to the left! */
else
- gain2_Q10 = WEBRTC_SPL_RSHIFT_W32(FRAMESAMPLES, 2);
+ gain2_Q10 = FRAMESAMPLES >> 2;
/* quantize & code gain2_Q10 */
if (WebRtcIsacfix_EncodeGain2(&gain2_Q10, streamdata))
@@ -715,20 +711,20 @@ static void Lar2RcFix(const int32_t *larQ17, int16_t *rcQ15, int16_t order) {
for (k = 0; k < order; k++) {
- larAbsQ11 = (int16_t) WEBRTC_SPL_ABS_W32(WEBRTC_SPL_RSHIFT_W32(larQ17[k]+32,6)); //Q11
+ larAbsQ11 = (int16_t)WEBRTC_SPL_ABS_W32((larQ17[k] + 32) >> 6); // Q11
if (larAbsQ11<4097) { //2.000012018559 in Q11
// Q11*Q16>>12 = Q15
rc = WEBRTC_SPL_MUL_16_16_RSFT(larAbsQ11, 24957, 12);
} else if (larAbsQ11<6393) { //3.121320351712 in Q11
// (Q11*Q17 + Q13)>>13 = Q15
- rc = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(larAbsQ11, 17993) + 130738688), 13);
+ rc = (larAbsQ11 * 17993 + 130738688) >> 13;
} else if (larAbsQ11<11255) { //5.495270168700 in Q11
// (Q11*Q19 + Q30)>>15 = Q15
- rc = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(larAbsQ11, 16850) + 875329820), 15);
+ rc = (larAbsQ11 * 16850 + 875329820) >> 15;
} else {
// (Q11*Q24>>16 + Q19)>>4 = Q15
- rc = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16_RSFT(larAbsQ11, 24433, 16)) + 515804), 4);
+ rc = (((larAbsQ11 * 24433) >> 16) + 515804) >> 4;
}
if (larQ17[k]<=0) {
@@ -1020,14 +1016,16 @@ int WebRtcIsacfix_DecodeLpcCoef(Bitstr_dec *streamdata,
for (k=0; k<SUBFRAMES; k++) {
/* log gains */
- sumQQ16 = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmpcoeffs_gQ17[posg], 2+9); //Divide by 4 and get Q17 to Q8, i.e. shift 2+9
+ // Divide by 4 and get Q17 to Q8, i.e. shift 2+9.
+ sumQQ16 = (int16_t)(tmpcoeffs_gQ17[posg] >> 11);
sumQQ16 += WebRtcIsacfix_kMeansGainQ8[model][posg];
sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out
gain_lo_hiQ17[gainpos] = sumQQ; //Q17
gainpos++;
posg++;
- sumQQ16 = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmpcoeffs_gQ17[posg], 2+9); //Divide by 4 and get Q17 to Q8, i.e. shift 2+9
+ // Divide by 4 and get Q17 to Q8, i.e. shift 2+9.
+ sumQQ16 = (int16_t)(tmpcoeffs_gQ17[posg] >> 11);
sumQQ16 += WebRtcIsacfix_kMeansGainQ8[model][posg];
sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out
gain_lo_hiQ17[gainpos] = sumQQ; //Q17
@@ -1321,7 +1319,8 @@ static int EstCodeLpcCoef(int32_t *LPCCoefQ17,
gainpos = 0;
for (k=0; k<2*SUBFRAMES; k++) {
- sumQQ16 = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmpcoeffs_gQ17[posg], 2+9); //Divide by 4 and get Q17 to Q8, i.e. shift 2+9
+ // Divide by 4 and get Q17 to Q8, i.e. shift 2+9.
+ sumQQ16 = (int16_t)(tmpcoeffs_gQ17[posg] >> 11);
sumQQ16 += WebRtcIsacfix_kMeansGainQ8[0][posg];
sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out
gain_lo_hiQ17[gainpos] = sumQQ; //Q17
@@ -1687,7 +1686,7 @@ int WebRtcIsacfix_DecodePitchLag(Bitstr_dec *streamdata,
for (k = 0; k < 4; k++)
meangainQ12 += PitchGain_Q12[k];
- meangainQ12 = WEBRTC_SPL_RSHIFT_W32(meangainQ12, 2); // Get average
+ meangainQ12 >>= 2; // Get average.
/* voicing classificiation */
if (meangainQ12 <= 819) { // mean_gain < 0.2
@@ -1731,21 +1730,21 @@ int WebRtcIsacfix_DecodePitchLag(Bitstr_dec *streamdata,
CQ11 = WEBRTC_SPL_SHIFT_W32(CQ11,11-shft); // Scale with StepSize, Q11
for (k=0; k<PITCH_SUBFRAMES; k++) {
tmp32a = WEBRTC_SPL_MUL_16_32_RSFT11(WebRtcIsacfix_kTransform[0][k], CQ11);
- tmp16a = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32a, 5);
+ tmp16a = (int16_t)(tmp32a >> 5);
PitchLags_Q7[k] = tmp16a;
}
CQ10 = mean_val2Q10[index[1]];
for (k=0; k<PITCH_SUBFRAMES; k++) {
tmp32b = (int32_t) WEBRTC_SPL_MUL_16_16_RSFT((int16_t) WebRtcIsacfix_kTransform[1][k], (int16_t) CQ10,10);
- tmp16c = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5);
+ tmp16c = (int16_t)(tmp32b >> 5);
PitchLags_Q7[k] += tmp16c;
}
CQ10 = mean_val4Q10[index[3]];
for (k=0; k<PITCH_SUBFRAMES; k++) {
tmp32b = (int32_t) WEBRTC_SPL_MUL_16_16_RSFT((int16_t) WebRtcIsacfix_kTransform[3][k], (int16_t) CQ10,10);
- tmp16c = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5);
+ tmp16c = (int16_t)(tmp32b >> 5);
PitchLags_Q7[k] += tmp16c;
}
@@ -1775,7 +1774,7 @@ int WebRtcIsacfix_EncodePitchLag(int16_t *PitchLagsQ7,int16_t *PitchGain_Q12,
for (k = 0; k < 4; k++)
meangainQ12 += PitchGain_Q12[k];
- meangainQ12 = WEBRTC_SPL_RSHIFT_W32(meangainQ12, 2);
+ meangainQ12 >>= 2;
/* Save data for creation of multiple bitstreams */
if (encData != NULL) {
@@ -1817,7 +1816,7 @@ int WebRtcIsacfix_EncodePitchLag(int16_t *PitchLagsQ7,int16_t *PitchGain_Q12,
CQ17 = WEBRTC_SPL_SHIFT_W32(CQ17,shft); // Scale with StepSize
/* quantize */
- tmp16b = (int16_t) WEBRTC_SPL_RSHIFT_W32(CQ17 + 65536, 17 );
+ tmp16b = (int16_t)((CQ17 + 65536) >> 17);
index[k] = tmp16b;
/* check that the index is not outside the boundaries of the table */
@@ -1837,21 +1836,21 @@ int WebRtcIsacfix_EncodePitchLag(int16_t *PitchLagsQ7,int16_t *PitchGain_Q12,
for (k=0; k<PITCH_SUBFRAMES; k++) {
tmp32a = WEBRTC_SPL_MUL_16_32_RSFT11(WebRtcIsacfix_kTransform[0][k], CQ11); // Q12
- tmp16a = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32a, 5);// Q7
+ tmp16a = (int16_t)(tmp32a >> 5); // Q7.
PitchLagsQ7[k] = tmp16a;
}
CQ10 = mean_val2Q10[index[1]];
for (k=0; k<PITCH_SUBFRAMES; k++) {
tmp32b = (int32_t) WEBRTC_SPL_MUL_16_16_RSFT((int16_t) WebRtcIsacfix_kTransform[1][k], (int16_t) CQ10,10);
- tmp16c = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); // Q7
+ tmp16c = (int16_t)(tmp32b >> 5); // Q7.
PitchLagsQ7[k] += tmp16c;
}
CQ10 = mean_val4Q10[index[3]];
for (k=0; k<PITCH_SUBFRAMES; k++) {
tmp32b = (int32_t) WEBRTC_SPL_MUL_16_16_RSFT((int16_t) WebRtcIsacfix_kTransform[3][k], (int16_t) CQ10,10);
- tmp16c = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); // Q7
+ tmp16c = (int16_t)(tmp32b >> 5); // Q7.
PitchLagsQ7[k] += tmp16c;
}
diff --git a/modules/audio_coding/codecs/isac/fix/source/filterbanks.c b/modules/audio_coding/codecs/isac/fix/source/filterbanks.c
index 8be427af..cbaaae80 100644
--- a/modules/audio_coding/codecs/isac/fix/source/filterbanks.c
+++ b/modules/audio_coding/codecs/isac/fix/source/filterbanks.c
@@ -141,7 +141,7 @@ void WebRtcIsacfix_HighpassFilterFixDec32C(int16_t *io,
(WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[2], state1) >> 16);
#endif
- c = ((int32_t)in) + WEBRTC_SPL_RSHIFT_W32(a1+b1, 7); // Q0
+ c = in + ((a1 + b1) >> 7); // Q0.
io[k] = (int16_t)WebRtcSpl_SatW32ToW16(c); // Write output as Q0.
c = WEBRTC_SPL_LSHIFT_W32((int32_t)in, 2) - a2 - b2; // In Q2.
@@ -223,9 +223,9 @@ void WebRtcIsacfix_SplitAndFilter1(int16_t *pin,
int32_t tmp1, tmp2, tmp3;
tmp1 = (int32_t)tempin_ch1[k]; // Q0 -> Q0
tmp2 = (int32_t)tempin_ch2[k]; // Q0 -> Q0
- tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/
+ tmp3 = (tmp1 + tmp2) >> 1; /* Low pass signal. */
LP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*low pass */
- tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/
+ tmp3 = (tmp1 - tmp2) >> 1; /* High pass signal. */
HP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*high pass */
}
@@ -282,9 +282,9 @@ void WebRtcIsacfix_SplitAndFilter2(int16_t *pin,
int32_t tmp1, tmp2, tmp3;
tmp1 = (int32_t)tempin_ch1[k]; // Q0 -> Q0
tmp2 = (int32_t)tempin_ch2[k]; // Q0 -> Q0
- tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/
+ tmp3 = (tmp1 + tmp2) >> 1; /* Low pass signal. */
LP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*low pass */
- tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/
+ tmp3 = (tmp1 - tmp2) >> 1; /* High pass signal. */
HP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*high pass */
}
diff --git a/modules/audio_coding/codecs/isac/fix/source/filters.c b/modules/audio_coding/codecs/isac/fix/source/filters.c
index cf92a4d1..2a74fc0f 100644
--- a/modules/audio_coding/codecs/isac/fix/source/filters.c
+++ b/modules/audio_coding/codecs/isac/fix/source/filters.c
@@ -76,13 +76,12 @@ static void AllpassFilterForDec32(int16_t *InOut16, //Q0
a = WEBRTC_SPL_MUL_16_32_RSFT16(InOut16[n], APSectionFactors[j]); //Q0*Q31=Q31 shifted 16 gives Q15
a = WEBRTC_SPL_LSHIFT_W32(a, 1); // Q15 -> Q16
b = WebRtcSpl_AddSatW32(a, FilterState[j]); //Q16+Q16=Q16
- a = WEBRTC_SPL_MUL_16_32_RSFT16(
- (int16_t) WEBRTC_SPL_RSHIFT_W32(b, 16),
- -APSectionFactors[j]); //Q0*Q31=Q31 shifted 16 gives Q15
+ // |a| in Q15 (Q0*Q31=Q31 shifted 16 gives Q15).
+ a = WEBRTC_SPL_MUL_16_32_RSFT16(b >> 16, -APSectionFactors[j]);
FilterState[j] = WebRtcSpl_AddSatW32(
WEBRTC_SPL_LSHIFT_W32(a,1),
WEBRTC_SPL_LSHIFT_W32((uint32_t)InOut16[n], 16)); // Q15<<1 + Q0<<16 = Q16 + Q16 = Q16
- InOut16[n] = (int16_t) WEBRTC_SPL_RSHIFT_W32(b, 16); //Save as Q0
+ InOut16[n] = (int16_t)(b >> 16); // Save as Q0.
}
}
}
@@ -102,7 +101,7 @@ void WebRtcIsacfix_DecimateAllpass32(const int16_t *in,
memcpy(data_vec+1, in, WEBRTC_SPL_MUL_16_16(sizeof(int16_t), (N-1)));
- data_vec[0] = (int16_t) WEBRTC_SPL_RSHIFT_W32(state_in[WEBRTC_SPL_MUL_16_16(2, ALLPASSSECTIONS)],16); //the z^(-1) state
+ data_vec[0] = (int16_t)(state_in[2 * ALLPASSSECTIONS] >> 16); // z^-1 state.
state_in[WEBRTC_SPL_MUL_16_16(2, ALLPASSSECTIONS)] = WEBRTC_SPL_LSHIFT_W32((uint32_t)in[N-1],16);
diff --git a/modules/audio_coding/codecs/isac/fix/source/isacfix.c b/modules/audio_coding/codecs/isac/fix/source/isacfix.c
index 1c1a7201..5e8fd4f0 100644
--- a/modules/audio_coding/codecs/isac/fix/source/isacfix.c
+++ b/modules/audio_coding/codecs/isac/fix/source/isacfix.c
@@ -345,6 +345,35 @@ int16_t WebRtcIsacfix_EncoderInit(ISACFIX_MainStruct *ISAC_main_inst,
return statusInit;
}
+/* Read the given number of bytes of big-endian 16-bit integers from |src| and
+ write them to |dest| in host endian. If |nbytes| is odd, the number of
+ output elements is rounded up, and the least significant byte of the last
+ element is set to 0. */
+static void read_be16(const uint8_t* src, size_t nbytes, uint16_t* dest) {
+ size_t i;
+ for (i = 0; i < nbytes / 2; ++i)
+ dest[i] = src[2 * i] << 8 | src[2 * i + 1];
+ if (nbytes % 2 == 1)
+ dest[nbytes / 2] = src[nbytes - 1] << 8;
+}
+
+/* Read the given number of bytes of host-endian 16-bit integers from |src| and
+ write them to |dest| in big endian. If |nbytes| is odd, the number of source
+ elements is rounded up (but only the most significant byte of the last
+ element is used), and the number of output bytes written will be
+ nbytes + 1. */
+static void write_be16(const uint16_t* src, size_t nbytes, uint8_t* dest) {
+ size_t i;
+ for (i = 0; i < nbytes / 2; ++i) {
+ dest[2 * i] = src[i] >> 8;
+ dest[2 * i + 1] = src[i];
+ }
+ if (nbytes % 2 == 1) {
+ dest[nbytes - 1] = src[nbytes / 2] >> 8;
+ dest[nbytes] = 0;
+ }
+}
+
/****************************************************************************
* WebRtcIsacfix_Encode(...)
*
@@ -372,10 +401,7 @@ int16_t WebRtcIsacfix_Encode(ISACFIX_MainStruct *ISAC_main_inst,
uint8_t* encoded)
{
ISACFIX_SubStruct *ISAC_inst;
- int16_t stream_len, stream_len_even;
-#ifndef WEBRTC_ARCH_BIG_ENDIAN
- int k;
-#endif
+ int16_t stream_len;
/* typecast pointer to rela structure */
ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
@@ -396,29 +422,7 @@ int16_t WebRtcIsacfix_Encode(ISACFIX_MainStruct *ISAC_main_inst,
return -1;
}
- /* One would think that only even stream lengths would make sense here. We do
- in fact observe odd lengths, however, and in those cases we copy an extra
- byte. */
- stream_len_even = stream_len % 2 == 0 ? stream_len : stream_len + 1;
-
- /* convert from bytes to int16_t */
-#ifndef WEBRTC_ARCH_BIG_ENDIAN
- /* The encoded data vector is supposesd to be big-endian, but our internal
- representation is little-endian. So byteswap. */
- for (k = 0; k < stream_len_even / 2; ++k) {
- uint16_t s = ISAC_inst->ISACenc_obj.bitstr_obj.stream[k];
- /* In big-endian, we have... */
- encoded[2 * k] = s >> 8; /* ...most significant byte at low address... */
- encoded[2 * k + 1] = s; /* ...least significant byte at high address. */
- }
-#else
- /* The encoded data vector and our internal representation are both
- big-endian. */
- memcpy(encoded, ISAC_inst->ISACenc_obj.bitstr_obj.stream, stream_len_even);
-#endif
-
-
-
+ write_be16(ISAC_inst->ISACenc_obj.bitstr_obj.stream, stream_len, encoded);
return stream_len;
}
@@ -495,20 +499,9 @@ int16_t WebRtcIsacfix_EncodeNb(ISACFIX_MainStruct *ISAC_main_inst,
return -1;
}
-
- /* convert from bytes to int16_t */
-#ifndef WEBRTC_ARCH_BIG_ENDIAN
- for (k=0;k<(stream_len+1)>>1;k++) {
- encoded[k] = (int16_t)(((uint16_t)(ISAC_inst->ISACenc_obj.bitstr_obj).stream[k] >> 8)
- | (((ISAC_inst->ISACenc_obj.bitstr_obj).stream[k] & 0x00FF) << 8));
- }
-
-#else
- WEBRTC_SPL_MEMCPY_W16(encoded, (ISAC_inst->ISACenc_obj.bitstr_obj).stream, (stream_len + 1)>>1);
-#endif
-
-
-
+ write_be16(ISAC_inst->ISACenc_obj.bitstr_obj.stream,
+ stream_len,
+ (uint8_t*)encoded);
return stream_len;
}
#endif /* WEBRTC_ISAC_FIX_NB_CALLS_ENABLED */
@@ -540,9 +533,6 @@ int16_t WebRtcIsacfix_GetNewBitStream(ISACFIX_MainStruct *ISAC_main_inst,
{
ISACFIX_SubStruct *ISAC_inst;
int16_t stream_len;
-#ifndef WEBRTC_ARCH_BIG_ENDIAN
- int k;
-#endif
/* typecast pointer to rela structure */
ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
@@ -562,19 +552,8 @@ int16_t WebRtcIsacfix_GetNewBitStream(ISACFIX_MainStruct *ISAC_main_inst,
return -1;
}
-#ifndef WEBRTC_ARCH_BIG_ENDIAN
- for (k=0;k<(stream_len+1)>>1;k++) {
- ((int16_t*)encoded)[k] = (int16_t)(
- ((uint16_t)(ISAC_inst->ISACenc_obj.bitstr_obj).stream[k] >> 8) |
- (((ISAC_inst->ISACenc_obj.bitstr_obj).stream[k] & 0x00FF) << 8));
- }
-
-#else
- WEBRTC_SPL_MEMCPY_W16(encoded, (ISAC_inst->ISACenc_obj.bitstr_obj).stream, (stream_len + 1)>>1);
-#endif
-
+ write_be16(ISAC_inst->ISACenc_obj.bitstr_obj.stream, stream_len, encoded);
return stream_len;
-
}
@@ -643,9 +622,6 @@ int16_t WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_MainStruct *ISAC_main_inst,
{
ISACFIX_SubStruct *ISAC_inst;
Bitstr_dec streamdata;
-#ifndef WEBRTC_ARCH_BIG_ENDIAN
- int k;
-#endif
int16_t err;
const int kRequiredEncodedLenBytes = 10;
@@ -671,14 +647,7 @@ int16_t WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_MainStruct *ISAC_main_inst,
InitializeDecoderBitstream(packet_size, &streamdata);
-#ifndef WEBRTC_ARCH_BIG_ENDIAN
- for (k = 0; k < kRequiredEncodedLenBytes / 2; k++) {
- uint16_t ek = ((const uint16_t*)encoded)[k];
- streamdata.stream[k] = (uint16_t) ((ek >> 8)|((ek & 0xff) << 8));
- }
-#else
- memcpy(streamdata.stream, encoded, kRequiredEncodedLenBytes);
-#endif
+ read_be16(encoded, kRequiredEncodedLenBytes, streamdata.stream);
err = WebRtcIsacfix_EstimateBandwidth(&ISAC_inst->bwestimator_obj,
&streamdata,
@@ -726,9 +695,6 @@ int16_t WebRtcIsacfix_UpdateBwEstimate(ISACFIX_MainStruct *ISAC_main_inst,
{
ISACFIX_SubStruct *ISAC_inst;
Bitstr_dec streamdata;
-#ifndef WEBRTC_ARCH_BIG_ENDIAN
- int k;
-#endif
int16_t err;
const int kRequiredEncodedLenBytes = 10;
@@ -757,14 +723,7 @@ int16_t WebRtcIsacfix_UpdateBwEstimate(ISACFIX_MainStruct *ISAC_main_inst,
InitializeDecoderBitstream(packet_size, &streamdata);
-#ifndef WEBRTC_ARCH_BIG_ENDIAN
- for (k = 0; k < kRequiredEncodedLenBytes / 2; k++) {
- uint16_t ek = ((const uint16_t*)encoded)[k];
- streamdata.stream[k] = (uint16_t) ((ek >> 8)|((ek & 0xff) <<8 ));
- }
-#else
- memcpy(streamdata.stream, encoded, kRequiredEncodedLenBytes);
-#endif
+ read_be16(encoded, kRequiredEncodedLenBytes, streamdata.stream);
err = WebRtcIsacfix_EstimateBandwidth(&ISAC_inst->bwestimator_obj,
&streamdata,
@@ -814,9 +773,6 @@ int16_t WebRtcIsacfix_Decode(ISACFIX_MainStruct *ISAC_main_inst,
/* number of samples (480 or 960), output from decoder */
/* that were actually used in the encoder/decoder (determined on the fly) */
int16_t number_of_samples;
-#ifndef WEBRTC_ARCH_BIG_ENDIAN
- int k;
-#endif
int16_t declen = 0;
/* typecast pointer to real structure */
@@ -841,19 +797,7 @@ int16_t WebRtcIsacfix_Decode(ISACFIX_MainStruct *ISAC_main_inst,
InitializeDecoderBitstream(len, &ISAC_inst->ISACdec_obj.bitstr_obj);
- /* convert bitstream from int16_t to bytes */
-#ifndef WEBRTC_ARCH_BIG_ENDIAN
- for (k=0; k<(len>>1); k++) {
- uint16_t ek = ((const uint16_t*)encoded)[k];
- ISAC_inst->ISACdec_obj.bitstr_obj.stream[k] =
- (uint16_t)((ek >> 8) | ((ek & 0xff) << 8));
- }
- if (len & 0x0001)
- ISAC_inst->ISACdec_obj.bitstr_obj.stream[k] =
- (uint16_t)((((const uint16_t*)encoded)[k] & 0xff) << 8);
-#else
- memcpy(ISAC_inst->ISACdec_obj.bitstr_obj.stream, encoded, len);
-#endif
+ read_be16(encoded, len, ISAC_inst->ISACdec_obj.bitstr_obj.stream);
/* added for NetEq purposes (VAD/DTX related) */
*speechType=1;
@@ -922,9 +866,6 @@ int16_t WebRtcIsacfix_DecodeNb(ISACFIX_MainStruct *ISAC_main_inst,
/* twice the number of samples (480 or 960), output from decoder */
/* that were actually used in the encoder/decoder (determined on the fly) */
int16_t number_of_samples;
-#ifndef WEBRTC_ARCH_BIG_ENDIAN
- int k;
-#endif
int16_t declen = 0;
int16_t dummy[FRAMESAMPLES/2];
@@ -950,16 +891,7 @@ int16_t WebRtcIsacfix_DecodeNb(ISACFIX_MainStruct *ISAC_main_inst,
InitializeDecoderBitstream(len, &ISAC_inst->ISACdec_obj.bitstr_obj);
- /* convert bitstream from int16_t to bytes */
-#ifndef WEBRTC_ARCH_BIG_ENDIAN
- for (k=0; k<(len>>1); k++) {
- (ISAC_inst->ISACdec_obj.bitstr_obj).stream[k] = (uint16_t) ((encoded[k] >> 8)|((encoded[k] & 0xFF)<<8));
- }
- if (len & 0x0001)
- (ISAC_inst->ISACdec_obj.bitstr_obj).stream[k] = (uint16_t) ((encoded[k] & 0xFF)<<8);
-#else
- memcpy(ISAC_inst->ISACdec_obj.bitstr_obj.stream, encoded, len);
-#endif
+ read_be16(encoded, len, ISAC_inst->ISACdec_obj.bitstr_obj.stream);
/* added for NetEq purposes (VAD/DTX related) */
*speechType=1;
@@ -1326,9 +1258,6 @@ int16_t WebRtcIsacfix_ReadFrameLen(const uint8_t* encoded,
int16_t* frameLength)
{
Bitstr_dec streamdata;
-#ifndef WEBRTC_ARCH_BIG_ENDIAN
- int k;
-#endif
int16_t err;
const int kRequiredEncodedLenBytes = 10;
@@ -1338,14 +1267,7 @@ int16_t WebRtcIsacfix_ReadFrameLen(const uint8_t* encoded,
InitializeDecoderBitstream(encoded_len_bytes, &streamdata);
-#ifndef WEBRTC_ARCH_BIG_ENDIAN
- for (k = 0; k < kRequiredEncodedLenBytes / 2; k++) {
- uint16_t ek = ((uint16_t*)encoded)[k];
- streamdata.stream[k] = (uint16_t)((ek >> 8) | ((ek & 0xff) << 8));
- }
-#else
- memcpy(streamdata.stream, encoded, kRequiredEncodedLenBytes);
-#endif
+ read_be16(encoded, kRequiredEncodedLenBytes, streamdata.stream);
/* decode frame length */
err = WebRtcIsacfix_DecodeFrameLen(&streamdata, frameLength);
@@ -1375,9 +1297,6 @@ int16_t WebRtcIsacfix_ReadBwIndex(const uint8_t* encoded,
int16_t* rateIndex)
{
Bitstr_dec streamdata;
-#ifndef WEBRTC_ARCH_BIG_ENDIAN
- int k;
-#endif
int16_t err;
const int kRequiredEncodedLenBytes = 10;
@@ -1387,14 +1306,7 @@ int16_t WebRtcIsacfix_ReadBwIndex(const uint8_t* encoded,
InitializeDecoderBitstream(encoded_len_bytes, &streamdata);
-#ifndef WEBRTC_ARCH_BIG_ENDIAN
- for (k = 0; k < kRequiredEncodedLenBytes / 2; k++) {
- uint16_t ek = ((uint16_t*)encoded)[k];
- streamdata.stream[k] = (uint16_t)((ek >> 8) | ((ek & 0xff) << 8));
- }
-#else
- memcpy(streamdata.stream, encoded, kRequiredEncodedLenBytes);
-#endif
+ read_be16(encoded, kRequiredEncodedLenBytes, streamdata.stream);
/* decode frame length, needed to get to the rateIndex in the bitstream */
err = WebRtcIsacfix_DecodeFrameLen(&streamdata, rateIndex);
diff --git a/modules/audio_coding/codecs/isac/fix/source/isacfix.gypi b/modules/audio_coding/codecs/isac/fix/source/isacfix.gypi
index 7bef170d..2a36309f 100644
--- a/modules/audio_coding/codecs/isac/fix/source/isacfix.gypi
+++ b/modules/audio_coding/codecs/isac/fix/source/isacfix.gypi
@@ -87,7 +87,7 @@
'pitch_filter_c.c',
],
}],
- ['target_arch=="mipsel"', {
+ ['target_arch=="mipsel" and mips_arch_variant!="r6"', {
'sources': [
'entropy_coding_mips.c',
'filters_mips.c',
diff --git a/modules/audio_coding/codecs/isac/fix/source/lattice.c b/modules/audio_coding/codecs/isac/fix/source/lattice.c
index 6b3a6bfa..6bb987b9 100644
--- a/modules/audio_coding/codecs/isac/fix/source/lattice.c
+++ b/modules/audio_coding/codecs/isac/fix/source/lattice.c
@@ -136,7 +136,7 @@ void WebRtcIsacfix_NormLatticeFilterMa(int16_t orderCoef,
gain32 = WEBRTC_SPL_MUL_16_32_RSFT15(cthQ15[k], gain32); //Q15*Q(17+gain_sh)>>15 = Q(17+gain_sh)
inv_cthQ16[k] = WebRtcSpl_DivW32W16((int32_t)2147483647, cthQ15[k]); // 1/cth[k] in Q31/Q15 = Q16
}
- gain16 = (int16_t) WEBRTC_SPL_RSHIFT_W32(gain32, 16); //Q(1+gain_sh)
+ gain16 = (int16_t)(gain32 >> 16); // Q(1+gain_sh).
/* normalized lattice filter */
/*****************************/
@@ -158,7 +158,7 @@ void WebRtcIsacfix_NormLatticeFilterMa(int16_t orderCoef,
tmp32 = WEBRTC_SPL_MUL_16_32_RSFT15(sthQ15[i-1], stateGQ15[i-1]);//Q15*Q15>>15 = Q15
tmp32b= fQtmp + tmp32; //Q15+Q15=Q15
tmp32 = inv_cthQ16[i-1]; //Q16
- t16a = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32, 16);
+ t16a = (int16_t)(tmp32 >> 16);
t16b = (int16_t) (tmp32-WEBRTC_SPL_LSHIFT_W32(((int32_t)t16a), 16));
if (t16b<0) t16a++;
tmp32 = LATTICE_MUL_32_32_RSFT16(t16a, t16b, tmp32b);
@@ -186,7 +186,7 @@ void WebRtcIsacfix_NormLatticeFilterMa(int16_t orderCoef,
for(n=0;n<HALF_SUBFRAMELEN;n++)
{
- //gain32 = WEBRTC_SPL_RSHIFT_W32(gain32, gain_sh); // Q(17+gain_sh) -> Q17
+ //gain32 >>= gain_sh; // Q(17+gain_sh) -> Q17
tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(gain16, fQ15vec[n]); //Q(1+gain_sh)*Q15>>16 = Q(gain_sh)
sh = 9-gain_sh; //number of needed shifts to reach Q9
t16a = (int16_t) WEBRTC_SPL_SHIFT_W32(tmp32, sh);
@@ -267,7 +267,7 @@ void WebRtcIsacfix_NormLatticeFilterAr(int16_t orderCoef,
inv_gain32 = WebRtcSpl_DivW32W16((int32_t)2147483647, den16); // 1/gain in Q31/Q(sh+11) = Q(20-sh)
//initial conditions
- inv_gain16 = (int16_t) WEBRTC_SPL_RSHIFT_W32(inv_gain32, 2); // 1/gain in Q(20-sh-2) = Q(18-sh)
+ inv_gain16 = (int16_t)(inv_gain32 >> 2); // 1/gain in Q(20-sh-2) = Q(18-sh)
for (i=0;i<HALF_SUBFRAMELEN;i++)
{
@@ -281,10 +281,10 @@ void WebRtcIsacfix_NormLatticeFilterAr(int16_t orderCoef,
for (i=orderCoef-1;i>=0;i--) //get the state of f&g for the first input, for all orders
{
- tmp32 = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16(cthQ15[i],ARfQ0vec[0])) - (WEBRTC_SPL_MUL_16_16(sthQ15[i],stateGQ0[i])) + 16384), 15);
+ tmp32 = (cthQ15[i] * ARfQ0vec[0] - sthQ15[i] * stateGQ0[i] + 16384) >> 15;
tmpAR = (int16_t)WebRtcSpl_SatW32ToW16(tmp32); // Q0
- tmp32 = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16(sthQ15[i],ARfQ0vec[0])) + (WEBRTC_SPL_MUL_16_16(cthQ15[i], stateGQ0[i])) + 16384), 15);
+ tmp32 = (sthQ15[i] * ARfQ0vec[0] + cthQ15[i] * stateGQ0[i] + 16384) >> 15;
ARgQ0vec[i+1] = (int16_t)WebRtcSpl_SatW32ToW16(tmp32); // Q0
ARfQ0vec[0] = tmpAR;
}
diff --git a/modules/audio_coding/codecs/isac/fix/source/lattice_c.c b/modules/audio_coding/codecs/isac/fix/source/lattice_c.c
index d7d198ca..8c53b0bf 100644
--- a/modules/audio_coding/codecs/isac/fix/source/lattice_c.c
+++ b/modules/audio_coding/codecs/isac/fix/source/lattice_c.c
@@ -36,10 +36,8 @@ void WebRtcIsacfix_FilterArLoop(int16_t* ar_g_Q0, // Input samples
tmpAR = ar_f_Q0[n + 1];
for (k = order_coef - 1; k >= 0; k--) {
- tmp32 = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16(cth_Q15[k], tmpAR))
- - (WEBRTC_SPL_MUL_16_16(sth_Q15[k], ar_g_Q0[k])) + 16384), 15);
- tmp32_2 = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16(sth_Q15[k], tmpAR))
- + (WEBRTC_SPL_MUL_16_16(cth_Q15[k], ar_g_Q0[k])) + 16384), 15);
+ tmp32 = (cth_Q15[k] * tmpAR - sth_Q15[k] * ar_g_Q0[k] + 16384) >> 15;
+ tmp32_2 = (sth_Q15[k] * tmpAR + cth_Q15[k] * ar_g_Q0[k] + 16384) >> 15;
tmpAR = (int16_t)WebRtcSpl_SatW32ToW16(tmp32);
ar_g_Q0[k + 1] = (int16_t)WebRtcSpl_SatW32ToW16(tmp32_2);
}
diff --git a/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.c b/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.c
index dba92f88..555cca0f 100644
--- a/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.c
+++ b/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.c
@@ -39,7 +39,7 @@ void WebRtcSpl_AToK_JSK(
for (m=useOrder-1; m>0; m--) {
tmp_inv_denum32 = ((int32_t) 1073741823) - WEBRTC_SPL_MUL_16_16(k16[m], k16[m]); // (1 - k^2) in Q30
- tmp_inv_denum16 = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp_inv_denum32, 15); // (1 - k^2) in Q15
+ tmp_inv_denum16 = (int16_t)(tmp_inv_denum32 >> 15); // (1 - k^2) in Q15.
for (k=1; k<=m; k++) {
tmp32b = WEBRTC_SPL_LSHIFT_W32((int32_t)a16[k], 16) -
@@ -49,7 +49,7 @@ void WebRtcSpl_AToK_JSK(
}
for (k=1; k<m; k++) {
- a16[k] = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32[k], 1); //Q12>>1 => Q11
+ a16[k] = (int16_t)(tmp32[k] >> 1); // Q12>>1 => Q11
}
tmp32[m] = WEBRTC_SPL_SAT(4092, tmp32[m], -4092);
@@ -90,8 +90,8 @@ int16_t WebRtcSpl_LevinsonW32_JSK(
for (i=order;i>=0;i--) {
temp1W32 = WEBRTC_SPL_LSHIFT_W32(R[i], norm);
/* Put R in hi and low format */
- R_hi[i] = (int16_t) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
- R_low[i] = (int16_t)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((int32_t)R_hi[i], 16)), 1);
+ R_hi[i] = (int16_t)(temp1W32 >> 16);
+ R_low[i] = (int16_t)((temp1W32 - ((int32_t)R_hi[i] << 16)) >> 1);
}
/* K = A[1] = -R[1] / R[0] */
@@ -106,41 +106,39 @@ int16_t WebRtcSpl_LevinsonW32_JSK(
}
/* Put K in hi and low format */
- K_hi = (int16_t) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
- K_low = (int16_t)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((int32_t)K_hi, 16)), 1);
+ K_hi = (int16_t)(temp1W32 >> 16);
+ K_low = (int16_t)((temp1W32 - ((int32_t)K_hi << 16)) >> 1);
/* Store first reflection coefficient */
K[0] = K_hi;
- temp1W32 = WEBRTC_SPL_RSHIFT_W32(temp1W32, 4); /* A[1] in Q27 */
+ temp1W32 >>= 4; /* A[1] in Q27. */
/* Put A[1] in hi and low format */
- A_hi[1] = (int16_t) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
- A_low[1] = (int16_t)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((int32_t)A_hi[1], 16)), 1);
+ A_hi[1] = (int16_t)(temp1W32 >> 16);
+ A_low[1] = (int16_t)((temp1W32 - ((int32_t)A_hi[1] << 16)) >> 1);
/* Alpha = R[0] * (1-K^2) */
- temp1W32 = WEBRTC_SPL_LSHIFT_W32((WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(K_hi, K_low), 14) +
- WEBRTC_SPL_MUL_16_16(K_hi, K_hi)), 1); /* temp1W32 = k^2 in Q31 */
+ temp1W32 = (((K_hi * K_low) >> 14) + K_hi * K_hi) << 1; /* = k^2 in Q31 */
temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); /* Guard against <0 */
temp1W32 = (int32_t)0x7fffffffL - temp1W32; /* temp1W32 = (1 - K[0]*K[0]) in Q31 */
/* Store temp1W32 = 1 - K[0]*K[0] on hi and low format */
- tmp_hi = (int16_t) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
- tmp_low = (int16_t)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((int32_t)tmp_hi, 16)), 1);
+ tmp_hi = (int16_t)(temp1W32 >> 16);
+ tmp_low = (int16_t)((temp1W32 - ((int32_t)tmp_hi << 16)) >> 1);
/* Calculate Alpha in Q31 */
- temp1W32 = WEBRTC_SPL_LSHIFT_W32((WEBRTC_SPL_MUL_16_16(R_hi[0], tmp_hi) +
- WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(R_hi[0], tmp_low), 15) +
- WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(R_low[0], tmp_hi), 15) ), 1);
+ temp1W32 = (R_hi[0] * tmp_hi + ((R_hi[0] * tmp_low) >> 15) +
+ ((R_low[0] * tmp_hi) >> 15)) << 1;
/* Normalize Alpha and put it in hi and low format */
Alpha_exp = WebRtcSpl_NormW32(temp1W32);
temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, Alpha_exp);
- Alpha_hi = (int16_t) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
- Alpha_low = (int16_t)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((int32_t)Alpha_hi, 16)), 1);
+ Alpha_hi = (int16_t)(temp1W32 >> 16);
+ Alpha_low = (int16_t)((temp1W32 - ((int32_t)Alpha_hi<< 16)) >> 1);
/* Perform the iterative calculations in the
Levinson Durbin algorithm */
@@ -150,7 +148,7 @@ int16_t WebRtcSpl_LevinsonW32_JSK(
/* ----
\
- temp1W32 = R[i] + > R[j]*A[i-j]
+ temp1W32 = R[i] + > R[j]*A[i-j]
/
----
j=1..i-1
@@ -160,9 +158,9 @@ int16_t WebRtcSpl_LevinsonW32_JSK(
for(j=1; j<i; j++) {
/* temp1W32 is in Q31 */
- temp1W32 += (WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(R_hi[j], A_hi[i-j]), 1) +
- WEBRTC_SPL_LSHIFT_W32(( WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(R_hi[j], A_low[i-j]), 15) +
- WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(R_low[j], A_hi[i-j]), 15) ), 1));
+ temp1W32 += ((R_hi[j] * A_hi[i - j]) << 1) +
+ ((((R_hi[j] * A_low[i - j]) >> 15) +
+ ((R_low[j] * A_hi[i - j]) >> 15)) << 1);
}
temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, 4);
@@ -193,8 +191,8 @@ int16_t WebRtcSpl_LevinsonW32_JSK(
}
/* Put K on hi and low format */
- K_hi = (int16_t) WEBRTC_SPL_RSHIFT_W32(temp3W32, 16);
- K_low = (int16_t)WEBRTC_SPL_RSHIFT_W32((temp3W32 - WEBRTC_SPL_LSHIFT_W32((int32_t)K_hi, 16)), 1);
+ K_hi = (int16_t)(temp3W32 >> 16);
+ K_low = (int16_t)((temp3W32 - ((int32_t)K_hi << 16)) >> 1);
/* Store Reflection coefficient in Q15 */
K[i-1] = K_hi;
@@ -218,45 +216,42 @@ int16_t WebRtcSpl_LevinsonW32_JSK(
temp1W32 = WEBRTC_SPL_LSHIFT_W32((int32_t)A_hi[j],16) +
WEBRTC_SPL_LSHIFT_W32((int32_t)A_low[j],1); /* temp1W32 = A[j] in Q27 */
- temp1W32 += WEBRTC_SPL_LSHIFT_W32(( WEBRTC_SPL_MUL_16_16(K_hi, A_hi[i-j]) +
- WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(K_hi, A_low[i-j]), 15) +
- WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(K_low, A_hi[i-j]), 15) ), 1); /* temp1W32 += K*A[i-j] in Q27 */
+ temp1W32 += (K_hi * A_hi[i - j] + ((K_hi * A_low[i - j]) >> 15) +
+ ((K_low * A_hi[i - j]) >> 15)) << 1; // temp1W32 += K*A[i-j] in Q27.
/* Put Anew in hi and low format */
- A_upd_hi[j] = (int16_t) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
- A_upd_low[j] = (int16_t)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((int32_t)A_upd_hi[j], 16)), 1);
+ A_upd_hi[j] = (int16_t)(temp1W32 >> 16);
+ A_upd_low[j] = (int16_t)((temp1W32 - ((int32_t)A_upd_hi[j] << 16)) >> 1);
}
- temp3W32 = WEBRTC_SPL_RSHIFT_W32(temp3W32, 4); /* temp3W32 = K in Q27 (Convert from Q31 to Q27) */
+ temp3W32 >>= 4; /* temp3W32 = K in Q27 (Convert from Q31 to Q27) */
/* Store Anew in hi and low format */
- A_upd_hi[i] = (int16_t) WEBRTC_SPL_RSHIFT_W32(temp3W32, 16);
- A_upd_low[i] = (int16_t)WEBRTC_SPL_RSHIFT_W32((temp3W32 - WEBRTC_SPL_LSHIFT_W32((int32_t)A_upd_hi[i], 16)), 1);
+ A_upd_hi[i] = (int16_t)(temp3W32 >> 16);
+ A_upd_low[i] = (int16_t)((temp3W32 - ((int32_t)A_upd_hi[i] << 16)) >> 1);
/* Alpha = Alpha * (1-K^2) */
- temp1W32 = WEBRTC_SPL_LSHIFT_W32((WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(K_hi, K_low), 14) +
- WEBRTC_SPL_MUL_16_16(K_hi, K_hi)), 1); /* K*K in Q31 */
+ temp1W32 = (((K_hi * K_low) >> 14) + K_hi * K_hi) << 1; /* K*K in Q31 */
temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); /* Guard against <0 */
temp1W32 = (int32_t)0x7fffffffL - temp1W32; /* 1 - K*K in Q31 */
/* Convert 1- K^2 in hi and low format */
- tmp_hi = (int16_t) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
- tmp_low = (int16_t)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((int32_t)tmp_hi, 16)), 1);
+ tmp_hi = (int16_t)(temp1W32 >> 16);
+ tmp_low = (int16_t)((temp1W32 - ((int32_t)tmp_hi << 16)) >> 1);
/* Calculate Alpha = Alpha * (1-K^2) in Q31 */
- temp1W32 = WEBRTC_SPL_LSHIFT_W32(( WEBRTC_SPL_MUL_16_16(Alpha_hi, tmp_hi) +
- WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(Alpha_hi, tmp_low), 15) +
- WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(Alpha_low, tmp_hi), 15)), 1);
+ temp1W32 = (Alpha_hi * tmp_hi + ((Alpha_hi * tmp_low) >> 15) +
+ ((Alpha_low * tmp_hi) >> 15)) << 1;
/* Normalize Alpha and store it on hi and low format */
norm = WebRtcSpl_NormW32(temp1W32);
temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, norm);
- Alpha_hi = (int16_t) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
- Alpha_low = (int16_t)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((int32_t)Alpha_hi, 16)), 1);
+ Alpha_hi = (int16_t)(temp1W32 >> 16);
+ Alpha_low = (int16_t)((temp1W32 - ((int32_t)Alpha_hi << 16)) >> 1);
/* Update the total nomalization of Alpha */
Alpha_exp = Alpha_exp + norm;
@@ -282,7 +277,7 @@ int16_t WebRtcSpl_LevinsonW32_JSK(
temp1W32 = WEBRTC_SPL_LSHIFT_W32((int32_t)A_hi[i], 16) +
WEBRTC_SPL_LSHIFT_W32((int32_t)A_low[i], 1);
/* Round and store upper word */
- A[i] = (int16_t)WEBRTC_SPL_RSHIFT_W32(temp1W32+(int32_t)32768, 16);
+ A[i] = (int16_t)((temp1W32 + 32768) >> 16);
}
return(1); /* Stable filters */
}
@@ -350,7 +345,7 @@ static __inline int32_t log2_Q8_LPC( uint32_t x ) {
int16_t frac;
zeros=WebRtcSpl_NormU32(x);
- frac=(int16_t)WEBRTC_SPL_RSHIFT_W32(((uint32_t)WEBRTC_SPL_LSHIFT_W32(x, zeros)&0x7FFFFFFF), 23);
+ frac = (int16_t)(((x << zeros) & 0x7FFFFFFF) >> 23);
/* log2(x) */
return ((31 - zeros) << 8) + frac;
@@ -601,9 +596,7 @@ void WebRtcIsacfix_GetLpcCoef(int16_t *inLoQ0,
With 0.35 in Q16 (0.35 ~= 22938/65536.0 = 0.3500061) and varscaleQ14 in Q14,
we get Q16*Q14>>16 = Q14
*/
- aaQ14 = (int16_t) WEBRTC_SPL_RSHIFT_W32(
- (WEBRTC_SPL_MUL_16_16(22938, (8192 + WEBRTC_SPL_RSHIFT_W32(varscaleQ14, 1)))
- + ((int32_t)32768)), 16);
+ aaQ14 = (int16_t)((22938 * (8192 + (varscaleQ14 >> 1)) + 32768) >> 16);
/* Calculate tmp = (1.0 + aa*aa); in Q12 */
tmp16 = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(aaQ14, aaQ14, 15); //Q14*Q14>>15 = Q13
@@ -673,16 +666,16 @@ void WebRtcIsacfix_GetLpcCoef(int16_t *inLoQ0,
/* less noise for lower frequencies, by filtering/scaling autocorrelation sequences */
/* Calculate corrlo2[0] = tmpQQlo * corrlo[0] - 2.0*tmpQQlo * corrlo[1];*/
- corrlo2QQ[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(tmpQQlo, corrloQQ[0]), 1)- // Q(12+QdomLO-16)>>1 = Q(QdomLO-5)
- WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(aaQ14, corrloQQ[1]), 2); // 2*Q(14+QdomLO-16)>>3 = Q(QdomLO-2)>>2 = Q(QdomLO-5)
+ // |corrlo2QQ| in Q(QdomLO-5).
+ corrlo2QQ[0] = (WEBRTC_SPL_MUL_16_32_RSFT16(tmpQQlo, corrloQQ[0]) >> 1) -
+ (WEBRTC_SPL_MUL_16_32_RSFT16(aaQ14, corrloQQ[1]) >> 2);
/* Calculate corrlo2[n] = tmpQQlo * corrlo[n] - tmpQQlo * (corrlo[n-1] + corrlo[n+1]);*/
for (n = 1; n <= ORDERLO; n++) {
- tmp32 = WEBRTC_SPL_RSHIFT_W32(corrloQQ[n-1], 1) + WEBRTC_SPL_RSHIFT_W32(corrloQQ[n+1], 1); // Q(QdomLO-1)
- corrlo2QQ[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(tmpQQlo, corrloQQ[n]), 1)- // Q(12+QdomLO-16)>>1 = Q(QdomLO-5)
- WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(aaQ14, tmp32), 2); // Q(14+QdomLO-1-16)>>2 = Q(QdomLO-3)>>2 = Q(QdomLO-5)
-
+ tmp32 = (corrloQQ[n - 1] >> 1) + (corrloQQ[n + 1] >> 1); // Q(QdomLO-1).
+ corrlo2QQ[n] = (WEBRTC_SPL_MUL_16_32_RSFT16(tmpQQlo, corrloQQ[n]) >> 1) -
+ (WEBRTC_SPL_MUL_16_32_RSFT16(aaQ14, tmp32) >> 2);
}
QdomLO -= 5;
@@ -705,12 +698,12 @@ void WebRtcIsacfix_GetLpcCoef(int16_t *inLoQ0,
/* corrlo2QQ is in Q(QdomLO) and corrhiQQ is in Q(QdomHI) before the following
code segment, where we want to make sure we get a 1-bit margin */
for (n = 0; n <= ORDERLO; n++) {
- corrlo2QQ[n] = WEBRTC_SPL_RSHIFT_W32(corrlo2QQ[n], 1); // Make sure we have a 1-bit margin
+ corrlo2QQ[n] >>= 1; // Make sure we have a 1-bit margin.
}
QdomLO -= 1; // Now, corrlo2QQ is in Q(QdomLO), with a 1-bit margin
for (n = 0; n <= ORDERHI; n++) {
- corrhiQQ[n] = WEBRTC_SPL_RSHIFT_W32(corrhiQQ[n], 1); // Make sure we have a 1-bit margin
+ corrhiQQ[n] >>= 1; // Make sure we have a 1-bit margin.
}
QdomHI -= 1; // Now, corrhiQQ is in Q(QdomHI), with a 1-bit margin
@@ -738,7 +731,7 @@ void WebRtcIsacfix_GetLpcCoef(int16_t *inLoQ0,
// Shift |alpha| as much as possible without overflow the number of
// times required to get |tmp| in QdomLO.
tmp = WEBRTC_SPL_MUL_16_32_RSFT15(alpha << 6, tmp);
- tmpCorr = WEBRTC_SPL_RSHIFT_W32(corrloQQ[n], sh-shMem-6);
+ tmpCorr = corrloQQ[n] >> (sh - shMem - 6);
tmp = tmp + tmpCorr;
maskdata->CorrBufLoQQ[n] = tmp;
newQdomLO = QdomLO-(sh-shMem-6);
@@ -759,7 +752,7 @@ void WebRtcIsacfix_GetLpcCoef(int16_t *inLoQ0,
if( newQdomLO!=QdomLO) {
for (n = 0; n <= ORDERLO; n++) {
if (maskdata->CorrBufLoQdom[n] != newQdomLO)
- corrloQQ[n] = WEBRTC_SPL_RSHIFT_W32(corrloQQ[n], maskdata->CorrBufLoQdom[n]-newQdomLO);
+ corrloQQ[n] >>= maskdata->CorrBufLoQdom[n] - newQdomLO;
}
QdomLO = newQdomLO;
}
@@ -795,7 +788,7 @@ void WebRtcIsacfix_GetLpcCoef(int16_t *inLoQ0,
// Shift |alpha| as much as possible without overflow the number of
// times required to get |tmp| in QdomHI.
tmp = WEBRTC_SPL_MUL_16_32_RSFT15(alpha << 6, tmp);
- tmpCorr = WEBRTC_SPL_RSHIFT_W32(corrhiQQ[n], sh-shMem-6);
+ tmpCorr = corrhiQQ[n] >> (sh - shMem - 6);
tmp = tmp + tmpCorr;
maskdata->CorrBufHiQQ[n] = tmp;
newQdomHI = QdomHI-(sh-shMem-6);
@@ -816,7 +809,7 @@ void WebRtcIsacfix_GetLpcCoef(int16_t *inLoQ0,
if( newQdomHI!=QdomHI) {
for (n = 0; n <= ORDERHI; n++) {
if (maskdata->CorrBufHiQdom[n] != newQdomHI)
- corrhiQQ[n] = WEBRTC_SPL_RSHIFT_W32(corrhiQQ[n], maskdata->CorrBufHiQdom[n]-newQdomHI);
+ corrhiQQ[n] >>= maskdata->CorrBufHiQdom[n] - newQdomHI;
}
QdomHI = newQdomHI;
}
@@ -867,7 +860,7 @@ void WebRtcIsacfix_GetLpcCoef(int16_t *inLoQ0,
WebRtcSpl_AToK_JSK(a_LOQ11, ORDERLO, rcQ15_lo);
if (sh_lo & 0x0001) {
- res_nrgQQ=WEBRTC_SPL_RSHIFT_W32(res_nrgQQ, 1);
+ res_nrgQQ >>= 1;
sh_lo-=1;
}
@@ -916,7 +909,7 @@ void WebRtcIsacfix_GetLpcCoef(int16_t *inLoQ0,
WebRtcSpl_LpcToReflCoef(polyHI, ORDERHI, rcQ15_hi);
if (sh_hi & 0x0001) {
- res_nrgQQ=WEBRTC_SPL_RSHIFT_W32(res_nrgQQ, 1);
+ res_nrgQQ >>= 1;
sh_hi-=1;
}
@@ -930,9 +923,9 @@ void WebRtcIsacfix_GetLpcCoef(int16_t *inLoQ0,
/* hi_coeff = varscale * S_N_R / (sqrt_nrg + varscale * H_T_H); */
//tmp32a=WEBRTC_SPL_MUL_16_16_RSFT(varscaleQ14, H_T_HQ19, 17); // Q14
- tmp32a=WEBRTC_SPL_RSHIFT_W32((int32_t) varscaleQ14,1); // H_T_HQ19=65536 (16-17=-1)
+ tmp32a = varscaleQ14 >> 1; // H_T_HQ19=65536 (16-17=-1)
- ssh= WEBRTC_SPL_RSHIFT_W32(sh_hi, 1); // sqrt_nrg is in Qssh
+ ssh = sh_hi >> 1; // |sqrt_nrg| is in Qssh.
sh = ssh - 14;
tmp32b = WEBRTC_SPL_SHIFT_W32(tmp32a, sh); // Q14->Qssh
tmp32c = sqrt_nrg + tmp32b; // Qssh (denominator)
diff --git a/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.c b/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.c
index bdb54bba..a315c47a 100644
--- a/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.c
+++ b/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.c
@@ -32,7 +32,7 @@ int32_t WebRtcIsacfix_Log2Q8(uint32_t x) {
int16_t frac;
zeros=WebRtcSpl_NormU32(x);
- frac=(int16_t)WEBRTC_SPL_RSHIFT_W32(((uint32_t)(WEBRTC_SPL_LSHIFT_W32(x, zeros))&0x7FFFFFFF), 23);
+ frac = (int16_t)(((x << zeros) & 0x7FFFFFFF) >> 23);
/* log2(magn(i)) */
lg2= (WEBRTC_SPL_LSHIFT_W32((31-zeros), 8)+frac);
@@ -77,7 +77,7 @@ static __inline void Intrp1DQ8(int32_t *x, int32_t *fx, int32_t *y, int32_t *fy)
/* t in Q31, without signs */
t32 = WebRtcSpl_DivResultInQ31(nom32 * sign1, den32 * sign2);
- t16=(int16_t)WEBRTC_SPL_RSHIFT_W32(t32, 23); /* Q8 */
+ t16 = (int16_t)(t32 >> 23); /* Q8 */
t16=t16*sign1*sign2; /* t in Q8 with signs */
*y = x[0]+t16; /* Q8 */
@@ -327,7 +327,7 @@ void WebRtcIsacfix_InitialPitch(const int16_t *in, /* Q0 */
/* Bias towards constant pitch */
tmp32a = lagsQ8[0] - PITCH_MIN_LAG_Q8;
- ratq = WEBRTC_SPL_RSHIFT_W32(tmp32a, 1) + OFFSET_Q8;
+ ratq = (tmp32a >> 1) + OFFSET_Q8;
for (k = 1; k <= PITCH_LAG_SPAN2; k++)
{
@@ -335,7 +335,7 @@ void WebRtcIsacfix_InitialPitch(const int16_t *in, /* Q0 */
tmp32b = (int32_t) (WEBRTC_SPL_LSHIFT_W32(tmp32a, 1)) - ratq; // Q8
tmp32c = WEBRTC_SPL_MUL_16_16_RSFT((int16_t) tmp32b, (int16_t) tmp32b, 8); // Q8
- tmp32b = (int32_t)tmp32c + (int32_t)WEBRTC_SPL_RSHIFT_W32(ratq, 1);
+ tmp32b = tmp32c + (ratq >> 1);
// (k-r)^2 + 0.5 * r Q8
tmp32c = WebRtcIsacfix_Log2Q8((uint32_t)tmp32a) - 2048;
// offset 8*2^8 , log2(0.5*k) Q8
@@ -343,7 +343,7 @@ void WebRtcIsacfix_InitialPitch(const int16_t *in, /* Q0 */
// offset 8*2^8 , log2(0.5*k) Q8
tmp32e = tmp32c - tmp32d;
- cv2q[k] += WEBRTC_SPL_RSHIFT_W32(tmp32e, 1);
+ cv2q[k] += tmp32e >> 1;
}
@@ -401,12 +401,10 @@ void WebRtcIsacfix_InitialPitch(const int16_t *in, /* Q0 */
lagsQ8[3] = lagsQ8[0];
}
- lagsQ7[0]=(int16_t) WEBRTC_SPL_RSHIFT_W32(lagsQ8[0], 1);
- lagsQ7[1]=(int16_t) WEBRTC_SPL_RSHIFT_W32(lagsQ8[1], 1);
- lagsQ7[2]=(int16_t) WEBRTC_SPL_RSHIFT_W32(lagsQ8[2], 1);
- lagsQ7[3]=(int16_t) WEBRTC_SPL_RSHIFT_W32(lagsQ8[3], 1);
-
-
+ lagsQ7[0] = (int16_t)(lagsQ8[0] >> 1);
+ lagsQ7[1] = (int16_t)(lagsQ8[1] >> 1);
+ lagsQ7[2] = (int16_t)(lagsQ8[2] >> 1);
+ lagsQ7[3] = (int16_t)(lagsQ8[3] >> 1);
}
diff --git a/modules/audio_coding/codecs/isac/fix/source/pitch_estimator_c.c b/modules/audio_coding/codecs/isac/fix/source/pitch_estimator_c.c
index 82155d27..b3f9f2f4 100644
--- a/modules/audio_coding/codecs/isac/fix/source/pitch_estimator_c.c
+++ b/modules/audio_coding/codecs/isac/fix/source/pitch_estimator_c.c
@@ -44,8 +44,7 @@ void WebRtcIsacfix_PCorr2Q32(const int16_t* in, int32_t* logcorQ8) {
scaling); // Q0
}
logcorQ8 += PITCH_LAG_SPAN2 - 1;
- lys = WebRtcIsacfix_Log2Q8((uint32_t)ysum32); // Q8
- lys = WEBRTC_SPL_RSHIFT_W32(lys, 1); //sqrt(ysum);
+ lys = WebRtcIsacfix_Log2Q8((uint32_t)ysum32) >> 1; // Q8, sqrt(ysum)
if (csum32 > 0) {
lcs = WebRtcIsacfix_Log2Q8((uint32_t)csum32); // 2log(csum) in Q8
if (lcs > (lys + oneQ8)) { // csum/sqrt(ysum) > 2 in Q8
@@ -105,8 +104,7 @@ void WebRtcIsacfix_PCorr2Q32(const int16_t* in, int32_t* logcorQ8) {
logcorQ8--;
- lys = WebRtcIsacfix_Log2Q8((uint32_t)ysum32); // Q8
- lys = WEBRTC_SPL_RSHIFT_W32(lys, 1); //sqrt(ysum);
+ lys = WebRtcIsacfix_Log2Q8((uint32_t)ysum32) >> 1; // Q8, sqrt(ysum)
if (csum32 > 0) {
lcs = WebRtcIsacfix_Log2Q8((uint32_t)csum32); // 2log(csum) in Q8
diff --git a/modules/audio_coding/codecs/isac/fix/source/pitch_estimator_mips.c b/modules/audio_coding/codecs/isac/fix/source/pitch_estimator_mips.c
index fa426e98..2ce48887 100644
--- a/modules/audio_coding/codecs/isac/fix/source/pitch_estimator_mips.c
+++ b/modules/audio_coding/codecs/isac/fix/source/pitch_estimator_mips.c
@@ -86,8 +86,7 @@ void WebRtcIsacfix_PCorr2Q32(const int16_t* in, int32_t* logcorQ8) {
);
}
logcorQ8 += PITCH_LAG_SPAN2 - 1;
- lys = WebRtcIsacfix_Log2Q8((uint32_t)ysum32); // Q8
- lys = WEBRTC_SPL_RSHIFT_W32(lys, 1); //sqrt(ysum);
+ lys = WebRtcIsacfix_Log2Q8((uint32_t)ysum32) >> 1; // Q8, sqrt(ysum)
if (csum32 > 0) {
lcs = WebRtcIsacfix_Log2Q8((uint32_t)csum32); // 2log(csum) in Q8
if (lcs > (lys + oneQ8)) { // csum/sqrt(ysum) > 2 in Q8
@@ -180,8 +179,7 @@ void WebRtcIsacfix_PCorr2Q32(const int16_t* in, int32_t* logcorQ8) {
);
logcorQ8--;
- lys = WebRtcIsacfix_Log2Q8((uint32_t)ysum32); // Q8
- lys = WEBRTC_SPL_RSHIFT_W32(lys, 1); //sqrt(ysum);
+ lys = WebRtcIsacfix_Log2Q8((uint32_t)ysum32) >> 1; // Q8, sqrt(ysum)
if (csum32 > 0) {
lcs = WebRtcIsacfix_Log2Q8((uint32_t)csum32); // 2log(csum) in Q8
if (lcs > (lys + oneQ8)) { // csum/sqrt(ysum) > 2
diff --git a/modules/audio_coding/codecs/isac/fix/source/pitch_filter.c b/modules/audio_coding/codecs/isac/fix/source/pitch_filter.c
index ca810a56..d27daf33 100644
--- a/modules/audio_coding/codecs/isac/fix/source/pitch_filter.c
+++ b/modules/audio_coding/codecs/isac/fix/source/pitch_filter.c
@@ -53,7 +53,7 @@ static __inline int32_t CalcLrIntQ(int32_t fixVal,
int32_t roundVal;
roundVal = WEBRTC_SPL_LSHIFT_W32((int32_t)1, qDomain - 1);
- intgr = WEBRTC_SPL_RSHIFT_W32(fixVal + roundVal, qDomain);
+ intgr = (fixVal + roundVal) >> qDomain;
return intgr;
}
@@ -132,8 +132,7 @@ void WebRtcIsacfix_PitchFilter(int16_t* indatQQ, // Q10 if type is 1 or 4,
indW32 = CalcLrIntQ(curLagQ7, 7);
tmpW32 = WEBRTC_SPL_LSHIFT_W32(indW32, 7);
tmpW32 -= curLagQ7;
- frcQQ = WEBRTC_SPL_RSHIFT_W32(tmpW32, 4);
- frcQQ += 4;
+ frcQQ = (tmpW32 >> 4) + 4;
if (frcQQ == PITCH_FRACS) {
frcQQ = 0;
@@ -228,19 +227,17 @@ void WebRtcIsacfix_PitchFilterGains(const int16_t* indatQ0,
tmp2W32 = WEBRTC_SPL_MUL_16_32_RSFT14(indatQ0[ind], tmpW32);
tmpW32 += 8192;
- tmpW16 = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmpW32, 14);
+ tmpW16 = (int16_t)(tmpW32 >> 14);
tmpW32 = WEBRTC_SPL_MUL_16_16(tmpW16, tmpW16);
if ((tmp2W32 > 1073700000) || (csum1QQ > 1073700000) ||
(tmpW32 > 1073700000) || (esumxQQ > 1073700000)) { // 2^30
scale++;
- csum1QQ = WEBRTC_SPL_RSHIFT_W32(csum1QQ, 1);
- esumxQQ = WEBRTC_SPL_RSHIFT_W32(esumxQQ, 1);
+ csum1QQ >>= 1;
+ esumxQQ >>= 1;
}
- tmp2W32 = WEBRTC_SPL_RSHIFT_W32(tmp2W32, scale);
- csum1QQ += tmp2W32;
- tmpW32 = WEBRTC_SPL_RSHIFT_W32(tmpW32, scale);
- esumxQQ += tmpW32;
+ csum1QQ += tmp2W32 >> scale;
+ esumxQQ += tmpW32 >> scale;
ind++;
pos++;
@@ -252,7 +249,7 @@ void WebRtcIsacfix_PitchFilterGains(const int16_t* indatQ0,
tmp2W32 = WebRtcSpl_DivResultInQ31(csum1QQ, esumxQQ);
// Gain should be half the correlation.
- tmpW32 = WEBRTC_SPL_RSHIFT_W32(tmp2W32, 20);
+ tmpW32 = tmp2W32 >> 20;
} else {
tmpW32 = 4096;
}
diff --git a/modules/audio_coding/codecs/isac/fix/source/pitch_filter_c.c b/modules/audio_coding/codecs/isac/fix/source/pitch_filter_c.c
index 5b1b3f17..2f3fb4b8 100644
--- a/modules/audio_coding/codecs/isac/fix/source/pitch_filter_c.c
+++ b/modules/audio_coding/codecs/isac/fix/source/pitch_filter_c.c
@@ -41,7 +41,7 @@ void WebRtcIsacfix_PitchFilterCore(int loopNumber,
/* Saturate to avoid overflow in tmpW16. */
tmpW32 = WEBRTC_SPL_SAT(536862719, tmpW32, -536879104);
tmpW32 += 8192;
- tmpW16 = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmpW32, 14);
+ tmpW16 = (int16_t)(tmpW32 >> 14);
/* Shift low pass filter state. */
memmove(&inputState[1], &inputState[0],
@@ -60,7 +60,7 @@ void WebRtcIsacfix_PitchFilterCore(int loopNumber,
/* Saturate to avoid overflow in tmpW16. */
tmpW32 = WEBRTC_SPL_SAT(1073725439, tmpW32, -1073758208);
tmpW32 += 16384;
- tmpW16 = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmpW32, 15);
+ tmpW16 = (int16_t)(tmpW32 >> 15);
/* Subtract from input and update buffer. */
tmpW32 = inputBuf[*index2] - WEBRTC_SPL_MUL_16_16(sign, tmpW16);
@@ -71,4 +71,3 @@ void WebRtcIsacfix_PitchFilterCore(int loopNumber,
(*index2)++;
}
}
-
diff --git a/modules/audio_coding/codecs/isac/fix/source/transform.c b/modules/audio_coding/codecs/isac/fix/source/transform.c
index 24ccc821..e675e15f 100644
--- a/modules/audio_coding/codecs/isac/fix/source/transform.c
+++ b/modules/audio_coding/codecs/isac/fix/source/transform.c
@@ -45,10 +45,11 @@ void WebRtcIsacfix_Time2SpecC(int16_t *inre1Q9,
for (k = 0; k < FRAMESAMPLES/2; k++) {
tmp1rQ14 = WebRtcIsacfix_kCosTab1[k];
tmp1iQ14 = WebRtcIsacfix_kSinTab1[k];
- xrQ16 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(tmp1rQ14, inre1Q9[k]) + WEBRTC_SPL_MUL_16_16(tmp1iQ14, inre2Q9[k]), 7);
- xiQ16 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(tmp1rQ14, inre2Q9[k]) - WEBRTC_SPL_MUL_16_16(tmp1iQ14, inre1Q9[k]), 7);
- tmpreQ16[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(factQ19, xrQ16)+4, 3); // (Q16*Q19>>16)>>3 = Q16
- tmpimQ16[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(factQ19, xiQ16)+4, 3); // (Q16*Q19>>16)>>3 = Q16
+ xrQ16 = (tmp1rQ14 * inre1Q9[k] + tmp1iQ14 * inre2Q9[k]) >> 7;
+ xiQ16 = (tmp1rQ14 * inre2Q9[k] - tmp1iQ14 * inre1Q9[k]) >> 7;
+ // Q-domains below: (Q16*Q19>>16)>>3 = Q16
+ tmpreQ16[k] = (WEBRTC_SPL_MUL_16_32_RSFT16(factQ19, xrQ16) + 4) >> 3;
+ tmpimQ16[k] = (WEBRTC_SPL_MUL_16_32_RSFT16(factQ19, xiQ16) + 4) >> 3;
}
@@ -71,8 +72,8 @@ void WebRtcIsacfix_Time2SpecC(int16_t *inre1Q9,
} else {
int32_t round = WEBRTC_SPL_LSHIFT_W32((int32_t)1, -sh-1);
for (k=0; k<FRAMESAMPLES/2; k++) {
- inre1Q9[k] = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmpreQ16[k]+round, -sh); //Q(16+sh)
- inre2Q9[k] = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmpimQ16[k]+round, -sh); //Q(16+sh)
+ inre1Q9[k] = (int16_t)((tmpreQ16[k] + round) >> -sh); // Q(16+sh)
+ inre2Q9[k] = (int16_t)((tmpimQ16[k] + round) >> -sh); // Q(16+sh)
}
}
@@ -82,8 +83,8 @@ void WebRtcIsacfix_Time2SpecC(int16_t *inre1Q9,
//"Fastest" vectors
if (sh>=0) {
for (k=0; k<FRAMESAMPLES/2; k++) {
- tmpreQ16[k] = WEBRTC_SPL_RSHIFT_W32((int32_t)inre1Q9[k], sh); //Q(16+sh) -> Q16
- tmpimQ16[k] = WEBRTC_SPL_RSHIFT_W32((int32_t)inre2Q9[k], sh); //Q(16+sh) -> Q16
+ tmpreQ16[k] = inre1Q9[k] >> sh; // Q(16+sh) -> Q16
+ tmpimQ16[k] = inre2Q9[k] >> sh; // Q(16+sh) -> Q16
}
} else {
for (k=0; k<FRAMESAMPLES/2; k++) {
@@ -103,12 +104,14 @@ void WebRtcIsacfix_Time2SpecC(int16_t *inre1Q9,
tmp1iQ14 = WebRtcIsacfix_kSinTab2[k];
v1Q16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, xrQ16) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, xiQ16);
v2Q16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, xrQ16) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, xiQ16);
- outreQ7[k] = (int16_t) WEBRTC_SPL_RSHIFT_W32(v1Q16, 9);
- outimQ7[k] = (int16_t) WEBRTC_SPL_RSHIFT_W32(v2Q16, 9);
+ outreQ7[k] = (int16_t)(v1Q16 >> 9);
+ outimQ7[k] = (int16_t)(v2Q16 >> 9);
v1Q16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, yrQ16) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, yiQ16);
v2Q16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, yrQ16) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, yiQ16);
- outreQ7[FRAMESAMPLES/2 - 1 - k] = (int16_t)WEBRTC_SPL_RSHIFT_W32(v1Q16, 9); //CalcLrIntQ(v1Q16, 9);
- outimQ7[FRAMESAMPLES/2 - 1 - k] = (int16_t)WEBRTC_SPL_RSHIFT_W32(v2Q16, 9); //CalcLrIntQ(v2Q16, 9);
+ // CalcLrIntQ(v1Q16, 9);
+ outreQ7[FRAMESAMPLES / 2 - 1 - k] = (int16_t)(v1Q16 >> 9);
+ // CalcLrIntQ(v2Q16, 9);
+ outimQ7[FRAMESAMPLES / 2 - 1 - k] = (int16_t)(v2Q16 >> 9);
}
}
@@ -166,8 +169,8 @@ void WebRtcIsacfix_Spec2TimeC(int16_t *inreQ7, int16_t *inimQ7, int32_t *outre1Q
} else {
int32_t round = WEBRTC_SPL_LSHIFT_W32((int32_t)1, -sh-1);
for (k=0; k<240; k++) {
- inreQ7[k] = (int16_t) WEBRTC_SPL_RSHIFT_W32(outre1Q16[k]+round, -sh); //Q(16+sh)
- inimQ7[k] = (int16_t) WEBRTC_SPL_RSHIFT_W32(outre2Q16[k]+round, -sh); //Q(16+sh)
+ inreQ7[k] = (int16_t)((outre1Q16[k] + round) >> -sh); // Q(16+sh)
+ inimQ7[k] = (int16_t)((outre2Q16[k] + round) >> -sh); // Q(16+sh)
}
}
@@ -176,8 +179,8 @@ void WebRtcIsacfix_Spec2TimeC(int16_t *inreQ7, int16_t *inimQ7, int32_t *outre1Q
//"Fastest" vectors
if (sh>=0) {
for (k=0; k<240; k++) {
- outre1Q16[k] = WEBRTC_SPL_RSHIFT_W32((int32_t)inreQ7[k], sh); //Q(16+sh) -> Q16
- outre2Q16[k] = WEBRTC_SPL_RSHIFT_W32((int32_t)inimQ7[k], sh); //Q(16+sh) -> Q16
+ outre1Q16[k] = inreQ7[k] >> sh; // Q(16+sh) -> Q16
+ outre2Q16[k] = inimQ7[k] >> sh; // Q(16+sh) -> Q16
}
} else {
for (k=0; k<240; k++) {
diff --git a/modules/audio_coding/codecs/isac/main/source/entropy_coding.c b/modules/audio_coding/codecs/isac/main/source/entropy_coding.c
index 9ae69a0b..6cd33105 100644
--- a/modules/audio_coding/codecs/isac/main/source/entropy_coding.c
+++ b/modules/audio_coding/codecs/isac/main/source/entropy_coding.c
@@ -106,14 +106,13 @@ static void FindInvArSpec(const int16_t* ARCoefQ12,
for (n = 0; n < AR_ORDER + 1; n++) {
sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]); /* Q24 */
}
- sum = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(sum, 6),
- 65) + 32768, 16); /* Q8 */
- CorrQ11[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, gainQ10) + 256, 9);
+ sum = ((sum >> 6) * 65 + 32768) >> 16; /* Q8 */
+ CorrQ11[0] = (sum * gainQ10 + 256) >> 9;
/* To avoid overflow, we shift down gainQ10 if it is large.
* We will not lose any precision */
if (gainQ10 > 400000) {
- tmpGain = WEBRTC_SPL_RSHIFT_W32(gainQ10, 3);
+ tmpGain = gainQ10 >> 3;
round = 32;
shftVal = 6;
} else {
@@ -126,9 +125,8 @@ static void FindInvArSpec(const int16_t* ARCoefQ12,
sum = 16384;
for (n = k; n < AR_ORDER + 1; n++)
sum += WEBRTC_SPL_MUL(ARCoefQ12[n - k], ARCoefQ12[n]); /* Q24 */
- sum = WEBRTC_SPL_RSHIFT_W32(sum, 15);
- CorrQ11[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, tmpGain) + round,
- shftVal);
+ sum >>= 15;
+ CorrQ11[k] = (sum * tmpGain + round) >> shftVal;
}
sum = WEBRTC_SPL_LSHIFT_W32(CorrQ11[0], 7);
for (n = 0; n < FRAMESAMPLES / 8; n++) {
@@ -136,8 +134,7 @@ static void FindInvArSpec(const int16_t* ARCoefQ12,
}
for (k = 1; k < AR_ORDER; k += 2) {
for (n = 0; n < FRAMESAMPLES / 8; n++) {
- CurveQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(
- WebRtcIsac_kCos[k][n], CorrQ11[k + 1]) + 2, 2);
+ CurveQ16[n] += (WebRtcIsac_kCos[k][n] * CorrQ11[k + 1] + 2) >> 2;
}
}
@@ -155,14 +152,12 @@ static void FindInvArSpec(const int16_t* ARCoefQ12,
shftVal = 0;
}
for (n = 0; n < FRAMESAMPLES / 8; n++) {
- diffQ16[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(
- CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[1], shftVal)) + 2, 2);
+ diffQ16[n] = (CS_ptrQ9[n] * (CorrQ11[1] >> shftVal) + 2) >> 2;
}
for (k = 2; k < AR_ORDER; k += 2) {
CS_ptrQ9 = WebRtcIsac_kCos[k];
for (n = 0; n < FRAMESAMPLES / 8; n++) {
- diffQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(
- CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[k + 1], shftVal)) + 2, 2);
+ diffQ16[n] += (CS_ptrQ9[n] * (CorrQ11[k + 1] >> shftVal) + 2) >> 2;
}
}
diff --git a/modules/audio_coding/codecs/isac/main/test/ReleaseTest-API/ReleaseTest-API.cc b/modules/audio_coding/codecs/isac/main/test/ReleaseTest-API/ReleaseTest-API.cc
index 567ec85b..ffdcc0c1 100644
--- a/modules/audio_coding/codecs/isac/main/test/ReleaseTest-API/ReleaseTest-API.cc
+++ b/modules/audio_coding/codecs/isac/main/test/ReleaseTest-API/ReleaseTest-API.cc
@@ -448,7 +448,7 @@ int main(int argc, char* argv[])
{
printf(" Error iSAC Cannot write file %s.\n", outname);
cout << flush;
- getchar();
+ getc(stdin);
exit(1);
}
if(VADusage)
diff --git a/modules/audio_coding/codecs/isac/main/test/simpleKenny.c b/modules/audio_coding/codecs/isac/main/test/simpleKenny.c
index 1e752a18..d10b4add 100644
--- a/modules/audio_coding/codecs/isac/main/test/simpleKenny.c
+++ b/modules/audio_coding/codecs/isac/main/test/simpleKenny.c
@@ -383,7 +383,7 @@ valid values are 8 and 16.\n", sampFreqKHz);
// exit if returned with error
//errType=WebRtcIsac_GetErrorCode(ISAC_main_inst);
fprintf(stderr,"\nError in encoder\n");
- getchar();
+ getc(stdin);
exit(EXIT_FAILURE);
}
@@ -479,7 +479,7 @@ valid values are 8 and 16.\n", sampFreqKHz);
{
//errType=WebRtcIsac_GetErrorCode(ISAC_main_inst);
fprintf(stderr,"\nError in decoder.\n");
- getchar();
+ getc(stdin);
exit(1);
}
diff --git a/modules/audio_coding/codecs/opus/audio_encoder_opus.cc b/modules/audio_coding/codecs/opus/audio_encoder_opus.cc
new file mode 100644
index 00000000..6349b5c2
--- /dev/null
+++ b/modules/audio_coding/codecs/opus/audio_encoder_opus.cc
@@ -0,0 +1,104 @@
+/*
+ * 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 "webrtc/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h"
+
+#include "webrtc/modules/audio_coding/codecs/opus/interface/opus_interface.h"
+
+namespace webrtc {
+
+namespace {
+
+// We always encode at 48 kHz.
+const int kSampleRateHz = 48000;
+
+int DivExact(int a, int b) {
+ CHECK_EQ(a % b, 0);
+ return a / b;
+}
+
+int16_t ClampInt16(size_t x) {
+ return static_cast<int16_t>(
+ std::min(x, static_cast<size_t>(std::numeric_limits<int16_t>::max())));
+}
+
+int16_t CastInt16(size_t x) {
+ DCHECK_LE(x, static_cast<size_t>(std::numeric_limits<int16_t>::max()));
+ return static_cast<int16_t>(x);
+}
+
+} // namespace
+
+AudioEncoderOpus::Config::Config() : frame_size_ms(20), num_channels(1) {}
+
+bool AudioEncoderOpus::Config::IsOk() const {
+ if (frame_size_ms <= 0 || frame_size_ms % 10 != 0)
+ return false;
+ if (num_channels <= 0)
+ return false;
+ return true;
+}
+
+AudioEncoderOpus::AudioEncoderOpus(const Config& config)
+ : num_10ms_frames_per_packet_(DivExact(config.frame_size_ms, 10)),
+ num_channels_(config.num_channels),
+ samples_per_10ms_frame_(DivExact(kSampleRateHz, 100) * num_channels_) {
+ CHECK(config.IsOk());
+ input_buffer_.reserve(num_10ms_frames_per_packet_ * samples_per_10ms_frame_);
+ CHECK_EQ(0, WebRtcOpus_EncoderCreate(&inst_, num_channels_));
+}
+
+AudioEncoderOpus::~AudioEncoderOpus() {
+ CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_));
+}
+
+int AudioEncoderOpus::sample_rate_hz() const {
+ return kSampleRateHz;
+}
+
+int AudioEncoderOpus::num_channels() const {
+ return num_channels_;
+}
+
+int AudioEncoderOpus::Num10MsFramesInNextPacket() const {
+ return num_10ms_frames_per_packet_;
+}
+
+bool AudioEncoderOpus::Encode(uint32_t timestamp,
+ const int16_t* audio,
+ size_t max_encoded_bytes,
+ uint8_t* encoded,
+ size_t* encoded_bytes,
+ uint32_t* encoded_timestamp) {
+ if (input_buffer_.empty())
+ first_timestamp_in_buffer_ = timestamp;
+ input_buffer_.insert(input_buffer_.end(), audio,
+ audio + samples_per_10ms_frame_);
+ if (input_buffer_.size() < (static_cast<size_t>(num_10ms_frames_per_packet_) *
+ samples_per_10ms_frame_)) {
+ *encoded_bytes = 0;
+ return true;
+ }
+ CHECK_EQ(input_buffer_.size(),
+ static_cast<size_t>(num_10ms_frames_per_packet_) *
+ samples_per_10ms_frame_);
+ int16_t r = WebRtcOpus_Encode(
+ inst_, &input_buffer_[0],
+ DivExact(CastInt16(input_buffer_.size()), num_channels_),
+ ClampInt16(max_encoded_bytes), encoded);
+ input_buffer_.clear();
+ if (r < 0)
+ return false;
+ *encoded_bytes = r;
+ *encoded_timestamp = first_timestamp_in_buffer_;
+ return true;
+}
+
+} // namespace webrtc
diff --git a/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h b/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h
new file mode 100644
index 00000000..e2e5c73f
--- /dev/null
+++ b/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h
@@ -0,0 +1,55 @@
+/*
+ * 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 WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_INTERFACE_AUDIO_ENCODER_OPUS_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_INTERFACE_AUDIO_ENCODER_OPUS_H_
+
+#include <vector>
+
+#include "webrtc/modules/audio_coding/codecs/opus/interface/opus_interface.h"
+#include "webrtc/modules/audio_coding/codecs/audio_encoder.h"
+
+namespace webrtc {
+
+class AudioEncoderOpus : public AudioEncoder {
+ public:
+ struct Config {
+ Config();
+ bool IsOk() const;
+ int frame_size_ms;
+ int num_channels;
+ };
+
+ explicit AudioEncoderOpus(const Config& config);
+ virtual ~AudioEncoderOpus() OVERRIDE;
+
+ virtual int sample_rate_hz() const OVERRIDE;
+ virtual int num_channels() const OVERRIDE;
+ virtual int Num10MsFramesInNextPacket() const OVERRIDE;
+
+ protected:
+ virtual bool Encode(uint32_t timestamp,
+ const int16_t* audio,
+ size_t max_encoded_bytes,
+ uint8_t* encoded,
+ size_t* encoded_bytes,
+ uint32_t* encoded_timestamp) OVERRIDE;
+
+ private:
+ const int num_10ms_frames_per_packet_;
+ const int num_channels_;
+ const int samples_per_10ms_frame_;
+ std::vector<int16_t> input_buffer_;
+ OpusEncInst* inst_;
+ uint32_t first_timestamp_in_buffer_;
+};
+
+} // namespace webrtc
+#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_INTERFACE_AUDIO_ENCODER_OPUS_H_
diff --git a/modules/audio_coding/codecs/opus/opus.gypi b/modules/audio_coding/codecs/opus/opus.gypi
index 89f0a54a..b537285a 100644
--- a/modules/audio_coding/codecs/opus/opus.gypi
+++ b/modules/audio_coding/codecs/opus/opus.gypi
@@ -27,6 +27,8 @@
'<(webrtc_root)',
],
'sources': [
+ 'audio_encoder_opus.cc',
+ 'interface/audio_encoder_opus.h',
'interface/opus_interface.h',
'opus_inst.h',
'opus_interface.c',
diff --git a/modules/audio_coding/codecs/pcm16b/include/pcm16b.h b/modules/audio_coding/codecs/pcm16b/include/pcm16b.h
index 9c96b830..86b32fe2 100644
--- a/modules/audio_coding/codecs/pcm16b/include/pcm16b.h
+++ b/modules/audio_coding/codecs/pcm16b/include/pcm16b.h
@@ -73,8 +73,7 @@ int16_t WebRtcPcm16b_Encode(int16_t *speech16b,
* Returned value : Samples in speechOut16b
*/
-int16_t WebRtcPcm16b_DecodeW16(void *inst,
- int16_t *speechIn16b,
+int16_t WebRtcPcm16b_DecodeW16(int16_t *speechIn16b,
int16_t length_bytes,
int16_t *speechOut16b,
int16_t* speechType);
diff --git a/modules/audio_coding/codecs/pcm16b/pcm16b.c b/modules/audio_coding/codecs/pcm16b/pcm16b.c
index af6720f6..2c6bea6a 100644
--- a/modules/audio_coding/codecs/pcm16b/pcm16b.c
+++ b/modules/audio_coding/codecs/pcm16b/pcm16b.c
@@ -61,8 +61,7 @@ int16_t WebRtcPcm16b_Encode(int16_t *speech16b,
/* Decoder with int16_t Input instead of char when the int16_t Encoder is used */
-int16_t WebRtcPcm16b_DecodeW16(void *inst,
- int16_t *speechIn16b,
+int16_t WebRtcPcm16b_DecodeW16(int16_t *speechIn16b,
int16_t length_bytes,
int16_t *speechOut16b,
int16_t* speechType)
@@ -80,9 +79,6 @@ int16_t WebRtcPcm16b_DecodeW16(void *inst,
*speechType=1;
- // Avoid warning.
- (void)(inst = NULL);
-
return length_bytes >> 1;
}
diff --git a/modules/audio_coding/codecs/tools/audio_codec_speed_tests.gypi b/modules/audio_coding/codecs/tools/audio_codec_speed_tests.gypi
index 6503a51e..a9a5bb94 100644
--- a/modules/audio_coding/codecs/tools/audio_codec_speed_tests.gypi
+++ b/modules/audio_coding/codecs/tools/audio_codec_speed_tests.gypi
@@ -55,7 +55,6 @@
],
'includes': [
'../../../../build/isolate.gypi',
- 'audio_codec_speed_tests.isolate',
],
'sources': [
'audio_codec_speed_tests.isolate',
diff --git a/modules/audio_coding/codecs/tools/audio_codec_speed_tests.isolate b/modules/audio_coding/codecs/tools/audio_codec_speed_tests.isolate
index 8c5a2bd0..ed7599d7 100644
--- a/modules/audio_coding/codecs/tools/audio_codec_speed_tests.isolate
+++ b/modules/audio_coding/codecs/tools/audio_codec_speed_tests.isolate
@@ -9,7 +9,7 @@
'conditions': [
['OS=="android"', {
'variables': {
- 'isolate_dependency_untracked': [
+ 'files': [
'<(DEPTH)/resources/',
'<(DEPTH)/data/',
],
@@ -21,19 +21,14 @@
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/audio_codec_speed_tests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_touched': [
+ 'files': [
'<(DEPTH)/DEPS',
- ],
- 'isolate_dependency_tracked': [
'<(DEPTH)/resources/audio_coding/music_stereo_48kHz.pcm',
'<(DEPTH)/resources/audio_coding/speech_mono_16kHz.pcm',
'<(DEPTH)/resources/audio_coding/speech_mono_32_48kHz.pcm',
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/audio_codec_speed_tests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_untracked': [
- '<(DEPTH)/tools/swarming_client/',
- ],
},
}],
],
diff --git a/modules/audio_coding/main/acm2/acm_isac.cc b/modules/audio_coding/main/acm2/acm_isac.cc
index 6ee26825..bc20c961 100644
--- a/modules/audio_coding/main/acm2/acm_isac.cc
+++ b/modules/audio_coding/main/acm2/acm_isac.cc
@@ -262,8 +262,7 @@ static uint16_t ACMISACFixGetDecSampRate(ACM_ISAC_STRUCT* /* inst */) {
#endif
ACMISAC::ACMISAC(int16_t codec_id)
- : AudioDecoder(ACMCodecDB::neteq_decoders_[codec_id]),
- codec_inst_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
+ : codec_inst_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
is_enc_initialized_(false),
isac_coding_mode_(CHANNEL_INDEPENDENT),
enforce_frame_size_(false),
diff --git a/modules/audio_coding/main/acm2/acm_pcma.cc b/modules/audio_coding/main/acm2/acm_pcma.cc
index 548e8fda..41d4d085 100644
--- a/modules/audio_coding/main/acm2/acm_pcma.cc
+++ b/modules/audio_coding/main/acm2/acm_pcma.cc
@@ -27,7 +27,7 @@ ACMPCMA::~ACMPCMA() { return; }
int16_t ACMPCMA::InternalEncode(uint8_t* bitstream,
int16_t* bitstream_len_byte) {
*bitstream_len_byte = WebRtcG711_EncodeA(
- NULL, &in_audio_[in_audio_ix_read_], frame_len_smpl_ * num_channels_,
+ &in_audio_[in_audio_ix_read_], frame_len_smpl_ * num_channels_,
reinterpret_cast<int16_t*>(bitstream));
// Increment the read index this tell the caller that how far
// we have gone forward in reading the audio buffer.
diff --git a/modules/audio_coding/main/acm2/acm_pcmu.cc b/modules/audio_coding/main/acm2/acm_pcmu.cc
index 5c032363..4f16062f 100644
--- a/modules/audio_coding/main/acm2/acm_pcmu.cc
+++ b/modules/audio_coding/main/acm2/acm_pcmu.cc
@@ -27,7 +27,7 @@ ACMPCMU::~ACMPCMU() {}
int16_t ACMPCMU::InternalEncode(uint8_t* bitstream,
int16_t* bitstream_len_byte) {
*bitstream_len_byte = WebRtcG711_EncodeU(
- NULL, &in_audio_[in_audio_ix_read_], frame_len_smpl_ * num_channels_,
+ &in_audio_[in_audio_ix_read_], frame_len_smpl_ * num_channels_,
reinterpret_cast<int16_t*>(bitstream));
// Increment the read index this tell the caller that how far
diff --git a/modules/audio_coding/main/acm2/acm_receiver.cc b/modules/audio_coding/main/acm2/acm_receiver.cc
index 0c7e6c72..07447541 100644
--- a/modules/audio_coding/main/acm2/acm_receiver.cc
+++ b/modules/audio_coding/main/acm2/acm_receiver.cc
@@ -122,11 +122,14 @@ AcmReceiver::AcmReceiver(const AudioCodingModule::Config& config)
last_audio_decoder_(-1), // Invalid value.
previous_audio_activity_(AudioFrame::kVadPassive),
current_sample_rate_hz_(config.neteq_config.sample_rate_hz),
+ audio_buffer_(new int16_t[AudioFrame::kMaxDataSizeSamples]),
+ last_audio_buffer_(new int16_t[AudioFrame::kMaxDataSizeSamples]),
nack_(),
nack_enabled_(false),
neteq_(NetEq::Create(config.neteq_config)),
vad_enabled_(true),
clock_(config.clock),
+ resampled_last_output_frame_(true),
av_sync_(false),
initial_delay_manager_(),
missing_packets_sync_stream_(),
@@ -143,6 +146,9 @@ AcmReceiver::AcmReceiver(const AudioCodingModule::Config& config)
neteq_->EnableVad();
else
neteq_->DisableVad();
+
+ memset(audio_buffer_.get(), 0, AudioFrame::kMaxDataSizeSamples);
+ memset(last_audio_buffer_.get(), 0, AudioFrame::kMaxDataSizeSamples);
}
AcmReceiver::~AcmReceiver() {
@@ -342,7 +348,6 @@ int AcmReceiver::InsertPacket(const WebRtcRTPHeader& rtp_header,
int AcmReceiver::GetAudio(int desired_freq_hz, AudioFrame* audio_frame) {
enum NetEqOutputType type;
- int16_t* ptr_audio_buffer = audio_frame->data_;
int samples_per_channel;
int num_channels;
bool return_silence = false;
@@ -359,18 +364,6 @@ int AcmReceiver::GetAudio(int desired_freq_hz, AudioFrame* audio_frame) {
initial_delay_manager_->LatePackets(timestamp_now,
late_packets_sync_stream_.get());
}
-
- if (!return_silence) {
- // This is our initial guess regarding whether a resampling will be
- // required. It is based on previous sample rate of netEq. Most often,
- // this is a correct guess, however, in case that incoming payload changes
- // the resampling might might be needed. By doing so, we avoid an
- // unnecessary memcpy().
- if (desired_freq_hz != -1 &&
- current_sample_rate_hz_ != desired_freq_hz) {
- ptr_audio_buffer = audio_buffer_;
- }
- }
}
// If |late_packets_sync_stream_| is allocated then we have been in AV-sync
@@ -381,17 +374,19 @@ int AcmReceiver::GetAudio(int desired_freq_hz, AudioFrame* audio_frame) {
return 0;
}
+ // Accessing members, take the lock.
+ CriticalSectionScoped lock(crit_sect_.get());
+
+ // Always write the output to |audio_buffer_| first.
if (neteq_->GetAudio(AudioFrame::kMaxDataSizeSamples,
- ptr_audio_buffer,
+ audio_buffer_.get(),
&samples_per_channel,
- &num_channels, &type) != NetEq::kOK) {
+ &num_channels,
+ &type) != NetEq::kOK) {
LOG_FERR0(LS_ERROR, "AcmReceiver::GetAudio") << "NetEq Failed.";
return -1;
}
- // Accessing members, take the lock.
- CriticalSectionScoped lock(crit_sect_.get());
-
// Update NACK.
int decoded_sequence_num = 0;
uint32_t decoded_timestamp = 0;
@@ -409,45 +404,53 @@ int AcmReceiver::GetAudio(int desired_freq_hz, AudioFrame* audio_frame) {
bool need_resampling = (desired_freq_hz != -1) &&
(current_sample_rate_hz_ != desired_freq_hz);
- if (ptr_audio_buffer == audio_buffer_) {
- // Data is written to local buffer.
- if (need_resampling) {
- samples_per_channel =
- resampler_.Resample10Msec(audio_buffer_,
- current_sample_rate_hz_,
- desired_freq_hz,
- num_channels,
- AudioFrame::kMaxDataSizeSamples,
- audio_frame->data_);
- if (samples_per_channel < 0) {
- LOG_FERR0(LS_ERROR, "AcmReceiver::GetAudio") << "Resampler Failed.";
- return -1;
- }
- } else {
- // We might end up here ONLY if codec is changed.
- memcpy(audio_frame->data_, audio_buffer_, samples_per_channel *
- num_channels * sizeof(int16_t));
+ if (need_resampling && !resampled_last_output_frame_) {
+ // Prime the resampler with the last frame.
+ int16_t temp_output[AudioFrame::kMaxDataSizeSamples];
+ samples_per_channel =
+ resampler_.Resample10Msec(last_audio_buffer_.get(),
+ current_sample_rate_hz_,
+ desired_freq_hz,
+ num_channels,
+ AudioFrame::kMaxDataSizeSamples,
+ temp_output);
+ if (samples_per_channel < 0) {
+ LOG_FERR0(LS_ERROR, "AcmReceiver::GetAudio")
+ << "Resampling last_audio_buffer_ failed.";
+ return -1;
}
- } else {
- // Data is written into |audio_frame|.
- if (need_resampling) {
- // We might end up here ONLY if codec is changed.
- samples_per_channel =
- resampler_.Resample10Msec(audio_frame->data_,
- current_sample_rate_hz_,
- desired_freq_hz,
- num_channels,
- AudioFrame::kMaxDataSizeSamples,
- audio_buffer_);
- if (samples_per_channel < 0) {
- LOG_FERR0(LS_ERROR, "AcmReceiver::GetAudio") << "Resampler Failed.";
- return -1;
- }
- memcpy(audio_frame->data_, audio_buffer_, samples_per_channel *
- num_channels * sizeof(int16_t));
+ }
+
+ // The audio in |audio_buffer_| is tansferred to |audio_frame_| below, either
+ // through resampling, or through straight memcpy.
+ // TODO(henrik.lundin) Glitches in the output may appear if the output rate
+ // from NetEq changes. See WebRTC issue 3923.
+ if (need_resampling) {
+ samples_per_channel =
+ resampler_.Resample10Msec(audio_buffer_.get(),
+ current_sample_rate_hz_,
+ desired_freq_hz,
+ num_channels,
+ AudioFrame::kMaxDataSizeSamples,
+ audio_frame->data_);
+ if (samples_per_channel < 0) {
+ LOG_FERR0(LS_ERROR, "AcmReceiver::GetAudio")
+ << "Resampling audio_buffer_ failed.";
+ return -1;
}
+ resampled_last_output_frame_ = true;
+ } else {
+ resampled_last_output_frame_ = false;
+ // We might end up here ONLY if codec is changed.
+ memcpy(audio_frame->data_,
+ audio_buffer_.get(),
+ samples_per_channel * num_channels * sizeof(int16_t));
}
+ // Swap buffers, so that the current audio is stored in |last_audio_buffer_|
+ // for next time.
+ audio_buffer_.swap(last_audio_buffer_);
+
audio_frame->num_channels_ = num_channels;
audio_frame->samples_per_channel_ = samples_per_channel;
audio_frame->sample_rate_hz_ = samples_per_channel * 100;
diff --git a/modules/audio_coding/main/acm2/acm_receiver.h b/modules/audio_coding/main/acm2/acm_receiver.h
index 94ea5b01..6d31b9a5 100644
--- a/modules/audio_coding/main/acm2/acm_receiver.h
+++ b/modules/audio_coding/main/acm2/acm_receiver.h
@@ -334,7 +334,8 @@ class AcmReceiver {
ACMResampler resampler_ GUARDED_BY(crit_sect_);
// Used in GetAudio, declared as member to avoid allocating every 10ms.
// TODO(henrik.lundin) Stack-allocate in GetAudio instead?
- int16_t audio_buffer_[AudioFrame::kMaxDataSizeSamples] GUARDED_BY(crit_sect_);
+ scoped_ptr<int16_t[]> audio_buffer_ GUARDED_BY(crit_sect_);
+ scoped_ptr<int16_t[]> last_audio_buffer_ GUARDED_BY(crit_sect_);
scoped_ptr<Nack> nack_ GUARDED_BY(crit_sect_);
bool nack_enabled_ GUARDED_BY(crit_sect_);
CallStatistics call_stats_ GUARDED_BY(crit_sect_);
@@ -342,6 +343,7 @@ class AcmReceiver {
Decoder decoders_[ACMCodecDB::kMaxNumCodecs];
bool vad_enabled_;
Clock* clock_; // TODO(henrik.lundin) Make const if possible.
+ bool resampled_last_output_frame_ GUARDED_BY(crit_sect_);
// Indicates if a non-zero initial delay is set, and the receiver is in
// AV-sync mode.
diff --git a/modules/audio_coding/main/acm2/audio_coding_module.gypi b/modules/audio_coding/main/acm2/audio_coding_module.gypi
index d746a80b..8dfdb563 100644
--- a/modules/audio_coding/main/acm2/audio_coding_module.gypi
+++ b/modules/audio_coding/main/acm2/audio_coding_module.gypi
@@ -162,7 +162,7 @@
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(webrtc_root)/test/test.gyp:test_support',
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
- '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default',
+ '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers_default',
'<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
],
'sources': [
@@ -180,7 +180,7 @@
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(webrtc_root)/test/test.gyp:test_support',
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
- '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default',
+ '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers_default',
'<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
],
'sources': [
diff --git a/modules/audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc b/modules/audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc
index 7ffcac73..d9ed32c1 100644
--- a/modules/audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc
+++ b/modules/audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc
@@ -1034,7 +1034,7 @@ TEST_F(AcmSwitchingOutputFrequencyOldApi, TestWithoutToggling) {
Run(16000, 16000, 1000);
}
-TEST_F(AcmSwitchingOutputFrequencyOldApi, DISABLED_Toggle16KhzTo32Khz) {
+TEST_F(AcmSwitchingOutputFrequencyOldApi, Toggle16KhzTo32Khz) {
Run(16000, 32000, 1000);
}
@@ -1042,7 +1042,7 @@ TEST_F(AcmSwitchingOutputFrequencyOldApi, Toggle32KhzTo16Khz) {
Run(32000, 16000, 1000);
}
-TEST_F(AcmSwitchingOutputFrequencyOldApi, DISABLED_Toggle16KhzTo8Khz) {
+TEST_F(AcmSwitchingOutputFrequencyOldApi, Toggle16KhzTo8Khz) {
Run(16000, 8000, 1000);
}
diff --git a/modules/audio_coding/main/test/APITest.cc b/modules/audio_coding/main/test/APITest.cc
index 82940fa3..b6e47145 100644
--- a/modules/audio_coding/main/test/APITest.cc
+++ b/modules/audio_coding/main/test/APITest.cc
@@ -503,7 +503,7 @@ void APITest::RunTest(char thread) {
break;
default:
fprintf(stderr, "Wrong Test Number\n");
- getchar();
+ getc(stdin);
exit(1);
}
}
diff --git a/modules/audio_coding/neteq/audio_decoder.cc b/modules/audio_coding/neteq/audio_decoder.cc
index 0fdaa44b..04a74eef 100644
--- a/modules/audio_coding/neteq/audio_decoder.cc
+++ b/modules/audio_coding/neteq/audio_decoder.cc
@@ -51,8 +51,6 @@ bool AudioDecoder::PacketHasFec(const uint8_t* encoded,
return false;
}
-NetEqDecoder AudioDecoder::codec_type() const { return codec_type_; }
-
bool AudioDecoder::CodecSupported(NetEqDecoder codec_type) {
switch (codec_type) {
case kDecoderPCMu:
@@ -197,26 +195,24 @@ AudioDecoder* AudioDecoder::CreateAudioDecoder(NetEqDecoder codec_type) {
return new AudioDecoderIsacFix;
#elif defined(WEBRTC_CODEC_ISAC)
case kDecoderISAC:
- return new AudioDecoderIsac;
-#endif
-#ifdef WEBRTC_CODEC_ISAC
+ return new AudioDecoderIsac(16000);
case kDecoderISACswb:
- return new AudioDecoderIsacSwb;
case kDecoderISACfb:
- return new AudioDecoderIsacFb;
+ return new AudioDecoderIsac(32000);
#endif
#ifdef WEBRTC_CODEC_PCM16
case kDecoderPCM16B:
case kDecoderPCM16Bwb:
case kDecoderPCM16Bswb32kHz:
case kDecoderPCM16Bswb48kHz:
- return new AudioDecoderPcm16B(codec_type);
+ return new AudioDecoderPcm16B;
case kDecoderPCM16B_2ch:
case kDecoderPCM16Bwb_2ch:
case kDecoderPCM16Bswb32kHz_2ch:
case kDecoderPCM16Bswb48kHz_2ch:
+ return new AudioDecoderPcm16BMultiCh(2);
case kDecoderPCM16B_5ch:
- return new AudioDecoderPcm16BMultiCh(codec_type);
+ return new AudioDecoderPcm16BMultiCh(5);
#endif
#ifdef WEBRTC_CODEC_G722
case kDecoderG722:
@@ -226,19 +222,21 @@ AudioDecoder* AudioDecoder::CreateAudioDecoder(NetEqDecoder codec_type) {
#endif
#ifdef WEBRTC_CODEC_CELT
case kDecoderCELT_32:
+ return new AudioDecoderCelt(1);
case kDecoderCELT_32_2ch:
- return new AudioDecoderCelt(codec_type);
+ return new AudioDecoderCelt(2);
#endif
#ifdef WEBRTC_CODEC_OPUS
case kDecoderOpus:
+ return new AudioDecoderOpus(1);
case kDecoderOpus_2ch:
- return new AudioDecoderOpus(codec_type);
+ return new AudioDecoderOpus(2);
#endif
case kDecoderCNGnb:
case kDecoderCNGwb:
case kDecoderCNGswb32kHz:
case kDecoderCNGswb48kHz:
- return new AudioDecoderCng(codec_type);
+ return new AudioDecoderCng;
case kDecoderRED:
case kDecoderAVT:
case kDecoderArbitrary:
diff --git a/modules/audio_coding/neteq/audio_decoder_impl.cc b/modules/audio_coding/neteq/audio_decoder_impl.cc
index 661f2b11..07b1b4be 100644
--- a/modules/audio_coding/neteq/audio_decoder_impl.cc
+++ b/modules/audio_coding/neteq/audio_decoder_impl.cc
@@ -13,6 +13,7 @@
#include <assert.h>
#include <string.h> // memmove
+#include "webrtc/base/checks.h"
#ifdef WEBRTC_CODEC_CELT
#include "webrtc/modules/audio_coding/codecs/celt/include/celt_interface.h"
#endif
@@ -44,7 +45,7 @@ int AudioDecoderPcmU::Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type) {
int16_t temp_type = 1; // Default is speech.
int16_t ret = WebRtcG711_DecodeU(
- state_, reinterpret_cast<int16_t*>(const_cast<uint8_t*>(encoded)),
+ reinterpret_cast<int16_t*>(const_cast<uint8_t*>(encoded)),
static_cast<int16_t>(encoded_len), decoded, &temp_type);
*speech_type = ConvertSpeechType(temp_type);
return ret;
@@ -61,7 +62,7 @@ int AudioDecoderPcmA::Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type) {
int16_t temp_type = 1; // Default is speech.
int16_t ret = WebRtcG711_DecodeA(
- state_, reinterpret_cast<int16_t*>(const_cast<uint8_t*>(encoded)),
+ reinterpret_cast<int16_t*>(const_cast<uint8_t*>(encoded)),
static_cast<int16_t>(encoded_len), decoded, &temp_type);
*speech_type = ConvertSpeechType(temp_type);
return ret;
@@ -75,19 +76,13 @@ int AudioDecoderPcmA::PacketDuration(const uint8_t* encoded,
// PCM16B
#ifdef WEBRTC_CODEC_PCM16
-AudioDecoderPcm16B::AudioDecoderPcm16B(enum NetEqDecoder type)
- : AudioDecoder(type) {
- assert(type == kDecoderPCM16B ||
- type == kDecoderPCM16Bwb ||
- type == kDecoderPCM16Bswb32kHz ||
- type == kDecoderPCM16Bswb48kHz);
-}
+AudioDecoderPcm16B::AudioDecoderPcm16B() {}
int AudioDecoderPcm16B::Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type) {
int16_t temp_type = 1; // Default is speech.
int16_t ret = WebRtcPcm16b_DecodeW16(
- state_, reinterpret_cast<int16_t*>(const_cast<uint8_t*>(encoded)),
+ reinterpret_cast<int16_t*>(const_cast<uint8_t*>(encoded)),
static_cast<int16_t>(encoded_len), decoded, &temp_type);
*speech_type = ConvertSpeechType(temp_type);
return ret;
@@ -99,29 +94,15 @@ int AudioDecoderPcm16B::PacketDuration(const uint8_t* encoded,
return static_cast<int>(encoded_len / (2 * channels_));
}
-AudioDecoderPcm16BMultiCh::AudioDecoderPcm16BMultiCh(
- enum NetEqDecoder type)
- : AudioDecoderPcm16B(kDecoderPCM16B) { // This will be changed below.
- codec_type_ = type; // Changing to actual type here.
- switch (codec_type_) {
- case kDecoderPCM16B_2ch:
- case kDecoderPCM16Bwb_2ch:
- case kDecoderPCM16Bswb32kHz_2ch:
- case kDecoderPCM16Bswb48kHz_2ch:
- channels_ = 2;
- break;
- case kDecoderPCM16B_5ch:
- channels_ = 5;
- break;
- default:
- assert(false);
- }
+AudioDecoderPcm16BMultiCh::AudioDecoderPcm16BMultiCh(int num_channels) {
+ DCHECK(num_channels > 0);
+ channels_ = num_channels;
}
#endif
// iLBC
#ifdef WEBRTC_CODEC_ILBC
-AudioDecoderIlbc::AudioDecoderIlbc() : AudioDecoder(kDecoderILBC) {
+AudioDecoderIlbc::AudioDecoderIlbc() {
WebRtcIlbcfix_DecoderCreate(reinterpret_cast<iLBC_decinst_t**>(&state_));
}
@@ -152,9 +133,11 @@ int AudioDecoderIlbc::Init() {
// iSAC float
#ifdef WEBRTC_CODEC_ISAC
-AudioDecoderIsac::AudioDecoderIsac() : AudioDecoder(kDecoderISAC) {
+AudioDecoderIsac::AudioDecoderIsac(int decode_sample_rate_hz) {
+ DCHECK(decode_sample_rate_hz == 16000 || decode_sample_rate_hz == 32000);
WebRtcIsac_Create(reinterpret_cast<ISACStruct**>(&state_));
- WebRtcIsac_SetDecSampRate(static_cast<ISACStruct*>(state_), 16000);
+ WebRtcIsac_SetDecSampRate(static_cast<ISACStruct*>(state_),
+ decode_sample_rate_hz);
}
AudioDecoderIsac::~AudioDecoderIsac() {
@@ -209,22 +192,11 @@ int AudioDecoderIsac::IncomingPacket(const uint8_t* payload,
int AudioDecoderIsac::ErrorCode() {
return WebRtcIsac_GetErrorCode(static_cast<ISACStruct*>(state_));
}
-
-// iSAC SWB
-AudioDecoderIsacSwb::AudioDecoderIsacSwb() : AudioDecoderIsac() {
- codec_type_ = kDecoderISACswb;
- WebRtcIsac_SetDecSampRate(static_cast<ISACStruct*>(state_), 32000);
-}
-
-// iSAC FB
-AudioDecoderIsacFb::AudioDecoderIsacFb() : AudioDecoderIsacSwb() {
- codec_type_ = kDecoderISACfb;
-}
#endif
// iSAC fix
#ifdef WEBRTC_CODEC_ISACFX
-AudioDecoderIsacFix::AudioDecoderIsacFix() : AudioDecoder(kDecoderISAC) {
+AudioDecoderIsacFix::AudioDecoderIsacFix() {
WebRtcIsacfix_Create(reinterpret_cast<ISACFIX_MainStruct**>(&state_));
}
@@ -266,7 +238,7 @@ int AudioDecoderIsacFix::ErrorCode() {
// G.722
#ifdef WEBRTC_CODEC_G722
-AudioDecoderG722::AudioDecoderG722() : AudioDecoder(kDecoderG722) {
+AudioDecoderG722::AudioDecoderG722() {
WebRtcG722_CreateDecoder(reinterpret_cast<G722DecInst**>(&state_));
}
@@ -382,14 +354,9 @@ void AudioDecoderG722Stereo::SplitStereoPacket(const uint8_t* encoded,
// CELT
#ifdef WEBRTC_CODEC_CELT
-AudioDecoderCelt::AudioDecoderCelt(enum NetEqDecoder type)
- : AudioDecoder(type) {
- assert(type == kDecoderCELT_32 || type == kDecoderCELT_32_2ch);
- if (type == kDecoderCELT_32) {
- channels_ = 1;
- } else {
- channels_ = 2;
- }
+AudioDecoderCelt::AudioDecoderCelt(int num_channels) {
+ DCHECK(num_channels == 1 || num_channels == 2);
+ channels_ = num_channels;
WebRtcCelt_CreateDec(reinterpret_cast<CELT_decinst_t**>(&state_),
static_cast<int>(channels_));
}
@@ -431,13 +398,9 @@ int AudioDecoderCelt::DecodePlc(int num_frames, int16_t* decoded) {
// Opus
#ifdef WEBRTC_CODEC_OPUS
-AudioDecoderOpus::AudioDecoderOpus(enum NetEqDecoder type)
- : AudioDecoder(type) {
- if (type == kDecoderOpus_2ch) {
- channels_ = 2;
- } else {
- channels_ = 1;
- }
+AudioDecoderOpus::AudioDecoderOpus(int num_channels) {
+ DCHECK(num_channels == 1 || num_channels == 2);
+ channels_ = num_channels;
WebRtcOpus_DecoderCreate(reinterpret_cast<OpusDecInst**>(&state_),
static_cast<int>(channels_));
}
@@ -494,10 +457,7 @@ bool AudioDecoderOpus::PacketHasFec(const uint8_t* encoded,
}
#endif
-AudioDecoderCng::AudioDecoderCng(enum NetEqDecoder type)
- : AudioDecoder(type) {
- assert(type == kDecoderCNGnb || type == kDecoderCNGwb ||
- kDecoderCNGswb32kHz || type == kDecoderCNGswb48kHz);
+AudioDecoderCng::AudioDecoderCng() {
WebRtcCng_CreateDec(reinterpret_cast<CNG_dec_inst**>(&state_));
assert(state_);
}
diff --git a/modules/audio_coding/neteq/audio_decoder_impl.h b/modules/audio_coding/neteq/audio_decoder_impl.h
index 265d660b..214392e7 100644
--- a/modules/audio_coding/neteq/audio_decoder_impl.h
+++ b/modules/audio_coding/neteq/audio_decoder_impl.h
@@ -26,7 +26,7 @@ namespace webrtc {
class AudioDecoderPcmU : public AudioDecoder {
public:
- AudioDecoderPcmU() : AudioDecoder(kDecoderPCMu) {}
+ AudioDecoderPcmU() {}
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type);
virtual int Init() { return 0; }
@@ -38,7 +38,7 @@ class AudioDecoderPcmU : public AudioDecoder {
class AudioDecoderPcmA : public AudioDecoder {
public:
- AudioDecoderPcmA() : AudioDecoder(kDecoderPCMa) {}
+ AudioDecoderPcmA() {}
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type);
virtual int Init() { return 0; }
@@ -75,7 +75,7 @@ class AudioDecoderPcmAMultiCh : public AudioDecoderPcmA {
// The type is specified in the constructor parameter |type|.
class AudioDecoderPcm16B : public AudioDecoder {
public:
- explicit AudioDecoderPcm16B(enum NetEqDecoder type);
+ AudioDecoderPcm16B();
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type);
virtual int Init() { return 0; }
@@ -90,7 +90,7 @@ class AudioDecoderPcm16B : public AudioDecoder {
// of channels is derived from the type.
class AudioDecoderPcm16BMultiCh : public AudioDecoderPcm16B {
public:
- explicit AudioDecoderPcm16BMultiCh(enum NetEqDecoder type);
+ explicit AudioDecoderPcm16BMultiCh(int num_channels);
private:
DISALLOW_COPY_AND_ASSIGN(AudioDecoderPcm16BMultiCh);
@@ -116,7 +116,7 @@ class AudioDecoderIlbc : public AudioDecoder {
#ifdef WEBRTC_CODEC_ISAC
class AudioDecoderIsac : public AudioDecoder {
public:
- AudioDecoderIsac();
+ explicit AudioDecoderIsac(int decode_sample_rate_hz);
virtual ~AudioDecoderIsac();
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type);
@@ -135,22 +135,6 @@ class AudioDecoderIsac : public AudioDecoder {
private:
DISALLOW_COPY_AND_ASSIGN(AudioDecoderIsac);
};
-
-class AudioDecoderIsacSwb : public AudioDecoderIsac {
- public:
- AudioDecoderIsacSwb();
-
- private:
- DISALLOW_COPY_AND_ASSIGN(AudioDecoderIsacSwb);
-};
-
-class AudioDecoderIsacFb : public AudioDecoderIsacSwb {
- public:
- AudioDecoderIsacFb();
-
- private:
- DISALLOW_COPY_AND_ASSIGN(AudioDecoderIsacFb);
-};
#endif
#ifdef WEBRTC_CODEC_ISACFX
@@ -215,7 +199,7 @@ class AudioDecoderG722Stereo : public AudioDecoderG722 {
#ifdef WEBRTC_CODEC_CELT
class AudioDecoderCelt : public AudioDecoder {
public:
- explicit AudioDecoderCelt(enum NetEqDecoder type);
+ explicit AudioDecoderCelt(int num_channels);
virtual ~AudioDecoderCelt();
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
@@ -232,7 +216,7 @@ class AudioDecoderCelt : public AudioDecoder {
#ifdef WEBRTC_CODEC_OPUS
class AudioDecoderOpus : public AudioDecoder {
public:
- explicit AudioDecoderOpus(enum NetEqDecoder type);
+ explicit AudioDecoderOpus(int num_channels);
virtual ~AudioDecoderOpus();
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type);
@@ -257,7 +241,7 @@ class AudioDecoderOpus : public AudioDecoder {
// specific CngDecoder class could both inherit from that class.
class AudioDecoderCng : public AudioDecoder {
public:
- explicit AudioDecoderCng(enum NetEqDecoder type);
+ explicit AudioDecoderCng();
virtual ~AudioDecoderCng();
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type) { return -1; }
diff --git a/modules/audio_coding/neteq/audio_decoder_unittest.cc b/modules/audio_coding/neteq/audio_decoder_unittest.cc
index 624e6a4d..c95214b2 100644
--- a/modules/audio_coding/neteq/audio_decoder_unittest.cc
+++ b/modules/audio_coding/neteq/audio_decoder_unittest.cc
@@ -14,56 +14,106 @@
#include <stdlib.h>
#include <string>
+#include <vector>
#include "testing/gtest/include/gtest/gtest.h"
-#include "webrtc/common_audio/resampler/include/resampler.h"
#ifdef WEBRTC_CODEC_CELT
#include "webrtc/modules/audio_coding/codecs/celt/include/celt_interface.h"
#endif
#include "webrtc/modules/audio_coding/codecs/g711/include/g711_interface.h"
+#include "webrtc/modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h"
#include "webrtc/modules/audio_coding/codecs/g722/include/g722_interface.h"
#include "webrtc/modules/audio_coding/codecs/ilbc/interface/ilbc.h"
#include "webrtc/modules/audio_coding/codecs/isac/fix/interface/isacfix.h"
#include "webrtc/modules/audio_coding/codecs/isac/main/interface/isac.h"
-#include "webrtc/modules/audio_coding/codecs/opus/interface/opus_interface.h"
+#include "webrtc/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h"
#include "webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h"
+#include "webrtc/modules/audio_coding/neteq/tools/resample_input_audio_file.h"
#include "webrtc/system_wrappers/interface/data_log.h"
+#include "webrtc/system_wrappers/interface/scoped_ptr.h"
#include "webrtc/test/testsupport/fileutils.h"
namespace webrtc {
+namespace {
+// The absolute difference between the input and output (the first channel) is
+// compared vs |tolerance|. The parameter |delay| is used to correct for codec
+// delays.
+void CompareInputOutput(const std::vector<int16_t>& input,
+ const std::vector<int16_t>& output,
+ size_t num_samples,
+ size_t channels,
+ int tolerance,
+ int delay) {
+ ASSERT_LE(num_samples, input.size());
+ ASSERT_LE(num_samples * channels, output.size());
+ for (unsigned int n = 0; n < num_samples - delay; ++n) {
+ ASSERT_NEAR(input[n], output[channels * n + delay], tolerance)
+ << "Exit test on first diff; n = " << n;
+ DataLog::InsertCell("CodecTest", "input", input[n]);
+ DataLog::InsertCell("CodecTest", "output", output[channels * n]);
+ DataLog::NextRow("CodecTest");
+ }
+}
+
+// The absolute difference between the first two channels in |output| is
+// compared vs |tolerance|.
+void CompareTwoChannels(const std::vector<int16_t>& output,
+ size_t samples_per_channel,
+ size_t channels,
+ int tolerance) {
+ ASSERT_GE(channels, 2u);
+ ASSERT_LE(samples_per_channel * channels, output.size());
+ for (unsigned int n = 0; n < samples_per_channel; ++n)
+ ASSERT_NEAR(output[channels * n], output[channels * n + 1], tolerance)
+ << "Stereo samples differ.";
+}
+
+// Calculates mean-squared error between input and output (the first channel).
+// The parameter |delay| is used to correct for codec delays.
+double MseInputOutput(const std::vector<int16_t>& input,
+ const std::vector<int16_t>& output,
+ size_t num_samples,
+ size_t channels,
+ int delay) {
+ assert(delay < static_cast<int>(num_samples));
+ assert(num_samples <= input.size());
+ assert(num_samples * channels <= output.size());
+ if (num_samples == 0)
+ return 0.0;
+ double squared_sum = 0.0;
+ for (unsigned int n = 0; n < num_samples - delay; ++n) {
+ squared_sum += (input[n] - output[channels * n + delay]) *
+ (input[n] - output[channels * n + delay]);
+ }
+ return squared_sum / (num_samples - delay);
+}
+} // namespace
+
class AudioDecoderTest : public ::testing::Test {
protected:
AudioDecoderTest()
- : input_fp_(NULL),
- input_(NULL),
- encoded_(NULL),
- decoded_(NULL),
- frame_size_(0),
- data_length_(0),
- encoded_bytes_(0),
- channels_(1),
- decoder_(NULL) {
- input_file_ = webrtc::test::ProjectRootPath() +
- "resources/audio_coding/testfile32kHz.pcm";
- }
+ : input_audio_(webrtc::test::ProjectRootPath() +
+ "resources/audio_coding/testfile32kHz.pcm",
+ 32000),
+ codec_input_rate_hz_(32000), // Legacy default value.
+ encoded_(NULL),
+ frame_size_(0),
+ data_length_(0),
+ encoded_bytes_(0),
+ channels_(1),
+ output_timestamp_(0),
+ decoder_(NULL) {}
virtual ~AudioDecoderTest() {}
virtual void SetUp() {
+ if (audio_encoder_)
+ codec_input_rate_hz_ = audio_encoder_->sample_rate_hz();
// Create arrays.
ASSERT_GT(data_length_, 0u) << "The test must set data_length_ > 0";
- input_ = new int16_t[data_length_];
// Longest encoded data is produced by PCM16b with 2 bytes per sample.
encoded_ = new uint8_t[data_length_ * 2];
- decoded_ = new int16_t[data_length_ * channels_];
- // Open input file.
- input_fp_ = fopen(input_file_.c_str(), "rb");
- ASSERT_TRUE(input_fp_ != NULL) << "Failed to open file " << input_file_;
- // Read data to |input_|.
- ASSERT_EQ(data_length_,
- fread(input_, sizeof(int16_t), data_length_, input_fp_)) <<
- "Could not read enough data from file";
// Logging to view input and output in Matlab.
// Use 'gyp -Denable_data_logging=1' to enable logging.
DataLog::CreateLog();
@@ -75,24 +125,37 @@ class AudioDecoderTest : public ::testing::Test {
virtual void TearDown() {
delete decoder_;
decoder_ = NULL;
- // Close input file.
- fclose(input_fp_);
// Delete arrays.
- delete [] input_;
- input_ = NULL;
delete [] encoded_;
encoded_ = NULL;
- delete [] decoded_;
- decoded_ = NULL;
// Close log.
DataLog::ReturnLog();
}
virtual void InitEncoder() { }
- // This method must be implemented for all tests derived from this class.
- virtual int EncodeFrame(const int16_t* input, size_t input_len,
- uint8_t* output) = 0;
+ // TODO(henrik.lundin) Change return type to size_t once most/all overriding
+ // implementations are gone.
+ virtual int EncodeFrame(const int16_t* input,
+ size_t input_len_samples,
+ uint8_t* output) {
+ size_t enc_len_bytes = 0;
+ scoped_ptr<int16_t[]> interleaved_input(
+ new int16_t[channels_ * input_len_samples]);
+ for (int i = 0; i < audio_encoder_->Num10MsFramesInNextPacket(); ++i) {
+ EXPECT_EQ(0u, enc_len_bytes);
+
+ // Duplicate the mono input signal to however many channels the test
+ // wants.
+ test::InputAudioFile::DuplicateInterleaved(
+ input, input_len_samples, channels_, interleaved_input.get());
+
+ EXPECT_TRUE(audio_encoder_->Encode(
+ 0, interleaved_input.get(), audio_encoder_->sample_rate_hz() / 100,
+ data_length_ * 2, output, &enc_len_bytes, &output_timestamp_));
+ }
+ return static_cast<int>(enc_len_bytes);
+ }
// Encodes and decodes audio. The absolute difference between the input and
// output is compared vs |tolerance|, and the mean-squared error is compared
@@ -108,13 +171,23 @@ class AudioDecoderTest : public ::testing::Test {
encoded_bytes_ = 0u;
InitEncoder();
EXPECT_EQ(0, decoder_->Init());
+ std::vector<int16_t> input;
+ std::vector<int16_t> decoded;
while (processed_samples + frame_size_ <= data_length_) {
- size_t enc_len = EncodeFrame(&input_[processed_samples], frame_size_,
- &encoded_[encoded_bytes_]);
+ // Extend input vector with |frame_size_|.
+ input.resize(input.size() + frame_size_, 0);
+ // Read from input file.
+ ASSERT_GE(input.size() - processed_samples, frame_size_);
+ ASSERT_TRUE(input_audio_.Read(
+ frame_size_, codec_input_rate_hz_, &input[processed_samples]));
+ size_t enc_len = EncodeFrame(
+ &input[processed_samples], frame_size_, &encoded_[encoded_bytes_]);
+ // Make sure that frame_size_ * channels_ samples are allocated and free.
+ decoded.resize((processed_samples + frame_size_) * channels_, 0);
AudioDecoder::SpeechType speech_type;
- size_t dec_len = decoder_->Decode(&encoded_[encoded_bytes_], enc_len,
- &decoded_[processed_samples *
- channels_],
+ size_t dec_len = decoder_->Decode(&encoded_[encoded_bytes_],
+ enc_len,
+ &decoded[processed_samples * channels_],
&speech_type);
EXPECT_EQ(frame_size_ * channels_, dec_len);
encoded_bytes_ += enc_len;
@@ -126,65 +199,36 @@ class AudioDecoderTest : public ::testing::Test {
if (expected_bytes) {
EXPECT_EQ(expected_bytes, encoded_bytes_);
}
- CompareInputOutput(processed_samples, tolerance, delay);
+ CompareInputOutput(
+ input, decoded, processed_samples, channels_, tolerance, delay);
if (channels_ == 2)
- CompareTwoChannels(processed_samples, channel_diff_tolerance);
- EXPECT_LE(MseInputOutput(processed_samples, delay), mse);
- }
-
- // The absolute difference between the input and output (the first channel) is
- // compared vs |tolerance|. The parameter |delay| is used to correct for codec
- // delays.
- virtual void CompareInputOutput(size_t num_samples, int tolerance,
- int delay) const {
- assert(num_samples <= data_length_);
- for (unsigned int n = 0; n < num_samples - delay; ++n) {
- ASSERT_NEAR(input_[n], decoded_[channels_ * n + delay], tolerance) <<
- "Exit test on first diff; n = " << n;
- DataLog::InsertCell("CodecTest", "input", input_[n]);
- DataLog::InsertCell("CodecTest", "output", decoded_[channels_ * n]);
- DataLog::NextRow("CodecTest");
- }
- }
-
- // The absolute difference between the two channels in a stereo is compared vs
- // |tolerance|.
- virtual void CompareTwoChannels(size_t samples_per_channel,
- int tolerance) const {
- assert(samples_per_channel <= data_length_);
- for (unsigned int n = 0; n < samples_per_channel; ++n)
- ASSERT_NEAR(decoded_[channels_ * n], decoded_[channels_ * n + 1],
- tolerance) << "Stereo samples differ.";
- }
-
- // Calculates mean-squared error between input and output (the first channel).
- // The parameter |delay| is used to correct for codec delays.
- virtual double MseInputOutput(size_t num_samples, int delay) const {
- assert(num_samples <= data_length_);
- if (num_samples == 0) return 0.0;
- double squared_sum = 0.0;
- for (unsigned int n = 0; n < num_samples - delay; ++n) {
- squared_sum += (input_[n] - decoded_[channels_ * n + delay]) *
- (input_[n] - decoded_[channels_ * n + delay]);
- }
- return squared_sum / (num_samples - delay);
+ CompareTwoChannels(
+ decoded, processed_samples, channels_, channel_diff_tolerance);
+ EXPECT_LE(
+ MseInputOutput(input, decoded, processed_samples, channels_, delay),
+ mse);
}
// Encodes a payload and decodes it twice with decoder re-init before each
// decode. Verifies that the decoded result is the same.
void ReInitTest() {
- int16_t* output1 = decoded_;
- int16_t* output2 = decoded_ + frame_size_;
InitEncoder();
- size_t enc_len = EncodeFrame(input_, frame_size_, encoded_);
+ scoped_ptr<int16_t[]> input(new int16_t[frame_size_]);
+ ASSERT_TRUE(
+ input_audio_.Read(frame_size_, codec_input_rate_hz_, input.get()));
+ size_t enc_len = EncodeFrame(input.get(), frame_size_, encoded_);
size_t dec_len;
AudioDecoder::SpeechType speech_type1, speech_type2;
EXPECT_EQ(0, decoder_->Init());
- dec_len = decoder_->Decode(encoded_, enc_len, output1, &speech_type1);
+ scoped_ptr<int16_t[]> output1(new int16_t[frame_size_ * channels_]);
+ dec_len = decoder_->Decode(encoded_, enc_len, output1.get(), &speech_type1);
+ ASSERT_LE(dec_len, frame_size_ * channels_);
EXPECT_EQ(frame_size_ * channels_, dec_len);
// Re-init decoder and decode again.
EXPECT_EQ(0, decoder_->Init());
- dec_len = decoder_->Decode(encoded_, enc_len, output2, &speech_type2);
+ scoped_ptr<int16_t[]> output2(new int16_t[frame_size_ * channels_]);
+ dec_len = decoder_->Decode(encoded_, enc_len, output2.get(), &speech_type2);
+ ASSERT_LE(dec_len, frame_size_ * channels_);
EXPECT_EQ(frame_size_ * channels_, dec_len);
for (unsigned int n = 0; n < frame_size_; ++n) {
ASSERT_EQ(output1[n], output2[n]) << "Exit test on first diff; n = " << n;
@@ -195,29 +239,33 @@ class AudioDecoderTest : public ::testing::Test {
// Call DecodePlc and verify that the correct number of samples is produced.
void DecodePlcTest() {
InitEncoder();
- size_t enc_len = EncodeFrame(input_, frame_size_, encoded_);
+ scoped_ptr<int16_t[]> input(new int16_t[frame_size_]);
+ ASSERT_TRUE(
+ input_audio_.Read(frame_size_, codec_input_rate_hz_, input.get()));
+ size_t enc_len = EncodeFrame(input.get(), frame_size_, encoded_);
AudioDecoder::SpeechType speech_type;
EXPECT_EQ(0, decoder_->Init());
+ scoped_ptr<int16_t[]> output(new int16_t[frame_size_ * channels_]);
size_t dec_len =
- decoder_->Decode(encoded_, enc_len, decoded_, &speech_type);
+ decoder_->Decode(encoded_, enc_len, output.get(), &speech_type);
EXPECT_EQ(frame_size_ * channels_, dec_len);
// Call DecodePlc and verify that we get one frame of data.
// (Overwrite the output from the above Decode call, but that does not
// matter.)
- dec_len = decoder_->DecodePlc(1, decoded_);
+ dec_len = decoder_->DecodePlc(1, output.get());
EXPECT_EQ(frame_size_ * channels_, dec_len);
}
- std::string input_file_;
- FILE* input_fp_;
- int16_t* input_;
+ test::ResampleInputAudioFile input_audio_;
+ int codec_input_rate_hz_;
uint8_t* encoded_;
- int16_t* decoded_;
size_t frame_size_;
size_t data_length_;
size_t encoded_bytes_;
size_t channels_;
+ uint32_t output_timestamp_;
AudioDecoder* decoder_;
+ scoped_ptr<AudioEncoder> audio_encoder_;
};
class AudioDecoderPcmUTest : public AudioDecoderTest {
@@ -226,17 +274,9 @@ class AudioDecoderPcmUTest : public AudioDecoderTest {
frame_size_ = 160;
data_length_ = 10 * frame_size_;
decoder_ = new AudioDecoderPcmU;
- assert(decoder_);
- }
-
- virtual int EncodeFrame(const int16_t* input, size_t input_len_samples,
- uint8_t* output) {
- int enc_len_bytes =
- WebRtcG711_EncodeU(NULL, const_cast<int16_t*>(input),
- static_cast<int>(input_len_samples),
- reinterpret_cast<int16_t*>(output));
- EXPECT_EQ(input_len_samples, static_cast<size_t>(enc_len_bytes));
- return enc_len_bytes;
+ AudioEncoderPcmU::Config config;
+ config.frame_size_ms = static_cast<int>(frame_size_ / 8);
+ audio_encoder_.reset(new AudioEncoderPcmU(config));
}
};
@@ -246,26 +286,19 @@ class AudioDecoderPcmATest : public AudioDecoderTest {
frame_size_ = 160;
data_length_ = 10 * frame_size_;
decoder_ = new AudioDecoderPcmA;
- assert(decoder_);
- }
-
- virtual int EncodeFrame(const int16_t* input, size_t input_len_samples,
- uint8_t* output) {
- int enc_len_bytes =
- WebRtcG711_EncodeA(NULL, const_cast<int16_t*>(input),
- static_cast<int>(input_len_samples),
- reinterpret_cast<int16_t*>(output));
- EXPECT_EQ(input_len_samples, static_cast<size_t>(enc_len_bytes));
- return enc_len_bytes;
+ AudioEncoderPcmA::Config config;
+ config.frame_size_ms = static_cast<int>(frame_size_ / 8);
+ audio_encoder_.reset(new AudioEncoderPcmA(config));
}
};
class AudioDecoderPcm16BTest : public AudioDecoderTest {
protected:
AudioDecoderPcm16BTest() : AudioDecoderTest() {
+ codec_input_rate_hz_ = 8000;
frame_size_ = 160;
data_length_ = 10 * frame_size_;
- decoder_ = new AudioDecoderPcm16B(kDecoderPCM16B);
+ decoder_ = new AudioDecoderPcm16B;
assert(decoder_);
}
@@ -282,6 +315,7 @@ class AudioDecoderPcm16BTest : public AudioDecoderTest {
class AudioDecoderIlbcTest : public AudioDecoderTest {
protected:
AudioDecoderIlbcTest() : AudioDecoderTest() {
+ codec_input_rate_hz_ = 8000;
frame_size_ = 240;
data_length_ = 10 * frame_size_;
decoder_ = new AudioDecoderIlbc;
@@ -311,14 +345,18 @@ class AudioDecoderIlbcTest : public AudioDecoderTest {
// not return any data. It simply resets a few states and returns 0.
void DecodePlcTest() {
InitEncoder();
- size_t enc_len = EncodeFrame(input_, frame_size_, encoded_);
+ scoped_ptr<int16_t[]> input(new int16_t[frame_size_]);
+ ASSERT_TRUE(
+ input_audio_.Read(frame_size_, codec_input_rate_hz_, input.get()));
+ size_t enc_len = EncodeFrame(input.get(), frame_size_, encoded_);
AudioDecoder::SpeechType speech_type;
EXPECT_EQ(0, decoder_->Init());
+ scoped_ptr<int16_t[]> output(new int16_t[frame_size_ * channels_]);
size_t dec_len =
- decoder_->Decode(encoded_, enc_len, decoded_, &speech_type);
+ decoder_->Decode(encoded_, enc_len, output.get(), &speech_type);
EXPECT_EQ(frame_size_, dec_len);
// Simply call DecodePlc and verify that we get 0 as return value.
- EXPECT_EQ(0, decoder_->DecodePlc(1, decoded_));
+ EXPECT_EQ(0, decoder_->DecodePlc(1, output.get()));
}
iLBC_encinst_t* encoder_;
@@ -327,10 +365,11 @@ class AudioDecoderIlbcTest : public AudioDecoderTest {
class AudioDecoderIsacFloatTest : public AudioDecoderTest {
protected:
AudioDecoderIsacFloatTest() : AudioDecoderTest() {
+ codec_input_rate_hz_ = 16000;
input_size_ = 160;
frame_size_ = 480;
data_length_ = 10 * frame_size_;
- decoder_ = new AudioDecoderIsac;
+ decoder_ = new AudioDecoderIsac(16000);
assert(decoder_);
WebRtcIsac_Create(&encoder_);
WebRtcIsac_SetEncSampRate(encoder_, 16000);
@@ -364,10 +403,11 @@ class AudioDecoderIsacFloatTest : public AudioDecoderTest {
class AudioDecoderIsacSwbTest : public AudioDecoderTest {
protected:
AudioDecoderIsacSwbTest() : AudioDecoderTest() {
+ codec_input_rate_hz_ = 32000;
input_size_ = 320;
frame_size_ = 960;
data_length_ = 10 * frame_size_;
- decoder_ = new AudioDecoderIsacSwb;
+ decoder_ = new AudioDecoderIsac(32000);
assert(decoder_);
WebRtcIsac_Create(&encoder_);
WebRtcIsac_SetEncSampRate(encoder_, 32000);
@@ -398,22 +438,10 @@ class AudioDecoderIsacSwbTest : public AudioDecoderTest {
int input_size_;
};
-// This test is identical to AudioDecoderIsacSwbTest, except that it creates
-// an AudioDecoderIsacFb decoder object.
-class AudioDecoderIsacFbTest : public AudioDecoderIsacSwbTest {
- protected:
- AudioDecoderIsacFbTest() : AudioDecoderIsacSwbTest() {
- // Delete the |decoder_| that was created by AudioDecoderIsacSwbTest and
- // create an AudioDecoderIsacFb object instead.
- delete decoder_;
- decoder_ = new AudioDecoderIsacFb;
- assert(decoder_);
- }
-};
-
class AudioDecoderIsacFixTest : public AudioDecoderTest {
protected:
AudioDecoderIsacFixTest() : AudioDecoderTest() {
+ codec_input_rate_hz_ = 16000;
input_size_ = 160;
frame_size_ = 480;
data_length_ = 10 * frame_size_;
@@ -451,6 +479,7 @@ class AudioDecoderIsacFixTest : public AudioDecoderTest {
class AudioDecoderG722Test : public AudioDecoderTest {
protected:
AudioDecoderG722Test() : AudioDecoderTest() {
+ codec_input_rate_hz_ = 16000;
frame_size_ = 160;
data_length_ = 10 * frame_size_;
decoder_ = new AudioDecoderG722;
@@ -593,79 +622,26 @@ class AudioDecoderCeltStereoTest : public AudioDecoderTest {
class AudioDecoderOpusTest : public AudioDecoderTest {
protected:
AudioDecoderOpusTest() : AudioDecoderTest() {
+ codec_input_rate_hz_ = 48000;
frame_size_ = 480;
data_length_ = 10 * frame_size_;
- decoder_ = new AudioDecoderOpus(kDecoderOpus);
- assert(decoder_);
- WebRtcOpus_EncoderCreate(&encoder_, 1);
- }
-
- ~AudioDecoderOpusTest() {
- WebRtcOpus_EncoderFree(encoder_);
- }
-
- virtual void SetUp() OVERRIDE {
- AudioDecoderTest::SetUp();
- // Upsample from 32 to 48 kHz.
- // Because Opus is 48 kHz codec but the input file is 32 kHz, so the data
- // read in |AudioDecoderTest::SetUp| has to be upsampled.
- // |AudioDecoderTest::SetUp| has read |data_length_| samples, which is more
- // than necessary after upsampling, so the end of audio that has been read
- // is unused and the end of the buffer is overwritten by the resampled data.
- Resampler rs;
- rs.Reset(32000, 48000, kResamplerSynchronous);
- const int before_resamp_len_samples = static_cast<int>(data_length_) * 2
- / 3;
- int16_t* before_resamp_input = new int16_t[before_resamp_len_samples];
- memcpy(before_resamp_input, input_,
- sizeof(int16_t) * before_resamp_len_samples);
- int resamp_len_samples;
- EXPECT_EQ(0, rs.Push(before_resamp_input, before_resamp_len_samples,
- input_, static_cast<int>(data_length_),
- resamp_len_samples));
- EXPECT_EQ(static_cast<int>(data_length_), resamp_len_samples);
- delete[] before_resamp_input;
- }
-
- virtual void InitEncoder() {}
-
- virtual int EncodeFrame(const int16_t* input, size_t input_len_samples,
- uint8_t* output) OVERRIDE {
- int enc_len_bytes = WebRtcOpus_Encode(encoder_, const_cast<int16_t*>(input),
- static_cast<int16_t>(input_len_samples),
- static_cast<int16_t>(data_length_), output);
- EXPECT_GT(enc_len_bytes, 0);
- return enc_len_bytes;
+ decoder_ = new AudioDecoderOpus(1);
+ AudioEncoderOpus::Config config;
+ config.frame_size_ms = static_cast<int>(frame_size_) / 48;
+ audio_encoder_.reset(new AudioEncoderOpus(config));
}
-
- OpusEncInst* encoder_;
};
class AudioDecoderOpusStereoTest : public AudioDecoderOpusTest {
protected:
AudioDecoderOpusStereoTest() : AudioDecoderOpusTest() {
channels_ = 2;
- WebRtcOpus_EncoderFree(encoder_);
delete decoder_;
- decoder_ = new AudioDecoderOpus(kDecoderOpus_2ch);
- assert(decoder_);
- WebRtcOpus_EncoderCreate(&encoder_, 2);
- }
-
- virtual int EncodeFrame(const int16_t* input, size_t input_len_samples,
- uint8_t* output) OVERRIDE {
- // Create stereo by duplicating each sample in |input|.
- const int input_stereo_samples = static_cast<int>(input_len_samples) * 2;
- int16_t* input_stereo = new int16_t[input_stereo_samples];
- for (size_t i = 0; i < input_len_samples; i++)
- input_stereo[i * 2] = input_stereo[i * 2 + 1] = input[i];
-
- int enc_len_bytes = WebRtcOpus_Encode(
- encoder_, input_stereo, static_cast<int16_t>(input_len_samples),
- static_cast<int16_t>(data_length_), output);
- EXPECT_GT(enc_len_bytes, 0);
- delete[] input_stereo;
- return enc_len_bytes;
+ decoder_ = new AudioDecoderOpus(2);
+ AudioEncoderOpus::Config config;
+ config.frame_size_ms = static_cast<int>(frame_size_) / 48;
+ config.num_channels = 2;
+ audio_encoder_.reset(new AudioEncoderOpus(config));
}
};
@@ -732,17 +708,6 @@ TEST_F(AudioDecoderIsacSwbTest, EncodeDecode) {
DecodePlcTest();
}
-TEST_F(AudioDecoderIsacFbTest, EncodeDecode) {
- int tolerance = 19757;
- double mse = 8.18e6;
- int delay = 160; // Delay from input to output.
- EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderISACswb));
- EncodeDecodeTest(0, tolerance, mse, delay);
- ReInitTest();
- EXPECT_TRUE(decoder_->HasDecodePlc());
- DecodePlcTest();
-}
-
TEST_F(AudioDecoderIsacFixTest, DISABLED_EncodeDecode) {
int tolerance = 11034;
double mse = 3.46e6;
diff --git a/modules/audio_coding/neteq/audio_decoder_unittests.isolate b/modules/audio_coding/neteq/audio_decoder_unittests.isolate
index e4a18ca8..f10b327b 100644
--- a/modules/audio_coding/neteq/audio_decoder_unittests.isolate
+++ b/modules/audio_coding/neteq/audio_decoder_unittests.isolate
@@ -9,7 +9,7 @@
'conditions': [
['OS=="android"', {
'variables': {
- 'isolate_dependency_untracked': [
+ 'files': [
'<(DEPTH)/resources/',
'<(DEPTH)/data/',
],
@@ -21,17 +21,12 @@
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/audio_decoder_unittests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_touched': [
+ 'files': [
'<(DEPTH)/DEPS',
- ],
- 'isolate_dependency_tracked': [
'<(DEPTH)/resources/audio_coding/testfile32kHz.pcm',
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/audio_decoder_unittests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_untracked': [
- '<(DEPTH)/tools/swarming_client/',
- ],
},
}],
],
diff --git a/modules/audio_coding/neteq/decision_logic_normal.cc b/modules/audio_coding/neteq/decision_logic_normal.cc
index 9e422041..f2382845 100644
--- a/modules/audio_coding/neteq/decision_logic_normal.cc
+++ b/modules/audio_coding/neteq/decision_logic_normal.cc
@@ -67,19 +67,19 @@ Operations DecisionLogicNormal::GetDecisionSpecialized(
return kNormal;
}
+ const uint32_t five_seconds_samples = 5 * 8000 * fs_mult_;
// Check if the required packet is available.
if (target_timestamp == available_timestamp) {
return ExpectedPacketAvailable(prev_mode, play_dtmf);
- } else if (IsNewerTimestamp(available_timestamp, target_timestamp)) {
+ } else if (!PacketBuffer::IsObsoleteTimestamp(
+ available_timestamp, target_timestamp, five_seconds_samples)) {
return FuturePacketAvailable(sync_buffer, expand, decoder_frame_length,
prev_mode, target_timestamp,
available_timestamp, play_dtmf);
} else {
// This implies that available_timestamp < target_timestamp, which can
- // happen when a new stream or codec is received. Do Expand instead, and
- // wait for a newer packet to arrive, or for the buffer to flush (resulting
- // in a master reset).
- return kExpand;
+ // happen when a new stream or codec is received. Signal for a reset.
+ return kUndefined;
}
}
diff --git a/modules/audio_coding/neteq/decoder_database_unittest.cc b/modules/audio_coding/neteq/decoder_database_unittest.cc
index 6f497199..1e4e58af 100644
--- a/modules/audio_coding/neteq/decoder_database_unittest.cc
+++ b/modules/audio_coding/neteq/decoder_database_unittest.cc
@@ -189,21 +189,18 @@ TEST(DecoderDatabase, ActiveDecoders) {
EXPECT_TRUE(changed);
AudioDecoder* decoder = db.GetActiveDecoder();
ASSERT_FALSE(decoder == NULL); // Should get a decoder here.
- EXPECT_EQ(kDecoderPCMu, decoder->codec_type());
// Set the same again. Expect no change.
EXPECT_EQ(DecoderDatabase::kOK, db.SetActiveDecoder(0, &changed));
EXPECT_FALSE(changed);
decoder = db.GetActiveDecoder();
ASSERT_FALSE(decoder == NULL); // Should get a decoder here.
- EXPECT_EQ(kDecoderPCMu, decoder->codec_type());
// Change active decoder.
EXPECT_EQ(DecoderDatabase::kOK, db.SetActiveDecoder(103, &changed));
EXPECT_TRUE(changed);
decoder = db.GetActiveDecoder();
ASSERT_FALSE(decoder == NULL); // Should get a decoder here.
- EXPECT_EQ(kDecoderISAC, decoder->codec_type());
// Remove the active decoder, and verify that the active becomes NULL.
EXPECT_EQ(DecoderDatabase::kOK, db.Remove(103));
@@ -213,7 +210,6 @@ TEST(DecoderDatabase, ActiveDecoders) {
EXPECT_EQ(DecoderDatabase::kOK, db.SetActiveCngDecoder(13));
decoder = db.GetActiveCngDecoder();
ASSERT_FALSE(decoder == NULL); // Should get a decoder here.
- EXPECT_EQ(kDecoderCNGnb, decoder->codec_type());
// Remove the active CNG decoder, and verify that the active becomes NULL.
EXPECT_EQ(DecoderDatabase::kOK, db.Remove(13));
diff --git a/modules/audio_coding/neteq/expand.cc b/modules/audio_coding/neteq/expand.cc
index 1f46e66c..49ea45f4 100644
--- a/modules/audio_coding/neteq/expand.cc
+++ b/modules/audio_coding/neteq/expand.cc
@@ -488,7 +488,7 @@ void Expand::AnalyzeSignal(int16_t* random_vector) {
// Calculate scaled_energy1 / scaled_energy2 in Q13.
int32_t energy_ratio = WebRtcSpl_DivW32W16(
WEBRTC_SPL_SHIFT_W32(energy1, -scaled_energy1),
- WEBRTC_SPL_RSHIFT_W32(energy2, scaled_energy2));
+ energy2 >> scaled_energy2);
// Calculate sqrt ratio in Q13 (sqrt of en1/en2 in Q26).
amplitude_ratio = WebRtcSpl_SqrtFloor(energy_ratio << 13);
// Copy the two vectors and give them the same energy.
diff --git a/modules/audio_coding/neteq/interface/audio_decoder.h b/modules/audio_coding/neteq/interface/audio_decoder.h
index 9a2fb8b4..16d78c9e 100644
--- a/modules/audio_coding/neteq/interface/audio_decoder.h
+++ b/modules/audio_coding/neteq/interface/audio_decoder.h
@@ -63,12 +63,7 @@ class AudioDecoder {
// Used by PacketDuration below. Save the value -1 for errors.
enum { kNotImplemented = -2 };
- explicit AudioDecoder(enum NetEqDecoder type)
- : codec_type_(type),
- channels_(1),
- state_(NULL) {
- }
-
+ AudioDecoder() : channels_(1), state_(NULL) {}
virtual ~AudioDecoder() {}
// Decodes |encode_len| bytes from |encoded| and writes the result in
@@ -119,8 +114,6 @@ class AudioDecoder {
// Returns true if the packet has FEC and false otherwise.
virtual bool PacketHasFec(const uint8_t* encoded, size_t encoded_len) const;
- virtual NetEqDecoder codec_type() const;
-
// Returns the underlying decoder state.
void* state() { return state_; }
@@ -140,7 +133,6 @@ class AudioDecoder {
protected:
static SpeechType ConvertSpeechType(int16_t type);
- enum NetEqDecoder codec_type_;
size_t channels_;
void* state_;
diff --git a/modules/audio_coding/neteq/interface/neteq.h b/modules/audio_coding/neteq/interface/neteq.h
index 925cb231..560e77ba 100644
--- a/modules/audio_coding/neteq/interface/neteq.h
+++ b/modules/audio_coding/neteq/interface/neteq.h
@@ -248,7 +248,7 @@ class NetEq {
// Returns the error code for the last occurred error. If no error has
// occurred, 0 is returned.
- virtual int LastError() = 0;
+ virtual int LastError() const = 0;
// Returns the error code last returned by a decoder (audio or comfort noise).
// When LastError() returns kDecoderErrorCode or kComfortNoiseErrorCode, check
diff --git a/modules/audio_coding/neteq/mock/mock_audio_decoder.h b/modules/audio_coding/neteq/mock/mock_audio_decoder.h
index f3cecc24..95b564d1 100644
--- a/modules/audio_coding/neteq/mock/mock_audio_decoder.h
+++ b/modules/audio_coding/neteq/mock/mock_audio_decoder.h
@@ -19,7 +19,7 @@ namespace webrtc {
class MockAudioDecoder : public AudioDecoder {
public:
- MockAudioDecoder() : AudioDecoder(kDecoderArbitrary) {}
+ MockAudioDecoder() {}
virtual ~MockAudioDecoder() { Die(); }
MOCK_METHOD0(Die, void());
MOCK_METHOD4(Decode, int(const uint8_t*, size_t, int16_t*,
diff --git a/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h b/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h
index ef5e03e5..400c0b03 100644
--- a/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h
+++ b/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h
@@ -27,15 +27,13 @@ using ::testing::Invoke;
// audio_decoder_impl.{cc, h}.
class ExternalPcm16B : public AudioDecoder {
public:
- explicit ExternalPcm16B(enum NetEqDecoder type)
- : AudioDecoder(type) {
- }
+ ExternalPcm16B() {}
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type) {
int16_t temp_type;
int16_t ret = WebRtcPcm16b_DecodeW16(
- state_, reinterpret_cast<int16_t*>(const_cast<uint8_t*>(encoded)),
+ reinterpret_cast<int16_t*>(const_cast<uint8_t*>(encoded)),
static_cast<int16_t>(encoded_len), decoded, &temp_type);
*speech_type = ConvertSpeechType(temp_type);
return ret;
@@ -51,9 +49,7 @@ class ExternalPcm16B : public AudioDecoder {
// The reason is that we can then track that the correct calls are being made.
class MockExternalPcm16B : public ExternalPcm16B {
public:
- explicit MockExternalPcm16B(enum NetEqDecoder type)
- : ExternalPcm16B(type),
- real_(type) {
+ MockExternalPcm16B() {
// By default, all calls are delegated to the real object.
ON_CALL(*this, Decode(_, _, _, _))
.WillByDefault(Invoke(&real_, &ExternalPcm16B::Decode));
@@ -67,8 +63,6 @@ class MockExternalPcm16B : public ExternalPcm16B {
.WillByDefault(Invoke(&real_, &ExternalPcm16B::IncomingPacket));
ON_CALL(*this, ErrorCode())
.WillByDefault(Invoke(&real_, &ExternalPcm16B::ErrorCode));
- ON_CALL(*this, codec_type())
- .WillByDefault(Invoke(&real_, &ExternalPcm16B::codec_type));
}
virtual ~MockExternalPcm16B() { Die(); }
diff --git a/modules/audio_coding/neteq/mock/mock_packet_buffer.h b/modules/audio_coding/neteq/mock/mock_packet_buffer.h
index 74eea6f0..0eb7edc9 100644
--- a/modules/audio_coding/neteq/mock/mock_packet_buffer.h
+++ b/modules/audio_coding/neteq/mock/mock_packet_buffer.h
@@ -44,7 +44,9 @@ class MockPacketBuffer : public PacketBuffer {
Packet*(int* discard_count));
MOCK_METHOD0(DiscardNextPacket,
int());
- MOCK_METHOD1(DiscardOldPackets,
+ MOCK_METHOD2(DiscardOldPackets,
+ int(uint32_t timestamp_limit, uint32_t horizon_samples));
+ MOCK_METHOD1(DiscardAllOldPackets,
int(uint32_t timestamp_limit));
MOCK_CONST_METHOD0(NumPacketsInBuffer,
int());
diff --git a/modules/audio_coding/neteq/neteq.gypi b/modules/audio_coding/neteq/neteq.gypi
index 0901615a..c68651d6 100644
--- a/modules/audio_coding/neteq/neteq.gypi
+++ b/modules/audio_coding/neteq/neteq.gypi
@@ -136,6 +136,7 @@
'type': '<(gtest_target_type)',
'dependencies': [
'<@(codecs)',
+ 'neteq_unittest_tools',
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(webrtc_root)/common_audio/common_audio.gyp:common_audio',
'<(webrtc_root)/test/test.gyp:test_support_main',
@@ -170,7 +171,7 @@
'type': 'static_library',
'dependencies': [
'rtp_rtcp',
- '<(webrtc_root)/test/webrtc_test_common.gyp:webrtc_test_common',
+ '<(webrtc_root)/test/test.gyp:rtp_test_utils',
],
'direct_dependent_settings': {
'include_dirs': [
@@ -193,6 +194,8 @@
'tools/packet.cc',
'tools/packet.h',
'tools/packet_source.h',
+ 'tools/resample_input_audio_file.cc',
+ 'tools/resample_input_audio_file.h',
'tools/rtp_file_source.cc',
'tools/rtp_file_source.h',
'tools/rtp_generator.cc',
@@ -222,7 +225,6 @@
],
'includes': [
'../../../build/isolate.gypi',
- 'audio_decoder_unittests.isolate',
],
'sources': [
'audio_decoder_unittests.isolate',
diff --git a/modules/audio_coding/neteq/neteq_external_decoder_unittest.cc b/modules/audio_coding/neteq/neteq_external_decoder_unittest.cc
index 6a8eafa1..d41bc543 100644
--- a/modules/audio_coding/neteq/neteq_external_decoder_unittest.cc
+++ b/modules/audio_coding/neteq/neteq_external_decoder_unittest.cc
@@ -47,7 +47,7 @@ class NetEqExternalDecoderTest : public ::testing::Test {
frame_size_ms_(10),
frame_size_samples_(frame_size_ms_ * samples_per_ms_),
output_size_samples_(frame_size_ms_ * samples_per_ms_),
- external_decoder_(new MockExternalPcm16B(kDecoderPCM16Bswb32kHz)),
+ external_decoder_(new MockExternalPcm16B),
rtp_generator_(new test::RtpGenerator(samples_per_ms_)),
payload_size_bytes_(0),
last_send_time_(0),
@@ -241,7 +241,7 @@ class LargeTimestampJumpTest : public NetEqExternalDecoderTest {
frame_size_samples_ = frame_size_ms_ * samples_per_ms_;
output_size_samples_ = frame_size_ms_ * samples_per_ms_;
EXPECT_CALL(*external_decoder_, Die()).Times(1);
- external_decoder_.reset(new MockExternalPcm16B(kDecoderPCM16B));
+ external_decoder_.reset(new MockExternalPcm16B);
}
void SetUp() OVERRIDE {
@@ -308,6 +308,8 @@ class LargeTimestampJumpTest : public NetEqExternalDecoderTest {
case kExpandPhase: {
if (output_type == kOutputPLCtoCNG) {
test_state_ = kFadedExpandPhase;
+ } else if (output_type == kOutputNormal) {
+ test_state_ = kRecovered;
}
break;
}
@@ -337,9 +339,14 @@ class LargeTimestampJumpTest : public NetEqExternalDecoderTest {
}
int NumExpectedDecodeCalls(int num_loops) const OVERRIDE {
- // Some packets won't be decoded because of the buffer being flushed after
- // the timestamp jump.
- return num_loops - (config_.max_packets_in_buffer + 1);
+ // Some packets at the end of the stream won't be decoded. When the jump in
+ // timestamp happens, NetEq will do Expand during one GetAudio call. In the
+ // next call it will decode the packet after the jump, but the net result is
+ // that the delay increased by 1 packet. In another call, a Pre-emptive
+ // Expand operation is performed, leading to delay increase by 1 packet. In
+ // total, the test will end with a 2-packet delay, which results in the 2
+ // last packets not being decoded.
+ return num_loops - 2;
}
TestStates test_state_;
diff --git a/modules/audio_coding/neteq/neteq_impl.cc b/modules/audio_coding/neteq/neteq_impl.cc
index edf618ef..f3d1a4f6 100644
--- a/modules/audio_coding/neteq/neteq_impl.cc
+++ b/modules/audio_coding/neteq/neteq_impl.cc
@@ -352,7 +352,7 @@ bool NetEqImpl::GetPlayoutTimestamp(uint32_t* timestamp) {
return true;
}
-int NetEqImpl::LastError() {
+int NetEqImpl::LastError() const {
CriticalSectionScoped lock(crit_sect_.get());
return error_code_;
}
@@ -868,6 +868,10 @@ int NetEqImpl::GetDecision(Operations* operation,
assert(sync_buffer_.get());
uint32_t end_timestamp = sync_buffer_->end_timestamp();
+ if (!new_codec_) {
+ const uint32_t five_seconds_samples = 5 * fs_hz_;
+ packet_buffer_->DiscardOldPackets(end_timestamp, five_seconds_samples);
+ }
const RTPHeader* header = packet_buffer_->NextRtpHeader();
if (decision_logic_->CngRfc3389On() || last_mode_ == kModeRfc3389Cng) {
@@ -884,7 +888,7 @@ int NetEqImpl::GetDecision(Operations* operation,
}
// Check buffer again.
if (!new_codec_) {
- packet_buffer_->DiscardOldPackets(end_timestamp);
+ packet_buffer_->DiscardOldPackets(end_timestamp, 5 * fs_hz_);
}
header = packet_buffer_->NextRtpHeader();
}
@@ -1823,7 +1827,7 @@ int NetEqImpl::ExtractPackets(int required_samples, PacketList* packet_list) {
// we could end up in the situation where we never decode anything, since
// all incoming packets are considered too old but the buffer will also
// never be flooded and flushed.
- packet_buffer_->DiscardOldPackets(timestamp_);
+ packet_buffer_->DiscardAllOldPackets(timestamp_);
}
return extracted_samples;
diff --git a/modules/audio_coding/neteq/neteq_impl.h b/modules/audio_coding/neteq/neteq_impl.h
index fc2284d9..348f483c 100644
--- a/modules/audio_coding/neteq/neteq_impl.h
+++ b/modules/audio_coding/neteq/neteq_impl.h
@@ -178,7 +178,7 @@ class NetEqImpl : public webrtc::NetEq {
// Returns the error code for the last occurred error. If no error has
// occurred, 0 is returned.
- virtual int LastError() OVERRIDE;
+ virtual int LastError() const OVERRIDE;
// Returns the error code last returned by a decoder (audio or comfort noise).
// When LastError() returns kDecoderErrorCode or kComfortNoiseErrorCode, check
diff --git a/modules/audio_coding/neteq/neteq_impl_unittest.cc b/modules/audio_coding/neteq/neteq_impl_unittest.cc
index d5676d7b..8047fe20 100644
--- a/modules/audio_coding/neteq/neteq_impl_unittest.cc
+++ b/modules/audio_coding/neteq/neteq_impl_unittest.cc
@@ -32,9 +32,11 @@ using ::testing::Return;
using ::testing::ReturnNull;
using ::testing::_;
using ::testing::SetArgPointee;
+using ::testing::SetArrayArgument;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::WithArg;
+using ::testing::Pointee;
namespace webrtc {
@@ -422,8 +424,7 @@ TEST_F(NetEqImplTest, VerifyTimestampPropagation) {
// sample, and then increasing by 1 for each sample.
class CountingSamplesDecoder : public AudioDecoder {
public:
- explicit CountingSamplesDecoder(enum NetEqDecoder type)
- : AudioDecoder(type), next_value_(1) {}
+ CountingSamplesDecoder() : next_value_(1) {}
// Produce as many samples as input bytes (|encoded_len|).
virtual int Decode(const uint8_t* encoded,
@@ -446,7 +447,7 @@ TEST_F(NetEqImplTest, VerifyTimestampPropagation) {
private:
int16_t next_value_;
- } decoder_(kDecoderPCM16B);
+ } decoder_;
EXPECT_EQ(NetEq::kOK,
neteq_->RegisterExternalDecoder(
@@ -495,4 +496,95 @@ TEST_F(NetEqImplTest, VerifyTimestampPropagation) {
static_cast<int>(sync_buffer->FutureLength()));
}
+TEST_F(NetEqImplTest, ReorderedPacket) {
+ UseNoMocks();
+ CreateInstance();
+
+ const uint8_t kPayloadType = 17; // Just an arbitrary number.
+ const uint32_t kReceiveTime = 17; // Value doesn't matter for this test.
+ const int kSampleRateHz = 8000;
+ const int kPayloadLengthSamples = 10 * kSampleRateHz / 1000; // 10 ms.
+ const size_t kPayloadLengthBytes = kPayloadLengthSamples;
+ uint8_t payload[kPayloadLengthBytes] = {0};
+ WebRtcRTPHeader rtp_header;
+ rtp_header.header.payloadType = kPayloadType;
+ rtp_header.header.sequenceNumber = 0x1234;
+ rtp_header.header.timestamp = 0x12345678;
+ rtp_header.header.ssrc = 0x87654321;
+
+ // Create a mock decoder object.
+ MockAudioDecoder mock_decoder;
+ EXPECT_CALL(mock_decoder, Init()).WillRepeatedly(Return(0));
+ EXPECT_CALL(mock_decoder, IncomingPacket(_, kPayloadLengthBytes, _, _, _))
+ .WillRepeatedly(Return(0));
+ int16_t dummy_output[kPayloadLengthSamples] = {0};
+ // The below expectation will make the mock decoder write
+ // |kPayloadLengthSamples| zeros to the output array, and mark it as speech.
+ EXPECT_CALL(mock_decoder, Decode(Pointee(0), kPayloadLengthBytes, _, _))
+ .WillOnce(DoAll(SetArrayArgument<2>(dummy_output,
+ dummy_output + kPayloadLengthSamples),
+ SetArgPointee<3>(AudioDecoder::kSpeech),
+ Return(kPayloadLengthSamples)));
+ EXPECT_EQ(NetEq::kOK,
+ neteq_->RegisterExternalDecoder(
+ &mock_decoder, kDecoderPCM16B, kPayloadType));
+
+ // Insert one packet.
+ EXPECT_EQ(NetEq::kOK,
+ neteq_->InsertPacket(
+ rtp_header, payload, kPayloadLengthBytes, kReceiveTime));
+
+ // Pull audio once.
+ const int kMaxOutputSize = 10 * kSampleRateHz / 1000;
+ int16_t output[kMaxOutputSize];
+ int samples_per_channel;
+ int num_channels;
+ NetEqOutputType type;
+ EXPECT_EQ(
+ NetEq::kOK,
+ neteq_->GetAudio(
+ kMaxOutputSize, output, &samples_per_channel, &num_channels, &type));
+ ASSERT_EQ(kMaxOutputSize, samples_per_channel);
+ EXPECT_EQ(1, num_channels);
+ EXPECT_EQ(kOutputNormal, type);
+
+ // Insert two more packets. The first one is out of order, and is already too
+ // old, the second one is the expected next packet.
+ rtp_header.header.sequenceNumber -= 1;
+ rtp_header.header.timestamp -= kPayloadLengthSamples;
+ payload[0] = 1;
+ EXPECT_EQ(NetEq::kOK,
+ neteq_->InsertPacket(
+ rtp_header, payload, kPayloadLengthBytes, kReceiveTime));
+ rtp_header.header.sequenceNumber += 2;
+ rtp_header.header.timestamp += 2 * kPayloadLengthSamples;
+ payload[0] = 2;
+ EXPECT_EQ(NetEq::kOK,
+ neteq_->InsertPacket(
+ rtp_header, payload, kPayloadLengthBytes, kReceiveTime));
+
+ // Expect only the second packet to be decoded (the one with "2" as the first
+ // payload byte).
+ EXPECT_CALL(mock_decoder, Decode(Pointee(2), kPayloadLengthBytes, _, _))
+ .WillOnce(DoAll(SetArrayArgument<2>(dummy_output,
+ dummy_output + kPayloadLengthSamples),
+ SetArgPointee<3>(AudioDecoder::kSpeech),
+ Return(kPayloadLengthSamples)));
+
+ // Pull audio once.
+ EXPECT_EQ(
+ NetEq::kOK,
+ neteq_->GetAudio(
+ kMaxOutputSize, output, &samples_per_channel, &num_channels, &type));
+ ASSERT_EQ(kMaxOutputSize, samples_per_channel);
+ EXPECT_EQ(1, num_channels);
+ EXPECT_EQ(kOutputNormal, type);
+
+ // Now check the packet buffer, and make sure it is empty, since the
+ // out-of-order packet should have been discarded.
+ EXPECT_TRUE(packet_buffer_->Empty());
+
+ EXPECT_CALL(mock_decoder, Die());
+}
+
} // namespace webrtc
diff --git a/modules/audio_coding/neteq/neteq_tests.gypi b/modules/audio_coding/neteq/neteq_tests.gypi
index d134dcd4..48cd9ebe 100644
--- a/modules/audio_coding/neteq/neteq_tests.gypi
+++ b/modules/audio_coding/neteq/neteq_tests.gypi
@@ -87,7 +87,7 @@
'neteq_unittest_tools',
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
- '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default',
+ '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers_default',
],
'sources': [
'tools/rtp_analyze.cc',
diff --git a/modules/audio_coding/neteq/packet_buffer.cc b/modules/audio_coding/neteq/packet_buffer.cc
index 4c484185..816713d8 100644
--- a/modules/audio_coding/neteq/packet_buffer.cc
+++ b/modules/audio_coding/neteq/packet_buffer.cc
@@ -216,12 +216,12 @@ int PacketBuffer::DiscardNextPacket() {
return kOK;
}
-int PacketBuffer::DiscardOldPackets(uint32_t timestamp_limit) {
- while (!Empty() &&
- timestamp_limit != buffer_.front()->header.timestamp &&
- static_cast<uint32_t>(timestamp_limit
- - buffer_.front()->header.timestamp) <
- 0xFFFFFFFF / 2) {
+int PacketBuffer::DiscardOldPackets(uint32_t timestamp_limit,
+ uint32_t horizon_samples) {
+ while (!Empty() && timestamp_limit != buffer_.front()->header.timestamp &&
+ IsObsoleteTimestamp(buffer_.front()->header.timestamp,
+ timestamp_limit,
+ horizon_samples)) {
if (DiscardNextPacket() != kOK) {
assert(false); // Must be ok by design.
}
diff --git a/modules/audio_coding/neteq/packet_buffer.h b/modules/audio_coding/neteq/packet_buffer.h
index 76c4ddd1..b9a16189 100644
--- a/modules/audio_coding/neteq/packet_buffer.h
+++ b/modules/audio_coding/neteq/packet_buffer.h
@@ -95,9 +95,19 @@ class PacketBuffer {
// PacketBuffer::kOK otherwise.
virtual int DiscardNextPacket();
- // Discards all packets that are (strictly) older than |timestamp_limit|.
+ // Discards all packets that are (strictly) older than timestamp_limit,
+ // but newer than timestamp_limit - horizon_samples. Setting horizon_samples
+ // to zero implies that the horizon is set to half the timestamp range. That
+ // is, if a packet is more than 2^31 timestamps into the future compared with
+ // timestamp_limit (including wrap-around), it is considered old.
// Returns number of packets discarded.
- virtual int DiscardOldPackets(uint32_t timestamp_limit);
+ virtual int DiscardOldPackets(uint32_t timestamp_limit,
+ uint32_t horizon_samples);
+
+ // Discards all packets that are (strictly) older than timestamp_limit.
+ virtual int DiscardAllOldPackets(uint32_t timestamp_limit) {
+ return DiscardOldPackets(timestamp_limit, 0);
+ }
// Returns the number of packets in the buffer, including duplicates and
// redundant packets.
@@ -125,6 +135,20 @@ class PacketBuffer {
// in |packet_list|.
static void DeleteAllPackets(PacketList* packet_list);
+ // Static method returning true if |timestamp| is older than |timestamp_limit|
+ // but less than |horizon_samples| behind |timestamp_limit|. For instance,
+ // with timestamp_limit = 100 and horizon_samples = 10, a timestamp in the
+ // range (90, 100) is considered obsolete, and will yield true.
+ // Setting |horizon_samples| to 0 is the same as setting it to 2^31, i.e.,
+ // half the 32-bit timestamp range.
+ static bool IsObsoleteTimestamp(uint32_t timestamp,
+ uint32_t timestamp_limit,
+ uint32_t horizon_samples) {
+ return IsNewerTimestamp(timestamp_limit, timestamp) &&
+ (horizon_samples == 0 ||
+ IsNewerTimestamp(timestamp, timestamp_limit - horizon_samples));
+ }
+
private:
size_t max_number_of_packets_;
PacketList buffer_;
diff --git a/modules/audio_coding/neteq/packet_buffer_unittest.cc b/modules/audio_coding/neteq/packet_buffer_unittest.cc
index 478328cb..dc8b68c3 100644
--- a/modules/audio_coding/neteq/packet_buffer_unittest.cc
+++ b/modules/audio_coding/neteq/packet_buffer_unittest.cc
@@ -391,7 +391,7 @@ TEST(PacketBuffer, Failures) {
EXPECT_EQ(NULL, buffer->NextRtpHeader());
EXPECT_EQ(NULL, buffer->GetNextPacket(NULL));
EXPECT_EQ(PacketBuffer::kBufferEmpty, buffer->DiscardNextPacket());
- EXPECT_EQ(0, buffer->DiscardOldPackets(0)); // 0 packets discarded.
+ EXPECT_EQ(0, buffer->DiscardAllOldPackets(0)); // 0 packets discarded.
// Insert one packet to make the buffer non-empty.
packet = gen.NextPacket(payload_len);
@@ -513,4 +513,61 @@ TEST(PacketBuffer, DeleteAllPackets) {
EXPECT_FALSE(PacketBuffer::DeleteFirstPacket(&list));
}
+namespace {
+void TestIsObsoleteTimestamp(uint32_t limit_timestamp) {
+ // Check with zero horizon, which implies that the horizon is at 2^31, i.e.,
+ // half the timestamp range.
+ static const uint32_t kZeroHorizon = 0;
+ static const uint32_t k2Pow31Minus1 = 0x7FFFFFFF;
+ // Timestamp on the limit is not old.
+ EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
+ limit_timestamp, limit_timestamp, kZeroHorizon));
+ // 1 sample behind is old.
+ EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(
+ limit_timestamp - 1, limit_timestamp, kZeroHorizon));
+ // 2^31 - 1 samples behind is old.
+ EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(
+ limit_timestamp - k2Pow31Minus1, limit_timestamp, kZeroHorizon));
+ // 1 sample ahead is not old.
+ EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
+ limit_timestamp + 1, limit_timestamp, kZeroHorizon));
+ // 2^31 samples ahead is not old.
+ EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
+ limit_timestamp + (1 << 31), limit_timestamp, kZeroHorizon));
+
+ // Fixed horizon at 10 samples.
+ static const uint32_t kHorizon = 10;
+ // Timestamp on the limit is not old.
+ EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
+ limit_timestamp, limit_timestamp, kHorizon));
+ // 1 sample behind is old.
+ EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(
+ limit_timestamp - 1, limit_timestamp, kHorizon));
+ // 9 samples behind is old.
+ EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(
+ limit_timestamp - 9, limit_timestamp, kHorizon));
+ // 10 samples behind is not old.
+ EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
+ limit_timestamp - 10, limit_timestamp, kHorizon));
+ // 2^31 - 1 samples behind is not old.
+ EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
+ limit_timestamp - k2Pow31Minus1, limit_timestamp, kHorizon));
+ // 1 sample ahead is not old.
+ EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
+ limit_timestamp + 1, limit_timestamp, kHorizon));
+ // 2^31 samples ahead is not old.
+ EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
+ limit_timestamp + (1 << 31), limit_timestamp, kHorizon));
+}
+} // namespace
+
+// Test the IsObsoleteTimestamp method with different limit timestamps.
+TEST(PacketBuffer, IsObsoleteTimestamp) {
+ TestIsObsoleteTimestamp(0);
+ TestIsObsoleteTimestamp(1);
+ TestIsObsoleteTimestamp(0xFFFFFFFF); // -1 in uint32_t.
+ TestIsObsoleteTimestamp(0x80000000); // 2^31.
+ TestIsObsoleteTimestamp(0x80000001); // 2^31 + 1.
+ TestIsObsoleteTimestamp(0x7FFFFFFF); // 2^31 - 1.
+}
} // namespace webrtc
diff --git a/modules/audio_coding/neteq/test/RTPencode.cc b/modules/audio_coding/neteq/test/RTPencode.cc
index ab338a73..b73e70e5 100644
--- a/modules/audio_coding/neteq/test/RTPencode.cc
+++ b/modules/audio_coding/neteq/test/RTPencode.cc
@@ -235,9 +235,6 @@ WebRtcVadInst *VAD_inst[2];
#ifdef CODEC_CELT_32
CELT_encinst_t *CELT32enc_inst[2];
#endif
-#ifdef CODEC_G711
- void *G711state[2]={NULL, NULL};
-#endif
int main(int argc, char* argv[])
@@ -1602,12 +1599,12 @@ int NetEQTest_encode(int coder, int16_t *indata, int frameLen, unsigned char * e
/* Encode with the selected coder type */
if (coder==webrtc::kDecoderPCMu) { /*g711 u-law */
#ifdef CODEC_G711
- cdlen = WebRtcG711_EncodeU(G711state[k], indata, frameLen, (int16_t*) encoded);
+ cdlen = WebRtcG711_EncodeU(indata, frameLen, (int16_t*) encoded);
#endif
}
else if (coder==webrtc::kDecoderPCMa) { /*g711 A-law */
#ifdef CODEC_G711
- cdlen = WebRtcG711_EncodeA(G711state[k], indata, frameLen, (int16_t*) encoded);
+ cdlen = WebRtcG711_EncodeA(indata, frameLen, (int16_t*) encoded);
}
#endif
#ifdef CODEC_PCM16B
diff --git a/modules/audio_coding/neteq/tools/neteq_rtpplay.cc b/modules/audio_coding/neteq/tools/neteq_rtpplay.cc
index 46ef3d08..ef2c0b6b 100644
--- a/modules/audio_coding/neteq/tools/neteq_rtpplay.cc
+++ b/modules/audio_coding/neteq/tools/neteq_rtpplay.cc
@@ -92,6 +92,9 @@ static const bool isac_dummy =
DEFINE_int32(isac_swb, 104, "RTP payload type for iSAC-swb (32 kHz)");
static const bool isac_swb_dummy =
google::RegisterFlagValidator(&FLAGS_isac_swb, &ValidatePayloadType);
+DEFINE_int32(opus, 111, "RTP payload type for Opus");
+static const bool opus_dummy =
+ google::RegisterFlagValidator(&FLAGS_opus, &ValidatePayloadType);
DEFINE_int32(pcm16b, 93, "RTP payload type for PCM16b-nb (8 kHz)");
static const bool pcm16b_dummy =
google::RegisterFlagValidator(&FLAGS_pcm16b, &ValidatePayloadType);
@@ -286,8 +289,24 @@ int main(int argc, char* argv[]) {
static_cast<int>(payload_len),
packet->time_ms() * sample_rate_hz / 1000);
if (error != NetEq::kOK) {
- std::cerr << "InsertPacket returned error code " << neteq->LastError()
- << std::endl;
+ if (neteq->LastError() == NetEq::kUnknownRtpPayloadType) {
+ std::cerr << "RTP Payload type "
+ << static_cast<int>(rtp_header.header.payloadType)
+ << " is unknown." << std::endl;
+ std::cerr << "Use --codec_map to view default mapping." << std::endl;
+ std::cerr << "Use --helpshort for information on how to make custom "
+ "mappings." << std::endl;
+ } else {
+ std::cerr << "InsertPacket returned error code " << neteq->LastError()
+ << std::endl;
+ std::cerr << "Header data:" << std::endl;
+ std::cerr << " PT = "
+ << static_cast<int>(rtp_header.header.payloadType)
+ << std::endl;
+ std::cerr << " SN = " << rtp_header.header.sequenceNumber
+ << std::endl;
+ std::cerr << " TS = " << rtp_header.header.timestamp << std::endl;
+ }
}
// Get next packet from file.
@@ -366,6 +385,8 @@ std::string CodecName(webrtc::NetEqDecoder codec) {
return "iSAC";
case webrtc::kDecoderISACswb:
return "iSAC-swb (32 kHz)";
+ case webrtc::kDecoderOpus:
+ return "Opus";
case webrtc::kDecoderPCM16B:
return "PCM16b-nb (8 kHz)";
case webrtc::kDecoderPCM16Bwb:
@@ -428,6 +449,12 @@ void RegisterPayloadTypes(NetEq* neteq) {
" as " << CodecName(webrtc::kDecoderISACswb).c_str() << std::endl;
exit(1);
}
+ error = neteq->RegisterPayloadType(webrtc::kDecoderOpus, FLAGS_opus);
+ if (error) {
+ std::cerr << "Cannot register payload type " << FLAGS_opus << " as "
+ << CodecName(webrtc::kDecoderOpus).c_str() << std::endl;
+ exit(1);
+ }
error = neteq->RegisterPayloadType(webrtc::kDecoderPCM16B, FLAGS_pcm16b);
if (error) {
std::cerr << "Cannot register payload type " << FLAGS_pcm16b <<
@@ -514,6 +541,8 @@ void PrintCodecMapping() {
std::endl;
std::cout << CodecName(webrtc::kDecoderISACswb).c_str() << ": " <<
FLAGS_isac_swb << std::endl;
+ std::cout << CodecName(webrtc::kDecoderOpus).c_str() << ": " << FLAGS_opus
+ << std::endl;
std::cout << CodecName(webrtc::kDecoderPCM16B).c_str() << ": " <<
FLAGS_pcm16b << std::endl;
std::cout << CodecName(webrtc::kDecoderPCM16Bwb).c_str() << ": " <<
@@ -637,8 +666,8 @@ int CodecSampleRate(uint8_t payload_type) {
payload_type == FLAGS_pcm16b_swb32 ||
payload_type == FLAGS_cn_swb32) {
return 32000;
- } else if (payload_type == FLAGS_pcm16b_swb48 ||
- payload_type == FLAGS_cn_swb48) {
+ } else if (payload_type == FLAGS_opus || payload_type == FLAGS_pcm16b_swb48 ||
+ payload_type == FLAGS_cn_swb48) {
return 48000;
} else if (payload_type == FLAGS_avt ||
payload_type == FLAGS_red) {
diff --git a/modules/audio_coding/neteq/tools/resample_input_audio_file.cc b/modules/audio_coding/neteq/tools/resample_input_audio_file.cc
new file mode 100644
index 00000000..f391466c
--- /dev/null
+++ b/modules/audio_coding/neteq/tools/resample_input_audio_file.cc
@@ -0,0 +1,42 @@
+/*
+ * 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 "webrtc/modules/audio_coding/neteq/tools/resample_input_audio_file.h"
+
+#include "webrtc/base/checks.h"
+#include "webrtc/system_wrappers/interface/scoped_ptr.h"
+
+namespace webrtc {
+namespace test {
+
+bool ResampleInputAudioFile::Read(size_t samples,
+ int output_rate_hz,
+ int16_t* destination) {
+ const size_t samples_to_read = samples * file_rate_hz_ / output_rate_hz;
+ CHECK_EQ(samples_to_read * output_rate_hz, samples * file_rate_hz_)
+ << "Frame size and sample rates don't add up to an integer.";
+ scoped_ptr<int16_t[]> temp_destination(new int16_t[samples_to_read]);
+ if (!InputAudioFile::Read(samples_to_read, temp_destination.get()))
+ return false;
+ resampler_.ResetIfNeeded(
+ file_rate_hz_, output_rate_hz, kResamplerSynchronous);
+ int output_length = 0;
+ CHECK_EQ(resampler_.Push(temp_destination.get(),
+ static_cast<int>(samples_to_read),
+ destination,
+ static_cast<int>(samples),
+ output_length),
+ 0);
+ CHECK_EQ(static_cast<int>(samples), output_length);
+ return true;
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/modules/audio_coding/neteq/tools/resample_input_audio_file.h b/modules/audio_coding/neteq/tools/resample_input_audio_file.h
new file mode 100644
index 00000000..8c028005
--- /dev/null
+++ b/modules/audio_coding/neteq/tools/resample_input_audio_file.h
@@ -0,0 +1,40 @@
+/*
+ * 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 WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_RESAMPLE_INPUT_AUDIO_FILE_H_
+#define WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_RESAMPLE_INPUT_AUDIO_FILE_H_
+
+#include <string>
+
+#include "webrtc/base/constructormagic.h"
+#include "webrtc/common_audio/resampler/include/resampler.h"
+#include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h"
+#include "webrtc/typedefs.h"
+
+namespace webrtc {
+namespace test {
+
+// Class for handling a looping input audio file with resampling.
+class ResampleInputAudioFile : public InputAudioFile {
+ public:
+ ResampleInputAudioFile(const std::string file_name, int file_rate_hz)
+ : InputAudioFile(file_name), file_rate_hz_(file_rate_hz) {}
+
+ bool Read(size_t samples, int output_rate_hz, int16_t* destination);
+
+ private:
+ const int file_rate_hz_;
+ Resampler resampler_;
+ DISALLOW_COPY_AND_ASSIGN(ResampleInputAudioFile);
+};
+
+} // namespace test
+} // namespace webrtc
+#endif // WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_RESAMPLE_INPUT_AUDIO_FILE_H_
diff --git a/modules/audio_coding_module.target.darwin-arm.mk b/modules/audio_coding_module.target.darwin-arm.mk
index d197c4d5..3257c966 100644
--- a/modules/audio_coding_module.target.darwin-arm.mk
+++ b/modules/audio_coding_module.target.darwin-arm.mk
@@ -114,11 +114,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -135,6 +137,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -248,11 +251,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -269,6 +274,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_coding_module.target.darwin-arm64.mk b/modules/audio_coding_module.target.darwin-arm64.mk
index a34666d1..ba0c3fc4 100644
--- a/modules/audio_coding_module.target.darwin-arm64.mk
+++ b/modules/audio_coding_module.target.darwin-arm64.mk
@@ -103,11 +103,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -116,11 +118,13 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -222,11 +226,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -235,11 +241,13 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_coding_module.target.darwin-mips.mk b/modules/audio_coding_module.target.darwin-mips.mk
index 1d8fdfeb..aba873a7 100644
--- a/modules/audio_coding_module.target.darwin-mips.mk
+++ b/modules/audio_coding_module.target.darwin-mips.mk
@@ -108,11 +108,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -128,6 +130,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -235,11 +238,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -255,6 +260,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_coding_module.target.darwin-mips64.mk b/modules/audio_coding_module.target.darwin-mips64.mk
new file mode 100644
index 00000000..70d3832a
--- /dev/null
+++ b/modules/audio_coding_module.target.darwin-mips64.mk
@@ -0,0 +1,328 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_audio_coding_module_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_amr.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_amrwb.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_celt.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_cng.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_codec_database.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_dtmf_playout.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_g722.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_g7221.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_g7221c.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_g729.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_g7291.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_gsmfr.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_ilbc.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_isac.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_opus.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_speex.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_pcm16b.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_pcma.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_pcmu.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_red.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_receiver.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_resampler.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/audio_coding_module.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/call_statistics.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/initial_delay_manager.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/nack.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/cng/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g711/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g722/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/ilbc/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/fix/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/pcm16b/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/opus/src/celt \
+ $(LOCAL_PATH)/third_party/opus/src/src \
+ $(LOCAL_PATH)/third_party/opus/src/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/cng/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g711/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g722/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/ilbc/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/fix/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/pcm16b/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/opus/src/celt \
+ $(LOCAL_PATH)/third_party/opus/src/src \
+ $(LOCAL_PATH)/third_party/opus/src/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_audio_coding_module_gyp
+
+# Alias gyp target name.
+.PHONY: audio_coding_module
+audio_coding_module: third_party_webrtc_modules_audio_coding_module_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/audio_coding_module.target.darwin-x86.mk b/modules/audio_coding_module.target.darwin-x86.mk
index b0da6dfd..4b134573 100644
--- a/modules/audio_coding_module.target.darwin-x86.mk
+++ b/modules/audio_coding_module.target.darwin-x86.mk
@@ -109,11 +109,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -127,6 +129,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -234,11 +237,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -252,6 +257,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_coding_module.target.darwin-x86_64.mk b/modules/audio_coding_module.target.darwin-x86_64.mk
index ce06a110..d3c7fe2f 100644
--- a/modules/audio_coding_module.target.darwin-x86_64.mk
+++ b/modules/audio_coding_module.target.darwin-x86_64.mk
@@ -108,11 +108,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -126,6 +128,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -232,11 +235,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -250,6 +255,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_coding_module.target.linux-arm.mk b/modules/audio_coding_module.target.linux-arm.mk
index d197c4d5..3257c966 100644
--- a/modules/audio_coding_module.target.linux-arm.mk
+++ b/modules/audio_coding_module.target.linux-arm.mk
@@ -114,11 +114,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -135,6 +137,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -248,11 +251,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -269,6 +274,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_coding_module.target.linux-arm64.mk b/modules/audio_coding_module.target.linux-arm64.mk
index a34666d1..ba0c3fc4 100644
--- a/modules/audio_coding_module.target.linux-arm64.mk
+++ b/modules/audio_coding_module.target.linux-arm64.mk
@@ -103,11 +103,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -116,11 +118,13 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -222,11 +226,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -235,11 +241,13 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_coding_module.target.linux-mips.mk b/modules/audio_coding_module.target.linux-mips.mk
index 1d8fdfeb..aba873a7 100644
--- a/modules/audio_coding_module.target.linux-mips.mk
+++ b/modules/audio_coding_module.target.linux-mips.mk
@@ -108,11 +108,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -128,6 +130,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -235,11 +238,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -255,6 +260,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_coding_module.target.linux-mips64.mk b/modules/audio_coding_module.target.linux-mips64.mk
new file mode 100644
index 00000000..70d3832a
--- /dev/null
+++ b/modules/audio_coding_module.target.linux-mips64.mk
@@ -0,0 +1,328 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_audio_coding_module_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_amr.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_amrwb.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_celt.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_cng.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_codec_database.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_dtmf_playout.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_g722.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_g7221.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_g7221c.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_g729.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_g7291.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_gsmfr.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_ilbc.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_isac.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_opus.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_speex.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_pcm16b.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_pcma.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_pcmu.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_red.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_receiver.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/acm_resampler.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/audio_coding_module.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/call_statistics.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/initial_delay_manager.cc \
+ third_party/webrtc/modules/audio_coding/main/acm2/nack.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/cng/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g711/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g722/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/ilbc/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/fix/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/pcm16b/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/opus/src/celt \
+ $(LOCAL_PATH)/third_party/opus/src/src \
+ $(LOCAL_PATH)/third_party/opus/src/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/cng/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g711/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g722/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/ilbc/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/fix/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/pcm16b/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/opus/src/celt \
+ $(LOCAL_PATH)/third_party/opus/src/src \
+ $(LOCAL_PATH)/third_party/opus/src/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_audio_coding_module_gyp
+
+# Alias gyp target name.
+.PHONY: audio_coding_module
+audio_coding_module: third_party_webrtc_modules_audio_coding_module_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/audio_coding_module.target.linux-x86.mk b/modules/audio_coding_module.target.linux-x86.mk
index b0da6dfd..4b134573 100644
--- a/modules/audio_coding_module.target.linux-x86.mk
+++ b/modules/audio_coding_module.target.linux-x86.mk
@@ -109,11 +109,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -127,6 +129,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -234,11 +237,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -252,6 +257,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_coding_module.target.linux-x86_64.mk b/modules/audio_coding_module.target.linux-x86_64.mk
index ce06a110..d3c7fe2f 100644
--- a/modules/audio_coding_module.target.linux-x86_64.mk
+++ b/modules/audio_coding_module.target.linux-x86_64.mk
@@ -108,11 +108,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -126,6 +128,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -232,11 +235,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -250,6 +255,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_conference_mixer.target.darwin-arm.mk b/modules/audio_conference_mixer.target.darwin-arm.mk
index d4e718dc..75287abc 100644
--- a/modules/audio_conference_mixer.target.darwin-arm.mk
+++ b/modules/audio_conference_mixer.target.darwin-arm.mk
@@ -90,11 +90,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -110,6 +112,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -209,11 +212,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -229,6 +234,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_conference_mixer.target.darwin-arm64.mk b/modules/audio_conference_mixer.target.darwin-arm64.mk
index 3e63a074..c0efb572 100644
--- a/modules/audio_conference_mixer.target.darwin-arm64.mk
+++ b/modules/audio_conference_mixer.target.darwin-arm64.mk
@@ -79,11 +79,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -92,10 +94,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -183,11 +187,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -196,10 +202,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_conference_mixer.target.darwin-mips.mk b/modules/audio_conference_mixer.target.darwin-mips.mk
index e410e9fc..c11bc929 100644
--- a/modules/audio_conference_mixer.target.darwin-mips.mk
+++ b/modules/audio_conference_mixer.target.darwin-mips.mk
@@ -84,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -103,6 +105,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -196,11 +199,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -215,6 +220,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_conference_mixer.target.darwin-mips64.mk b/modules/audio_conference_mixer.target.darwin-mips64.mk
new file mode 100644
index 00000000..ae70af69
--- /dev/null
+++ b/modules/audio_conference_mixer.target.darwin-mips64.mk
@@ -0,0 +1,274 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_audio_conference_mixer_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_conference_mixer/source/audio_frame_manipulator.cc \
+ third_party/webrtc/modules/audio_conference_mixer/source/level_indicator.cc \
+ third_party/webrtc/modules/audio_conference_mixer/source/audio_conference_mixer_impl.cc \
+ third_party/webrtc/modules/audio_conference_mixer/source/time_scheduler.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_conference_mixer/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_conference_mixer/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_audio_conference_mixer_gyp
+
+# Alias gyp target name.
+.PHONY: audio_conference_mixer
+audio_conference_mixer: third_party_webrtc_modules_audio_conference_mixer_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/audio_conference_mixer.target.darwin-x86.mk b/modules/audio_conference_mixer.target.darwin-x86.mk
index b95f6c96..c37a30b4 100644
--- a/modules/audio_conference_mixer.target.darwin-x86.mk
+++ b/modules/audio_conference_mixer.target.darwin-x86.mk
@@ -85,11 +85,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -102,6 +104,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -195,11 +198,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -212,6 +217,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_conference_mixer.target.darwin-x86_64.mk b/modules/audio_conference_mixer.target.darwin-x86_64.mk
index 39a5a64c..0fea5942 100644
--- a/modules/audio_conference_mixer.target.darwin-x86_64.mk
+++ b/modules/audio_conference_mixer.target.darwin-x86_64.mk
@@ -84,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -193,11 +196,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -210,6 +215,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_conference_mixer.target.linux-arm.mk b/modules/audio_conference_mixer.target.linux-arm.mk
index d4e718dc..75287abc 100644
--- a/modules/audio_conference_mixer.target.linux-arm.mk
+++ b/modules/audio_conference_mixer.target.linux-arm.mk
@@ -90,11 +90,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -110,6 +112,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -209,11 +212,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -229,6 +234,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_conference_mixer.target.linux-arm64.mk b/modules/audio_conference_mixer.target.linux-arm64.mk
index 3e63a074..c0efb572 100644
--- a/modules/audio_conference_mixer.target.linux-arm64.mk
+++ b/modules/audio_conference_mixer.target.linux-arm64.mk
@@ -79,11 +79,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -92,10 +94,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -183,11 +187,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -196,10 +202,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_conference_mixer.target.linux-mips.mk b/modules/audio_conference_mixer.target.linux-mips.mk
index e410e9fc..c11bc929 100644
--- a/modules/audio_conference_mixer.target.linux-mips.mk
+++ b/modules/audio_conference_mixer.target.linux-mips.mk
@@ -84,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -103,6 +105,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -196,11 +199,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -215,6 +220,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_conference_mixer.target.linux-mips64.mk b/modules/audio_conference_mixer.target.linux-mips64.mk
new file mode 100644
index 00000000..ae70af69
--- /dev/null
+++ b/modules/audio_conference_mixer.target.linux-mips64.mk
@@ -0,0 +1,274 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_audio_conference_mixer_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_conference_mixer/source/audio_frame_manipulator.cc \
+ third_party/webrtc/modules/audio_conference_mixer/source/level_indicator.cc \
+ third_party/webrtc/modules/audio_conference_mixer/source/audio_conference_mixer_impl.cc \
+ third_party/webrtc/modules/audio_conference_mixer/source/time_scheduler.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_conference_mixer/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_conference_mixer/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_audio_conference_mixer_gyp
+
+# Alias gyp target name.
+.PHONY: audio_conference_mixer
+audio_conference_mixer: third_party_webrtc_modules_audio_conference_mixer_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/audio_conference_mixer.target.linux-x86.mk b/modules/audio_conference_mixer.target.linux-x86.mk
index b95f6c96..c37a30b4 100644
--- a/modules/audio_conference_mixer.target.linux-x86.mk
+++ b/modules/audio_conference_mixer.target.linux-x86.mk
@@ -85,11 +85,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -102,6 +104,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -195,11 +198,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -212,6 +217,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_conference_mixer.target.linux-x86_64.mk b/modules/audio_conference_mixer.target.linux-x86_64.mk
index 39a5a64c..0fea5942 100644
--- a/modules/audio_conference_mixer.target.linux-x86_64.mk
+++ b/modules/audio_conference_mixer.target.linux-x86_64.mk
@@ -84,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -193,11 +196,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -210,6 +215,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_device.target.darwin-arm.mk b/modules/audio_device.target.darwin-arm.mk
index ef5bdaad..0a99c174 100644
--- a/modules/audio_device.target.darwin-arm.mk
+++ b/modules/audio_device.target.darwin-arm.mk
@@ -93,11 +93,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -114,6 +116,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -219,11 +222,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -240,6 +245,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_device.target.darwin-arm64.mk b/modules/audio_device.target.darwin-arm64.mk
index df040e41..78a3fe45 100644
--- a/modules/audio_device.target.darwin-arm64.mk
+++ b/modules/audio_device.target.darwin-arm64.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -95,11 +97,13 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -193,11 +197,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -206,11 +212,13 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_device.target.darwin-mips.mk b/modules/audio_device.target.darwin-mips.mk
index f94aea4e..7d6d1b31 100644
--- a/modules/audio_device.target.darwin-mips.mk
+++ b/modules/audio_device.target.darwin-mips.mk
@@ -87,11 +87,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +109,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -206,11 +209,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -226,6 +231,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_device.target.darwin-mips64.mk b/modules/audio_device.target.darwin-mips64.mk
new file mode 100644
index 00000000..bf93e626
--- /dev/null
+++ b/modules/audio_device.target.darwin-mips64.mk
@@ -0,0 +1,291 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_audio_device_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_device/audio_device_buffer.cc \
+ third_party/webrtc/modules/audio_device/audio_device_generic.cc \
+ third_party/webrtc/modules/audio_device/audio_device_utility.cc \
+ third_party/webrtc/modules/audio_device/audio_device_impl.cc \
+ third_party/webrtc/modules/audio_device/dummy/audio_device_dummy.cc \
+ third_party/webrtc/modules/audio_device/dummy/audio_device_utility_dummy.cc \
+ third_party/webrtc/modules/audio_device/dummy/file_audio_device.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_device \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_device/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_device/dummy \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_device/android \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_device \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_device/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_device/dummy \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_device/android \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_audio_device_gyp
+
+# Alias gyp target name.
+.PHONY: audio_device
+audio_device: third_party_webrtc_modules_audio_device_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/audio_device.target.darwin-x86.mk b/modules/audio_device.target.darwin-x86.mk
index 4bab7019..92c610f6 100644
--- a/modules/audio_device.target.darwin-x86.mk
+++ b/modules/audio_device.target.darwin-x86.mk
@@ -88,11 +88,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -106,6 +108,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -205,11 +208,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -223,6 +228,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_device.target.darwin-x86_64.mk b/modules/audio_device.target.darwin-x86_64.mk
index c4e534d3..8f05fd29 100644
--- a/modules/audio_device.target.darwin-x86_64.mk
+++ b/modules/audio_device.target.darwin-x86_64.mk
@@ -87,11 +87,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -105,6 +107,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -203,11 +206,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -221,6 +226,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_device.target.linux-arm.mk b/modules/audio_device.target.linux-arm.mk
index ef5bdaad..0a99c174 100644
--- a/modules/audio_device.target.linux-arm.mk
+++ b/modules/audio_device.target.linux-arm.mk
@@ -93,11 +93,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -114,6 +116,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -219,11 +222,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -240,6 +245,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_device.target.linux-arm64.mk b/modules/audio_device.target.linux-arm64.mk
index df040e41..78a3fe45 100644
--- a/modules/audio_device.target.linux-arm64.mk
+++ b/modules/audio_device.target.linux-arm64.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -95,11 +97,13 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -193,11 +197,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -206,11 +212,13 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_device.target.linux-mips.mk b/modules/audio_device.target.linux-mips.mk
index f94aea4e..7d6d1b31 100644
--- a/modules/audio_device.target.linux-mips.mk
+++ b/modules/audio_device.target.linux-mips.mk
@@ -87,11 +87,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +109,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -206,11 +209,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -226,6 +231,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_device.target.linux-mips64.mk b/modules/audio_device.target.linux-mips64.mk
new file mode 100644
index 00000000..bf93e626
--- /dev/null
+++ b/modules/audio_device.target.linux-mips64.mk
@@ -0,0 +1,291 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_audio_device_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_device/audio_device_buffer.cc \
+ third_party/webrtc/modules/audio_device/audio_device_generic.cc \
+ third_party/webrtc/modules/audio_device/audio_device_utility.cc \
+ third_party/webrtc/modules/audio_device/audio_device_impl.cc \
+ third_party/webrtc/modules/audio_device/dummy/audio_device_dummy.cc \
+ third_party/webrtc/modules/audio_device/dummy/audio_device_utility_dummy.cc \
+ third_party/webrtc/modules/audio_device/dummy/file_audio_device.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_device \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_device/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_device/dummy \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_device/android \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_device \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_device/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_device/dummy \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_device/android \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_audio_device_gyp
+
+# Alias gyp target name.
+.PHONY: audio_device
+audio_device: third_party_webrtc_modules_audio_device_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/audio_device.target.linux-x86.mk b/modules/audio_device.target.linux-x86.mk
index 4bab7019..92c610f6 100644
--- a/modules/audio_device.target.linux-x86.mk
+++ b/modules/audio_device.target.linux-x86.mk
@@ -88,11 +88,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -106,6 +108,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -205,11 +208,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -223,6 +228,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_device.target.linux-x86_64.mk b/modules/audio_device.target.linux-x86_64.mk
index c4e534d3..8f05fd29 100644
--- a/modules/audio_device.target.linux-x86_64.mk
+++ b/modules/audio_device.target.linux-x86_64.mk
@@ -87,11 +87,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -105,6 +107,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -203,11 +206,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -221,6 +226,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_DUMMY_AUDIO_BUILD' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_device/audio_device.gypi b/modules/audio_device/audio_device.gypi
index 23f417f9..add3be2a 100644
--- a/modules/audio_device/audio_device.gypi
+++ b/modules/audio_device/audio_device.gypi
@@ -260,7 +260,6 @@
],
'includes': [
'../../build/isolate.gypi',
- 'audio_device_tests.isolate',
],
'sources': [
'audio_device_tests.isolate',
diff --git a/modules/audio_device/audio_device_tests.isolate b/modules/audio_device/audio_device_tests.isolate
index ebe8bfb4..a3550b79 100644
--- a/modules/audio_device/audio_device_tests.isolate
+++ b/modules/audio_device/audio_device_tests.isolate
@@ -9,7 +9,7 @@
'conditions': [
['OS=="android"', {
'variables': {
- 'isolate_dependency_untracked': [
+ 'files': [
'<(DEPTH)/data/',
'<(DEPTH)/resources/',
],
@@ -21,13 +21,10 @@
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/audio_device_tests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/audio_device_tests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_untracked': [
- '<(DEPTH)/tools/swarming_client/',
- ],
},
}],
],
diff --git a/modules/audio_device/audio_device_utility.cc b/modules/audio_device/audio_device_utility.cc
index b6c5c482..182329c4 100644
--- a/modules/audio_device/audio_device_utility.cc
+++ b/modules/audio_device/audio_device_utility.cc
@@ -82,9 +82,9 @@ void AudioDeviceUtility::WaitForKey()
// choose enter out of all available keys
- if (getchar() == '\n')
+ if (getc(stdin) == '\n')
{
- getchar();
+ getc(stdin);
}
tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
diff --git a/modules/audio_device/win/audio_device_core_win.cc b/modules/audio_device/win/audio_device_core_win.cc
index 3708c540..bcf1c1bb 100644
--- a/modules/audio_device/win/audio_device_core_win.cc
+++ b/modules/audio_device/win/audio_device_core_win.cc
@@ -3893,6 +3893,12 @@ DWORD AudioDeviceWindowsCore::DoCaptureThread()
// This value is fixed during the capturing session.
//
UINT32 bufferLength = 0;
+ if (_ptrClientIn == NULL)
+ {
+ WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
+ "input state has been modified before capture loop starts.");
+ return 1;
+ }
hr = _ptrClientIn->GetBufferSize(&bufferLength);
EXIT_ON_ERROR(hr);
WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "[CAPT] size of buffer : %u", bufferLength);
@@ -4113,7 +4119,10 @@ DWORD AudioDeviceWindowsCore::DoCaptureThread()
// ---------------------------- THREAD LOOP ---------------------------- <<
- hr = _ptrClientIn->Stop();
+ if (_ptrClientIn)
+ {
+ hr = _ptrClientIn->Stop();
+ }
Exit:
if (FAILED(hr))
diff --git a/modules/audio_processing.target.darwin-arm.mk b/modules/audio_processing.target.darwin-arm.mk
index b963cbf2..67640455 100644
--- a/modules/audio_processing.target.darwin-arm.mk
+++ b/modules/audio_processing.target.darwin-arm.mk
@@ -115,11 +115,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -140,6 +142,7 @@ MY_DEFS_Debug := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -243,11 +246,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -268,6 +273,7 @@ MY_DEFS_Release := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_processing.target.darwin-arm64.mk b/modules/audio_processing.target.darwin-arm64.mk
index 63b3628f..ad0582fc 100644
--- a/modules/audio_processing.target.darwin-arm64.mk
+++ b/modules/audio_processing.target.darwin-arm64.mk
@@ -103,11 +103,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -116,6 +118,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
@@ -125,6 +128,7 @@ MY_DEFS_Debug := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -216,11 +220,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -229,6 +235,7 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
@@ -238,6 +245,7 @@ MY_DEFS_Release := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_processing.target.darwin-mips.mk b/modules/audio_processing.target.darwin-mips.mk
index 028bf75e..03384eec 100644
--- a/modules/audio_processing.target.darwin-mips.mk
+++ b/modules/audio_processing.target.darwin-mips.mk
@@ -110,11 +110,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -134,6 +136,7 @@ MY_DEFS_Debug := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -231,11 +234,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -255,6 +260,7 @@ MY_DEFS_Release := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_processing.target.darwin-mips64.mk b/modules/audio_processing.target.darwin-mips64.mk
new file mode 100644
index 00000000..3f0f6ef4
--- /dev/null
+++ b/modules/audio_processing.target.darwin-mips64.mk
@@ -0,0 +1,316 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_audio_processing_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audioproc_debug_proto_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audioproc_debug_proto_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_processing/aec/echo_cancellation.c \
+ third_party/webrtc/modules/audio_processing/aec/aec_core.c \
+ third_party/webrtc/modules/audio_processing/aec/aec_rdft.c \
+ third_party/webrtc/modules/audio_processing/aec/aec_resampler.c \
+ third_party/webrtc/modules/audio_processing/aecm/echo_control_mobile.c \
+ third_party/webrtc/modules/audio_processing/aecm/aecm_core.c \
+ third_party/webrtc/modules/audio_processing/agc/analog_agc.c \
+ third_party/webrtc/modules/audio_processing/agc/digital_agc.c \
+ third_party/webrtc/modules/audio_processing/audio_buffer.cc \
+ third_party/webrtc/modules/audio_processing/audio_processing_impl.cc \
+ third_party/webrtc/modules/audio_processing/echo_cancellation_impl.cc \
+ third_party/webrtc/modules/audio_processing/echo_control_mobile_impl.cc \
+ third_party/webrtc/modules/audio_processing/gain_control_impl.cc \
+ third_party/webrtc/modules/audio_processing/high_pass_filter_impl.cc \
+ third_party/webrtc/modules/audio_processing/level_estimator_impl.cc \
+ third_party/webrtc/modules/audio_processing/noise_suppression_impl.cc \
+ third_party/webrtc/modules/audio_processing/processing_component.cc \
+ third_party/webrtc/modules/audio_processing/rms_level.cc \
+ third_party/webrtc/modules/audio_processing/typing_detection.cc \
+ third_party/webrtc/modules/audio_processing/utility/delay_estimator.c \
+ third_party/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c \
+ third_party/webrtc/modules/audio_processing/utility/fft4g.c \
+ third_party/webrtc/modules/audio_processing/utility/ring_buffer.c \
+ third_party/webrtc/modules/audio_processing/voice_detection_impl.cc \
+ third_party/webrtc/modules/audio_processing/ns/noise_suppression.c \
+ third_party/webrtc/modules/audio_processing/ns/ns_core.c \
+ third_party/webrtc/modules/audio_processing/aecm/aecm_core_c.c
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DWEBRTC_AUDIOPROC_DEBUG_DUMP' \
+ '-DWEBRTC_NS_FLOAT' \
+ '-DPROTOBUF_USE_DLLS' \
+ '-DGOOGLE_PROTOBUF_NO_RTTI' \
+ '-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(gyp_shared_intermediate_dir)/protoc_out \
+ $(LOCAL_PATH)/third_party/protobuf \
+ $(LOCAL_PATH)/third_party/protobuf/src
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DWEBRTC_AUDIOPROC_DEBUG_DUMP' \
+ '-DWEBRTC_NS_FLOAT' \
+ '-DPROTOBUF_USE_DLLS' \
+ '-DGOOGLE_PROTOBUF_NO_RTTI' \
+ '-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(gyp_shared_intermediate_dir)/protoc_out \
+ $(LOCAL_PATH)/third_party/protobuf \
+ $(LOCAL_PATH)/third_party/protobuf/src
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_audio_processing_gyp
+
+# Alias gyp target name.
+.PHONY: audio_processing
+audio_processing: third_party_webrtc_modules_audio_processing_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/audio_processing.target.darwin-x86.mk b/modules/audio_processing.target.darwin-x86.mk
index b222dedd..68405656 100644
--- a/modules/audio_processing.target.darwin-x86.mk
+++ b/modules/audio_processing.target.darwin-x86.mk
@@ -109,11 +109,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -131,6 +133,7 @@ MY_DEFS_Debug := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -228,11 +231,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -250,6 +255,7 @@ MY_DEFS_Release := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_processing.target.darwin-x86_64.mk b/modules/audio_processing.target.darwin-x86_64.mk
index 37fc5181..57c22b84 100644
--- a/modules/audio_processing.target.darwin-x86_64.mk
+++ b/modules/audio_processing.target.darwin-x86_64.mk
@@ -108,11 +108,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -130,6 +132,7 @@ MY_DEFS_Debug := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -226,11 +229,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -248,6 +253,7 @@ MY_DEFS_Release := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_processing.target.linux-arm.mk b/modules/audio_processing.target.linux-arm.mk
index b963cbf2..67640455 100644
--- a/modules/audio_processing.target.linux-arm.mk
+++ b/modules/audio_processing.target.linux-arm.mk
@@ -115,11 +115,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -140,6 +142,7 @@ MY_DEFS_Debug := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -243,11 +246,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -268,6 +273,7 @@ MY_DEFS_Release := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_processing.target.linux-arm64.mk b/modules/audio_processing.target.linux-arm64.mk
index 63b3628f..ad0582fc 100644
--- a/modules/audio_processing.target.linux-arm64.mk
+++ b/modules/audio_processing.target.linux-arm64.mk
@@ -103,11 +103,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -116,6 +118,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
@@ -125,6 +128,7 @@ MY_DEFS_Debug := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -216,11 +220,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -229,6 +235,7 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
@@ -238,6 +245,7 @@ MY_DEFS_Release := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_processing.target.linux-mips.mk b/modules/audio_processing.target.linux-mips.mk
index 028bf75e..03384eec 100644
--- a/modules/audio_processing.target.linux-mips.mk
+++ b/modules/audio_processing.target.linux-mips.mk
@@ -110,11 +110,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -134,6 +136,7 @@ MY_DEFS_Debug := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -231,11 +234,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -255,6 +260,7 @@ MY_DEFS_Release := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_processing.target.linux-mips64.mk b/modules/audio_processing.target.linux-mips64.mk
new file mode 100644
index 00000000..3f0f6ef4
--- /dev/null
+++ b/modules/audio_processing.target.linux-mips64.mk
@@ -0,0 +1,316 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_audio_processing_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audioproc_debug_proto_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audioproc_debug_proto_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_processing/aec/echo_cancellation.c \
+ third_party/webrtc/modules/audio_processing/aec/aec_core.c \
+ third_party/webrtc/modules/audio_processing/aec/aec_rdft.c \
+ third_party/webrtc/modules/audio_processing/aec/aec_resampler.c \
+ third_party/webrtc/modules/audio_processing/aecm/echo_control_mobile.c \
+ third_party/webrtc/modules/audio_processing/aecm/aecm_core.c \
+ third_party/webrtc/modules/audio_processing/agc/analog_agc.c \
+ third_party/webrtc/modules/audio_processing/agc/digital_agc.c \
+ third_party/webrtc/modules/audio_processing/audio_buffer.cc \
+ third_party/webrtc/modules/audio_processing/audio_processing_impl.cc \
+ third_party/webrtc/modules/audio_processing/echo_cancellation_impl.cc \
+ third_party/webrtc/modules/audio_processing/echo_control_mobile_impl.cc \
+ third_party/webrtc/modules/audio_processing/gain_control_impl.cc \
+ third_party/webrtc/modules/audio_processing/high_pass_filter_impl.cc \
+ third_party/webrtc/modules/audio_processing/level_estimator_impl.cc \
+ third_party/webrtc/modules/audio_processing/noise_suppression_impl.cc \
+ third_party/webrtc/modules/audio_processing/processing_component.cc \
+ third_party/webrtc/modules/audio_processing/rms_level.cc \
+ third_party/webrtc/modules/audio_processing/typing_detection.cc \
+ third_party/webrtc/modules/audio_processing/utility/delay_estimator.c \
+ third_party/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.c \
+ third_party/webrtc/modules/audio_processing/utility/fft4g.c \
+ third_party/webrtc/modules/audio_processing/utility/ring_buffer.c \
+ third_party/webrtc/modules/audio_processing/voice_detection_impl.cc \
+ third_party/webrtc/modules/audio_processing/ns/noise_suppression.c \
+ third_party/webrtc/modules/audio_processing/ns/ns_core.c \
+ third_party/webrtc/modules/audio_processing/aecm/aecm_core_c.c
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DWEBRTC_AUDIOPROC_DEBUG_DUMP' \
+ '-DWEBRTC_NS_FLOAT' \
+ '-DPROTOBUF_USE_DLLS' \
+ '-DGOOGLE_PROTOBUF_NO_RTTI' \
+ '-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(gyp_shared_intermediate_dir)/protoc_out \
+ $(LOCAL_PATH)/third_party/protobuf \
+ $(LOCAL_PATH)/third_party/protobuf/src
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DWEBRTC_AUDIOPROC_DEBUG_DUMP' \
+ '-DWEBRTC_NS_FLOAT' \
+ '-DPROTOBUF_USE_DLLS' \
+ '-DGOOGLE_PROTOBUF_NO_RTTI' \
+ '-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(gyp_shared_intermediate_dir)/protoc_out \
+ $(LOCAL_PATH)/third_party/protobuf \
+ $(LOCAL_PATH)/third_party/protobuf/src
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_audio_processing_gyp
+
+# Alias gyp target name.
+.PHONY: audio_processing
+audio_processing: third_party_webrtc_modules_audio_processing_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/audio_processing.target.linux-x86.mk b/modules/audio_processing.target.linux-x86.mk
index b222dedd..68405656 100644
--- a/modules/audio_processing.target.linux-x86.mk
+++ b/modules/audio_processing.target.linux-x86.mk
@@ -109,11 +109,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -131,6 +133,7 @@ MY_DEFS_Debug := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -228,11 +231,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -250,6 +255,7 @@ MY_DEFS_Release := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_processing.target.linux-x86_64.mk b/modules/audio_processing.target.linux-x86_64.mk
index 37fc5181..57c22b84 100644
--- a/modules/audio_processing.target.linux-x86_64.mk
+++ b/modules/audio_processing.target.linux-x86_64.mk
@@ -108,11 +108,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -130,6 +132,7 @@ MY_DEFS_Debug := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -226,11 +229,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -248,6 +253,7 @@ MY_DEFS_Release := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_processing/aec/aec_core.c b/modules/audio_processing/aec/aec_core.c
index 1e217eb5..50457d9b 100644
--- a/modules/audio_processing/aec/aec_core.c
+++ b/modules/audio_processing/aec/aec_core.c
@@ -1351,7 +1351,7 @@ int WebRtcAec_FreeAec(AecCore* aec) {
#ifdef WEBRTC_AEC_DEBUG_DUMP
// Open a new Wav file for writing. If it was already open with a different
// sample frequency, close it first.
-static void ReopenWav(rtc_WavFile** wav_file,
+static void ReopenWav(rtc_WavWriter** wav_file,
const char* name,
int seq1,
int seq2,
diff --git a/modules/audio_processing/aec/aec_core_internal.h b/modules/audio_processing/aec/aec_core_internal.h
index 6adc4d68..5e30366d 100644
--- a/modules/audio_processing/aec/aec_core_internal.h
+++ b/modules/audio_processing/aec/aec_core_internal.h
@@ -11,7 +11,7 @@
#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AEC_AEC_CORE_INTERNAL_H_
#define WEBRTC_MODULES_AUDIO_PROCESSING_AEC_AEC_CORE_INTERNAL_H_
-#include "webrtc/common_audio/wav_writer.h"
+#include "webrtc/common_audio/wav_file.h"
#include "webrtc/modules/audio_processing/aec/aec_common.h"
#include "webrtc/modules/audio_processing/aec/aec_core.h"
#include "webrtc/modules/audio_processing/utility/ring_buffer.h"
@@ -147,10 +147,10 @@ struct AecCore {
int debug_dump_count;
RingBuffer* far_time_buf;
- rtc_WavFile* farFile;
- rtc_WavFile* nearFile;
- rtc_WavFile* outFile;
- rtc_WavFile* outLinearFile;
+ rtc_WavWriter* farFile;
+ rtc_WavWriter* nearFile;
+ rtc_WavWriter* outFile;
+ rtc_WavWriter* outLinearFile;
#endif
};
diff --git a/modules/audio_processing/audio_buffer.cc b/modules/audio_processing/audio_buffer.cc
index 8aff61cc..63d69cfb 100644
--- a/modules/audio_processing/audio_buffer.cc
+++ b/modules/audio_processing/audio_buffer.cc
@@ -51,18 +51,11 @@ int KeyboardChannelIndex(AudioProcessing::ChannelLayout layout) {
return -1;
}
-void StereoToMono(const float* left, const float* right, float* out,
+template <typename T>
+void StereoToMono(const T* left, const T* right, T* out,
int samples_per_channel) {
- for (int i = 0; i < samples_per_channel; ++i) {
+ for (int i = 0; i < samples_per_channel; ++i)
out[i] = (left[i] + right[i]) / 2;
- }
-}
-
-void StereoToMono(const int16_t* left, const int16_t* right, int16_t* out,
- int samples_per_channel) {
- for (int i = 0; i < samples_per_channel; ++i) {
- out[i] = (left[i] + right[i]) >> 1;
- }
}
} // namespace
@@ -114,13 +107,7 @@ class IFChannelBuffer {
void RefreshI() {
if (!ivalid_) {
assert(fvalid_);
- const float* const float_data = fbuf_.data();
- int16_t* const int_data = ibuf_.data();
- const int length = ibuf_.length();
- for (int i = 0; i < length; ++i)
- int_data[i] = WEBRTC_SPL_SAT(std::numeric_limits<int16_t>::max(),
- float_data[i],
- std::numeric_limits<int16_t>::min());
+ FloatS16ToS16(fbuf_.data(), ibuf_.length(), ibuf_.data());
ivalid_ = true;
}
}
@@ -228,10 +215,10 @@ void AudioBuffer::CopyFrom(const float* const* data,
data_ptr = process_buffer_->channels();
}
- // Convert to int16.
+ // Convert to the S16 range.
for (int i = 0; i < num_proc_channels_; ++i) {
- ScaleAndRoundToInt16(data_ptr[i], proc_samples_per_channel_,
- channels_->ibuf()->channel(i));
+ FloatToFloatS16(data_ptr[i], proc_samples_per_channel_,
+ channels_->fbuf()->channel(i));
}
}
@@ -241,16 +228,15 @@ void AudioBuffer::CopyTo(int samples_per_channel,
assert(samples_per_channel == output_samples_per_channel_);
assert(ChannelsFromLayout(layout) == num_proc_channels_);
- // Convert to float.
+ // Convert to the float range.
float* const* data_ptr = data;
if (output_samples_per_channel_ != proc_samples_per_channel_) {
// Convert to an intermediate buffer for subsequent resampling.
data_ptr = process_buffer_->channels();
}
for (int i = 0; i < num_proc_channels_; ++i) {
- ScaleToFloat(channels_->ibuf()->channel(i),
- proc_samples_per_channel_,
- data_ptr[i]);
+ FloatS16ToFloat(channels_->fbuf()->channel(i), proc_samples_per_channel_,
+ data_ptr[i]);
}
// Resample.
@@ -449,12 +435,7 @@ void AudioBuffer::DeinterleaveFrom(AudioFrame* frame) {
// Downmix directly; no explicit deinterleaving needed.
int16_t* downmixed = channels_->ibuf()->channel(0);
for (int i = 0; i < input_samples_per_channel_; ++i) {
- // HACK(ajm): The downmixing in the int16_t path is in practice never
- // called from production code. We do this weird scaling to and from float
- // to satisfy tests checking for bit-exactness with the float path.
- float downmix_float = (ScaleToFloat(frame->data_[i * 2]) +
- ScaleToFloat(frame->data_[i * 2 + 1])) / 2;
- downmixed[i] = ScaleAndRoundToInt16(downmix_float);
+ downmixed[i] = (frame->data_[i * 2] + frame->data_[i * 2 + 1]) / 2;
}
} else {
assert(num_proc_channels_ == num_input_channels_);
diff --git a/modules/audio_processing/audio_processing.gypi b/modules/audio_processing/audio_processing.gypi
index ce65f643..2ddcffc9 100644
--- a/modules/audio_processing/audio_processing.gypi
+++ b/modules/audio_processing/audio_processing.gypi
@@ -112,7 +112,7 @@
'ns/nsx_defines.h',
],
'conditions': [
- ['target_arch=="mipsel"', {
+ ['target_arch=="mipsel" and mips_arch_variant!="r6"', {
'sources': [
'ns/nsx_core_mips.c',
],
@@ -139,7 +139,7 @@
['(target_arch=="arm" and arm_version==7) or target_arch=="armv7"', {
'dependencies': ['audio_processing_neon',],
}],
- ['target_arch=="mipsel"', {
+ ['target_arch=="mipsel" and mips_arch_variant!="r6"', {
'sources': [
'aecm/aecm_core_mips.c',
],
diff --git a/modules/audio_processing/gen_aecm_core_neon_offsets_h.target.darwin-arm.mk b/modules/audio_processing/gen_aecm_core_neon_offsets_h.target.darwin-arm.mk
index 16ac3886..5cb73703 100644
--- a/modules/audio_processing/gen_aecm_core_neon_offsets_h.target.darwin-arm.mk
+++ b/modules/audio_processing/gen_aecm_core_neon_offsets_h.target.darwin-arm.mk
@@ -112,11 +112,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -132,6 +134,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -224,11 +227,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -244,6 +249,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_processing/gen_aecm_core_neon_offsets_h.target.linux-arm.mk b/modules/audio_processing/gen_aecm_core_neon_offsets_h.target.linux-arm.mk
index 16ac3886..5cb73703 100644
--- a/modules/audio_processing/gen_aecm_core_neon_offsets_h.target.linux-arm.mk
+++ b/modules/audio_processing/gen_aecm_core_neon_offsets_h.target.linux-arm.mk
@@ -112,11 +112,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -132,6 +134,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -224,11 +227,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -244,6 +249,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_processing/gen_nsx_core_neon_offsets_h.target.darwin-arm.mk b/modules/audio_processing/gen_nsx_core_neon_offsets_h.target.darwin-arm.mk
index e7163393..3582a9a6 100644
--- a/modules/audio_processing/gen_nsx_core_neon_offsets_h.target.darwin-arm.mk
+++ b/modules/audio_processing/gen_nsx_core_neon_offsets_h.target.darwin-arm.mk
@@ -112,11 +112,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -132,6 +134,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -224,11 +227,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -244,6 +249,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_processing/gen_nsx_core_neon_offsets_h.target.linux-arm.mk b/modules/audio_processing/gen_nsx_core_neon_offsets_h.target.linux-arm.mk
index e7163393..3582a9a6 100644
--- a/modules/audio_processing/gen_nsx_core_neon_offsets_h.target.linux-arm.mk
+++ b/modules/audio_processing/gen_nsx_core_neon_offsets_h.target.linux-arm.mk
@@ -112,11 +112,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -132,6 +134,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -224,11 +227,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -244,6 +249,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_processing/lib_core_neon_offsets.target.darwin-arm.mk b/modules/audio_processing/lib_core_neon_offsets.target.darwin-arm.mk
index 224685c9..917720d0 100644
--- a/modules/audio_processing/lib_core_neon_offsets.target.darwin-arm.mk
+++ b/modules/audio_processing/lib_core_neon_offsets.target.darwin-arm.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -103,6 +105,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -195,11 +198,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -215,6 +220,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_processing/lib_core_neon_offsets.target.linux-arm.mk b/modules/audio_processing/lib_core_neon_offsets.target.linux-arm.mk
index 224685c9..917720d0 100644
--- a/modules/audio_processing/lib_core_neon_offsets.target.linux-arm.mk
+++ b/modules/audio_processing/lib_core_neon_offsets.target.linux-arm.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -103,6 +105,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -195,11 +198,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -215,6 +220,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_processing/ns/ns_core.c b/modules/audio_processing/ns/ns_core.c
index 2c7c29dc..e026c29e 100644
--- a/modules/audio_processing/ns/ns_core.c
+++ b/modules/audio_processing/ns/ns_core.c
@@ -8,6 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
+#include <assert.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
@@ -18,312 +19,280 @@
#include "webrtc/modules/audio_processing/ns/windows_private.h"
#include "webrtc/modules/audio_processing/utility/fft4g.h"
-// Set Feature Extraction Parameters
-void WebRtcNs_set_feature_extraction_parameters(NSinst_t* inst) {
- // bin size of histogram
- inst->featureExtractionParams.binSizeLrt = 0.1f;
- inst->featureExtractionParams.binSizeSpecFlat = 0.05f;
- inst->featureExtractionParams.binSizeSpecDiff = 0.1f;
-
- // range of histogram over which lrt threshold is computed
- inst->featureExtractionParams.rangeAvgHistLrt = 1.f;
-
- // scale parameters: multiply dominant peaks of the histograms by scale factor
- // to obtain thresholds for prior model
- inst->featureExtractionParams.factor1ModelPars =
- 1.2f; // for lrt and spectral diff
- inst->featureExtractionParams.factor2ModelPars =
- 0.9f; // for spectral_flatness:
- // used when noise is flatter than speech
-
- // peak limit for spectral flatness (varies between 0 and 1)
- inst->featureExtractionParams.thresPosSpecFlat = 0.6f;
-
- // limit on spacing of two highest peaks in histogram: spacing determined by
- // bin size
- inst->featureExtractionParams.limitPeakSpacingSpecFlat =
- 2 * inst->featureExtractionParams.binSizeSpecFlat;
- inst->featureExtractionParams.limitPeakSpacingSpecDiff =
- 2 * inst->featureExtractionParams.binSizeSpecDiff;
-
- // limit on relevance of second peak:
- inst->featureExtractionParams.limitPeakWeightsSpecFlat = 0.5f;
- inst->featureExtractionParams.limitPeakWeightsSpecDiff = 0.5f;
-
- // fluctuation limit of lrt feature
- inst->featureExtractionParams.thresFluctLrt = 0.05f;
-
- // limit on the max and min values for the feature thresholds
- inst->featureExtractionParams.maxLrt = 1.f;
- inst->featureExtractionParams.minLrt = 0.2f;
-
- inst->featureExtractionParams.maxSpecFlat = 0.95f;
- inst->featureExtractionParams.minSpecFlat = 0.1f;
-
- inst->featureExtractionParams.maxSpecDiff = 1.f;
- inst->featureExtractionParams.minSpecDiff = 0.16f;
-
- // criteria of weight of histogram peak to accept/reject feature
- inst->featureExtractionParams.thresWeightSpecFlat =
- (int)(0.3 * (inst->modelUpdatePars[1])); // for spectral flatness
- inst->featureExtractionParams.thresWeightSpecDiff =
- (int)(0.3 * (inst->modelUpdatePars[1])); // for spectral difference
+// Set Feature Extraction Parameters.
+static void set_feature_extraction_parameters(NSinst_t* self) {
+ // Bin size of histogram.
+ self->featureExtractionParams.binSizeLrt = 0.1f;
+ self->featureExtractionParams.binSizeSpecFlat = 0.05f;
+ self->featureExtractionParams.binSizeSpecDiff = 0.1f;
+
+ // Range of histogram over which LRT threshold is computed.
+ self->featureExtractionParams.rangeAvgHistLrt = 1.f;
+
+ // Scale parameters: multiply dominant peaks of the histograms by scale factor
+ // to obtain thresholds for prior model.
+ // For LRT and spectral difference.
+ self->featureExtractionParams.factor1ModelPars = 1.2f;
+ // For spectral_flatness: used when noise is flatter than speech.
+ self->featureExtractionParams.factor2ModelPars = 0.9f;
+
+ // Peak limit for spectral flatness (varies between 0 and 1).
+ self->featureExtractionParams.thresPosSpecFlat = 0.6f;
+
+ // Limit on spacing of two highest peaks in histogram: spacing determined by
+ // bin size.
+ self->featureExtractionParams.limitPeakSpacingSpecFlat =
+ 2 * self->featureExtractionParams.binSizeSpecFlat;
+ self->featureExtractionParams.limitPeakSpacingSpecDiff =
+ 2 * self->featureExtractionParams.binSizeSpecDiff;
+
+ // Limit on relevance of second peak.
+ self->featureExtractionParams.limitPeakWeightsSpecFlat = 0.5f;
+ self->featureExtractionParams.limitPeakWeightsSpecDiff = 0.5f;
+
+ // Fluctuation limit of LRT feature.
+ self->featureExtractionParams.thresFluctLrt = 0.05f;
+
+ // Limit on the max and min values for the feature thresholds.
+ self->featureExtractionParams.maxLrt = 1.f;
+ self->featureExtractionParams.minLrt = 0.2f;
+
+ self->featureExtractionParams.maxSpecFlat = 0.95f;
+ self->featureExtractionParams.minSpecFlat = 0.1f;
+
+ self->featureExtractionParams.maxSpecDiff = 1.f;
+ self->featureExtractionParams.minSpecDiff = 0.16f;
+
+ // Criteria of weight of histogram peak to accept/reject feature.
+ self->featureExtractionParams.thresWeightSpecFlat =
+ (int)(0.3 * (self->modelUpdatePars[1])); // For spectral flatness.
+ self->featureExtractionParams.thresWeightSpecDiff =
+ (int)(0.3 * (self->modelUpdatePars[1])); // For spectral difference.
}
-// Initialize state
-int WebRtcNs_InitCore(NSinst_t* inst, uint32_t fs) {
+// Initialize state.
+int WebRtcNs_InitCore(NSinst_t* self, uint32_t fs) {
int i;
- // We only support 10ms frames
-
- // check for valid pointer
- if (inst == NULL) {
+ // Check for valid pointer.
+ if (self == NULL) {
return -1;
}
- // Initialization of struct
+ // Initialization of struct.
if (fs == 8000 || fs == 16000 || fs == 32000) {
- inst->fs = fs;
+ self->fs = fs;
} else {
return -1;
}
- inst->windShift = 0;
+ self->windShift = 0;
if (fs == 8000) {
- // We only support 10ms frames
- inst->blockLen = 80;
- inst->anaLen = 128;
- inst->window = kBlocks80w128;
+ // We only support 10ms frames.
+ self->blockLen = 80;
+ self->anaLen = 128;
+ self->window = kBlocks80w128;
} else if (fs == 16000) {
- // We only support 10ms frames
- inst->blockLen = 160;
- inst->anaLen = 256;
- inst->window = kBlocks160w256;
+ // We only support 10ms frames.
+ self->blockLen = 160;
+ self->anaLen = 256;
+ self->window = kBlocks160w256;
} else if (fs == 32000) {
- // We only support 10ms frames
- inst->blockLen = 160;
- inst->anaLen = 256;
- inst->window = kBlocks160w256;
+ // We only support 10ms frames.
+ self->blockLen = 160;
+ self->anaLen = 256;
+ self->window = kBlocks160w256;
}
- inst->magnLen = inst->anaLen / 2 + 1; // Number of frequency bins
+ self->magnLen = self->anaLen / 2 + 1; // Number of frequency bins.
- // Initialize fft work arrays.
- inst->ip[0] = 0; // Setting this triggers initialization.
- memset(inst->dataBuf, 0, sizeof(float) * ANAL_BLOCKL_MAX);
- WebRtc_rdft(inst->anaLen, 1, inst->dataBuf, inst->ip, inst->wfft);
+ // Initialize FFT work arrays.
+ self->ip[0] = 0; // Setting this triggers initialization.
+ memset(self->dataBuf, 0, sizeof(float) * ANAL_BLOCKL_MAX);
+ WebRtc_rdft(self->anaLen, 1, self->dataBuf, self->ip, self->wfft);
- memset(inst->analyzeBuf, 0, sizeof(float) * ANAL_BLOCKL_MAX);
- memset(inst->dataBuf, 0, sizeof(float) * ANAL_BLOCKL_MAX);
- memset(inst->syntBuf, 0, sizeof(float) * ANAL_BLOCKL_MAX);
+ memset(self->analyzeBuf, 0, sizeof(float) * ANAL_BLOCKL_MAX);
+ memset(self->dataBuf, 0, sizeof(float) * ANAL_BLOCKL_MAX);
+ memset(self->syntBuf, 0, sizeof(float) * ANAL_BLOCKL_MAX);
- // for HB processing
- memset(inst->dataBufHB, 0, sizeof(float) * ANAL_BLOCKL_MAX);
+ // For HB processing.
+ memset(self->dataBufHB, 0, sizeof(float) * ANAL_BLOCKL_MAX);
- // for quantile noise estimation
- memset(inst->quantile, 0, sizeof(float) * HALF_ANAL_BLOCKL);
+ // For quantile noise estimation.
+ memset(self->quantile, 0, sizeof(float) * HALF_ANAL_BLOCKL);
for (i = 0; i < SIMULT * HALF_ANAL_BLOCKL; i++) {
- inst->lquantile[i] = 8.f;
- inst->density[i] = 0.3f;
+ self->lquantile[i] = 8.f;
+ self->density[i] = 0.3f;
}
for (i = 0; i < SIMULT; i++) {
- inst->counter[i] =
+ self->counter[i] =
(int)floor((float)(END_STARTUP_LONG * (i + 1)) / (float)SIMULT);
}
- inst->updates = 0;
+ self->updates = 0;
- // Wiener filter initialization
+ // Wiener filter initialization.
for (i = 0; i < HALF_ANAL_BLOCKL; i++) {
- inst->smooth[i] = 1.f;
+ self->smooth[i] = 1.f;
}
- // Set the aggressiveness: default
- inst->aggrMode = 0;
-
- // initialize variables for new method
- inst->priorSpeechProb = 0.5f; // prior prob for speech/noise
- // previous analyze mag spectrum
- memset(inst->magnPrevAnalyze, 0, sizeof(float) * HALF_ANAL_BLOCKL);
- // previous process mag spectrum
- memset(inst->magnPrevProcess, 0, sizeof(float) * HALF_ANAL_BLOCKL);
- // current noise-spectrum
- memset(inst->noise, 0, sizeof(float) * HALF_ANAL_BLOCKL);
- // previous noise-spectrum
- memset(inst->noisePrev, 0, sizeof(float) * HALF_ANAL_BLOCKL);
- // conservative noise spectrum estimate
- memset(inst->magnAvgPause, 0, sizeof(float) * HALF_ANAL_BLOCKL);
- // for estimation of HB in second pass
- memset(inst->speechProb, 0, sizeof(float) * HALF_ANAL_BLOCKL);
- // initial average mag spectrum
- memset(inst->initMagnEst, 0, sizeof(float) * HALF_ANAL_BLOCKL);
+ // Set the aggressiveness: default.
+ self->aggrMode = 0;
+
+ // Initialize variables for new method.
+ self->priorSpeechProb = 0.5f; // Prior prob for speech/noise.
+ // Previous analyze mag spectrum.
+ memset(self->magnPrevAnalyze, 0, sizeof(float) * HALF_ANAL_BLOCKL);
+ // Previous process mag spectrum.
+ memset(self->magnPrevProcess, 0, sizeof(float) * HALF_ANAL_BLOCKL);
+ // Current noise-spectrum.
+ memset(self->noise, 0, sizeof(float) * HALF_ANAL_BLOCKL);
+ // Previous noise-spectrum.
+ memset(self->noisePrev, 0, sizeof(float) * HALF_ANAL_BLOCKL);
+ // Conservative noise spectrum estimate.
+ memset(self->magnAvgPause, 0, sizeof(float) * HALF_ANAL_BLOCKL);
+ // For estimation of HB in second pass.
+ memset(self->speechProb, 0, sizeof(float) * HALF_ANAL_BLOCKL);
+ // Initial average magnitude spectrum.
+ memset(self->initMagnEst, 0, sizeof(float) * HALF_ANAL_BLOCKL);
for (i = 0; i < HALF_ANAL_BLOCKL; i++) {
- inst->logLrtTimeAvg[i] =
- LRT_FEATURE_THR; // smooth LR ratio (same as threshold)
+ // Smooth LR (same as threshold).
+ self->logLrtTimeAvg[i] = LRT_FEATURE_THR;
}
- // feature quantities
- inst->featureData[0] =
- SF_FEATURE_THR; // spectral flatness (start on threshold)
- inst->featureData[1] = 0.f; // spectral entropy: not used in this version
- inst->featureData[2] = 0.f; // spectral variance: not used in this version
- inst->featureData[3] =
- LRT_FEATURE_THR; // average lrt factor (start on threshold)
- inst->featureData[4] =
- SF_FEATURE_THR; // spectral template diff (start on threshold)
- inst->featureData[5] = 0.f; // normalization for spectral-diff
- inst->featureData[6] =
- 0.f; // window time-average of input magnitude spectrum
-
- // histogram quantities: used to estimate/update thresholds for features
- memset(inst->histLrt, 0, sizeof(int) * HIST_PAR_EST);
- memset(inst->histSpecFlat, 0, sizeof(int) * HIST_PAR_EST);
- memset(inst->histSpecDiff, 0, sizeof(int) * HIST_PAR_EST);
-
-
- inst->blockInd = -1; // frame counter
- inst->priorModelPars[0] =
- LRT_FEATURE_THR; // default threshold for lrt feature
- inst->priorModelPars[1] = 0.5f; // threshold for spectral flatness:
- // determined on-line
- inst->priorModelPars[2] = 1.f; // sgn_map par for spectral measure:
- // 1 for flatness measure
- inst->priorModelPars[3] = 0.5f; // threshold for template-difference feature:
- // determined on-line
- inst->priorModelPars[4] = 1.f; // default weighting parameter for lrt feature
- inst->priorModelPars[5] = 0.f; // default weighting parameter for
- // spectral flatness feature
- inst->priorModelPars[6] = 0.f; // default weighting parameter for
- // spectral difference feature
-
- inst->modelUpdatePars[0] = 2; // update flag for parameters:
- // 0 no update, 1=update once, 2=update every window
- inst->modelUpdatePars[1] = 500; // window for update
- inst->modelUpdatePars[2] =
- 0; // counter for update of conservative noise spectrum
- // counter if the feature thresholds are updated during the sequence
- inst->modelUpdatePars[3] = inst->modelUpdatePars[1];
-
- inst->signalEnergy = 0.0;
- inst->sumMagn = 0.0;
- inst->whiteNoiseLevel = 0.0;
- inst->pinkNoiseNumerator = 0.0;
- inst->pinkNoiseExp = 0.0;
-
- WebRtcNs_set_feature_extraction_parameters(inst);
-
- // default mode
- WebRtcNs_set_policy_core(inst, 0);
-
- inst->initFlag = 1;
+ // Feature quantities.
+ // Spectral flatness (start on threshold).
+ self->featureData[0] = SF_FEATURE_THR;
+ self->featureData[1] = 0.f; // Spectral entropy: not used in this version.
+ self->featureData[2] = 0.f; // Spectral variance: not used in this version.
+ // Average LRT factor (start on threshold).
+ self->featureData[3] = LRT_FEATURE_THR;
+ // Spectral template diff (start on threshold).
+ self->featureData[4] = SF_FEATURE_THR;
+ self->featureData[5] = 0.f; // Normalization for spectral difference.
+ // Window time-average of input magnitude spectrum.
+ self->featureData[6] = 0.f;
+
+ // Histogram quantities: used to estimate/update thresholds for features.
+ memset(self->histLrt, 0, sizeof(int) * HIST_PAR_EST);
+ memset(self->histSpecFlat, 0, sizeof(int) * HIST_PAR_EST);
+ memset(self->histSpecDiff, 0, sizeof(int) * HIST_PAR_EST);
+
+
+ self->blockInd = -1; // Frame counter.
+ // Default threshold for LRT feature.
+ self->priorModelPars[0] = LRT_FEATURE_THR;
+ // Threshold for spectral flatness: determined on-line.
+ self->priorModelPars[1] = 0.5f;
+ // sgn_map par for spectral measure: 1 for flatness measure.
+ self->priorModelPars[2] = 1.f;
+ // Threshold for template-difference feature: determined on-line.
+ self->priorModelPars[3] = 0.5f;
+ // Default weighting parameter for LRT feature.
+ self->priorModelPars[4] = 1.f;
+ // Default weighting parameter for spectral flatness feature.
+ self->priorModelPars[5] = 0.f;
+ // Default weighting parameter for spectral difference feature.
+ self->priorModelPars[6] = 0.f;
+
+ // Update flag for parameters:
+ // 0 no update, 1 = update once, 2 = update every window.
+ self->modelUpdatePars[0] = 2;
+ self->modelUpdatePars[1] = 500; // Window for update.
+ // Counter for update of conservative noise spectrum.
+ self->modelUpdatePars[2] = 0;
+ // Counter if the feature thresholds are updated during the sequence.
+ self->modelUpdatePars[3] = self->modelUpdatePars[1];
+
+ self->signalEnergy = 0.0;
+ self->sumMagn = 0.0;
+ self->whiteNoiseLevel = 0.0;
+ self->pinkNoiseNumerator = 0.0;
+ self->pinkNoiseExp = 0.0;
+
+ set_feature_extraction_parameters(self);
+
+ // Default mode.
+ WebRtcNs_set_policy_core(self, 0);
+
+ self->initFlag = 1;
return 0;
}
-int WebRtcNs_set_policy_core(NSinst_t* inst, int mode) {
- // allow for modes:0,1,2,3
- if (mode < 0 || mode > 3) {
- return (-1);
- }
-
- inst->aggrMode = mode;
- if (mode == 0) {
- inst->overdrive = 1.f;
- inst->denoiseBound = 0.5f;
- inst->gainmap = 0;
- } else if (mode == 1) {
- // inst->overdrive = 1.25f;
- inst->overdrive = 1.f;
- inst->denoiseBound = 0.25f;
- inst->gainmap = 1;
- } else if (mode == 2) {
- // inst->overdrive = 1.25f;
- inst->overdrive = 1.1f;
- inst->denoiseBound = 0.125f;
- inst->gainmap = 1;
- } else if (mode == 3) {
- // inst->overdrive = 1.3f;
- inst->overdrive = 1.25f;
- inst->denoiseBound = 0.09f;
- inst->gainmap = 1;
- }
- return 0;
-}
-
-// Estimate noise
-void WebRtcNs_NoiseEstimation(NSinst_t* inst, float* magn, float* noise) {
+// Estimate noise.
+static void NoiseEstimation(NSinst_t* self, float* magn, float* noise) {
int i, s, offset;
float lmagn[HALF_ANAL_BLOCKL], delta;
- if (inst->updates < END_STARTUP_LONG) {
- inst->updates++;
+ if (self->updates < END_STARTUP_LONG) {
+ self->updates++;
}
- for (i = 0; i < inst->magnLen; i++) {
+ for (i = 0; i < self->magnLen; i++) {
lmagn[i] = (float)log(magn[i]);
}
- // loop over simultaneous estimates
+ // Loop over simultaneous estimates.
for (s = 0; s < SIMULT; s++) {
- offset = s * inst->magnLen;
+ offset = s * self->magnLen;
// newquantest(...)
- for (i = 0; i < inst->magnLen; i++) {
- // compute delta
- if (inst->density[offset + i] > 1.0) {
- delta = FACTOR * 1.f / inst->density[offset + i];
+ for (i = 0; i < self->magnLen; i++) {
+ // Compute delta.
+ if (self->density[offset + i] > 1.0) {
+ delta = FACTOR * 1.f / self->density[offset + i];
} else {
delta = FACTOR;
}
- // update log quantile estimate
- if (lmagn[i] > inst->lquantile[offset + i]) {
- inst->lquantile[offset + i] +=
- QUANTILE * delta / (float)(inst->counter[s] + 1);
+ // Update log quantile estimate.
+ if (lmagn[i] > self->lquantile[offset + i]) {
+ self->lquantile[offset + i] +=
+ QUANTILE * delta / (float)(self->counter[s] + 1);
} else {
- inst->lquantile[offset + i] -=
- (1.f - QUANTILE) * delta / (float)(inst->counter[s] + 1);
+ self->lquantile[offset + i] -=
+ (1.f - QUANTILE) * delta / (float)(self->counter[s] + 1);
}
- // update density estimate
- if (fabs(lmagn[i] - inst->lquantile[offset + i]) < WIDTH) {
- inst->density[offset + i] =
- ((float)inst->counter[s] * inst->density[offset + i] +
+ // Update density estimate.
+ if (fabs(lmagn[i] - self->lquantile[offset + i]) < WIDTH) {
+ self->density[offset + i] =
+ ((float)self->counter[s] * self->density[offset + i] +
1.f / (2.f * WIDTH)) /
- (float)(inst->counter[s] + 1);
+ (float)(self->counter[s] + 1);
}
- } // end loop over magnitude spectrum
+ } // End loop over magnitude spectrum.
- if (inst->counter[s] >= END_STARTUP_LONG) {
- inst->counter[s] = 0;
- if (inst->updates >= END_STARTUP_LONG) {
- for (i = 0; i < inst->magnLen; i++) {
- inst->quantile[i] = (float)exp(inst->lquantile[offset + i]);
+ if (self->counter[s] >= END_STARTUP_LONG) {
+ self->counter[s] = 0;
+ if (self->updates >= END_STARTUP_LONG) {
+ for (i = 0; i < self->magnLen; i++) {
+ self->quantile[i] = (float)exp(self->lquantile[offset + i]);
}
}
}
- inst->counter[s]++;
- } // end loop over simultaneous estimates
+ self->counter[s]++;
+ } // End loop over simultaneous estimates.
- // Sequentially update the noise during startup
- if (inst->updates < END_STARTUP_LONG) {
+ // Sequentially update the noise during startup.
+ if (self->updates < END_STARTUP_LONG) {
// Use the last "s" to get noise during startup that differ from zero.
- for (i = 0; i < inst->magnLen; i++) {
- inst->quantile[i] = (float)exp(inst->lquantile[offset + i]);
+ for (i = 0; i < self->magnLen; i++) {
+ self->quantile[i] = (float)exp(self->lquantile[offset + i]);
}
}
- for (i = 0; i < inst->magnLen; i++) {
- noise[i] = inst->quantile[i];
+ for (i = 0; i < self->magnLen; i++) {
+ noise[i] = self->quantile[i];
}
}
-// Extract thresholds for feature parameters
-// histograms are computed over some window_size (given by
-// inst->modelUpdatePars[1])
-// thresholds and weights are extracted every window
-// flag 0 means update histogram only, flag 1 means compute the
-// thresholds/weights
-// threshold and weights are returned in: inst->priorModelPars
-void WebRtcNs_FeatureParameterExtraction(NSinst_t* inst, int flag) {
+// Extract thresholds for feature parameters.
+// Histograms are computed over some window size (given by
+// self->modelUpdatePars[1]).
+// Thresholds and weights are extracted every window.
+// |flag| = 0 updates histogram only, |flag| = 1 computes the threshold/weights.
+// Threshold and weights are returned in: self->priorModelPars.
+static void FeatureParameterExtraction(NSinst_t* self, int flag) {
int i, useFeatureSpecFlat, useFeatureSpecDiff, numHistLrt;
int maxPeak1, maxPeak2;
int weightPeak1SpecFlat, weightPeak2SpecFlat, weightPeak1SpecDiff,
@@ -333,81 +302,81 @@ void WebRtcNs_FeatureParameterExtraction(NSinst_t* inst, int flag) {
float posPeak1SpecFlat, posPeak2SpecFlat, posPeak1SpecDiff, posPeak2SpecDiff;
float fluctLrt, avgHistLrt, avgSquareHistLrt, avgHistLrtCompl;
- // 3 features: lrt, flatness, difference
- // lrt_feature = inst->featureData[3];
- // flat_feature = inst->featureData[0];
- // diff_feature = inst->featureData[4];
+ // 3 features: LRT, flatness, difference.
+ // lrt_feature = self->featureData[3];
+ // flat_feature = self->featureData[0];
+ // diff_feature = self->featureData[4];
- // update histograms
+ // Update histograms.
if (flag == 0) {
// LRT
- if ((inst->featureData[3] <
- HIST_PAR_EST * inst->featureExtractionParams.binSizeLrt) &&
- (inst->featureData[3] >= 0.0)) {
- i = (int)(inst->featureData[3] /
- inst->featureExtractionParams.binSizeLrt);
- inst->histLrt[i]++;
+ if ((self->featureData[3] <
+ HIST_PAR_EST * self->featureExtractionParams.binSizeLrt) &&
+ (self->featureData[3] >= 0.0)) {
+ i = (int)(self->featureData[3] /
+ self->featureExtractionParams.binSizeLrt);
+ self->histLrt[i]++;
}
- // Spectral flatness
- if ((inst->featureData[0] <
- HIST_PAR_EST * inst->featureExtractionParams.binSizeSpecFlat) &&
- (inst->featureData[0] >= 0.0)) {
- i = (int)(inst->featureData[0] /
- inst->featureExtractionParams.binSizeSpecFlat);
- inst->histSpecFlat[i]++;
+ // Spectral flatness.
+ if ((self->featureData[0] <
+ HIST_PAR_EST * self->featureExtractionParams.binSizeSpecFlat) &&
+ (self->featureData[0] >= 0.0)) {
+ i = (int)(self->featureData[0] /
+ self->featureExtractionParams.binSizeSpecFlat);
+ self->histSpecFlat[i]++;
}
- // Spectral difference
- if ((inst->featureData[4] <
- HIST_PAR_EST * inst->featureExtractionParams.binSizeSpecDiff) &&
- (inst->featureData[4] >= 0.0)) {
- i = (int)(inst->featureData[4] /
- inst->featureExtractionParams.binSizeSpecDiff);
- inst->histSpecDiff[i]++;
+ // Spectral difference.
+ if ((self->featureData[4] <
+ HIST_PAR_EST * self->featureExtractionParams.binSizeSpecDiff) &&
+ (self->featureData[4] >= 0.0)) {
+ i = (int)(self->featureData[4] /
+ self->featureExtractionParams.binSizeSpecDiff);
+ self->histSpecDiff[i]++;
}
}
- // extract parameters for speech/noise probability
+ // Extract parameters for speech/noise probability.
if (flag == 1) {
- // lrt feature: compute the average over
- // inst->featureExtractionParams.rangeAvgHistLrt
+ // LRT feature: compute the average over
+ // self->featureExtractionParams.rangeAvgHistLrt.
avgHistLrt = 0.0;
avgHistLrtCompl = 0.0;
avgSquareHistLrt = 0.0;
numHistLrt = 0;
for (i = 0; i < HIST_PAR_EST; i++) {
- binMid = ((float)i + 0.5f) * inst->featureExtractionParams.binSizeLrt;
- if (binMid <= inst->featureExtractionParams.rangeAvgHistLrt) {
- avgHistLrt += inst->histLrt[i] * binMid;
- numHistLrt += inst->histLrt[i];
+ binMid = ((float)i + 0.5f) * self->featureExtractionParams.binSizeLrt;
+ if (binMid <= self->featureExtractionParams.rangeAvgHistLrt) {
+ avgHistLrt += self->histLrt[i] * binMid;
+ numHistLrt += self->histLrt[i];
}
- avgSquareHistLrt += inst->histLrt[i] * binMid * binMid;
- avgHistLrtCompl += inst->histLrt[i] * binMid;
+ avgSquareHistLrt += self->histLrt[i] * binMid * binMid;
+ avgHistLrtCompl += self->histLrt[i] * binMid;
}
if (numHistLrt > 0) {
avgHistLrt = avgHistLrt / ((float)numHistLrt);
}
- avgHistLrtCompl = avgHistLrtCompl / ((float)inst->modelUpdatePars[1]);
- avgSquareHistLrt = avgSquareHistLrt / ((float)inst->modelUpdatePars[1]);
+ avgHistLrtCompl = avgHistLrtCompl / ((float)self->modelUpdatePars[1]);
+ avgSquareHistLrt = avgSquareHistLrt / ((float)self->modelUpdatePars[1]);
fluctLrt = avgSquareHistLrt - avgHistLrt * avgHistLrtCompl;
- // get threshold for lrt feature:
- if (fluctLrt < inst->featureExtractionParams.thresFluctLrt) {
- // very low fluct, so likely noise
- inst->priorModelPars[0] = inst->featureExtractionParams.maxLrt;
+ // Get threshold for LRT feature.
+ if (fluctLrt < self->featureExtractionParams.thresFluctLrt) {
+ // Very low fluctuation, so likely noise.
+ self->priorModelPars[0] = self->featureExtractionParams.maxLrt;
} else {
- inst->priorModelPars[0] =
- inst->featureExtractionParams.factor1ModelPars * avgHistLrt;
- // check if value is within min/max range
- if (inst->priorModelPars[0] < inst->featureExtractionParams.minLrt) {
- inst->priorModelPars[0] = inst->featureExtractionParams.minLrt;
+ self->priorModelPars[0] =
+ self->featureExtractionParams.factor1ModelPars * avgHistLrt;
+ // Check if value is within min/max range.
+ if (self->priorModelPars[0] < self->featureExtractionParams.minLrt) {
+ self->priorModelPars[0] = self->featureExtractionParams.minLrt;
}
- if (inst->priorModelPars[0] > inst->featureExtractionParams.maxLrt) {
- inst->priorModelPars[0] = inst->featureExtractionParams.maxLrt;
+ if (self->priorModelPars[0] > self->featureExtractionParams.maxLrt) {
+ self->priorModelPars[0] = self->featureExtractionParams.maxLrt;
}
}
- // done with lrt feature
+ // Done with LRT feature.
- // for spectral flatness and spectral difference: compute the main peaks of
- // histogram
+ // For spectral flatness and spectral difference: compute the main peaks of
+ // histogram.
maxPeak1 = 0;
maxPeak2 = 0;
posPeak1SpecFlat = 0.0;
@@ -415,233 +384,266 @@ void WebRtcNs_FeatureParameterExtraction(NSinst_t* inst, int flag) {
weightPeak1SpecFlat = 0;
weightPeak2SpecFlat = 0;
- // peaks for flatness
+ // Peaks for flatness.
for (i = 0; i < HIST_PAR_EST; i++) {
binMid =
- (i + 0.5f) * inst->featureExtractionParams.binSizeSpecFlat;
- if (inst->histSpecFlat[i] > maxPeak1) {
- // Found new "first" peak
+ (i + 0.5f) * self->featureExtractionParams.binSizeSpecFlat;
+ if (self->histSpecFlat[i] > maxPeak1) {
+ // Found new "first" peak.
maxPeak2 = maxPeak1;
weightPeak2SpecFlat = weightPeak1SpecFlat;
posPeak2SpecFlat = posPeak1SpecFlat;
- maxPeak1 = inst->histSpecFlat[i];
- weightPeak1SpecFlat = inst->histSpecFlat[i];
+ maxPeak1 = self->histSpecFlat[i];
+ weightPeak1SpecFlat = self->histSpecFlat[i];
posPeak1SpecFlat = binMid;
- } else if (inst->histSpecFlat[i] > maxPeak2) {
- // Found new "second" peak
- maxPeak2 = inst->histSpecFlat[i];
- weightPeak2SpecFlat = inst->histSpecFlat[i];
+ } else if (self->histSpecFlat[i] > maxPeak2) {
+ // Found new "second" peak.
+ maxPeak2 = self->histSpecFlat[i];
+ weightPeak2SpecFlat = self->histSpecFlat[i];
posPeak2SpecFlat = binMid;
}
}
- // compute two peaks for spectral difference
+ // Compute two peaks for spectral difference.
maxPeak1 = 0;
maxPeak2 = 0;
posPeak1SpecDiff = 0.0;
posPeak2SpecDiff = 0.0;
weightPeak1SpecDiff = 0;
weightPeak2SpecDiff = 0;
- // peaks for spectral difference
+ // Peaks for spectral difference.
for (i = 0; i < HIST_PAR_EST; i++) {
binMid =
- ((float)i + 0.5f) * inst->featureExtractionParams.binSizeSpecDiff;
- if (inst->histSpecDiff[i] > maxPeak1) {
- // Found new "first" peak
+ ((float)i + 0.5f) * self->featureExtractionParams.binSizeSpecDiff;
+ if (self->histSpecDiff[i] > maxPeak1) {
+ // Found new "first" peak.
maxPeak2 = maxPeak1;
weightPeak2SpecDiff = weightPeak1SpecDiff;
posPeak2SpecDiff = posPeak1SpecDiff;
- maxPeak1 = inst->histSpecDiff[i];
- weightPeak1SpecDiff = inst->histSpecDiff[i];
+ maxPeak1 = self->histSpecDiff[i];
+ weightPeak1SpecDiff = self->histSpecDiff[i];
posPeak1SpecDiff = binMid;
- } else if (inst->histSpecDiff[i] > maxPeak2) {
- // Found new "second" peak
- maxPeak2 = inst->histSpecDiff[i];
- weightPeak2SpecDiff = inst->histSpecDiff[i];
+ } else if (self->histSpecDiff[i] > maxPeak2) {
+ // Found new "second" peak.
+ maxPeak2 = self->histSpecDiff[i];
+ weightPeak2SpecDiff = self->histSpecDiff[i];
posPeak2SpecDiff = binMid;
}
}
- // for spectrum flatness feature
+ // For spectrum flatness feature.
useFeatureSpecFlat = 1;
- // merge the two peaks if they are close
+ // Merge the two peaks if they are close.
if ((fabs(posPeak2SpecFlat - posPeak1SpecFlat) <
- inst->featureExtractionParams.limitPeakSpacingSpecFlat) &&
+ self->featureExtractionParams.limitPeakSpacingSpecFlat) &&
(weightPeak2SpecFlat >
- inst->featureExtractionParams.limitPeakWeightsSpecFlat *
+ self->featureExtractionParams.limitPeakWeightsSpecFlat *
weightPeak1SpecFlat)) {
weightPeak1SpecFlat += weightPeak2SpecFlat;
posPeak1SpecFlat = 0.5f * (posPeak1SpecFlat + posPeak2SpecFlat);
}
- // reject if weight of peaks is not large enough, or peak value too small
+ // Reject if weight of peaks is not large enough, or peak value too small.
if (weightPeak1SpecFlat <
- inst->featureExtractionParams.thresWeightSpecFlat ||
- posPeak1SpecFlat < inst->featureExtractionParams.thresPosSpecFlat) {
+ self->featureExtractionParams.thresWeightSpecFlat ||
+ posPeak1SpecFlat < self->featureExtractionParams.thresPosSpecFlat) {
useFeatureSpecFlat = 0;
}
- // if selected, get the threshold
+ // If selected, get the threshold.
if (useFeatureSpecFlat == 1) {
- // compute the threshold
- inst->priorModelPars[1] =
- inst->featureExtractionParams.factor2ModelPars * posPeak1SpecFlat;
- // check if value is within min/max range
- if (inst->priorModelPars[1] < inst->featureExtractionParams.minSpecFlat) {
- inst->priorModelPars[1] = inst->featureExtractionParams.minSpecFlat;
+ // Compute the threshold.
+ self->priorModelPars[1] =
+ self->featureExtractionParams.factor2ModelPars * posPeak1SpecFlat;
+ // Check if value is within min/max range.
+ if (self->priorModelPars[1] < self->featureExtractionParams.minSpecFlat) {
+ self->priorModelPars[1] = self->featureExtractionParams.minSpecFlat;
}
- if (inst->priorModelPars[1] > inst->featureExtractionParams.maxSpecFlat) {
- inst->priorModelPars[1] = inst->featureExtractionParams.maxSpecFlat;
+ if (self->priorModelPars[1] > self->featureExtractionParams.maxSpecFlat) {
+ self->priorModelPars[1] = self->featureExtractionParams.maxSpecFlat;
}
}
- // done with flatness feature
+ // Done with flatness feature.
- // for template feature
+ // For template feature.
useFeatureSpecDiff = 1;
- // merge the two peaks if they are close
+ // Merge the two peaks if they are close.
if ((fabs(posPeak2SpecDiff - posPeak1SpecDiff) <
- inst->featureExtractionParams.limitPeakSpacingSpecDiff) &&
+ self->featureExtractionParams.limitPeakSpacingSpecDiff) &&
(weightPeak2SpecDiff >
- inst->featureExtractionParams.limitPeakWeightsSpecDiff *
+ self->featureExtractionParams.limitPeakWeightsSpecDiff *
weightPeak1SpecDiff)) {
weightPeak1SpecDiff += weightPeak2SpecDiff;
posPeak1SpecDiff = 0.5f * (posPeak1SpecDiff + posPeak2SpecDiff);
}
- // get the threshold value
- inst->priorModelPars[3] =
- inst->featureExtractionParams.factor1ModelPars * posPeak1SpecDiff;
- // reject if weight of peaks is not large enough
+ // Get the threshold value.
+ self->priorModelPars[3] =
+ self->featureExtractionParams.factor1ModelPars * posPeak1SpecDiff;
+ // Reject if weight of peaks is not large enough.
if (weightPeak1SpecDiff <
- inst->featureExtractionParams.thresWeightSpecDiff) {
+ self->featureExtractionParams.thresWeightSpecDiff) {
useFeatureSpecDiff = 0;
}
- // check if value is within min/max range
- if (inst->priorModelPars[3] < inst->featureExtractionParams.minSpecDiff) {
- inst->priorModelPars[3] = inst->featureExtractionParams.minSpecDiff;
+ // Check if value is within min/max range.
+ if (self->priorModelPars[3] < self->featureExtractionParams.minSpecDiff) {
+ self->priorModelPars[3] = self->featureExtractionParams.minSpecDiff;
}
- if (inst->priorModelPars[3] > inst->featureExtractionParams.maxSpecDiff) {
- inst->priorModelPars[3] = inst->featureExtractionParams.maxSpecDiff;
+ if (self->priorModelPars[3] > self->featureExtractionParams.maxSpecDiff) {
+ self->priorModelPars[3] = self->featureExtractionParams.maxSpecDiff;
}
- // done with spectral difference feature
+ // Done with spectral difference feature.
- // don't use template feature if fluctuation of lrt feature is very low:
- // most likely just noise state
- if (fluctLrt < inst->featureExtractionParams.thresFluctLrt) {
+ // Don't use template feature if fluctuation of LRT feature is very low:
+ // most likely just noise state.
+ if (fluctLrt < self->featureExtractionParams.thresFluctLrt) {
useFeatureSpecDiff = 0;
}
- // select the weights between the features
- // inst->priorModelPars[4] is weight for lrt: always selected
- // inst->priorModelPars[5] is weight for spectral flatness
- // inst->priorModelPars[6] is weight for spectral difference
+ // Select the weights between the features.
+ // self->priorModelPars[4] is weight for LRT: always selected.
+ // self->priorModelPars[5] is weight for spectral flatness.
+ // self->priorModelPars[6] is weight for spectral difference.
featureSum = (float)(1 + useFeatureSpecFlat + useFeatureSpecDiff);
- inst->priorModelPars[4] = 1.f / featureSum;
- inst->priorModelPars[5] = ((float)useFeatureSpecFlat) / featureSum;
- inst->priorModelPars[6] = ((float)useFeatureSpecDiff) / featureSum;
+ self->priorModelPars[4] = 1.f / featureSum;
+ self->priorModelPars[5] = ((float)useFeatureSpecFlat) / featureSum;
+ self->priorModelPars[6] = ((float)useFeatureSpecDiff) / featureSum;
- // set hists to zero for next update
- if (inst->modelUpdatePars[0] >= 1) {
+ // Set hists to zero for next update.
+ if (self->modelUpdatePars[0] >= 1) {
for (i = 0; i < HIST_PAR_EST; i++) {
- inst->histLrt[i] = 0;
- inst->histSpecFlat[i] = 0;
- inst->histSpecDiff[i] = 0;
+ self->histLrt[i] = 0;
+ self->histSpecFlat[i] = 0;
+ self->histSpecDiff[i] = 0;
}
}
- } // end of flag == 1
+ } // End of flag == 1.
}
-// Compute spectral flatness on input spectrum
-// magnIn is the magnitude spectrum
-// spectral flatness is returned in inst->featureData[0]
-void WebRtcNs_ComputeSpectralFlatness(NSinst_t* inst, float* magnIn) {
+// Compute spectral flatness on input spectrum.
+// |magnIn| is the magnitude spectrum.
+// Spectral flatness is returned in self->featureData[0].
+static void ComputeSpectralFlatness(NSinst_t* self, const float* magnIn) {
int i;
- int shiftLP = 1; // option to remove first bin(s) from spectral measures
+ int shiftLP = 1; // Option to remove first bin(s) from spectral measures.
float avgSpectralFlatnessNum, avgSpectralFlatnessDen, spectralTmp;
- // comute spectral measures
- // for flatness
+ // Compute spectral measures.
+ // For flatness.
avgSpectralFlatnessNum = 0.0;
- avgSpectralFlatnessDen = inst->sumMagn;
+ avgSpectralFlatnessDen = self->sumMagn;
for (i = 0; i < shiftLP; i++) {
avgSpectralFlatnessDen -= magnIn[i];
}
- // compute log of ratio of the geometric to arithmetic mean: check for log(0)
- // case
- for (i = shiftLP; i < inst->magnLen; i++) {
+ // Compute log of ratio of the geometric to arithmetic mean: check for log(0)
+ // case.
+ for (i = shiftLP; i < self->magnLen; i++) {
if (magnIn[i] > 0.0) {
avgSpectralFlatnessNum += (float)log(magnIn[i]);
} else {
- inst->featureData[0] -= SPECT_FL_TAVG * inst->featureData[0];
+ self->featureData[0] -= SPECT_FL_TAVG * self->featureData[0];
return;
}
}
- // normalize
- avgSpectralFlatnessDen = avgSpectralFlatnessDen / inst->magnLen;
- avgSpectralFlatnessNum = avgSpectralFlatnessNum / inst->magnLen;
+ // Normalize.
+ avgSpectralFlatnessDen = avgSpectralFlatnessDen / self->magnLen;
+ avgSpectralFlatnessNum = avgSpectralFlatnessNum / self->magnLen;
- // ratio and inverse log: check for case of log(0)
+ // Ratio and inverse log: check for case of log(0).
spectralTmp = (float)exp(avgSpectralFlatnessNum) / avgSpectralFlatnessDen;
- // time-avg update of spectral flatness feature
- inst->featureData[0] += SPECT_FL_TAVG * (spectralTmp - inst->featureData[0]);
- // done with flatness feature
+ // Time-avg update of spectral flatness feature.
+ self->featureData[0] += SPECT_FL_TAVG * (spectralTmp - self->featureData[0]);
+ // Done with flatness feature.
+}
+
+// Compute prior and post SNR based on quantile noise estimation.
+// Compute DD estimate of prior SNR.
+// Inputs:
+// * |magn| is the signal magnitude spectrum estimate.
+// * |noise| is the magnitude noise spectrum estimate.
+// Outputs:
+// * |snrLocPrior| is the computed prior SNR.
+// * |snrLocPost| is the computed post SNR.
+static void ComputeSnr(const NSinst_t* self,
+ const float* magn,
+ const float* noise,
+ float* snrLocPrior,
+ float* snrLocPost) {
+ int i;
+
+ for (i = 0; i < self->magnLen; i++) {
+ // Previous post SNR.
+ // Previous estimate: based on previous frame with gain filter.
+ float previousEstimateStsa = self->magnPrevAnalyze[i] /
+ (self->noisePrev[i] + 0.0001f) * self->smooth[i];
+ // Post SNR.
+ snrLocPost[i] = 0.f;
+ if (magn[i] > noise[i]) {
+ snrLocPost[i] = magn[i] / (noise[i] + 0.0001f) - 1.f;
+ }
+ // DD estimate is sum of two terms: current estimate and previous estimate.
+ // Directed decision update of snrPrior.
+ snrLocPrior[i] =
+ DD_PR_SNR * previousEstimateStsa + (1.f - DD_PR_SNR) * snrLocPost[i];
+ } // End of loop over frequencies.
}
// Compute the difference measure between input spectrum and a template/learned
-// noise spectrum
-// magnIn is the input spectrum
-// the reference/template spectrum is inst->magnAvgPause[i]
-// returns (normalized) spectral difference in inst->featureData[4]
-void WebRtcNs_ComputeSpectralDifference(NSinst_t* inst, float* magnIn) {
+// noise spectrum.
+// |magnIn| is the input spectrum.
+// The reference/template spectrum is self->magnAvgPause[i].
+// Returns (normalized) spectral difference in self->featureData[4].
+static void ComputeSpectralDifference(NSinst_t* self,
+ const float* magnIn) {
// avgDiffNormMagn = var(magnIn) - cov(magnIn, magnAvgPause)^2 /
// var(magnAvgPause)
int i;
float avgPause, avgMagn, covMagnPause, varPause, varMagn, avgDiffNormMagn;
avgPause = 0.0;
- avgMagn = inst->sumMagn;
- // compute average quantities
- for (i = 0; i < inst->magnLen; i++) {
- // conservative smooth noise spectrum from pause frames
- avgPause += inst->magnAvgPause[i];
+ avgMagn = self->sumMagn;
+ // Compute average quantities.
+ for (i = 0; i < self->magnLen; i++) {
+ // Conservative smooth noise spectrum from pause frames.
+ avgPause += self->magnAvgPause[i];
}
- avgPause = avgPause / ((float)inst->magnLen);
- avgMagn = avgMagn / ((float)inst->magnLen);
+ avgPause = avgPause / ((float)self->magnLen);
+ avgMagn = avgMagn / ((float)self->magnLen);
covMagnPause = 0.0;
varPause = 0.0;
varMagn = 0.0;
- // compute variance and covariance quantities
- for (i = 0; i < inst->magnLen; i++) {
- covMagnPause += (magnIn[i] - avgMagn) * (inst->magnAvgPause[i] - avgPause);
+ // Compute variance and covariance quantities.
+ for (i = 0; i < self->magnLen; i++) {
+ covMagnPause += (magnIn[i] - avgMagn) * (self->magnAvgPause[i] - avgPause);
varPause +=
- (inst->magnAvgPause[i] - avgPause) * (inst->magnAvgPause[i] - avgPause);
+ (self->magnAvgPause[i] - avgPause) * (self->magnAvgPause[i] - avgPause);
varMagn += (magnIn[i] - avgMagn) * (magnIn[i] - avgMagn);
}
- covMagnPause = covMagnPause / ((float)inst->magnLen);
- varPause = varPause / ((float)inst->magnLen);
- varMagn = varMagn / ((float)inst->magnLen);
- // update of average magnitude spectrum
- inst->featureData[6] += inst->signalEnergy;
+ covMagnPause = covMagnPause / ((float)self->magnLen);
+ varPause = varPause / ((float)self->magnLen);
+ varMagn = varMagn / ((float)self->magnLen);
+ // Update of average magnitude spectrum.
+ self->featureData[6] += self->signalEnergy;
avgDiffNormMagn =
varMagn - (covMagnPause * covMagnPause) / (varPause + 0.0001f);
- // normalize and compute time-avg update of difference feature
- avgDiffNormMagn = (float)(avgDiffNormMagn / (inst->featureData[5] + 0.0001f));
- inst->featureData[4] +=
- SPECT_DIFF_TAVG * (avgDiffNormMagn - inst->featureData[4]);
+ // Normalize and compute time-avg update of difference feature.
+ avgDiffNormMagn = (float)(avgDiffNormMagn / (self->featureData[5] + 0.0001f));
+ self->featureData[4] +=
+ SPECT_DIFF_TAVG * (avgDiffNormMagn - self->featureData[4]);
}
-// Compute speech/noise probability
-// speech/noise probability is returned in: probSpeechFinal
-// magn is the input magnitude spectrum
-// noise is the noise spectrum
-// snrLocPrior is the prior snr for each freq.
-// snr loc_post is the post snr for each freq.
-void WebRtcNs_SpeechNoiseProb(NSinst_t* inst,
- float* probSpeechFinal,
- float* snrLocPrior,
- float* snrLocPost) {
+// Compute speech/noise probability.
+// Speech/noise probability is returned in |probSpeechFinal|.
+// |magn| is the input magnitude spectrum.
+// |noise| is the noise spectrum.
+// |snrLocPrior| is the prior SNR for each frequency.
+// |snrLocPost| is the post SNR for each frequency.
+static void SpeechNoiseProb(NSinst_t* self,
+ float* probSpeechFinal,
+ const float* snrLocPrior,
+ const float* snrLocPost) {
int i, sgnMap;
float invLrt, gainPrior, indPrior;
float logLrtTimeAvgKsum, besselTmp;
@@ -652,119 +654,406 @@ void WebRtcNs_SpeechNoiseProb(NSinst_t* inst,
float widthPrior, widthPrior0, widthPrior1, widthPrior2;
widthPrior0 = WIDTH_PR_MAP;
- widthPrior1 = 2.f * WIDTH_PR_MAP; // width for pause region:
- // lower range, so increase width in tanh map
- widthPrior2 = 2.f * WIDTH_PR_MAP; // for spectral-difference measure
+ // Width for pause region: lower range, so increase width in tanh map.
+ widthPrior1 = 2.f * WIDTH_PR_MAP;
+ widthPrior2 = 2.f * WIDTH_PR_MAP; // For spectral-difference measure.
- // threshold parameters for features
- threshPrior0 = inst->priorModelPars[0];
- threshPrior1 = inst->priorModelPars[1];
- threshPrior2 = inst->priorModelPars[3];
+ // Threshold parameters for features.
+ threshPrior0 = self->priorModelPars[0];
+ threshPrior1 = self->priorModelPars[1];
+ threshPrior2 = self->priorModelPars[3];
- // sign for flatness feature
- sgnMap = (int)(inst->priorModelPars[2]);
+ // Sign for flatness feature.
+ sgnMap = (int)(self->priorModelPars[2]);
- // weight parameters for features
- weightIndPrior0 = inst->priorModelPars[4];
- weightIndPrior1 = inst->priorModelPars[5];
- weightIndPrior2 = inst->priorModelPars[6];
+ // Weight parameters for features.
+ weightIndPrior0 = self->priorModelPars[4];
+ weightIndPrior1 = self->priorModelPars[5];
+ weightIndPrior2 = self->priorModelPars[6];
- // compute feature based on average LR factor
- // this is the average over all frequencies of the smooth log lrt
+ // Compute feature based on average LR factor.
+ // This is the average over all frequencies of the smooth log LRT.
logLrtTimeAvgKsum = 0.0;
- for (i = 0; i < inst->magnLen; i++) {
+ for (i = 0; i < self->magnLen; i++) {
tmpFloat1 = 1.f + 2.f * snrLocPrior[i];
tmpFloat2 = 2.f * snrLocPrior[i] / (tmpFloat1 + 0.0001f);
besselTmp = (snrLocPost[i] + 1.f) * tmpFloat2;
- inst->logLrtTimeAvg[i] +=
- LRT_TAVG * (besselTmp - (float)log(tmpFloat1) - inst->logLrtTimeAvg[i]);
- logLrtTimeAvgKsum += inst->logLrtTimeAvg[i];
+ self->logLrtTimeAvg[i] +=
+ LRT_TAVG * (besselTmp - (float)log(tmpFloat1) - self->logLrtTimeAvg[i]);
+ logLrtTimeAvgKsum += self->logLrtTimeAvg[i];
}
- logLrtTimeAvgKsum = (float)logLrtTimeAvgKsum / (inst->magnLen);
- inst->featureData[3] = logLrtTimeAvgKsum;
- // done with computation of LR factor
-
- //
- // compute the indicator functions
- //
+ logLrtTimeAvgKsum = (float)logLrtTimeAvgKsum / (self->magnLen);
+ self->featureData[3] = logLrtTimeAvgKsum;
+ // Done with computation of LR factor.
- // average lrt feature
+ // Compute the indicator functions.
+ // Average LRT feature.
widthPrior = widthPrior0;
- // use larger width in tanh map for pause regions
+ // Use larger width in tanh map for pause regions.
if (logLrtTimeAvgKsum < threshPrior0) {
widthPrior = widthPrior1;
}
- // compute indicator function: sigmoid map
+ // Compute indicator function: sigmoid map.
indicator0 =
0.5f *
((float)tanh(widthPrior * (logLrtTimeAvgKsum - threshPrior0)) + 1.f);
- // spectral flatness feature
- tmpFloat1 = inst->featureData[0];
+ // Spectral flatness feature.
+ tmpFloat1 = self->featureData[0];
widthPrior = widthPrior0;
- // use larger width in tanh map for pause regions
+ // Use larger width in tanh map for pause regions.
if (sgnMap == 1 && (tmpFloat1 > threshPrior1)) {
widthPrior = widthPrior1;
}
if (sgnMap == -1 && (tmpFloat1 < threshPrior1)) {
widthPrior = widthPrior1;
}
- // compute indicator function: sigmoid map
+ // Compute indicator function: sigmoid map.
indicator1 =
0.5f *
((float)tanh((float)sgnMap * widthPrior * (threshPrior1 - tmpFloat1)) +
1.f);
- // for template spectrum-difference
- tmpFloat1 = inst->featureData[4];
+ // For template spectrum-difference.
+ tmpFloat1 = self->featureData[4];
widthPrior = widthPrior0;
- // use larger width in tanh map for pause regions
+ // Use larger width in tanh map for pause regions.
if (tmpFloat1 < threshPrior2) {
widthPrior = widthPrior2;
}
- // compute indicator function: sigmoid map
+ // Compute indicator function: sigmoid map.
indicator2 =
0.5f * ((float)tanh(widthPrior * (tmpFloat1 - threshPrior2)) + 1.f);
- // combine the indicator function with the feature weights
+ // Combine the indicator function with the feature weights.
indPrior = weightIndPrior0 * indicator0 + weightIndPrior1 * indicator1 +
weightIndPrior2 * indicator2;
- // done with computing indicator function
+ // Done with computing indicator function.
- // compute the prior probability
- inst->priorSpeechProb += PRIOR_UPDATE * (indPrior - inst->priorSpeechProb);
- // make sure probabilities are within range: keep floor to 0.01
- if (inst->priorSpeechProb > 1.f) {
- inst->priorSpeechProb = 1.f;
+ // Compute the prior probability.
+ self->priorSpeechProb += PRIOR_UPDATE * (indPrior - self->priorSpeechProb);
+ // Make sure probabilities are within range: keep floor to 0.01.
+ if (self->priorSpeechProb > 1.f) {
+ self->priorSpeechProb = 1.f;
}
- if (inst->priorSpeechProb < 0.01f) {
- inst->priorSpeechProb = 0.01f;
+ if (self->priorSpeechProb < 0.01f) {
+ self->priorSpeechProb = 0.01f;
}
- // final speech probability: combine prior model with LR factor:
- gainPrior = (1.f - inst->priorSpeechProb) / (inst->priorSpeechProb + 0.0001f);
- for (i = 0; i < inst->magnLen; i++) {
- invLrt = (float)exp(-inst->logLrtTimeAvg[i]);
+ // Final speech probability: combine prior model with LR factor:.
+ gainPrior = (1.f - self->priorSpeechProb) / (self->priorSpeechProb + 0.0001f);
+ for (i = 0; i < self->magnLen; i++) {
+ invLrt = (float)exp(-self->logLrtTimeAvg[i]);
invLrt = (float)gainPrior * invLrt;
probSpeechFinal[i] = 1.f / (1.f + invLrt);
}
}
-int WebRtcNs_AnalyzeCore(NSinst_t* inst, float* speechFrame) {
+// Update the noise features.
+// Inputs:
+// * |magn| is the signal magnitude spectrum estimate.
+// * |updateParsFlag| is an update flag for parameters.
+static void FeatureUpdate(NSinst_t* self,
+ const float* magn,
+ int updateParsFlag) {
+ // Compute spectral flatness on input spectrum.
+ ComputeSpectralFlatness(self, magn);
+ // Compute difference of input spectrum with learned/estimated noise spectrum.
+ ComputeSpectralDifference(self, magn);
+ // Compute histograms for parameter decisions (thresholds and weights for
+ // features).
+ // Parameters are extracted once every window time.
+ // (=self->modelUpdatePars[1])
+ if (updateParsFlag >= 1) {
+ // Counter update.
+ self->modelUpdatePars[3]--;
+ // Update histogram.
+ if (self->modelUpdatePars[3] > 0) {
+ FeatureParameterExtraction(self, 0);
+ }
+ // Compute model parameters.
+ if (self->modelUpdatePars[3] == 0) {
+ FeatureParameterExtraction(self, 1);
+ self->modelUpdatePars[3] = self->modelUpdatePars[1];
+ // If wish to update only once, set flag to zero.
+ if (updateParsFlag == 1) {
+ self->modelUpdatePars[0] = 0;
+ } else {
+ // Update every window:
+ // Get normalization for spectral difference for next window estimate.
+ self->featureData[6] =
+ self->featureData[6] / ((float)self->modelUpdatePars[1]);
+ self->featureData[5] =
+ 0.5f * (self->featureData[6] + self->featureData[5]);
+ self->featureData[6] = 0.f;
+ }
+ }
+ }
+}
+
+// Update the noise estimate.
+// Inputs:
+// * |magn| is the signal magnitude spectrum estimate.
+// * |snrLocPrior| is the prior SNR.
+// * |snrLocPost| is the post SNR.
+// Output:
+// * |noise| is the updated noise magnitude spectrum estimate.
+static void UpdateNoiseEstimate(NSinst_t* self,
+ const float* magn,
+ const float* snrLocPrior,
+ const float* snrLocPost,
+ float* noise) {
+ int i;
+ float probSpeech, probNonSpeech;
+ // Time-avg parameter for noise update.
+ float gammaNoiseTmp = NOISE_UPDATE;
+ float gammaNoiseOld;
+ float noiseUpdateTmp;
+
+ for (i = 0; i < self->magnLen; i++) {
+ probSpeech = self->speechProb[i];
+ probNonSpeech = 1.f - probSpeech;
+ // Temporary noise update:
+ // Use it for speech frames if update value is less than previous.
+ noiseUpdateTmp = gammaNoiseTmp * self->noisePrev[i] +
+ (1.f - gammaNoiseTmp) * (probNonSpeech * magn[i] +
+ probSpeech * self->noisePrev[i]);
+ // Time-constant based on speech/noise state.
+ gammaNoiseOld = gammaNoiseTmp;
+ gammaNoiseTmp = NOISE_UPDATE;
+ // Increase gamma (i.e., less noise update) for frame likely to be speech.
+ if (probSpeech > PROB_RANGE) {
+ gammaNoiseTmp = SPEECH_UPDATE;
+ }
+ // Conservative noise update.
+ if (probSpeech < PROB_RANGE) {
+ self->magnAvgPause[i] += GAMMA_PAUSE * (magn[i] - self->magnAvgPause[i]);
+ }
+ // Noise update.
+ if (gammaNoiseTmp == gammaNoiseOld) {
+ noise[i] = noiseUpdateTmp;
+ } else {
+ noise[i] = gammaNoiseTmp * self->noisePrev[i] +
+ (1.f - gammaNoiseTmp) * (probNonSpeech * magn[i] +
+ probSpeech * self->noisePrev[i]);
+ // Allow for noise update downwards:
+ // If noise update decreases the noise, it is safe, so allow it to
+ // happen.
+ if (noiseUpdateTmp < noise[i]) {
+ noise[i] = noiseUpdateTmp;
+ }
+ }
+ } // End of freq loop.
+}
+
+// Updates |buffer| with a new |frame|.
+// Inputs:
+// * |frame| is a new speech frame or NULL for setting to zero.
+// * |frame_length| is the length of the new frame.
+// * |buffer_length| is the length of the buffer.
+// Output:
+// * |buffer| is the updated buffer.
+static void UpdateBuffer(const float* frame,
+ int frame_length,
+ int buffer_length,
+ float* buffer) {
+ assert(buffer_length < 2 * frame_length);
+
+ memcpy(buffer,
+ buffer + frame_length,
+ sizeof(*buffer) * (buffer_length - frame_length));
+ if (frame) {
+ memcpy(buffer + buffer_length - frame_length,
+ frame,
+ sizeof(*buffer) * frame_length);
+ } else {
+ memset(buffer + buffer_length - frame_length,
+ 0,
+ sizeof(*buffer) * frame_length);
+ }
+}
+
+// Transforms the signal from time to frequency domain.
+// Inputs:
+// * |time_data| is the signal in the time domain.
+// * |time_data_length| is the length of the analysis buffer.
+// * |magnitude_length| is the length of the spectrum magnitude, which equals
+// the length of both |real| and |imag| (time_data_length / 2 + 1).
+// Outputs:
+// * |time_data| is the signal in the frequency domain.
+// * |real| is the real part of the frequency domain.
+// * |imag| is the imaginary part of the frequency domain.
+// * |magn| is the calculated signal magnitude in the frequency domain.
+static void FFT(NSinst_t* self,
+ float* time_data,
+ int time_data_length,
+ int magnitude_length,
+ float* real,
+ float* imag,
+ float* magn) {
+ int i;
+
+ assert(magnitude_length == time_data_length / 2 + 1);
+
+ WebRtc_rdft(time_data_length, 1, time_data, self->ip, self->wfft);
+
+ imag[0] = 0;
+ real[0] = time_data[0];
+ magn[0] = fabs(real[0]) + 1.f;
+ imag[magnitude_length - 1] = 0;
+ real[magnitude_length - 1] = time_data[1];
+ magn[magnitude_length - 1] = fabs(real[magnitude_length - 1]) + 1.f;
+ for (i = 1; i < magnitude_length - 1; ++i) {
+ real[i] = time_data[2 * i];
+ imag[i] = time_data[2 * i + 1];
+ // Magnitude spectrum.
+ magn[i] = sqrtf(real[i] * real[i] + imag[i] * imag[i]) + 1.f;
+ }
+}
+
+// Transforms the signal from frequency to time domain.
+// Inputs:
+// * |real| is the real part of the frequency domain.
+// * |imag| is the imaginary part of the frequency domain.
+// * |magnitude_length| is the length of the spectrum magnitude, which equals
+// the length of both |real| and |imag|.
+// * |time_data_length| is the length of the analysis buffer
+// (2 * (magnitude_length - 1)).
+// Output:
+// * |time_data| is the signal in the time domain.
+static void IFFT(NSinst_t* self,
+ const float* real,
+ const float* imag,
+ int magnitude_length,
+ int time_data_length,
+ float* time_data) {
+ int i;
+
+ assert(time_data_length == 2 * (magnitude_length - 1));
+
+ time_data[0] = real[0];
+ time_data[1] = real[magnitude_length - 1];
+ for (i = 1; i < magnitude_length - 1; ++i) {
+ time_data[2 * i] = real[i];
+ time_data[2 * i + 1] = imag[i];
+ }
+ WebRtc_rdft(time_data_length, -1, time_data, self->ip, self->wfft);
+
+ for (i = 0; i < time_data_length; ++i) {
+ time_data[i] *= 2.f / time_data_length; // FFT scaling.
+ }
+}
+
+// Calculates the energy of a buffer.
+// Inputs:
+// * |buffer| is the buffer over which the energy is calculated.
+// * |length| is the length of the buffer.
+// Returns the calculated energy.
+static float Energy(const float* buffer, int length) {
+ int i;
+ float energy = 0.f;
+
+ for (i = 0; i < length; ++i) {
+ energy += buffer[i] * buffer[i];
+ }
+
+ return energy;
+}
+
+// Windows a buffer.
+// Inputs:
+// * |window| is the window by which to multiply.
+// * |data| is the data without windowing.
+// * |length| is the length of the window and data.
+// Output:
+// * |data_windowed| is the windowed data.
+static void Windowing(const float* window,
+ const float* data,
+ int length,
+ float* data_windowed) {
+ int i;
+
+ for (i = 0; i < length; ++i) {
+ data_windowed[i] = window[i] * data[i];
+ }
+}
+
+// Estimate prior SNR decision-directed and compute DD based Wiener Filter.
+// Input:
+// * |magn| is the signal magnitude spectrum estimate.
+// Output:
+// * |theFilter| is the frequency response of the computed Wiener filter.
+static void ComputeDdBasedWienerFilter(const NSinst_t* self,
+ const float* magn,
+ float* theFilter) {
+ int i;
+ float snrPrior, previousEstimateStsa, currentEstimateStsa;
+
+ for (i = 0; i < self->magnLen; i++) {
+ // Previous estimate: based on previous frame with gain filter.
+ previousEstimateStsa = self->magnPrevProcess[i] /
+ (self->noisePrev[i] + 0.0001f) * self->smooth[i];
+ // Post and prior SNR.
+ currentEstimateStsa = 0.f;
+ if (magn[i] > self->noise[i]) {
+ currentEstimateStsa = magn[i] / (self->noise[i] + 0.0001f) - 1.f;
+ }
+ // DD estimate is sum of two terms: current estimate and previous estimate.
+ // Directed decision update of |snrPrior|.
+ snrPrior = DD_PR_SNR * previousEstimateStsa +
+ (1.f - DD_PR_SNR) * currentEstimateStsa;
+ // Gain filter.
+ theFilter[i] = snrPrior / (self->overdrive + snrPrior);
+ } // End of loop over frequencies.
+}
+
+// Changes the aggressiveness of the noise suppression method.
+// |mode| = 0 is mild (6dB), |mode| = 1 is medium (10dB) and |mode| = 2 is
+// aggressive (15dB).
+// Returns 0 on success and -1 otherwise.
+int WebRtcNs_set_policy_core(NSinst_t* self, int mode) {
+ // Allow for modes: 0, 1, 2, 3.
+ if (mode < 0 || mode > 3) {
+ return (-1);
+ }
+
+ self->aggrMode = mode;
+ if (mode == 0) {
+ self->overdrive = 1.f;
+ self->denoiseBound = 0.5f;
+ self->gainmap = 0;
+ } else if (mode == 1) {
+ // self->overdrive = 1.25f;
+ self->overdrive = 1.f;
+ self->denoiseBound = 0.25f;
+ self->gainmap = 1;
+ } else if (mode == 2) {
+ // self->overdrive = 1.25f;
+ self->overdrive = 1.1f;
+ self->denoiseBound = 0.125f;
+ self->gainmap = 1;
+ } else if (mode == 3) {
+ // self->overdrive = 1.3f;
+ self->overdrive = 1.25f;
+ self->denoiseBound = 0.09f;
+ self->gainmap = 1;
+ }
+ return 0;
+}
+
+int WebRtcNs_AnalyzeCore(NSinst_t* self, float* speechFrame) {
int i;
const int kStartBand = 5; // Skip first frequency bins during estimation.
int updateParsFlag;
float energy;
- float signalEnergy, sumMagn;
- float tmpFloat1, tmpFloat2, tmpFloat3, probSpeech, probNonSpeech;
- float gammaNoiseTmp, gammaNoiseOld;
- float noiseUpdateTmp, fTmp;
+ float signalEnergy = 0.f;
+ float sumMagn = 0.f;
+ float tmpFloat1, tmpFloat2, tmpFloat3;
float winData[ANAL_BLOCKL_MAX];
float magn[HALF_ANAL_BLOCKL], noise[HALF_ANAL_BLOCKL];
float snrLocPost[HALF_ANAL_BLOCKL], snrLocPrior[HALF_ANAL_BLOCKL];
- float previousEstimateStsa[HALF_ANAL_BLOCKL];
float real[ANAL_BLOCKL_MAX], imag[HALF_ANAL_BLOCKL];
- // Variables during startup
+ // Variables during startup.
float sum_log_i = 0.0;
float sum_log_i_square = 0.0;
float sum_log_magn = 0.0;
@@ -772,30 +1061,19 @@ int WebRtcNs_AnalyzeCore(NSinst_t* inst, float* speechFrame) {
float parametric_exp = 0.0;
float parametric_num = 0.0;
- // Check that initiation has been done
- if (inst->initFlag != 1) {
+ // Check that initiation has been done.
+ if (self->initFlag != 1) {
return (-1);
}
- //
- updateParsFlag = inst->modelUpdatePars[0];
- //
-
- // update analysis buffer for L band
- memcpy(inst->analyzeBuf,
- inst->analyzeBuf + inst->blockLen,
- sizeof(float) * (inst->anaLen - inst->blockLen));
- memcpy(inst->analyzeBuf + inst->anaLen - inst->blockLen,
- speechFrame,
- sizeof(float) * inst->blockLen);
-
- // windowing
- energy = 0.0;
- for (i = 0; i < inst->anaLen; i++) {
- winData[i] = inst->window[i] * inst->analyzeBuf[i];
- energy += winData[i] * winData[i];
- }
+ updateParsFlag = self->modelUpdatePars[0];
+
+ // Update analysis buffer for L band.
+ UpdateBuffer(speechFrame, self->blockLen, self->anaLen, self->analyzeBuf);
+
+ Windowing(self->window, self->analyzeBuf, self->anaLen, winData);
+ energy = Energy(winData, self->anaLen);
if (energy == 0.0) {
- // we want to avoid updating statistics in this case:
+ // We want to avoid updating statistics in this case:
// Updating feature statistics when we have zeros only will cause
// thresholds to move towards zero signal situations. This in turn has the
// effect that once the signal is "turned on" (non-zero values) everything
@@ -806,38 +1084,14 @@ int WebRtcNs_AnalyzeCore(NSinst_t* inst, float* speechFrame) {
return 0;
}
- //
- inst->blockInd++; // Update the block index only when we process a block.
- // FFT
- WebRtc_rdft(inst->anaLen, 1, winData, inst->ip, inst->wfft);
+ self->blockInd++; // Update the block index only when we process a block.
- imag[0] = 0;
- real[0] = winData[0];
- magn[0] = fabs(real[0]) + 1.f;
- imag[inst->magnLen - 1] = 0;
- real[inst->magnLen - 1] = winData[1];
- magn[inst->magnLen - 1] = fabs(real[inst->magnLen - 1]) + 1.f;
- signalEnergy = (float)(real[0] * real[0]) +
- (float)(real[inst->magnLen - 1] * real[inst->magnLen - 1]);
- sumMagn = magn[0] + magn[inst->magnLen - 1];
- if (inst->blockInd < END_STARTUP_SHORT) {
- tmpFloat2 = log((float)(inst->magnLen - 1));
- sum_log_i = tmpFloat2;
- sum_log_i_square = tmpFloat2 * tmpFloat2;
- tmpFloat1 = log(magn[inst->magnLen - 1]);
- sum_log_magn = tmpFloat1;
- sum_log_i_log_magn = tmpFloat2 * tmpFloat1;
- }
- for (i = 1; i < inst->magnLen - 1; i++) {
- real[i] = winData[2 * i];
- imag[i] = winData[2 * i + 1];
- // magnitude spectrum
- fTmp = real[i] * real[i];
- fTmp += imag[i] * imag[i];
- signalEnergy += fTmp;
- magn[i] = ((float)sqrt(fTmp)) + 1.f;
+ FFT(self, winData, self->anaLen, self->magnLen, real, imag, magn);
+
+ for (i = 0; i < self->magnLen; i++) {
+ signalEnergy += real[i] * real[i] + imag[i] * imag[i];
sumMagn += magn[i];
- if (inst->blockInd < END_STARTUP_SHORT) {
+ if (self->blockInd < END_STARTUP_SHORT) {
if (i >= kStartBand) {
tmpFloat2 = log((float)i);
sum_log_i += tmpFloat2;
@@ -848,199 +1102,106 @@ int WebRtcNs_AnalyzeCore(NSinst_t* inst, float* speechFrame) {
}
}
}
- signalEnergy = signalEnergy / ((float)inst->magnLen);
- inst->signalEnergy = signalEnergy;
- inst->sumMagn = sumMagn;
-
- // compute spectral flatness on input spectrum
- WebRtcNs_ComputeSpectralFlatness(inst, magn);
- // quantile noise estimate
- WebRtcNs_NoiseEstimation(inst, magn, noise);
- // compute simplified noise model during startup
- if (inst->blockInd < END_STARTUP_SHORT) {
- // Estimate White noise
- inst->whiteNoiseLevel += sumMagn / ((float)inst->magnLen) * inst->overdrive;
- // Estimate Pink noise parameters
- tmpFloat1 = sum_log_i_square * ((float)(inst->magnLen - kStartBand));
+ signalEnergy = signalEnergy / ((float)self->magnLen);
+ self->signalEnergy = signalEnergy;
+ self->sumMagn = sumMagn;
+
+ // Quantile noise estimate.
+ NoiseEstimation(self, magn, noise);
+ // Compute simplified noise model during startup.
+ if (self->blockInd < END_STARTUP_SHORT) {
+ // Estimate White noise.
+ self->whiteNoiseLevel += sumMagn / ((float)self->magnLen) * self->overdrive;
+ // Estimate Pink noise parameters.
+ tmpFloat1 = sum_log_i_square * ((float)(self->magnLen - kStartBand));
tmpFloat1 -= (sum_log_i * sum_log_i);
tmpFloat2 =
(sum_log_i_square * sum_log_magn - sum_log_i * sum_log_i_log_magn);
tmpFloat3 = tmpFloat2 / tmpFloat1;
- // Constrain the estimated spectrum to be positive
+ // Constrain the estimated spectrum to be positive.
if (tmpFloat3 < 0.f) {
tmpFloat3 = 0.f;
}
- inst->pinkNoiseNumerator += tmpFloat3;
+ self->pinkNoiseNumerator += tmpFloat3;
tmpFloat2 = (sum_log_i * sum_log_magn);
- tmpFloat2 -= ((float)(inst->magnLen - kStartBand)) * sum_log_i_log_magn;
+ tmpFloat2 -= ((float)(self->magnLen - kStartBand)) * sum_log_i_log_magn;
tmpFloat3 = tmpFloat2 / tmpFloat1;
- // Constrain the pink noise power to be in the interval [0, 1];
+ // Constrain the pink noise power to be in the interval [0, 1].
if (tmpFloat3 < 0.f) {
tmpFloat3 = 0.f;
}
if (tmpFloat3 > 1.f) {
tmpFloat3 = 1.f;
}
- inst->pinkNoiseExp += tmpFloat3;
+ self->pinkNoiseExp += tmpFloat3;
// Calculate frequency independent parts of parametric noise estimate.
- if (inst->pinkNoiseExp > 0.f) {
- // Use pink noise estimate
+ if (self->pinkNoiseExp > 0.f) {
+ // Use pink noise estimate.
parametric_num =
- exp(inst->pinkNoiseNumerator / (float)(inst->blockInd + 1));
- parametric_num *= (float)(inst->blockInd + 1);
- parametric_exp = inst->pinkNoiseExp / (float)(inst->blockInd + 1);
+ exp(self->pinkNoiseNumerator / (float)(self->blockInd + 1));
+ parametric_num *= (float)(self->blockInd + 1);
+ parametric_exp = self->pinkNoiseExp / (float)(self->blockInd + 1);
}
- for (i = 0; i < inst->magnLen; i++) {
+ for (i = 0; i < self->magnLen; i++) {
// Estimate the background noise using the white and pink noise
- // parameters
- if (inst->pinkNoiseExp == 0.f) {
- // Use white noise estimate
- inst->parametricNoise[i] = inst->whiteNoiseLevel;
+ // parameters.
+ if (self->pinkNoiseExp == 0.f) {
+ // Use white noise estimate.
+ self->parametricNoise[i] = self->whiteNoiseLevel;
} else {
- // Use pink noise estimate
+ // Use pink noise estimate.
float use_band = (float)(i < kStartBand ? kStartBand : i);
- inst->parametricNoise[i] =
+ self->parametricNoise[i] =
parametric_num / pow(use_band, parametric_exp);
}
- // Weight quantile noise with modeled noise
- noise[i] *= (inst->blockInd);
+ // Weight quantile noise with modeled noise.
+ noise[i] *= (self->blockInd);
tmpFloat2 =
- inst->parametricNoise[i] * (END_STARTUP_SHORT - inst->blockInd);
- noise[i] += (tmpFloat2 / (float)(inst->blockInd + 1));
+ self->parametricNoise[i] * (END_STARTUP_SHORT - self->blockInd);
+ noise[i] += (tmpFloat2 / (float)(self->blockInd + 1));
noise[i] /= END_STARTUP_SHORT;
}
}
- // compute average signal during END_STARTUP_LONG time:
- // used to normalize spectral difference measure
- if (inst->blockInd < END_STARTUP_LONG) {
- inst->featureData[5] *= inst->blockInd;
- inst->featureData[5] += signalEnergy;
- inst->featureData[5] /= (inst->blockInd + 1);
+ // Compute average signal during END_STARTUP_LONG time:
+ // used to normalize spectral difference measure.
+ if (self->blockInd < END_STARTUP_LONG) {
+ self->featureData[5] *= self->blockInd;
+ self->featureData[5] += signalEnergy;
+ self->featureData[5] /= (self->blockInd + 1);
}
- // start processing at frames == converged+1
- // STEP 1: compute prior and post snr based on quantile noise est
- // compute DD estimate of prior SNR: needed for new method
- for (i = 0; i < inst->magnLen; i++) {
- // post snr
- snrLocPost[i] = 0.f;
- if (magn[i] > noise[i]) {
- snrLocPost[i] = magn[i] / (noise[i] + 0.0001f) - 1.f;
- }
- // previous post snr
- // previous estimate: based on previous frame with gain filter
- previousEstimateStsa[i] = inst->magnPrevAnalyze[i] /
- (inst->noisePrev[i] + 0.0001f) * inst->smooth[i];
- // DD estimate is sum of two terms: current estimate and previous estimate
- // directed decision update of snrPrior
- snrLocPrior[i] =
- DD_PR_SNR * previousEstimateStsa[i] + (1.f - DD_PR_SNR) * snrLocPost[i];
- // post and prior snr needed for step 2
- } // end of loop over freqs
- // done with step 1: dd computation of prior and post snr
-
- // STEP 2: compute speech/noise likelihood
- // compute difference of input spectrum with learned/estimated noise
- // spectrum
- WebRtcNs_ComputeSpectralDifference(inst, magn);
- // compute histograms for parameter decisions (thresholds and weights for
- // features)
- // parameters are extracted once every window time
- // (=inst->modelUpdatePars[1])
- if (updateParsFlag >= 1) {
- // counter update
- inst->modelUpdatePars[3]--;
- // update histogram
- if (inst->modelUpdatePars[3] > 0) {
- WebRtcNs_FeatureParameterExtraction(inst, 0);
- }
- // compute model parameters
- if (inst->modelUpdatePars[3] == 0) {
- WebRtcNs_FeatureParameterExtraction(inst, 1);
- inst->modelUpdatePars[3] = inst->modelUpdatePars[1];
- // if wish to update only once, set flag to zero
- if (updateParsFlag == 1) {
- inst->modelUpdatePars[0] = 0;
- } else {
- // update every window:
- // get normalization for spectral difference for next window estimate
- inst->featureData[6] =
- inst->featureData[6] / ((float)inst->modelUpdatePars[1]);
- inst->featureData[5] =
- 0.5f * (inst->featureData[6] + inst->featureData[5]);
- inst->featureData[6] = 0.f;
- }
- }
- }
- // compute speech/noise probability
- WebRtcNs_SpeechNoiseProb(inst, inst->speechProb, snrLocPrior, snrLocPost);
- // time-avg parameter for noise update
- gammaNoiseTmp = NOISE_UPDATE;
- for (i = 0; i < inst->magnLen; i++) {
- probSpeech = inst->speechProb[i];
- probNonSpeech = 1.f - probSpeech;
- // temporary noise update:
- // use it for speech frames if update value is less than previous
- noiseUpdateTmp = gammaNoiseTmp * inst->noisePrev[i] +
- (1.f - gammaNoiseTmp) * (probNonSpeech * magn[i] +
- probSpeech * inst->noisePrev[i]);
- //
- // time-constant based on speech/noise state
- gammaNoiseOld = gammaNoiseTmp;
- gammaNoiseTmp = NOISE_UPDATE;
- // increase gamma (i.e., less noise update) for frame likely to be speech
- if (probSpeech > PROB_RANGE) {
- gammaNoiseTmp = SPEECH_UPDATE;
- }
- // conservative noise update
- if (probSpeech < PROB_RANGE) {
- inst->magnAvgPause[i] += GAMMA_PAUSE * (magn[i] - inst->magnAvgPause[i]);
- }
- // noise update
- if (gammaNoiseTmp == gammaNoiseOld) {
- noise[i] = noiseUpdateTmp;
- } else {
- noise[i] = gammaNoiseTmp * inst->noisePrev[i] +
- (1.f - gammaNoiseTmp) * (probNonSpeech * magn[i] +
- probSpeech * inst->noisePrev[i]);
- // allow for noise update downwards:
- // if noise update decreases the noise, it is safe, so allow it to
- // happen
- if (noiseUpdateTmp < noise[i]) {
- noise[i] = noiseUpdateTmp;
- }
- }
- } // end of freq loop
- // done with step 2: noise update
+ // Post and prior SNR needed for SpeechNoiseProb.
+ ComputeSnr(self, magn, noise, snrLocPrior, snrLocPost);
- // keep track of noise spectrum for next frame
- memcpy(inst->noise, noise, sizeof(*noise) * inst->magnLen);
- memcpy(inst->magnPrevAnalyze, magn, sizeof(*magn) * inst->magnLen);
+ FeatureUpdate(self, magn, updateParsFlag);
+ SpeechNoiseProb(self, self->speechProb, snrLocPrior, snrLocPost);
+ UpdateNoiseEstimate(self, magn, snrLocPrior, snrLocPost, noise);
+
+ // Keep track of noise spectrum for next frame.
+ memcpy(self->noise, noise, sizeof(*noise) * self->magnLen);
+ memcpy(self->magnPrevAnalyze, magn, sizeof(*magn) * self->magnLen);
return 0;
}
-int WebRtcNs_ProcessCore(NSinst_t* inst,
+int WebRtcNs_ProcessCore(NSinst_t* self,
float* speechFrame,
float* speechFrameHB,
float* outFrame,
float* outFrameHB) {
- // main routine for noise reduction
+ // Main routine for noise reduction.
int flagHB = 0;
int i;
float energy1, energy2, gain, factor, factor1, factor2;
- float snrPrior, previousEstimateStsa, currentEstimateStsa;
- float tmpFloat1, tmpFloat2;
- float fTmp;
float fout[BLOCKL_MAX];
float winData[ANAL_BLOCKL_MAX];
float magn[HALF_ANAL_BLOCKL];
float theFilter[HALF_ANAL_BLOCKL], theFilterTmp[HALF_ANAL_BLOCKL];
float real[ANAL_BLOCKL_MAX], imag[HALF_ANAL_BLOCKL];
- // SWB variables
+ // SWB variables.
int deltaBweHB = 1;
int deltaGainHB = 1;
float decayBweHB = 1.0;
@@ -1049,178 +1210,111 @@ int WebRtcNs_ProcessCore(NSinst_t* inst,
float avgProbSpeechHB, avgProbSpeechHBTmp, avgFilterGainHB, gainModHB;
float sumMagnAnalyze, sumMagnProcess;
- // Check that initiation has been done
- if (inst->initFlag != 1) {
+ // Check that initiation has been done.
+ if (self->initFlag != 1) {
return (-1);
}
- // Check for valid pointers based on sampling rate
- if (inst->fs == 32000) {
+ // Check for valid pointers based on sampling rate.
+ if (self->fs == 32000) {
if (speechFrameHB == NULL) {
return -1;
}
flagHB = 1;
- // range for averaging low band quantities for H band gain
- deltaBweHB = (int)inst->magnLen / 4;
+ // Range for averaging low band quantities for H band gain.
+ deltaBweHB = (int)self->magnLen / 4;
deltaGainHB = deltaBweHB;
}
- // update analysis buffer for L band
- memcpy(inst->dataBuf,
- inst->dataBuf + inst->blockLen,
- sizeof(float) * (inst->anaLen - inst->blockLen));
- memcpy(inst->dataBuf + inst->anaLen - inst->blockLen,
- speechFrame,
- sizeof(float) * inst->blockLen);
+ // Update analysis buffer for L band.
+ UpdateBuffer(speechFrame, self->blockLen, self->anaLen, self->dataBuf);
if (flagHB == 1) {
- // update analysis buffer for H band
- memcpy(inst->dataBufHB,
- inst->dataBufHB + inst->blockLen,
- sizeof(float) * (inst->anaLen - inst->blockLen));
- memcpy(inst->dataBufHB + inst->anaLen - inst->blockLen,
- speechFrameHB,
- sizeof(float) * inst->blockLen);
+ // Update analysis buffer for H band.
+ UpdateBuffer(speechFrameHB, self->blockLen, self->anaLen, self->dataBufHB);
}
- // windowing
- energy1 = 0.0;
- for (i = 0; i < inst->anaLen; i++) {
- winData[i] = inst->window[i] * inst->dataBuf[i];
- energy1 += winData[i] * winData[i];
- }
+ Windowing(self->window, self->dataBuf, self->anaLen, winData);
+ energy1 = Energy(winData, self->anaLen);
if (energy1 == 0.0) {
- // synthesize the special case of zero input
- // read out fully processed segment
- for (i = inst->windShift; i < inst->blockLen + inst->windShift; i++) {
- fout[i - inst->windShift] = inst->syntBuf[i];
+ // Synthesize the special case of zero input.
+ // Read out fully processed segment.
+ for (i = self->windShift; i < self->blockLen + self->windShift; i++) {
+ fout[i - self->windShift] = self->syntBuf[i];
}
- // update synthesis buffer
- memcpy(inst->syntBuf,
- inst->syntBuf + inst->blockLen,
- sizeof(float) * (inst->anaLen - inst->blockLen));
- memset(inst->syntBuf + inst->anaLen - inst->blockLen,
- 0,
- sizeof(float) * inst->blockLen);
+ // Update synthesis buffer.
+ UpdateBuffer(NULL, self->blockLen, self->anaLen, self->syntBuf);
- for (i = 0; i < inst->blockLen; ++i)
+ for (i = 0; i < self->blockLen; ++i)
outFrame[i] =
WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, fout[i], WEBRTC_SPL_WORD16_MIN);
- // for time-domain gain of HB
+ // For time-domain gain of HB.
if (flagHB == 1)
- for (i = 0; i < inst->blockLen; ++i)
+ for (i = 0; i < self->blockLen; ++i)
outFrameHB[i] = WEBRTC_SPL_SAT(
- WEBRTC_SPL_WORD16_MAX, inst->dataBufHB[i], WEBRTC_SPL_WORD16_MIN);
+ WEBRTC_SPL_WORD16_MAX, self->dataBufHB[i], WEBRTC_SPL_WORD16_MIN);
return 0;
}
- // FFT
- WebRtc_rdft(inst->anaLen, 1, winData, inst->ip, inst->wfft);
- imag[0] = 0;
- real[0] = winData[0];
- magn[0] = fabs(real[0]) + 1.f;
- imag[inst->magnLen - 1] = 0;
- real[inst->magnLen - 1] = winData[1];
- magn[inst->magnLen - 1] = fabs(real[inst->magnLen - 1]) + 1.f;
- if (inst->blockInd < END_STARTUP_SHORT) {
- inst->initMagnEst[0] += magn[0];
- inst->initMagnEst[inst->magnLen - 1] += magn[inst->magnLen - 1];
- }
- for (i = 1; i < inst->magnLen - 1; i++) {
- real[i] = winData[2 * i];
- imag[i] = winData[2 * i + 1];
- // magnitude spectrum
- fTmp = real[i] * real[i];
- fTmp += imag[i] * imag[i];
- magn[i] = ((float)sqrt(fTmp)) + 1.f;
- if (inst->blockInd < END_STARTUP_SHORT) {
- inst->initMagnEst[i] += magn[i];
+ FFT(self, winData, self->anaLen, self->magnLen, real, imag, magn);
+
+ if (self->blockInd < END_STARTUP_SHORT) {
+ for (i = 0; i < self->magnLen; i++) {
+ self->initMagnEst[i] += magn[i];
}
}
- // Compute dd update of prior snr and post snr based on new noise estimate
- for (i = 0; i < inst->magnLen; i++) {
- // previous estimate: based on previous frame with gain filter
- previousEstimateStsa = inst->magnPrevProcess[i] /
- (inst->noisePrev[i] + 0.0001f) * inst->smooth[i];
- // post and prior snr
- currentEstimateStsa = 0.f;
- if (magn[i] > inst->noise[i]) {
- currentEstimateStsa = magn[i] / (inst->noise[i] + 0.0001f) - 1.f;
- }
- // DD estimate is sume of two terms: current estimate and previous
- // estimate
- // directed decision update of snrPrior
- snrPrior = DD_PR_SNR * previousEstimateStsa +
- (1.f - DD_PR_SNR) * currentEstimateStsa;
- // gain filter
- tmpFloat1 = inst->overdrive + snrPrior;
- tmpFloat2 = (float)snrPrior / tmpFloat1;
- theFilter[i] = (float)tmpFloat2;
- } // end of loop over freqs
-
- for (i = 0; i < inst->magnLen; i++) {
- // flooring bottom
- if (theFilter[i] < inst->denoiseBound) {
- theFilter[i] = inst->denoiseBound;
+ ComputeDdBasedWienerFilter(self, magn, theFilter);
+
+ for (i = 0; i < self->magnLen; i++) {
+ // Flooring bottom.
+ if (theFilter[i] < self->denoiseBound) {
+ theFilter[i] = self->denoiseBound;
}
- // flooring top
+ // Flooring top.
if (theFilter[i] > 1.f) {
theFilter[i] = 1.f;
}
- if (inst->blockInd < END_STARTUP_SHORT) {
+ if (self->blockInd < END_STARTUP_SHORT) {
theFilterTmp[i] =
- (inst->initMagnEst[i] - inst->overdrive * inst->parametricNoise[i]);
- theFilterTmp[i] /= (inst->initMagnEst[i] + 0.0001f);
- // flooring bottom
- if (theFilterTmp[i] < inst->denoiseBound) {
- theFilterTmp[i] = inst->denoiseBound;
+ (self->initMagnEst[i] - self->overdrive * self->parametricNoise[i]);
+ theFilterTmp[i] /= (self->initMagnEst[i] + 0.0001f);
+ // Flooring bottom.
+ if (theFilterTmp[i] < self->denoiseBound) {
+ theFilterTmp[i] = self->denoiseBound;
}
- // flooring top
+ // Flooring top.
if (theFilterTmp[i] > 1.f) {
theFilterTmp[i] = 1.f;
}
- // Weight the two suppression filters
- theFilter[i] *= (inst->blockInd);
- theFilterTmp[i] *= (END_STARTUP_SHORT - inst->blockInd);
+ // Weight the two suppression filters.
+ theFilter[i] *= (self->blockInd);
+ theFilterTmp[i] *= (END_STARTUP_SHORT - self->blockInd);
theFilter[i] += theFilterTmp[i];
theFilter[i] /= (END_STARTUP_SHORT);
}
- // smoothing
- inst->smooth[i] = theFilter[i];
- real[i] *= inst->smooth[i];
- imag[i] *= inst->smooth[i];
- }
- // keep track of magn spectrum for next frame
- memcpy(inst->magnPrevProcess, magn, sizeof(*magn) * inst->magnLen);
- memcpy(inst->noisePrev, inst->noise, sizeof(inst->noise[0]) * inst->magnLen);
- // back to time domain
- winData[0] = real[0];
- winData[1] = real[inst->magnLen - 1];
- for (i = 1; i < inst->magnLen - 1; i++) {
- winData[2 * i] = real[i];
- winData[2 * i + 1] = imag[i];
- }
- WebRtc_rdft(inst->anaLen, -1, winData, inst->ip, inst->wfft);
- for (i = 0; i < inst->anaLen; i++) {
- real[i] = 2.f * winData[i] / inst->anaLen; // fft scaling
+ self->smooth[i] = theFilter[i];
+ real[i] *= self->smooth[i];
+ imag[i] *= self->smooth[i];
}
+ // Keep track of |magn| spectrum for next frame.
+ memcpy(self->magnPrevProcess, magn, sizeof(*magn) * self->magnLen);
+ memcpy(self->noisePrev, self->noise, sizeof(self->noise[0]) * self->magnLen);
+ // Back to time domain.
+ IFFT(self, real, imag, self->magnLen, self->anaLen, winData);
- // scale factor: only do it after END_STARTUP_LONG time
+ // Scale factor: only do it after END_STARTUP_LONG time.
factor = 1.f;
- if (inst->gainmap == 1 && inst->blockInd > END_STARTUP_LONG) {
+ if (self->gainmap == 1 && self->blockInd > END_STARTUP_LONG) {
factor1 = 1.f;
factor2 = 1.f;
- energy2 = 0.0;
- for (i = 0; i < inst->anaLen; i++) {
- energy2 += (float)real[i] * (float)real[i];
- }
+ energy2 = Energy(winData, self->anaLen);
gain = (float)sqrt(energy2 / (energy1 + 1.f));
- // scaling for new version
+ // Scaling for new version.
if (gain > B_LIM) {
factor1 = 1.f + 1.3f * (gain - B_LIM);
if (gain * factor1 > 1.f) {
@@ -1228,46 +1322,43 @@ int WebRtcNs_ProcessCore(NSinst_t* inst,
}
}
if (gain < B_LIM) {
- // don't reduce scale too much for pause regions:
- // attenuation here should be controlled by flooring
- if (gain <= inst->denoiseBound) {
- gain = inst->denoiseBound;
+ // Don't reduce scale too much for pause regions:
+ // attenuation here should be controlled by flooring.
+ if (gain <= self->denoiseBound) {
+ gain = self->denoiseBound;
}
factor2 = 1.f - 0.3f * (B_LIM - gain);
}
- // combine both scales with speech/noise prob:
- // note prior (priorSpeechProb) is not frequency dependent
- factor = inst->priorSpeechProb * factor1 +
- (1.f - inst->priorSpeechProb) * factor2;
- } // out of inst->gainmap==1
-
- // synthesis
- for (i = 0; i < inst->anaLen; i++) {
- inst->syntBuf[i] += factor * inst->window[i] * (float)real[i];
+ // Combine both scales with speech/noise prob:
+ // note prior (priorSpeechProb) is not frequency dependent.
+ factor = self->priorSpeechProb * factor1 +
+ (1.f - self->priorSpeechProb) * factor2;
+ } // Out of self->gainmap == 1.
+
+ Windowing(self->window, winData, self->anaLen, winData);
+
+ // Synthesis.
+ for (i = 0; i < self->anaLen; i++) {
+ self->syntBuf[i] += factor * winData[i];
}
- // read out fully processed segment
- for (i = inst->windShift; i < inst->blockLen + inst->windShift; i++) {
- fout[i - inst->windShift] = inst->syntBuf[i];
+ // Read out fully processed segment.
+ for (i = self->windShift; i < self->blockLen + self->windShift; i++) {
+ fout[i - self->windShift] = self->syntBuf[i];
}
- // update synthesis buffer
- memcpy(inst->syntBuf,
- inst->syntBuf + inst->blockLen,
- sizeof(float) * (inst->anaLen - inst->blockLen));
- memset(inst->syntBuf + inst->anaLen - inst->blockLen,
- 0,
- sizeof(float) * inst->blockLen);
-
- for (i = 0; i < inst->blockLen; ++i)
+ // Update synthesis buffer.
+ UpdateBuffer(NULL, self->blockLen, self->anaLen, self->syntBuf);
+
+ for (i = 0; i < self->blockLen; ++i)
outFrame[i] =
WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, fout[i], WEBRTC_SPL_WORD16_MIN);
- // for time-domain gain of HB
+ // For time-domain gain of HB.
if (flagHB == 1) {
- // average speech prob from low band
- // avg over second half (i.e., 4->8kHz) of freq. spectrum
+ // Average speech prob from low band.
+ // Average over second half (i.e., 4->8kHz) of frequencies spectrum.
avgProbSpeechHB = 0.0;
- for (i = inst->magnLen - deltaBweHB - 1; i < inst->magnLen - 1; i++) {
- avgProbSpeechHB += inst->speechProb[i];
+ for (i = self->magnLen - deltaBweHB - 1; i < self->magnLen - 1; i++) {
+ avgProbSpeechHB += self->speechProb[i];
}
avgProbSpeechHB = avgProbSpeechHB / ((float)deltaBweHB);
// If the speech was suppressed by a component between Analyze and
@@ -1275,44 +1366,43 @@ int WebRtcNs_ProcessCore(NSinst_t* inst,
// for high band suppression purposes.
sumMagnAnalyze = 0;
sumMagnProcess = 0;
- for (i = 0; i < inst->magnLen; ++i) {
- sumMagnAnalyze += inst->magnPrevAnalyze[i];
- sumMagnProcess += inst->magnPrevProcess[i];
+ for (i = 0; i < self->magnLen; ++i) {
+ sumMagnAnalyze += self->magnPrevAnalyze[i];
+ sumMagnProcess += self->magnPrevProcess[i];
}
avgProbSpeechHB *= sumMagnProcess / sumMagnAnalyze;
- // average filter gain from low band
- // average over second half (i.e., 4->8kHz) of freq. spectrum
+ // Average filter gain from low band.
+ // Average over second half (i.e., 4->8kHz) of frequencies spectrum.
avgFilterGainHB = 0.0;
- for (i = inst->magnLen - deltaGainHB - 1; i < inst->magnLen - 1; i++) {
- avgFilterGainHB += inst->smooth[i];
+ for (i = self->magnLen - deltaGainHB - 1; i < self->magnLen - 1; i++) {
+ avgFilterGainHB += self->smooth[i];
}
avgFilterGainHB = avgFilterGainHB / ((float)(deltaGainHB));
avgProbSpeechHBTmp = 2.f * avgProbSpeechHB - 1.f;
- // gain based on speech prob:
+ // Gain based on speech probability.
gainModHB = 0.5f * (1.f + (float)tanh(gainMapParHB * avgProbSpeechHBTmp));
- // combine gain with low band gain
+ // Combine gain with low band gain.
gainTimeDomainHB = 0.5f * gainModHB + 0.5f * avgFilterGainHB;
if (avgProbSpeechHB >= 0.5f) {
gainTimeDomainHB = 0.25f * gainModHB + 0.75f * avgFilterGainHB;
}
gainTimeDomainHB = gainTimeDomainHB * decayBweHB;
- // make sure gain is within flooring range
- // flooring bottom
- if (gainTimeDomainHB < inst->denoiseBound) {
- gainTimeDomainHB = inst->denoiseBound;
+ // Make sure gain is within flooring range.
+ // Flooring bottom.
+ if (gainTimeDomainHB < self->denoiseBound) {
+ gainTimeDomainHB = self->denoiseBound;
}
- // flooring top
+ // Flooring top.
if (gainTimeDomainHB > 1.f) {
gainTimeDomainHB = 1.f;
}
- // apply gain
- for (i = 0; i < inst->blockLen; i++) {
- float o = gainTimeDomainHB * inst->dataBufHB[i];
+ // Apply gain.
+ for (i = 0; i < self->blockLen; i++) {
+ float o = gainTimeDomainHB * self->dataBufHB[i];
outFrameHB[i] =
WEBRTC_SPL_SAT(WEBRTC_SPL_WORD16_MAX, o, WEBRTC_SPL_WORD16_MIN);
}
- } // end of H band gain computation
- //
+ } // End of H band gain computation.
return 0;
}
diff --git a/modules/audio_processing/ns/ns_core.h b/modules/audio_processing/ns/ns_core.h
index a4718fb3..d20c60bf 100644
--- a/modules/audio_processing/ns/ns_core.h
+++ b/modules/audio_processing/ns/ns_core.h
@@ -14,36 +14,36 @@
#include "webrtc/modules/audio_processing/ns/defines.h"
typedef struct NSParaExtract_t_ {
- // bin size of histogram
+ // Bin size of histogram.
float binSizeLrt;
float binSizeSpecFlat;
float binSizeSpecDiff;
- // range of histogram over which lrt threshold is computed
+ // Range of histogram over which LRT threshold is computed.
float rangeAvgHistLrt;
- // scale parameters: multiply dominant peaks of the histograms by scale factor
- // to obtain thresholds for prior model
- float factor1ModelPars; // for lrt and spectral difference
- float factor2ModelPars; // for spectral_flatness: used when noise is flatter
- // than speech
- // peak limit for spectral flatness (varies between 0 and 1)
+ // Scale parameters: multiply dominant peaks of the histograms by scale factor
+ // to obtain thresholds for prior model.
+ float factor1ModelPars; // For LRT and spectral difference.
+ float factor2ModelPars; // For spectral_flatness: used when noise is flatter
+ // than speech.
+ // Peak limit for spectral flatness (varies between 0 and 1).
float thresPosSpecFlat;
- // limit on spacing of two highest peaks in histogram: spacing determined by
- // bin size
+ // Limit on spacing of two highest peaks in histogram: spacing determined by
+ // bin size.
float limitPeakSpacingSpecFlat;
float limitPeakSpacingSpecDiff;
- // limit on relevance of second peak:
+ // Limit on relevance of second peak.
float limitPeakWeightsSpecFlat;
float limitPeakWeightsSpecDiff;
- // limit on fluctuation of lrt feature
+ // Limit on fluctuation of LRT feature.
float thresFluctLrt;
- // limit on the max and min values for the feature thresholds
+ // Limit on the max and min values for the feature thresholds.
float maxLrt;
float minLrt;
float maxSpecFlat;
float minSpecFlat;
float maxSpecDiff;
float minSpecDiff;
- // criteria of weight of histogram peak to accept/reject feature
+ // Criteria of weight of histogram peak to accept/reject feature.
int thresWeightSpecFlat;
int thresWeightSpecDiff;
@@ -62,51 +62,53 @@ typedef struct NSinst_t_ {
float syntBuf[ANAL_BLOCKL_MAX];
int initFlag;
- // parameters for quantile noise estimation
+ // Parameters for quantile noise estimation.
float density[SIMULT * HALF_ANAL_BLOCKL];
float lquantile[SIMULT * HALF_ANAL_BLOCKL];
float quantile[HALF_ANAL_BLOCKL];
int counter[SIMULT];
int updates;
- // parameters for Wiener filter
+ // Parameters for Wiener filter.
float smooth[HALF_ANAL_BLOCKL];
float overdrive;
float denoiseBound;
int gainmap;
- // fft work arrays.
+ // FFT work arrays.
int ip[IP_LENGTH];
float wfft[W_LENGTH];
- // parameters for new method: some not needed, will reduce/cleanup later
- int32_t blockInd; // frame index counter
- int modelUpdatePars[4]; // parameters for updating or estimating
- // thresholds/weights for prior model
- float priorModelPars[7]; // parameters for prior model
- float noise[HALF_ANAL_BLOCKL]; // noise spectrum from current frame
- float noisePrev[HALF_ANAL_BLOCKL]; // noise spectrum from previous frame
- // magnitude spectrum of previous analyze frame
+ // Parameters for new method: some not needed, will reduce/cleanup later.
+ int32_t blockInd; // Frame index counter.
+ int modelUpdatePars[4]; // Parameters for updating or estimating.
+ // Thresholds/weights for prior model.
+ float priorModelPars[7]; // Parameters for prior model.
+ float noise[HALF_ANAL_BLOCKL]; // Noise spectrum from current frame.
+ float noisePrev[HALF_ANAL_BLOCKL]; // Noise spectrum from previous frame.
+ // Magnitude spectrum of previous analyze frame.
float magnPrevAnalyze[HALF_ANAL_BLOCKL];
- // magnitude spectrum of previous process frame
+ // Magnitude spectrum of previous process frame.
float magnPrevProcess[HALF_ANAL_BLOCKL];
- float logLrtTimeAvg[HALF_ANAL_BLOCKL]; // log lrt factor with time-smoothing
- float priorSpeechProb; // prior speech/noise probability
- float featureData[7]; // data for features
- float magnAvgPause[HALF_ANAL_BLOCKL]; // conservative noise spectrum estimate
- float signalEnergy; // energy of magn
- float sumMagn; // sum of magn
- float whiteNoiseLevel; // initial noise estimate
- float initMagnEst[HALF_ANAL_BLOCKL]; // initial magnitude spectrum estimate
- float pinkNoiseNumerator; // pink noise parameter: numerator
- float pinkNoiseExp; // pink noise parameter: power of freq
+ float logLrtTimeAvg[HALF_ANAL_BLOCKL]; // Log LRT factor with time-smoothing.
+ float priorSpeechProb; // Prior speech/noise probability.
+ float featureData[7];
+ // Conservative noise spectrum estimate.
+ float magnAvgPause[HALF_ANAL_BLOCKL];
+ float signalEnergy; // Energy of |magn|.
+ float sumMagn;
+ float whiteNoiseLevel; // Initial noise estimate.
+ float initMagnEst[HALF_ANAL_BLOCKL]; // Initial magnitude spectrum estimate.
+ float pinkNoiseNumerator; // Pink noise parameter: numerator.
+ float pinkNoiseExp; // Pink noise parameter: power of frequencies.
float parametricNoise[HALF_ANAL_BLOCKL];
- NSParaExtract_t featureExtractionParams; // parameters for feature extraction
- // histograms for parameter estimation
+ // Parameters for feature extraction.
+ NSParaExtract_t featureExtractionParams;
+ // Histograms for parameter estimation.
int histLrt[HIST_PAR_EST];
int histSpecFlat[HIST_PAR_EST];
int histSpecDiff[HIST_PAR_EST];
- // quantities for high band estimate
- float speechProb[HALF_ANAL_BLOCKL]; // final speech/noise prob: prior + LRT
- float dataBufHB[ANAL_BLOCKL_MAX]; // buffering data for HB
+ // Quantities for high band estimate.
+ float speechProb[HALF_ANAL_BLOCKL]; // Final speech/noise prob: prior + LRT.
+ float dataBufHB[ANAL_BLOCKL_MAX]; // Buffering data for HB.
} NSinst_t;
@@ -120,16 +122,16 @@ extern "C" {
* This function initializes a noise suppression instance
*
* Input:
- * - inst : Instance that should be initialized
+ * - self : Instance that should be initialized
* - fs : Sampling frequency
*
* Output:
- * - inst : Initialized instance
+ * - self : Initialized instance
*
* Return value : 0 - Ok
* -1 - Error
*/
-int WebRtcNs_InitCore(NSinst_t* inst, uint32_t fs);
+int WebRtcNs_InitCore(NSinst_t* self, uint32_t fs);
/****************************************************************************
* WebRtcNs_set_policy_core(...)
@@ -137,16 +139,16 @@ int WebRtcNs_InitCore(NSinst_t* inst, uint32_t fs);
* This changes the aggressiveness of the noise suppression method.
*
* Input:
- * - inst : Instance that should be initialized
+ * - self : Instance that should be initialized
* - mode : 0: Mild (6dB), 1: Medium (10dB), 2: Aggressive (15dB)
*
* Output:
- * - NS_inst : Initialized instance
+ * - self : Initialized instance
*
* Return value : 0 - Ok
* -1 - Error
*/
-int WebRtcNs_set_policy_core(NSinst_t* inst, int mode);
+int WebRtcNs_set_policy_core(NSinst_t* self, int mode);
/****************************************************************************
* WebRtcNs_AnalyzeCore
@@ -154,16 +156,16 @@ int WebRtcNs_set_policy_core(NSinst_t* inst, int mode);
* Estimate the background noise.
*
* Input:
- * - inst : Instance that should be initialized
+ * - self : Instance that should be initialized
* - speechFrame : Input speech frame for lower band
*
* Output:
- * - inst : Updated instance
+ * - self : Updated instance
*
* Return value : 0 - OK
* -1 - Error
*/
-int WebRtcNs_AnalyzeCore(NSinst_t* inst, float* speechFrame);
+int WebRtcNs_AnalyzeCore(NSinst_t* self, float* speechFrame);
/****************************************************************************
* WebRtcNs_ProcessCore
@@ -171,19 +173,19 @@ int WebRtcNs_AnalyzeCore(NSinst_t* inst, float* speechFrame);
* Do noise suppression.
*
* Input:
- * - inst : Instance that should be initialized
+ * - self : Instance that should be initialized
* - inFrameLow : Input speech frame for lower band
* - inFrameHigh : Input speech frame for higher band
*
* Output:
- * - inst : Updated instance
+ * - self : Updated instance
* - outFrameLow : Output speech frame for lower band
* - outFrameHigh : Output speech frame for higher band
*
* Return value : 0 - OK
* -1 - Error
*/
-int WebRtcNs_ProcessCore(NSinst_t* inst,
+int WebRtcNs_ProcessCore(NSinst_t* self,
float* inFrameLow,
float* inFrameHigh,
float* outFrameLow,
diff --git a/modules/audio_processing/ns/nsx_core_neon.c b/modules/audio_processing/ns/nsx_core_neon.c
index f2491417..93099dbf 100644
--- a/modules/audio_processing/ns/nsx_core_neon.c
+++ b/modules/audio_processing/ns/nsx_core_neon.c
@@ -490,110 +490,91 @@ void WebRtcNsx_DenormalizeNeon(NsxInst_t* inst, int16_t* in, int factor) {
void WebRtcNsx_SynthesisUpdateNeon(NsxInst_t* inst,
int16_t* out_frame,
int16_t gain_factor) {
- int16_t* ptr_real = &inst->real[0];
- int16_t* ptr_syn = &inst->synthesisBuffer[0];
- const int16_t* ptr_window = &inst->window[0];
-
- // synthesis
- __asm__ __volatile__("vdup.16 d24, %0" : : "r"(gain_factor) : "d24");
- // Loop unrolled once. All pointers are incremented in the assembly code.
- for (; ptr_syn < &inst->synthesisBuffer[inst->anaLen];) {
- __asm__ __volatile__(
- // Load variables.
- "vld1.16 d22, [%[ptr_real]]!\n\t"
- "vld1.16 d23, [%[ptr_window]]!\n\t"
- "vld1.16 d25, [%[ptr_syn]]\n\t"
- // tmp16a = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(
- // inst->window[i], inst->real[i], 14); // Q0, window in Q14
- "vmull.s16 q11, d22, d23\n\t"
- "vrshrn.i32 d22, q11, #14\n\t"
- // tmp32 = WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(tmp16a, gain_factor, 13);
- "vmull.s16 q11, d24, d22\n\t"
- // tmp16b = WebRtcSpl_SatW32ToW16(tmp32); // Q0
- "vqrshrn.s32 d22, q11, #13\n\t"
- // inst->synthesisBuffer[i] = WebRtcSpl_AddSatW16(
- // inst->synthesisBuffer[i], tmp16b); // Q0
- "vqadd.s16 d25, d22\n\t"
- "vst1.16 d25, [%[ptr_syn]]!\n\t"
-
- // Load variables.
- "vld1.16 d26, [%[ptr_real]]!\n\t"
- "vld1.16 d27, [%[ptr_window]]!\n\t"
- "vld1.16 d28, [%[ptr_syn]]\n\t"
- // tmp16a = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(
- // inst->window[i], inst->real[i], 14); // Q0, window in Q14
- "vmull.s16 q13, d26, d27\n\t"
- "vrshrn.i32 d26, q13, #14\n\t"
- // tmp32 = WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(tmp16a, gain_factor, 13);
- "vmull.s16 q13, d24, d26\n\t"
- // tmp16b = WebRtcSpl_SatW32ToW16(tmp32); // Q0
- "vqrshrn.s32 d26, q13, #13\n\t"
- // inst->synthesisBuffer[i] = WebRtcSpl_AddSatW16(
- // inst->synthesisBuffer[i], tmp16b); // Q0
- "vqadd.s16 d28, d26\n\t"
- "vst1.16 d28, [%[ptr_syn]]!\n\t"
-
- // Specify constraints.
- :[ptr_real]"+r"(ptr_real),
- [ptr_window]"+r"(ptr_window),
- [ptr_syn]"+r"(ptr_syn)
- :
- :"d22", "d23", "d24", "d25", "d26", "d27", "d28", "q11", "q12", "q13"
- );
+ assert(inst->anaLen % 16 == 0);
+ assert(inst->blockLen10ms % 16 == 0);
+
+ int16_t* preal_start = inst->real;
+ const int16_t* pwindow = inst->window;
+ int16_t* preal_end = preal_start + inst->anaLen;
+ int16_t* psynthesis_buffer = inst->synthesisBuffer;
+
+ while (preal_start < preal_end) {
+ // Loop unroll.
+ int16x8_t window_0 = vld1q_s16(pwindow);
+ int16x8_t real_0 = vld1q_s16(preal_start);
+ int16x8_t synthesis_buffer_0 = vld1q_s16(psynthesis_buffer);
+
+ int16x8_t window_1 = vld1q_s16(pwindow + 8);
+ int16x8_t real_1 = vld1q_s16(preal_start + 8);
+ int16x8_t synthesis_buffer_1 = vld1q_s16(psynthesis_buffer + 8);
+
+ int32x4_t tmp32a_0_low = vmull_s16(vget_low_s16(real_0),
+ vget_low_s16(window_0));
+ int32x4_t tmp32a_0_high = vmull_s16(vget_high_s16(real_0),
+ vget_high_s16(window_0));
+
+ int32x4_t tmp32a_1_low = vmull_s16(vget_low_s16(real_1),
+ vget_low_s16(window_1));
+ int32x4_t tmp32a_1_high = vmull_s16(vget_high_s16(real_1),
+ vget_high_s16(window_1));
+
+ int16x4_t tmp16a_0_low = vqrshrn_n_s32(tmp32a_0_low, 14);
+ int16x4_t tmp16a_0_high = vqrshrn_n_s32(tmp32a_0_high, 14);
+
+ int16x4_t tmp16a_1_low = vqrshrn_n_s32(tmp32a_1_low, 14);
+ int16x4_t tmp16a_1_high = vqrshrn_n_s32(tmp32a_1_high, 14);
+
+ int32x4_t tmp32b_0_low = vmull_n_s16(tmp16a_0_low, gain_factor);
+ int32x4_t tmp32b_0_high = vmull_n_s16(tmp16a_0_high, gain_factor);
+
+ int32x4_t tmp32b_1_low = vmull_n_s16(tmp16a_1_low, gain_factor);
+ int32x4_t tmp32b_1_high = vmull_n_s16(tmp16a_1_high, gain_factor);
+
+ int16x4_t tmp16b_0_low = vqrshrn_n_s32(tmp32b_0_low, 13);
+ int16x4_t tmp16b_0_high = vqrshrn_n_s32(tmp32b_0_high, 13);
+
+ int16x4_t tmp16b_1_low = vqrshrn_n_s32(tmp32b_1_low, 13);
+ int16x4_t tmp16b_1_high = vqrshrn_n_s32(tmp32b_1_high, 13);
+
+ synthesis_buffer_0 = vqaddq_s16(vcombine_s16(tmp16b_0_low, tmp16b_0_high),
+ synthesis_buffer_0);
+ synthesis_buffer_1 = vqaddq_s16(vcombine_s16(tmp16b_1_low, tmp16b_1_high),
+ synthesis_buffer_1);
+ vst1q_s16(psynthesis_buffer, synthesis_buffer_0);
+ vst1q_s16(psynthesis_buffer + 8, synthesis_buffer_1);
+
+ pwindow += 16;
+ preal_start += 16;
+ psynthesis_buffer += 16;
}
- int16_t* ptr_out = &out_frame[0];
- ptr_syn = &inst->synthesisBuffer[0];
- // read out fully processed segment
- for (; ptr_syn < &inst->synthesisBuffer[inst->blockLen10ms];) {
- // Loop unrolled once. Both pointers are incremented in the assembly code.
- __asm__ __volatile__(
- // out_frame[i] = inst->synthesisBuffer[i]; // Q0
- "vld1.16 {d22, d23}, [%[ptr_syn]]!\n\t"
- "vld1.16 {d24, d25}, [%[ptr_syn]]!\n\t"
- "vst1.16 {d22, d23}, [%[ptr_out]]!\n\t"
- "vst1.16 {d24, d25}, [%[ptr_out]]!\n\t"
- :[ptr_syn]"+r"(ptr_syn),
- [ptr_out]"+r"(ptr_out)
- :
- :"d22", "d23", "d24", "d25"
- );
+ // Read out fully processed segment.
+ int16_t * p_start = inst->synthesisBuffer;
+ int16_t * p_end = inst->synthesisBuffer + inst->blockLen10ms;
+ int16_t * p_frame = out_frame;
+ while (p_start < p_end) {
+ int16x8_t frame_0 = vld1q_s16(p_start);
+ vst1q_s16(p_frame, frame_0);
+ p_start += 8;
+ p_frame += 8;
}
// Update synthesis buffer.
- // C code:
- // WEBRTC_SPL_MEMCPY_W16(inst->synthesisBuffer,
- // inst->synthesisBuffer + inst->blockLen10ms,
- // inst->anaLen - inst->blockLen10ms);
- ptr_out = &inst->synthesisBuffer[0],
- ptr_syn = &inst->synthesisBuffer[inst->blockLen10ms];
- for (; ptr_syn < &inst->synthesisBuffer[inst->anaLen];) {
- // Loop unrolled once. Both pointers are incremented in the assembly code.
- __asm__ __volatile__(
- "vld1.16 {d22, d23}, [%[ptr_syn]]!\n\t"
- "vld1.16 {d24, d25}, [%[ptr_syn]]!\n\t"
- "vst1.16 {d22, d23}, [%[ptr_out]]!\n\t"
- "vst1.16 {d24, d25}, [%[ptr_out]]!\n\t"
- :[ptr_syn]"+r"(ptr_syn),
- [ptr_out]"+r"(ptr_out)
- :
- :"d22", "d23", "d24", "d25"
- );
+ int16_t* p_start_src = inst->synthesisBuffer + inst->blockLen10ms;
+ int16_t* p_end_src = inst->synthesisBuffer + inst->anaLen;
+ int16_t* p_start_dst = inst->synthesisBuffer;
+ while (p_start_src < p_end_src) {
+ int16x8_t frame = vld1q_s16(p_start_src);
+ vst1q_s16(p_start_dst, frame);
+ p_start_src += 8;
+ p_start_dst += 8;
}
- // C code:
- // WebRtcSpl_ZerosArrayW16(inst->synthesisBuffer
- // + inst->anaLen - inst->blockLen10ms, inst->blockLen10ms);
- __asm__ __volatile__("vdup.16 q10, %0" : : "r"(0) : "q10");
- for (; ptr_out < &inst->synthesisBuffer[inst->anaLen];) {
- // Loop unrolled once. Pointer is incremented in the assembly code.
- __asm__ __volatile__(
- "vst1.16 {d20, d21}, [%[ptr_out]]!\n\t"
- "vst1.16 {d20, d21}, [%[ptr_out]]!\n\t"
- :[ptr_out]"+r"(ptr_out)
- :
- :"d20", "d21"
- );
+ p_start = inst->synthesisBuffer + inst->anaLen - inst->blockLen10ms;
+ p_end = p_start + inst->blockLen10ms;
+ int16x8_t zero = vdupq_n_s16(0);
+ for (;p_start < p_end; p_start += 8) {
+ vst1q_s16(p_start, zero);
}
}
@@ -601,75 +582,64 @@ void WebRtcNsx_SynthesisUpdateNeon(NsxInst_t* inst,
void WebRtcNsx_AnalysisUpdateNeon(NsxInst_t* inst,
int16_t* out,
int16_t* new_speech) {
-
- int16_t* ptr_ana = &inst->analysisBuffer[inst->blockLen10ms];
- int16_t* ptr_out = &inst->analysisBuffer[0];
+ assert(inst->blockLen10ms % 16 == 0);
+ assert(inst->anaLen % 16 == 0);
// For lower band update analysis buffer.
// WEBRTC_SPL_MEMCPY_W16(inst->analysisBuffer,
// inst->analysisBuffer + inst->blockLen10ms,
// inst->anaLen - inst->blockLen10ms);
- for (; ptr_out < &inst->analysisBuffer[inst->anaLen - inst->blockLen10ms];) {
- // Loop unrolled once, so both pointers are incremented by 8 twice.
- __asm__ __volatile__(
- "vld1.16 {d20, d21}, [%[ptr_ana]]!\n\t"
- "vst1.16 {d20, d21}, [%[ptr_out]]!\n\t"
- "vld1.16 {d22, d23}, [%[ptr_ana]]!\n\t"
- "vst1.16 {d22, d23}, [%[ptr_out]]!\n\t"
- :[ptr_ana]"+r"(ptr_ana),
- [ptr_out]"+r"(ptr_out)
- :
- :"d20", "d21", "d22", "d23"
- );
+ int16_t* p_start_src = inst->analysisBuffer + inst->blockLen10ms;
+ int16_t* p_end_src = inst->analysisBuffer + inst->anaLen;
+ int16_t* p_start_dst = inst->analysisBuffer;
+ while (p_start_src < p_end_src) {
+ int16x8_t frame = vld1q_s16(p_start_src);
+ vst1q_s16(p_start_dst, frame);
+
+ p_start_src += 8;
+ p_start_dst += 8;
}
// WEBRTC_SPL_MEMCPY_W16(inst->analysisBuffer
// + inst->anaLen - inst->blockLen10ms, new_speech, inst->blockLen10ms);
- for (ptr_ana = new_speech; ptr_out < &inst->analysisBuffer[inst->anaLen];) {
- // Loop unrolled once, so both pointers are incremented by 8 twice.
- __asm__ __volatile__(
- "vld1.16 {d20, d21}, [%[ptr_ana]]!\n\t"
- "vst1.16 {d20, d21}, [%[ptr_out]]!\n\t"
- "vld1.16 {d22, d23}, [%[ptr_ana]]!\n\t"
- "vst1.16 {d22, d23}, [%[ptr_out]]!\n\t"
- :[ptr_ana]"+r"(ptr_ana),
- [ptr_out]"+r"(ptr_out)
- :
- :"d20", "d21", "d22", "d23"
- );
+ p_start_src = new_speech;
+ p_end_src = new_speech + inst->blockLen10ms;
+ p_start_dst = inst->analysisBuffer + inst->anaLen - inst->blockLen10ms;
+ while (p_start_src < p_end_src) {
+ int16x8_t frame = vld1q_s16(p_start_src);
+ vst1q_s16(p_start_dst, frame);
+
+ p_start_src += 8;
+ p_start_dst += 8;
}
- // Window data before FFT
- const int16_t* ptr_window = &inst->window[0];
- ptr_out = &out[0];
- ptr_ana = &inst->analysisBuffer[0];
- for (; ptr_out < &out[inst->anaLen];) {
-
- // Loop unrolled once, so all pointers are incremented by 4 twice.
- __asm__ __volatile__(
- "vld1.16 d20, [%[ptr_ana]]!\n\t"
- "vld1.16 d21, [%[ptr_window]]!\n\t"
- // out[i] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(
- // inst->window[i], inst->analysisBuffer[i], 14); // Q0
- "vmull.s16 q10, d20, d21\n\t"
- "vrshrn.i32 d20, q10, #14\n\t"
- "vst1.16 d20, [%[ptr_out]]!\n\t"
-
- "vld1.16 d22, [%[ptr_ana]]!\n\t"
- "vld1.16 d23, [%[ptr_window]]!\n\t"
- // out[i] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(
- // inst->window[i], inst->analysisBuffer[i], 14); // Q0
- "vmull.s16 q11, d22, d23\n\t"
- "vrshrn.i32 d22, q11, #14\n\t"
- "vst1.16 d22, [%[ptr_out]]!\n\t"
-
- // Specify constraints.
- :[ptr_ana]"+r"(ptr_ana),
- [ptr_window]"+r"(ptr_window),
- [ptr_out]"+r"(ptr_out)
- :
- :"d20", "d21", "d22", "d23", "q10", "q11"
- );
+ // Window data before FFT.
+ int16_t* p_start_window = (int16_t*) inst->window;
+ int16_t* p_start_buffer = inst->analysisBuffer;
+ int16_t* p_start_out = out;
+ const int16_t* p_end_out = out + inst->anaLen;
+
+ // Load the first element to reduce pipeline bubble.
+ int16x8_t window = vld1q_s16(p_start_window);
+ int16x8_t buffer = vld1q_s16(p_start_buffer);
+ p_start_window += 8;
+ p_start_buffer += 8;
+
+ while (p_start_out < p_end_out) {
+ // Unroll loop.
+ int32x4_t tmp32_low = vmull_s16(vget_low_s16(window), vget_low_s16(buffer));
+ int32x4_t tmp32_high = vmull_s16(vget_high_s16(window),
+ vget_high_s16(buffer));
+ window = vld1q_s16(p_start_window);
+ buffer = vld1q_s16(p_start_buffer);
+
+ int16x4_t result_low = vrshrn_n_s32(tmp32_low, 14);
+ int16x4_t result_high = vrshrn_n_s32(tmp32_high, 14);
+ vst1q_s16(p_start_out, vcombine_s16(result_low, result_high));
+
+ p_start_buffer += 8;
+ p_start_window += 8;
+ p_start_out += 8;
}
}
diff --git a/modules/audio_processing/test/audio_processing_unittest.cc b/modules/audio_processing/test/audio_processing_unittest.cc
index a0fb303b..401391aa 100644
--- a/modules/audio_processing/test/audio_processing_unittest.cc
+++ b/modules/audio_processing/test/audio_processing_unittest.cc
@@ -66,9 +66,9 @@ void ConvertToFloat(const int16_t* int_data, ChannelBuffer<float>* cb) {
cb->samples_per_channel(),
cb->num_channels(),
cb_int.channels());
- ScaleToFloat(cb_int.data(),
- cb->samples_per_channel() * cb->num_channels(),
- cb->data());
+ S16ToFloat(cb_int.data(),
+ cb->samples_per_channel() * cb->num_channels(),
+ cb->data());
}
void ConvertToFloat(const AudioFrame& frame, ChannelBuffer<float>* cb) {
@@ -96,14 +96,13 @@ int TruncateToMultipleOf10(int value) {
void MixStereoToMono(const float* stereo, float* mono,
int samples_per_channel) {
- for (int i = 0; i < samples_per_channel; ++i) {
+ for (int i = 0; i < samples_per_channel; ++i)
mono[i] = (stereo[i * 2] + stereo[i * 2 + 1]) / 2;
- }
}
void MixStereoToMono(const int16_t* stereo, int16_t* mono,
int samples_per_channel) {
- for (int i = 0; i < samples_per_channel; i++)
+ for (int i = 0; i < samples_per_channel; ++i)
mono[i] = (stereo[i * 2] + stereo[i * 2 + 1]) >> 1;
}
@@ -135,7 +134,7 @@ void SetFrameTo(AudioFrame* frame, int16_t left, int16_t right) {
void ScaleFrame(AudioFrame* frame, float scale) {
for (int i = 0; i < frame->samples_per_channel_ * frame->num_channels_; ++i) {
- frame->data_[i] = RoundToInt16(frame->data_[i] * scale);
+ frame->data_[i] = FloatS16ToS16(frame->data_[i] * scale);
}
}
@@ -1650,7 +1649,7 @@ TEST_F(ApmTest, DebugDumpFromFileHandle) {
#endif // WEBRTC_AUDIOPROC_DEBUG_DUMP
}
-TEST_F(ApmTest, FloatAndIntInterfacesGiveIdenticalResults) {
+TEST_F(ApmTest, FloatAndIntInterfacesGiveSimilarResults) {
audioproc::OutputData ref_data;
OpenFileAndReadMessage(ref_filename_, &ref_data);
@@ -1679,7 +1678,8 @@ TEST_F(ApmTest, FloatAndIntInterfacesGiveIdenticalResults) {
Init(fapm.get());
ChannelBuffer<int16_t> output_cb(samples_per_channel, num_input_channels);
- scoped_ptr<int16_t[]> output_int16(new int16_t[output_length]);
+ ChannelBuffer<int16_t> output_int16(samples_per_channel,
+ num_input_channels);
int analog_level = 127;
while (ReadFrame(far_file_, revframe_, revfloat_cb_.get()) &&
@@ -1701,7 +1701,9 @@ TEST_F(ApmTest, FloatAndIntInterfacesGiveIdenticalResults) {
EXPECT_NOERR(fapm->gain_control()->set_stream_analog_level(analog_level));
EXPECT_NOERR(apm_->ProcessStream(frame_));
- // TODO(ajm): Update to support different output rates.
+ Deinterleave(frame_->data_, samples_per_channel, num_output_channels,
+ output_int16.channels());
+
EXPECT_NOERR(fapm->ProcessStream(
float_cb_->channels(),
samples_per_channel,
@@ -1711,24 +1713,34 @@ TEST_F(ApmTest, FloatAndIntInterfacesGiveIdenticalResults) {
LayoutFromChannels(num_output_channels),
float_cb_->channels()));
- // Convert to interleaved int16.
- ScaleAndRoundToInt16(float_cb_->data(), output_length, output_cb.data());
- Interleave(output_cb.channels(),
- samples_per_channel,
- num_output_channels,
- output_int16.get());
- // Verify float and int16 paths produce identical output.
- EXPECT_EQ(0, memcmp(frame_->data_, output_int16.get(), output_length));
+ FloatToS16(float_cb_->data(), output_length, output_cb.data());
+ for (int j = 0; j < num_output_channels; ++j) {
+ float variance = 0;
+ float snr = ComputeSNR(output_int16.channel(j), output_cb.channel(j),
+ samples_per_channel, &variance);
+ #if defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)
+ // There are a few chunks in the fixed-point profile that give low SNR.
+ // Listening confirmed the difference is acceptable.
+ const float kVarianceThreshold = 150;
+ const float kSNRThreshold = 10;
+ #else
+ const float kVarianceThreshold = 20;
+ const float kSNRThreshold = 20;
+ #endif
+ // Skip frames with low energy.
+ if (sqrt(variance) > kVarianceThreshold) {
+ EXPECT_LT(kSNRThreshold, snr);
+ }
+ }
analog_level = fapm->gain_control()->stream_analog_level();
EXPECT_EQ(apm_->gain_control()->stream_analog_level(),
fapm->gain_control()->stream_analog_level());
EXPECT_EQ(apm_->echo_cancellation()->stream_has_echo(),
fapm->echo_cancellation()->stream_has_echo());
- EXPECT_EQ(apm_->voice_detection()->stream_has_voice(),
- fapm->voice_detection()->stream_has_voice());
- EXPECT_EQ(apm_->noise_suppression()->speech_probability(),
- fapm->noise_suppression()->speech_probability());
+ EXPECT_NEAR(apm_->noise_suppression()->speech_probability(),
+ fapm->noise_suppression()->speech_probability(),
+ 0.0005);
// Reset in case of downmixing.
frame_->num_channels_ = test->num_input_channels();
@@ -2002,7 +2014,7 @@ bool ReadChunk(FILE* file, int16_t* int_data, float* float_data,
return false; // This is expected.
}
- ScaleToFloat(int_data, frame_size, float_data);
+ S16ToFloat(int_data, frame_size, float_data);
if (cb->num_channels() == 1) {
MixStereoToMono(float_data, cb->data(), cb->samples_per_channel());
} else {
@@ -2109,7 +2121,9 @@ class AudioProcessingTest
int num_output_channels,
int num_reverse_channels,
std::string output_file_prefix) {
- scoped_ptr<AudioProcessing> ap(AudioProcessing::Create());
+ Config config;
+ config.Set<ExperimentalAgc>(new ExperimentalAgc(false));
+ scoped_ptr<AudioProcessing> ap(AudioProcessing::Create(config));
EnableAllAPComponents(ap.get());
ap->Initialize(input_rate,
output_rate,
diff --git a/modules/audio_processing/test/process_test.cc b/modules/audio_processing/test/process_test.cc
index b6d51e47..76a916da 100644
--- a/modules/audio_processing/test/process_test.cc
+++ b/modules/audio_processing/test/process_test.cc
@@ -489,7 +489,7 @@ void void_main(int argc, char* argv[]) {
FILE* aecm_echo_path_in_file = NULL;
FILE* aecm_echo_path_out_file = NULL;
- scoped_ptr<WavFile> output_wav_file;
+ scoped_ptr<WavWriter> output_wav_file;
scoped_ptr<RawFile> output_raw_file;
if (pb_filename) {
@@ -637,9 +637,9 @@ void void_main(int argc, char* argv[]) {
if (!raw_output) {
// The WAV file needs to be reset every time, because it cant change
// it's sample rate or number of channels.
- output_wav_file.reset(new WavFile(out_filename + ".wav",
- output_sample_rate,
- msg.num_output_channels()));
+ output_wav_file.reset(new WavWriter(out_filename + ".wav",
+ output_sample_rate,
+ msg.num_output_channels()));
}
} else if (event_msg.type() == Event::REVERSE_STREAM) {
@@ -876,9 +876,9 @@ void void_main(int argc, char* argv[]) {
if (!raw_output) {
// The WAV file needs to be reset every time, because it can't change
// it's sample rate or number of channels.
- output_wav_file.reset(new WavFile(out_filename + ".wav",
- sample_rate_hz,
- num_capture_output_channels));
+ output_wav_file.reset(new WavWriter(out_filename + ".wav",
+ sample_rate_hz,
+ num_capture_output_channels));
}
if (verbose) {
@@ -1029,9 +1029,9 @@ void void_main(int argc, char* argv[]) {
output_raw_file.reset(new RawFile(out_filename + ".pcm"));
}
if (!raw_output && !output_wav_file) {
- output_wav_file.reset(new WavFile(out_filename + ".wav",
- sample_rate_hz,
- num_capture_output_channels));
+ output_wav_file.reset(new WavWriter(out_filename + ".wav",
+ sample_rate_hz,
+ num_capture_output_channels));
}
WriteIntData(near_frame.data_,
size,
diff --git a/modules/audio_processing/test/test_utils.h b/modules/audio_processing/test/test_utils.h
index 61edd8f3..d0d08cb8 100644
--- a/modules/audio_processing/test/test_utils.h
+++ b/modules/audio_processing/test/test_utils.h
@@ -8,11 +8,12 @@
* be found in the AUTHORS file in the root of the source tree.
*/
+#include <math.h>
#include <limits>
#include "webrtc/audio_processing/debug.pb.h"
#include "webrtc/common_audio/include/audio_util.h"
-#include "webrtc/common_audio/wav_writer.h"
+#include "webrtc/common_audio/wav_file.h"
#include "webrtc/modules/audio_processing/common.h"
#include "webrtc/modules/audio_processing/include/audio_processing.h"
#include "webrtc/modules/interface/module_common_types.h"
@@ -49,7 +50,7 @@ class RawFile {
static inline void WriteIntData(const int16_t* data,
size_t length,
- WavFile* wav_file,
+ WavWriter* wav_file,
RawFile* raw_file) {
if (wav_file) {
wav_file->WriteSamples(data, length);
@@ -62,7 +63,7 @@ static inline void WriteIntData(const int16_t* data,
static inline void WriteFloatData(const float* const* data,
size_t samples_per_channel,
int num_channels,
- WavFile* wav_file,
+ WavWriter* wav_file,
RawFile* raw_file) {
size_t length = num_channels * samples_per_channel;
scoped_ptr<float[]> buffer(new float[length]);
@@ -153,4 +154,26 @@ static inline bool ReadMessageFromFile(FILE* file,
return msg->ParseFromArray(bytes.get(), size);
}
+template <typename T>
+float ComputeSNR(const T* ref, const T* test, int length, float* variance) {
+ float mse = 0;
+ float mean = 0;
+ *variance = 0;
+ for (int i = 0; i < length; ++i) {
+ T error = ref[i] - test[i];
+ mse += error * error;
+ *variance += ref[i] * ref[i];
+ mean += ref[i];
+ }
+ mse /= length;
+ *variance /= length;
+ mean /= length;
+ *variance -= mean * mean;
+
+ float snr = 100; // We assign 100 dB to the zero-error case.
+ if (mse > 0)
+ snr = 10 * log10(*variance / mse);
+ return snr;
+}
+
} // namespace webrtc
diff --git a/modules/audio_processing/test/unpack.cc b/modules/audio_processing/test/unpack.cc
index 249b6682..ee4e2632 100644
--- a/modules/audio_processing/test/unpack.cc
+++ b/modules/audio_processing/test/unpack.cc
@@ -73,9 +73,9 @@ int do_main(int argc, char* argv[]) {
int num_reverse_channels = 0;
int num_input_channels = 0;
int num_output_channels = 0;
- scoped_ptr<WavFile> reverse_wav_file;
- scoped_ptr<WavFile> input_wav_file;
- scoped_ptr<WavFile> output_wav_file;
+ scoped_ptr<WavWriter> reverse_wav_file;
+ scoped_ptr<WavWriter> input_wav_file;
+ scoped_ptr<WavWriter> output_wav_file;
scoped_ptr<RawFile> reverse_raw_file;
scoped_ptr<RawFile> input_raw_file;
scoped_ptr<RawFile> output_raw_file;
@@ -235,15 +235,15 @@ int do_main(int argc, char* argv[]) {
if (!FLAGS_raw) {
// The WAV files need to be reset every time, because they cant change
// their sample rate or number of channels.
- reverse_wav_file.reset(new WavFile(FLAGS_reverse_file + ".wav",
- reverse_sample_rate,
- num_reverse_channels));
- input_wav_file.reset(new WavFile(FLAGS_input_file + ".wav",
- input_sample_rate,
- num_input_channels));
- output_wav_file.reset(new WavFile(FLAGS_output_file + ".wav",
- output_sample_rate,
- num_output_channels));
+ reverse_wav_file.reset(new WavWriter(FLAGS_reverse_file + ".wav",
+ reverse_sample_rate,
+ num_reverse_channels));
+ input_wav_file.reset(new WavWriter(FLAGS_input_file + ".wav",
+ input_sample_rate,
+ num_input_channels));
+ output_wav_file.reset(new WavWriter(FLAGS_output_file + ".wav",
+ output_sample_rate,
+ num_output_channels));
}
}
}
diff --git a/modules/audio_processing_neon.target.darwin-arm.mk b/modules/audio_processing_neon.target.darwin-arm.mk
index fee19017..f3550b58 100644
--- a/modules/audio_processing_neon.target.darwin-arm.mk
+++ b/modules/audio_processing_neon.target.darwin-arm.mk
@@ -94,11 +94,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -114,6 +116,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -216,11 +219,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -236,6 +241,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_processing_neon.target.linux-arm.mk b/modules/audio_processing_neon.target.linux-arm.mk
index fee19017..f3550b58 100644
--- a/modules/audio_processing_neon.target.linux-arm.mk
+++ b/modules/audio_processing_neon.target.linux-arm.mk
@@ -94,11 +94,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -114,6 +116,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -216,11 +219,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -236,6 +241,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_processing_sse2.target.darwin-x86.mk b/modules/audio_processing_sse2.target.darwin-x86.mk
index b0d022ca..2abc781f 100644
--- a/modules/audio_processing_sse2.target.darwin-x86.mk
+++ b/modules/audio_processing_sse2.target.darwin-x86.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -208,6 +213,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_processing_sse2.target.darwin-x86_64.mk b/modules/audio_processing_sse2.target.darwin-x86_64.mk
index e24f149c..3de33584 100644
--- a/modules/audio_processing_sse2.target.darwin-x86_64.mk
+++ b/modules/audio_processing_sse2.target.darwin-x86_64.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -189,11 +192,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -206,6 +211,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_processing_sse2.target.linux-x86.mk b/modules/audio_processing_sse2.target.linux-x86.mk
index b0d022ca..2abc781f 100644
--- a/modules/audio_processing_sse2.target.linux-x86.mk
+++ b/modules/audio_processing_sse2.target.linux-x86.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -208,6 +213,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audio_processing_sse2.target.linux-x86_64.mk b/modules/audio_processing_sse2.target.linux-x86_64.mk
index e24f149c..3de33584 100644
--- a/modules/audio_processing_sse2.target.linux-x86_64.mk
+++ b/modules/audio_processing_sse2.target.linux-x86_64.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -189,11 +192,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -206,6 +211,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audioproc_debug_proto.target.darwin-arm.mk b/modules/audioproc_debug_proto.target.darwin-arm.mk
index 067c0743..9ffb17bc 100644
--- a/modules/audioproc_debug_proto.target.darwin-arm.mk
+++ b/modules/audioproc_debug_proto.target.darwin-arm.mk
@@ -111,11 +111,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -134,6 +136,7 @@ MY_DEFS_Debug := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -233,11 +236,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -256,6 +261,7 @@ MY_DEFS_Release := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audioproc_debug_proto.target.darwin-arm64.mk b/modules/audioproc_debug_proto.target.darwin-arm64.mk
index 72050f3c..80cc5b24 100644
--- a/modules/audioproc_debug_proto.target.darwin-arm64.mk
+++ b/modules/audioproc_debug_proto.target.darwin-arm64.mk
@@ -100,11 +100,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -113,6 +115,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
@@ -120,6 +123,7 @@ MY_DEFS_Debug := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -207,11 +211,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -220,6 +226,7 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
@@ -227,6 +234,7 @@ MY_DEFS_Release := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audioproc_debug_proto.target.darwin-mips.mk b/modules/audioproc_debug_proto.target.darwin-mips.mk
index b1598594..9a484012 100644
--- a/modules/audioproc_debug_proto.target.darwin-mips.mk
+++ b/modules/audioproc_debug_proto.target.darwin-mips.mk
@@ -105,11 +105,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -127,6 +129,7 @@ MY_DEFS_Debug := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -220,11 +223,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -242,6 +247,7 @@ MY_DEFS_Release := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audioproc_debug_proto.target.darwin-mips64.mk b/modules/audioproc_debug_proto.target.darwin-mips64.mk
new file mode 100644
index 00000000..04bc7123
--- /dev/null
+++ b/modules/audioproc_debug_proto.target.darwin-mips64.mk
@@ -0,0 +1,301 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_audioproc_debug_proto_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(gyp_shared_intermediate_dir)/protoc
+
+
+### Generated for rule "third_party_webrtc_modules_modules_gyp_audioproc_debug_proto_target_genproto":
+# "{'inputs': ['../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['audio_processing/debug.proto'], 'action': ['python', '../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'audio_processing', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
+$(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/debug_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/debug_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/debug_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/debug_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/debug_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/debug_pb2.py: $(LOCAL_PATH)/third_party/webrtc/modules/audio_processing/debug.proto $(LOCAL_PATH)/tools/protoc_wrapper/protoc_wrapper.py $(gyp_shared_intermediate_dir)/protoc $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing $(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing; cd $(gyp_local_path)/third_party/webrtc/modules; python ../../../tools/protoc_wrapper/protoc_wrapper.py --include "" --protobuf "$(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing/debug.pb.h" --proto-in-dir audio_processing --proto-in-file "debug$(suffix $<)" "--use-system-protobuf=0" -- "$(gyp_shared_intermediate_dir)/protoc" --cpp_out "$(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing" --python_out "$(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing"
+
+$(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing/debug.pb.cc: $(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/debug_pb2.py ;
+$(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing/debug.pb.h: $(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/debug_pb2.py ;
+
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/debug_pb2.py \
+ $(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing/debug.pb.cc \
+ $(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing/debug.pb.h
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+$(gyp_intermediate_dir)/debug.pb.cc: $(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing/debug.pb.cc
+ mkdir -p $(@D); cp $< $@
+LOCAL_GENERATED_SOURCES := \
+ $(gyp_intermediate_dir)/debug.pb.cc \
+ $(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/debug_pb2.py \
+ $(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing/debug.pb.h
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS := \
+ $(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing
+
+LOCAL_SRC_FILES :=
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DPROTOBUF_USE_DLLS' \
+ '-DGOOGLE_PROTOBUF_NO_RTTI' \
+ '-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(gyp_shared_intermediate_dir)/protoc_out \
+ $(LOCAL_PATH)/third_party/protobuf \
+ $(LOCAL_PATH)/third_party/protobuf/src
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DPROTOBUF_USE_DLLS' \
+ '-DGOOGLE_PROTOBUF_NO_RTTI' \
+ '-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(gyp_shared_intermediate_dir)/protoc_out \
+ $(LOCAL_PATH)/third_party/protobuf \
+ $(LOCAL_PATH)/third_party/protobuf/src
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_audioproc_debug_proto_gyp
+
+# Alias gyp target name.
+.PHONY: audioproc_debug_proto
+audioproc_debug_proto: third_party_webrtc_modules_audioproc_debug_proto_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/audioproc_debug_proto.target.darwin-x86.mk b/modules/audioproc_debug_proto.target.darwin-x86.mk
index 059d6cf3..67c77616 100644
--- a/modules/audioproc_debug_proto.target.darwin-x86.mk
+++ b/modules/audioproc_debug_proto.target.darwin-x86.mk
@@ -106,11 +106,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -126,6 +128,7 @@ MY_DEFS_Debug := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -219,11 +222,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -239,6 +244,7 @@ MY_DEFS_Release := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audioproc_debug_proto.target.darwin-x86_64.mk b/modules/audioproc_debug_proto.target.darwin-x86_64.mk
index 5729e023..ac69b6a5 100644
--- a/modules/audioproc_debug_proto.target.darwin-x86_64.mk
+++ b/modules/audioproc_debug_proto.target.darwin-x86_64.mk
@@ -105,11 +105,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -125,6 +127,7 @@ MY_DEFS_Debug := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -217,11 +220,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -237,6 +242,7 @@ MY_DEFS_Release := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audioproc_debug_proto.target.linux-arm.mk b/modules/audioproc_debug_proto.target.linux-arm.mk
index 067c0743..9ffb17bc 100644
--- a/modules/audioproc_debug_proto.target.linux-arm.mk
+++ b/modules/audioproc_debug_proto.target.linux-arm.mk
@@ -111,11 +111,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -134,6 +136,7 @@ MY_DEFS_Debug := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -233,11 +236,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -256,6 +261,7 @@ MY_DEFS_Release := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audioproc_debug_proto.target.linux-arm64.mk b/modules/audioproc_debug_proto.target.linux-arm64.mk
index 72050f3c..80cc5b24 100644
--- a/modules/audioproc_debug_proto.target.linux-arm64.mk
+++ b/modules/audioproc_debug_proto.target.linux-arm64.mk
@@ -100,11 +100,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -113,6 +115,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
@@ -120,6 +123,7 @@ MY_DEFS_Debug := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -207,11 +211,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -220,6 +226,7 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
@@ -227,6 +234,7 @@ MY_DEFS_Release := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audioproc_debug_proto.target.linux-mips.mk b/modules/audioproc_debug_proto.target.linux-mips.mk
index b1598594..9a484012 100644
--- a/modules/audioproc_debug_proto.target.linux-mips.mk
+++ b/modules/audioproc_debug_proto.target.linux-mips.mk
@@ -105,11 +105,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -127,6 +129,7 @@ MY_DEFS_Debug := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -220,11 +223,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -242,6 +247,7 @@ MY_DEFS_Release := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audioproc_debug_proto.target.linux-mips64.mk b/modules/audioproc_debug_proto.target.linux-mips64.mk
new file mode 100644
index 00000000..04bc7123
--- /dev/null
+++ b/modules/audioproc_debug_proto.target.linux-mips64.mk
@@ -0,0 +1,301 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_audioproc_debug_proto_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+ $(gyp_shared_intermediate_dir)/protoc
+
+
+### Generated for rule "third_party_webrtc_modules_modules_gyp_audioproc_debug_proto_target_genproto":
+# "{'inputs': ['../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['audio_processing/debug.proto'], 'action': ['python', '../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'audio_processing', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
+$(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/debug_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/debug_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/debug_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/debug_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/debug_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/debug_pb2.py: $(LOCAL_PATH)/third_party/webrtc/modules/audio_processing/debug.proto $(LOCAL_PATH)/tools/protoc_wrapper/protoc_wrapper.py $(gyp_shared_intermediate_dir)/protoc $(GYP_TARGET_DEPENDENCIES)
+ mkdir -p $(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing $(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing; cd $(gyp_local_path)/third_party/webrtc/modules; python ../../../tools/protoc_wrapper/protoc_wrapper.py --include "" --protobuf "$(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing/debug.pb.h" --proto-in-dir audio_processing --proto-in-file "debug$(suffix $<)" "--use-system-protobuf=0" -- "$(gyp_shared_intermediate_dir)/protoc" --cpp_out "$(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing" --python_out "$(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing"
+
+$(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing/debug.pb.cc: $(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/debug_pb2.py ;
+$(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing/debug.pb.h: $(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/debug_pb2.py ;
+
+
+GYP_GENERATED_OUTPUTS := \
+ $(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/debug_pb2.py \
+ $(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing/debug.pb.cc \
+ $(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing/debug.pb.h
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+$(gyp_intermediate_dir)/debug.pb.cc: $(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing/debug.pb.cc
+ mkdir -p $(@D); cp $< $@
+LOCAL_GENERATED_SOURCES := \
+ $(gyp_intermediate_dir)/debug.pb.cc \
+ $(gyp_shared_intermediate_dir)/pyproto/webrtc/audio_processing/debug_pb2.py \
+ $(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing/debug.pb.h
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS := \
+ $(gyp_shared_intermediate_dir)/protoc_out/webrtc/audio_processing
+
+LOCAL_SRC_FILES :=
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DPROTOBUF_USE_DLLS' \
+ '-DGOOGLE_PROTOBUF_NO_RTTI' \
+ '-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(gyp_shared_intermediate_dir)/protoc_out \
+ $(LOCAL_PATH)/third_party/protobuf \
+ $(LOCAL_PATH)/third_party/protobuf/src
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DPROTOBUF_USE_DLLS' \
+ '-DGOOGLE_PROTOBUF_NO_RTTI' \
+ '-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(gyp_shared_intermediate_dir)/protoc_out \
+ $(LOCAL_PATH)/third_party/protobuf \
+ $(LOCAL_PATH)/third_party/protobuf/src
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_audioproc_debug_proto_gyp
+
+# Alias gyp target name.
+.PHONY: audioproc_debug_proto
+audioproc_debug_proto: third_party_webrtc_modules_audioproc_debug_proto_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/audioproc_debug_proto.target.linux-x86.mk b/modules/audioproc_debug_proto.target.linux-x86.mk
index 059d6cf3..67c77616 100644
--- a/modules/audioproc_debug_proto.target.linux-x86.mk
+++ b/modules/audioproc_debug_proto.target.linux-x86.mk
@@ -106,11 +106,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -126,6 +128,7 @@ MY_DEFS_Debug := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -219,11 +222,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -239,6 +244,7 @@ MY_DEFS_Release := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/audioproc_debug_proto.target.linux-x86_64.mk b/modules/audioproc_debug_proto.target.linux-x86_64.mk
index 5729e023..ac69b6a5 100644
--- a/modules/audioproc_debug_proto.target.linux-x86_64.mk
+++ b/modules/audioproc_debug_proto.target.linux-x86_64.mk
@@ -105,11 +105,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -125,6 +127,7 @@ MY_DEFS_Debug := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -217,11 +220,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -237,6 +242,7 @@ MY_DEFS_Release := \
'-DPROTOBUF_USE_DLLS' \
'-DGOOGLE_PROTOBUF_NO_RTTI' \
'-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/bitrate_controller.target.darwin-arm.mk b/modules/bitrate_controller.target.darwin-arm.mk
index 0b66d54d..4d956c7e 100644
--- a/modules/bitrate_controller.target.darwin-arm.mk
+++ b/modules/bitrate_controller.target.darwin-arm.mk
@@ -88,11 +88,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -108,6 +110,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -205,11 +208,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -225,6 +230,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/bitrate_controller.target.darwin-arm64.mk b/modules/bitrate_controller.target.darwin-arm64.mk
index a9ae88a6..07c34c09 100644
--- a/modules/bitrate_controller.target.darwin-arm64.mk
+++ b/modules/bitrate_controller.target.darwin-arm64.mk
@@ -77,11 +77,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -90,10 +92,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -179,11 +183,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -192,10 +198,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/bitrate_controller.target.darwin-mips.mk b/modules/bitrate_controller.target.darwin-mips.mk
index ed387bcc..964e1713 100644
--- a/modules/bitrate_controller.target.darwin-mips.mk
+++ b/modules/bitrate_controller.target.darwin-mips.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -192,11 +195,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -211,6 +216,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/bitrate_controller.target.darwin-mips64.mk b/modules/bitrate_controller.target.darwin-mips64.mk
new file mode 100644
index 00000000..f3802c9e
--- /dev/null
+++ b/modules/bitrate_controller.target.darwin-mips64.mk
@@ -0,0 +1,268 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_bitrate_controller_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/bitrate_controller/bitrate_controller_impl.cc \
+ third_party/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_bitrate_controller_gyp
+
+# Alias gyp target name.
+.PHONY: bitrate_controller
+bitrate_controller: third_party_webrtc_modules_bitrate_controller_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/bitrate_controller.target.darwin-x86.mk b/modules/bitrate_controller.target.darwin-x86.mk
index def87d2f..36529ecf 100644
--- a/modules/bitrate_controller.target.darwin-x86.mk
+++ b/modules/bitrate_controller.target.darwin-x86.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -208,6 +213,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/bitrate_controller.target.darwin-x86_64.mk b/modules/bitrate_controller.target.darwin-x86_64.mk
index c5e90e9b..d7922a56 100644
--- a/modules/bitrate_controller.target.darwin-x86_64.mk
+++ b/modules/bitrate_controller.target.darwin-x86_64.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -189,11 +192,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -206,6 +211,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/bitrate_controller.target.linux-arm.mk b/modules/bitrate_controller.target.linux-arm.mk
index 0b66d54d..4d956c7e 100644
--- a/modules/bitrate_controller.target.linux-arm.mk
+++ b/modules/bitrate_controller.target.linux-arm.mk
@@ -88,11 +88,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -108,6 +110,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -205,11 +208,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -225,6 +230,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/bitrate_controller.target.linux-arm64.mk b/modules/bitrate_controller.target.linux-arm64.mk
index a9ae88a6..07c34c09 100644
--- a/modules/bitrate_controller.target.linux-arm64.mk
+++ b/modules/bitrate_controller.target.linux-arm64.mk
@@ -77,11 +77,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -90,10 +92,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -179,11 +183,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -192,10 +198,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/bitrate_controller.target.linux-mips.mk b/modules/bitrate_controller.target.linux-mips.mk
index ed387bcc..964e1713 100644
--- a/modules/bitrate_controller.target.linux-mips.mk
+++ b/modules/bitrate_controller.target.linux-mips.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -192,11 +195,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -211,6 +216,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/bitrate_controller.target.linux-mips64.mk b/modules/bitrate_controller.target.linux-mips64.mk
new file mode 100644
index 00000000..f3802c9e
--- /dev/null
+++ b/modules/bitrate_controller.target.linux-mips64.mk
@@ -0,0 +1,268 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_bitrate_controller_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/bitrate_controller/bitrate_controller_impl.cc \
+ third_party/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_bitrate_controller_gyp
+
+# Alias gyp target name.
+.PHONY: bitrate_controller
+bitrate_controller: third_party_webrtc_modules_bitrate_controller_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/bitrate_controller.target.linux-x86.mk b/modules/bitrate_controller.target.linux-x86.mk
index def87d2f..36529ecf 100644
--- a/modules/bitrate_controller.target.linux-x86.mk
+++ b/modules/bitrate_controller.target.linux-x86.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -208,6 +213,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/bitrate_controller.target.linux-x86_64.mk b/modules/bitrate_controller.target.linux-x86_64.mk
index c5e90e9b..d7922a56 100644
--- a/modules/bitrate_controller.target.linux-x86_64.mk
+++ b/modules/bitrate_controller.target.linux-x86_64.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -189,11 +192,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -206,6 +211,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/bitrate_controller/bitrate_controller_unittest.cc b/modules/bitrate_controller/bitrate_controller_unittest.cc
index 8523d505..fddab9da 100644
--- a/modules/bitrate_controller/bitrate_controller_unittest.cc
+++ b/modules/bitrate_controller/bitrate_controller_unittest.cc
@@ -83,6 +83,27 @@ TEST_F(BitrateControllerTest, Basic) {
controller_->RemoveBitrateObserver(&bitrate_observer);
}
+TEST_F(BitrateControllerTest, InitialRemb) {
+ TestBitrateObserver bitrate_observer;
+ controller_->SetBitrateObserver(&bitrate_observer, 200000, 100000, 1500000);
+ const uint32_t kRemb = 1000000u;
+ const uint32_t kSecondRemb = kRemb + 500000u;
+
+ // Initial REMB applies immediately.
+ bandwidth_observer_->OnReceivedEstimatedBitrate(kRemb);
+ webrtc::ReportBlockList report_blocks;
+ report_blocks.push_back(CreateReportBlock(1, 2, 0, 1));
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1);
+ report_blocks.clear();
+ EXPECT_EQ(kRemb, bitrate_observer.last_bitrate_);
+
+ // Second REMB doesn't apply immediately.
+ bandwidth_observer_->OnReceivedEstimatedBitrate(kRemb + 500000);
+ report_blocks.push_back(CreateReportBlock(1, 2, 0, 21));
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 2001);
+ EXPECT_LT(bitrate_observer.last_bitrate_, kSecondRemb);
+}
+
TEST_F(BitrateControllerTest, UpdatingBitrateObserver) {
TestBitrateObserver bitrate_observer;
controller_->SetBitrateObserver(&bitrate_observer, 200000, 100000, 1500000);
@@ -105,51 +126,65 @@ TEST_F(BitrateControllerTest, OneBitrateObserverOneRtcpObserver) {
TestBitrateObserver bitrate_observer;
controller_->SetBitrateObserver(&bitrate_observer, 200000, 100000, 300000);
- // Receive a high remb, test bitrate inc.
- bandwidth_observer_->OnReceivedEstimatedBitrate(400000);
+ // First REMB applies immediately.
+ int64_t time_ms = 1001;
+ webrtc::ReportBlockList report_blocks;
+ report_blocks.push_back(CreateReportBlock(1, 2, 0, 1));
+ bandwidth_observer_->OnReceivedEstimatedBitrate(200000);
EXPECT_EQ(200000u, bitrate_observer.last_bitrate_);
EXPECT_EQ(0, bitrate_observer.last_fraction_loss_);
EXPECT_EQ(0u, bitrate_observer.last_rtt_);
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
+ report_blocks.clear();
+ time_ms += 2000;
+
+ // Receive a high remb, test bitrate inc.
+ bandwidth_observer_->OnReceivedEstimatedBitrate(400000);
// Test bitrate increase 8% per second.
- webrtc::ReportBlockList report_blocks;
- report_blocks.push_back(CreateReportBlock(1, 2, 0, 1));
- bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1);
+ report_blocks.push_back(CreateReportBlock(1, 2, 0, 21));
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
EXPECT_EQ(217000u, bitrate_observer.last_bitrate_);
EXPECT_EQ(0, bitrate_observer.last_fraction_loss_);
EXPECT_EQ(50u, bitrate_observer.last_rtt_);
+ time_ms += 1000;
report_blocks.clear();
- report_blocks.push_back(CreateReportBlock(1, 2, 0, 21));
- bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1001);
+ report_blocks.push_back(CreateReportBlock(1, 2, 0, 41));
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
EXPECT_EQ(235360u, bitrate_observer.last_bitrate_);
EXPECT_EQ(0, bitrate_observer.last_fraction_loss_);
EXPECT_EQ(50u, bitrate_observer.last_rtt_);
+ time_ms += 1000;
report_blocks.clear();
- report_blocks.push_back(CreateReportBlock(1, 2, 0, 41));
- bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 2001);
+ report_blocks.push_back(CreateReportBlock(1, 2, 0, 61));
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
EXPECT_EQ(255189u, bitrate_observer.last_bitrate_);
+ time_ms += 1000;
report_blocks.clear();
- report_blocks.push_back(CreateReportBlock(1, 2, 0, 61));
- bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 3001);
+ report_blocks.push_back(CreateReportBlock(1, 2, 0, 81));
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
EXPECT_EQ(276604u, bitrate_observer.last_bitrate_);
+ time_ms += 1000;
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 801));
- bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 4001);
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
EXPECT_EQ(299732u, bitrate_observer.last_bitrate_);
+ time_ms += 1000;
// Reach max cap.
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 101));
- bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 5001);
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
EXPECT_EQ(300000u, bitrate_observer.last_bitrate_);
+ time_ms += 1000;
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 141));
- bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 7001);
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
EXPECT_EQ(300000u, bitrate_observer.last_bitrate_);
// Test that a low REMB trigger immediately.
@@ -167,78 +202,86 @@ TEST_F(BitrateControllerTest, OneBitrateObserverTwoRtcpObservers) {
TestBitrateObserver bitrate_observer;
controller_->SetBitrateObserver(&bitrate_observer, 200000, 100000, 300000);
+ // REMBs during the first 2 seconds apply immediately.
+ int64_t time_ms = 1;
+ webrtc::ReportBlockList report_blocks;
+ report_blocks.push_back(CreateReportBlock(1, 2, 0, 1));
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
+ report_blocks.clear();
+ time_ms += 500;
+
RtcpBandwidthObserver* second_bandwidth_observer =
controller_->CreateRtcpBandwidthObserver();
- // Receive a high remb, test bitrate inc.
- bandwidth_observer_->OnReceivedEstimatedBitrate(400000);
- EXPECT_EQ(200000u, bitrate_observer.last_bitrate_);
- EXPECT_EQ(0, bitrate_observer.last_fraction_loss_);
- EXPECT_EQ(0u, bitrate_observer.last_rtt_);
-
// Test start bitrate.
- webrtc::ReportBlockList report_blocks;
- report_blocks.push_back(CreateReportBlock(1, 2, 0, 1));
- bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1);
+ report_blocks.push_back(CreateReportBlock(1, 2, 0, 21));
second_bandwidth_observer->OnReceivedRtcpReceiverReport(
report_blocks, 100, 1);
EXPECT_EQ(217000u, bitrate_observer.last_bitrate_);
EXPECT_EQ(0, bitrate_observer.last_fraction_loss_);
EXPECT_EQ(100u, bitrate_observer.last_rtt_);
+ time_ms += 500;
// Test bitrate increase 8% per second.
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 21));
- bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 501);
- second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 100,
- 1001);
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
+ time_ms += 500;
+ second_bandwidth_observer->OnReceivedRtcpReceiverReport(
+ report_blocks, 100, time_ms);
EXPECT_EQ(235360u, bitrate_observer.last_bitrate_);
EXPECT_EQ(0, bitrate_observer.last_fraction_loss_);
EXPECT_EQ(100u, bitrate_observer.last_rtt_);
+ time_ms += 500;
// Extra report should not change estimate.
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 31));
- second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 100,
- 1501);
+ second_bandwidth_observer->OnReceivedRtcpReceiverReport(
+ report_blocks, 100, time_ms);
EXPECT_EQ(235360u, bitrate_observer.last_bitrate_);
+ time_ms += 500;
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 41));
- bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 2001);
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
EXPECT_EQ(255189u, bitrate_observer.last_bitrate_);
// Second report should not change estimate.
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 41));
- second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 100,
- 2001);
+ second_bandwidth_observer->OnReceivedRtcpReceiverReport(
+ report_blocks, 100, time_ms);
EXPECT_EQ(255189u, bitrate_observer.last_bitrate_);
+ time_ms += 1000;
// Reports from only one bandwidth observer is ok.
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 61));
- second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 50,
- 3001);
+ second_bandwidth_observer->OnReceivedRtcpReceiverReport(
+ report_blocks, 50, time_ms);
EXPECT_EQ(276604u, bitrate_observer.last_bitrate_);
+ time_ms += 1000;
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 81));
- second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 50,
- 4001);
+ second_bandwidth_observer->OnReceivedRtcpReceiverReport(
+ report_blocks, 50, time_ms);
EXPECT_EQ(299732u, bitrate_observer.last_bitrate_);
+ time_ms += 1000;
// Reach max cap.
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 121));
second_bandwidth_observer->OnReceivedRtcpReceiverReport(
- report_blocks, 50, 5001);
+ report_blocks, 50, time_ms);
EXPECT_EQ(300000u, bitrate_observer.last_bitrate_);
+ time_ms += 1000;
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 141));
second_bandwidth_observer->OnReceivedRtcpReceiverReport(
- report_blocks, 50, 6001);
+ report_blocks, 50, time_ms);
EXPECT_EQ(300000u, bitrate_observer.last_bitrate_);
// Test that a low REMB trigger immediately.
@@ -264,11 +307,18 @@ TEST_F(BitrateControllerTest, OneBitrateObserverMultipleReportBlocks) {
controller_->SetBitrateObserver(&bitrate_observer, kStartBitrate, kMinBitrate,
kMaxBitrate);
+ // REMBs during the first 2 seconds apply immediately.
+ int64_t time_ms = 1001;
+ webrtc::ReportBlockList report_blocks;
+ report_blocks.push_back(CreateReportBlock(1, 2, 0, sequence_number[0]));
+ bandwidth_observer_->OnReceivedEstimatedBitrate(kStartBitrate);
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
+ report_blocks.clear();
+ time_ms += 2000;
+
// Receive a high REMB, test bitrate increase.
bandwidth_observer_->OnReceivedEstimatedBitrate(400000);
- webrtc::ReportBlockList report_blocks;
- int64_t time_ms = 1001;
uint32_t last_bitrate = 0;
// Ramp up to max bitrate.
for (int i = 0; i < 6; ++i) {
@@ -333,20 +383,29 @@ TEST_F(BitrateControllerTest, TwoBitrateObserversOneRtcpObserver) {
controller_->SetBitrateObserver(&bitrate_observer_2, 200000, 200000, 300000);
controller_->SetBitrateObserver(&bitrate_observer_1, 200000, 100000, 300000);
- // Receive a high remb, test bitrate inc.
- // Test too low start bitrate, hence lower than sum of min.
- bandwidth_observer_->OnReceivedEstimatedBitrate(400000);
+ // REMBs during the first 2 seconds apply immediately.
+ int64_t time_ms = 1001;
+ webrtc::ReportBlockList report_blocks;
+ report_blocks.push_back(CreateReportBlock(1, 2, 0, 1));
+ bandwidth_observer_->OnReceivedEstimatedBitrate(200000);
EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_);
EXPECT_EQ(0, bitrate_observer_1.last_fraction_loss_);
EXPECT_EQ(0u, bitrate_observer_1.last_rtt_);
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
+ report_blocks.clear();
+ time_ms += 2000;
+
+ // Receive a high remb, test bitrate inc.
+ // Test too low start bitrate, hence lower than sum of min.
+ bandwidth_observer_->OnReceivedEstimatedBitrate(400000);
// Test bitrate increase 8% per second, distributed equally.
- webrtc::ReportBlockList report_blocks;
- report_blocks.push_back(CreateReportBlock(1, 2, 0, 1));
- bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1001);
+ report_blocks.push_back(CreateReportBlock(1, 2, 0, 21));
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
EXPECT_EQ(112500u, bitrate_observer_1.last_bitrate_);
EXPECT_EQ(0, bitrate_observer_1.last_fraction_loss_);
EXPECT_EQ(50u, bitrate_observer_1.last_rtt_);
+ time_ms += 1000;
EXPECT_EQ(212500u, bitrate_observer_2.last_bitrate_);
EXPECT_EQ(0, bitrate_observer_2.last_fraction_loss_);
@@ -354,59 +413,67 @@ TEST_F(BitrateControllerTest, TwoBitrateObserversOneRtcpObserver) {
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 41));
- bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 2001);
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
EXPECT_EQ(126000u, bitrate_observer_1.last_bitrate_);
EXPECT_EQ(226000u, bitrate_observer_2.last_bitrate_);
+ time_ms += 1000;
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 61));
- bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 3001);
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
EXPECT_EQ(140580u, bitrate_observer_1.last_bitrate_);
EXPECT_EQ(240580u, bitrate_observer_2.last_bitrate_);
+ time_ms += 1000;
// Check that the bitrate sum honor our REMB.
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 101));
- bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 5001);
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
EXPECT_EQ(150000u, bitrate_observer_1.last_bitrate_);
EXPECT_EQ(250000u, bitrate_observer_2.last_bitrate_);
+ time_ms += 1000;
// Remove REMB cap, higher than sum of max.
bandwidth_observer_->OnReceivedEstimatedBitrate(700000);
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 121));
- bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 6001);
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
EXPECT_EQ(166500u, bitrate_observer_1.last_bitrate_);
EXPECT_EQ(266500u, bitrate_observer_2.last_bitrate_);
+ time_ms += 1000;
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 141));
- bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 7001);
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
EXPECT_EQ(184320u, bitrate_observer_1.last_bitrate_);
EXPECT_EQ(284320u, bitrate_observer_2.last_bitrate_);
+ time_ms += 1000;
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 161));
- bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 8001);
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
EXPECT_EQ(207130u, bitrate_observer_1.last_bitrate_);
EXPECT_EQ(300000u, bitrate_observer_2.last_bitrate_); // Max cap.
+ time_ms += 1000;
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 181));
- bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 9001);
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
EXPECT_EQ(248700u, bitrate_observer_1.last_bitrate_);
EXPECT_EQ(300000u, bitrate_observer_2.last_bitrate_);
+ time_ms += 1000;
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 201));
- bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 10001);
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
EXPECT_EQ(293596u, bitrate_observer_1.last_bitrate_);
EXPECT_EQ(300000u, bitrate_observer_2.last_bitrate_);
+ time_ms += 1000;
report_blocks.clear();
report_blocks.push_back(CreateReportBlock(1, 2, 0, 221));
- bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 11001);
+ bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
EXPECT_EQ(300000u, bitrate_observer_1.last_bitrate_); // Max cap.
EXPECT_EQ(300000u, bitrate_observer_2.last_bitrate_);
diff --git a/modules/bitrate_controller/send_side_bandwidth_estimation.cc b/modules/bitrate_controller/send_side_bandwidth_estimation.cc
index 5da23f06..47a79ad2 100644
--- a/modules/bitrate_controller/send_side_bandwidth_estimation.cc
+++ b/modules/bitrate_controller/send_side_bandwidth_estimation.cc
@@ -13,6 +13,7 @@
#include <cmath>
#include "webrtc/system_wrappers/interface/logging.h"
+#include "webrtc/system_wrappers/interface/metrics.h"
namespace webrtc {
namespace {
@@ -20,6 +21,7 @@ enum { kBweIncreaseIntervalMs = 1000 };
enum { kBweDecreaseIntervalMs = 300 };
enum { kLimitNumPackets = 20 };
enum { kAvgPacketSizeBytes = 1000 };
+enum { kStartPhaseMs = 2000 };
// Calculate the rate that TCP-Friendly Rate Control (TFRC) would apply.
// The formula in RFC 3448, Section 3.1, is used.
@@ -56,7 +58,11 @@ SendSideBandwidthEstimation::SendSideBandwidthEstimation()
last_fraction_loss_(0),
last_round_trip_time_ms_(0),
bwe_incoming_(0),
- time_last_decrease_ms_(0) {}
+ time_last_decrease_ms_(0),
+ first_report_time_ms_(-1),
+ initially_lost_packets_(0),
+ uma_updated_(false) {
+}
SendSideBandwidthEstimation::~SendSideBandwidthEstimation() {}
@@ -88,7 +94,7 @@ void SendSideBandwidthEstimation::CurrentEstimate(uint32_t* bitrate,
void SendSideBandwidthEstimation::UpdateReceiverEstimate(uint32_t bandwidth) {
bwe_incoming_ = bandwidth;
- CapBitrateToThresholds();
+ bitrate_ = CapBitrateToThresholds(bitrate_);
}
void SendSideBandwidthEstimation::UpdateReceiverBlock(uint8_t fraction_loss,
@@ -121,11 +127,35 @@ void SendSideBandwidthEstimation::UpdateReceiverBlock(uint8_t fraction_loss,
}
time_last_receiver_block_ms_ = now_ms;
UpdateEstimate(now_ms);
+
+ if (first_report_time_ms_ == -1) {
+ first_report_time_ms_ = now_ms;
+ } else if (IsInStartPhase(now_ms)) {
+ initially_lost_packets_ += (fraction_loss * number_of_packets) >> 8;
+ } else if (!uma_updated_) {
+ uma_updated_ = true;
+ RTC_HISTOGRAM_COUNTS(
+ "WebRTC.BWE.InitiallyLostPackets", initially_lost_packets_, 0, 100, 50);
+ RTC_HISTOGRAM_COUNTS("WebRTC.BWE.InitialRtt", rtt, 0, 2000, 50);
+ RTC_HISTOGRAM_COUNTS("WebRTC.BWE.InitialBandwidthEstimate",
+ (bitrate_ + 500) / 1000,
+ 0,
+ 2000,
+ 50);
+ }
}
void SendSideBandwidthEstimation::UpdateEstimate(uint32_t now_ms) {
+ // We trust the REMB during the first 2 seconds if we haven't had any
+ // packet loss reported, to allow startup bitrate probing.
+ if (last_fraction_loss_ == 0 && IsInStartPhase(now_ms) &&
+ bwe_incoming_ > bitrate_) {
+ bitrate_ = CapBitrateToThresholds(bwe_incoming_);
+ min_bitrate_history_.clear();
+ min_bitrate_history_.push_back(std::make_pair(now_ms, bitrate_));
+ return;
+ }
UpdateMinHistory(now_ms);
-
// Only start updating bitrate when receiving receiver blocks.
if (time_last_receiver_block_ms_ != 0) {
if (last_fraction_loss_ <= 5) {
@@ -172,7 +202,12 @@ void SendSideBandwidthEstimation::UpdateEstimate(uint32_t now_ms) {
}
}
}
- CapBitrateToThresholds();
+ bitrate_ = CapBitrateToThresholds(bitrate_);
+}
+
+bool SendSideBandwidthEstimation::IsInStartPhase(int64_t now_ms) const {
+ return first_report_time_ms_ == -1 ||
+ now_ms - first_report_time_ms_ < kStartPhaseMs;
}
void SendSideBandwidthEstimation::UpdateMinHistory(uint32_t now_ms) {
@@ -195,19 +230,20 @@ void SendSideBandwidthEstimation::UpdateMinHistory(uint32_t now_ms) {
min_bitrate_history_.push_back(std::make_pair(now_ms, bitrate_));
}
-void SendSideBandwidthEstimation::CapBitrateToThresholds() {
- if (bwe_incoming_ > 0 && bitrate_ > bwe_incoming_) {
- bitrate_ = bwe_incoming_;
+uint32_t SendSideBandwidthEstimation::CapBitrateToThresholds(uint32_t bitrate) {
+ if (bwe_incoming_ > 0 && bitrate > bwe_incoming_) {
+ bitrate = bwe_incoming_;
}
- if (bitrate_ > max_bitrate_configured_) {
- bitrate_ = max_bitrate_configured_;
+ if (bitrate > max_bitrate_configured_) {
+ bitrate = max_bitrate_configured_;
}
- if (bitrate_ < min_bitrate_configured_) {
- LOG(LS_WARNING) << "Estimated available bandwidth " << bitrate_ / 1000
+ if (bitrate < min_bitrate_configured_) {
+ LOG(LS_WARNING) << "Estimated available bandwidth " << bitrate / 1000
<< " kbps is below configured min bitrate "
<< min_bitrate_configured_ / 1000 << " kbps.";
- bitrate_ = min_bitrate_configured_;
+ bitrate = min_bitrate_configured_;
}
+ return bitrate;
}
} // namespace webrtc
diff --git a/modules/bitrate_controller/send_side_bandwidth_estimation.h b/modules/bitrate_controller/send_side_bandwidth_estimation.h
index eb675d1c..0fe3ae67 100644
--- a/modules/bitrate_controller/send_side_bandwidth_estimation.h
+++ b/modules/bitrate_controller/send_side_bandwidth_estimation.h
@@ -43,7 +43,11 @@ class SendSideBandwidthEstimation {
void SetMinBitrate(uint32_t min_bitrate);
private:
- void CapBitrateToThresholds();
+ bool IsInStartPhase(int64_t now_ms) const;
+
+ // Returns the input bitrate capped to the thresholds defined by the max,
+ // min and incoming bandwidth.
+ uint32_t CapBitrateToThresholds(uint32_t bitrate);
// Updates history of min bitrates.
// After this method returns min_bitrate_history_.front().second contains the
@@ -66,6 +70,9 @@ class SendSideBandwidthEstimation {
uint32_t bwe_incoming_;
uint32_t time_last_decrease_ms_;
+ int64_t first_report_time_ms_;
+ int initially_lost_packets_;
+ bool uma_updated_;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_BITRATE_CONTROLLER_SEND_SIDE_BANDWIDTH_ESTIMATION_H_
diff --git a/modules/iLBC.target.darwin-arm.mk b/modules/iLBC.target.darwin-arm.mk
index f2df23a6..93ecd49a 100644
--- a/modules/iLBC.target.darwin-arm.mk
+++ b/modules/iLBC.target.darwin-arm.mk
@@ -154,11 +154,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -174,6 +176,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -275,11 +278,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -295,6 +300,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iLBC.target.darwin-arm64.mk b/modules/iLBC.target.darwin-arm64.mk
index 411bd417..821d452d 100644
--- a/modules/iLBC.target.darwin-arm64.mk
+++ b/modules/iLBC.target.darwin-arm64.mk
@@ -143,11 +143,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -156,10 +158,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -249,11 +253,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -262,10 +268,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iLBC.target.darwin-mips.mk b/modules/iLBC.target.darwin-mips.mk
index 8d36a772..779d109c 100644
--- a/modules/iLBC.target.darwin-mips.mk
+++ b/modules/iLBC.target.darwin-mips.mk
@@ -148,11 +148,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -167,6 +169,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -262,11 +265,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -281,6 +286,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iLBC.target.darwin-mips64.mk b/modules/iLBC.target.darwin-mips64.mk
new file mode 100644
index 00000000..0e6f5365
--- /dev/null
+++ b/modules/iLBC.target.darwin-mips64.mk
@@ -0,0 +1,342 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_iLBC_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/abs_quant.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/abs_quant_loop.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/augmented_cb_corr.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/bw_expand.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/cb_construct.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/cb_mem_energy.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/cb_mem_energy_augmentation.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/cb_mem_energy_calc.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/cb_search.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/cb_search_core.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/cb_update_best_index.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/chebyshev.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/comp_corr.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/constants.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/create_augmented_vec.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/decode.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/decode_residual.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/decoder_interpolate_lsf.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/do_plc.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/encode.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/energy_inverse.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/enh_upsample.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/enhancer.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/enhancer_interface.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/filtered_cb_vecs.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/frame_classify.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/gain_dequant.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/gain_quant.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/get_cd_vec.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/get_lsp_poly.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/get_sync_seq.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/hp_input.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/hp_output.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/ilbc.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/index_conv_dec.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/index_conv_enc.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/init_decode.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/init_encode.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/interpolate.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/interpolate_samples.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/lpc_encode.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/lsf_check.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/lsf_interpolate_to_poly_dec.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/lsf_interpolate_to_poly_enc.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/lsf_to_lsp.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/lsf_to_poly.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/lsp_to_lsf.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/my_corr.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/nearest_neighbor.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/pack_bits.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/poly_to_lsf.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/poly_to_lsp.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/refiner.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/simple_interpolate_lsf.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/simple_lpc_analysis.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/simple_lsf_dequant.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/simple_lsf_quant.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/smooth.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/smooth_out_data.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/sort_sq.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/split_vq.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/state_construct.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/state_search.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/swap_bytes.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/unpack_bits.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/vq3.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/vq4.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/window32_w32.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/xcorr_coef.c
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/ilbc/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/ilbc/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_iLBC_gyp
+
+# Alias gyp target name.
+.PHONY: iLBC
+iLBC: third_party_webrtc_modules_iLBC_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/iLBC.target.darwin-x86.mk b/modules/iLBC.target.darwin-x86.mk
index 9bbce451..fe2b0733 100644
--- a/modules/iLBC.target.darwin-x86.mk
+++ b/modules/iLBC.target.darwin-x86.mk
@@ -149,11 +149,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -166,6 +168,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -261,11 +264,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -278,6 +283,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iLBC.target.darwin-x86_64.mk b/modules/iLBC.target.darwin-x86_64.mk
index 0fe1602a..1d3aa7fc 100644
--- a/modules/iLBC.target.darwin-x86_64.mk
+++ b/modules/iLBC.target.darwin-x86_64.mk
@@ -148,11 +148,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -165,6 +167,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -259,11 +262,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -276,6 +281,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iLBC.target.linux-arm.mk b/modules/iLBC.target.linux-arm.mk
index f2df23a6..93ecd49a 100644
--- a/modules/iLBC.target.linux-arm.mk
+++ b/modules/iLBC.target.linux-arm.mk
@@ -154,11 +154,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -174,6 +176,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -275,11 +278,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -295,6 +300,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iLBC.target.linux-arm64.mk b/modules/iLBC.target.linux-arm64.mk
index 411bd417..821d452d 100644
--- a/modules/iLBC.target.linux-arm64.mk
+++ b/modules/iLBC.target.linux-arm64.mk
@@ -143,11 +143,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -156,10 +158,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -249,11 +253,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -262,10 +268,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iLBC.target.linux-mips.mk b/modules/iLBC.target.linux-mips.mk
index 8d36a772..779d109c 100644
--- a/modules/iLBC.target.linux-mips.mk
+++ b/modules/iLBC.target.linux-mips.mk
@@ -148,11 +148,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -167,6 +169,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -262,11 +265,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -281,6 +286,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iLBC.target.linux-mips64.mk b/modules/iLBC.target.linux-mips64.mk
new file mode 100644
index 00000000..0e6f5365
--- /dev/null
+++ b/modules/iLBC.target.linux-mips64.mk
@@ -0,0 +1,342 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_iLBC_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/abs_quant.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/abs_quant_loop.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/augmented_cb_corr.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/bw_expand.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/cb_construct.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/cb_mem_energy.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/cb_mem_energy_augmentation.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/cb_mem_energy_calc.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/cb_search.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/cb_search_core.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/cb_update_best_index.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/chebyshev.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/comp_corr.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/constants.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/create_augmented_vec.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/decode.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/decode_residual.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/decoder_interpolate_lsf.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/do_plc.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/encode.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/energy_inverse.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/enh_upsample.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/enhancer.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/enhancer_interface.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/filtered_cb_vecs.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/frame_classify.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/gain_dequant.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/gain_quant.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/get_cd_vec.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/get_lsp_poly.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/get_sync_seq.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/hp_input.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/hp_output.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/ilbc.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/index_conv_dec.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/index_conv_enc.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/init_decode.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/init_encode.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/interpolate.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/interpolate_samples.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/lpc_encode.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/lsf_check.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/lsf_interpolate_to_poly_dec.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/lsf_interpolate_to_poly_enc.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/lsf_to_lsp.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/lsf_to_poly.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/lsp_to_lsf.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/my_corr.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/nearest_neighbor.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/pack_bits.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/poly_to_lsf.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/poly_to_lsp.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/refiner.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/simple_interpolate_lsf.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/simple_lpc_analysis.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/simple_lsf_dequant.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/simple_lsf_quant.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/smooth.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/smooth_out_data.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/sort_sq.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/split_vq.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/state_construct.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/state_search.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/swap_bytes.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/unpack_bits.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/vq3.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/vq4.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/window32_w32.c \
+ third_party/webrtc/modules/audio_coding/codecs/ilbc/xcorr_coef.c
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/ilbc/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/ilbc/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_iLBC_gyp
+
+# Alias gyp target name.
+.PHONY: iLBC
+iLBC: third_party_webrtc_modules_iLBC_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/iLBC.target.linux-x86.mk b/modules/iLBC.target.linux-x86.mk
index 9bbce451..fe2b0733 100644
--- a/modules/iLBC.target.linux-x86.mk
+++ b/modules/iLBC.target.linux-x86.mk
@@ -149,11 +149,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -166,6 +168,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -261,11 +264,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -278,6 +283,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iLBC.target.linux-x86_64.mk b/modules/iLBC.target.linux-x86_64.mk
index 0fe1602a..1d3aa7fc 100644
--- a/modules/iLBC.target.linux-x86_64.mk
+++ b/modules/iLBC.target.linux-x86_64.mk
@@ -148,11 +148,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -165,6 +167,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -259,11 +262,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -276,6 +281,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iSAC.target.darwin-arm.mk b/modules/iSAC.target.darwin-arm.mk
index da974a09..be3fbf3c 100644
--- a/modules/iSAC.target.darwin-arm.mk
+++ b/modules/iSAC.target.darwin-arm.mk
@@ -113,11 +113,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -133,6 +135,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -234,11 +237,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -254,6 +259,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iSAC.target.darwin-arm64.mk b/modules/iSAC.target.darwin-arm64.mk
index 95e4e844..05f4e86b 100644
--- a/modules/iSAC.target.darwin-arm64.mk
+++ b/modules/iSAC.target.darwin-arm64.mk
@@ -102,11 +102,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -115,10 +117,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -208,11 +212,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -221,10 +227,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iSAC.target.darwin-mips.mk b/modules/iSAC.target.darwin-mips.mk
index a853b629..9c49163b 100644
--- a/modules/iSAC.target.darwin-mips.mk
+++ b/modules/iSAC.target.darwin-mips.mk
@@ -107,11 +107,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -126,6 +128,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -221,11 +224,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -240,6 +245,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iSAC.target.darwin-mips64.mk b/modules/iSAC.target.darwin-mips64.mk
new file mode 100644
index 00000000..f25e9984
--- /dev/null
+++ b/modules/iSAC.target.darwin-mips64.mk
@@ -0,0 +1,301 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_iSAC_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/arith_routines.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/arith_routines_hist.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/arith_routines_logist.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/bandwidth_estimator.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/crc.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/decode.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/decode_bwe.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/encode.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/encode_lpc_swb.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/entropy_coding.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/fft.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/filter_functions.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/filterbank_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/intialize.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/isac.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/filterbanks.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/pitch_lag_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/lattice.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/lpc_gain_swb_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/lpc_analysis.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb12_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb16_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/lpc_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/pitch_estimator.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/pitch_filter.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/pitch_gain_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/spectrum_ar_model_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/transform.c
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_iSAC_gyp
+
+# Alias gyp target name.
+.PHONY: iSAC
+iSAC: third_party_webrtc_modules_iSAC_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/iSAC.target.darwin-x86.mk b/modules/iSAC.target.darwin-x86.mk
index e7061b05..9a4fc483 100644
--- a/modules/iSAC.target.darwin-x86.mk
+++ b/modules/iSAC.target.darwin-x86.mk
@@ -108,11 +108,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -125,6 +127,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -220,11 +223,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -237,6 +242,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iSAC.target.darwin-x86_64.mk b/modules/iSAC.target.darwin-x86_64.mk
index e93fea67..b939b4aa 100644
--- a/modules/iSAC.target.darwin-x86_64.mk
+++ b/modules/iSAC.target.darwin-x86_64.mk
@@ -107,11 +107,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -124,6 +126,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -218,11 +221,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -235,6 +240,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iSAC.target.linux-arm.mk b/modules/iSAC.target.linux-arm.mk
index da974a09..be3fbf3c 100644
--- a/modules/iSAC.target.linux-arm.mk
+++ b/modules/iSAC.target.linux-arm.mk
@@ -113,11 +113,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -133,6 +135,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -234,11 +237,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -254,6 +259,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iSAC.target.linux-arm64.mk b/modules/iSAC.target.linux-arm64.mk
index 95e4e844..05f4e86b 100644
--- a/modules/iSAC.target.linux-arm64.mk
+++ b/modules/iSAC.target.linux-arm64.mk
@@ -102,11 +102,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -115,10 +117,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -208,11 +212,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -221,10 +227,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iSAC.target.linux-mips.mk b/modules/iSAC.target.linux-mips.mk
index a853b629..9c49163b 100644
--- a/modules/iSAC.target.linux-mips.mk
+++ b/modules/iSAC.target.linux-mips.mk
@@ -107,11 +107,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -126,6 +128,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -221,11 +224,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -240,6 +245,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iSAC.target.linux-mips64.mk b/modules/iSAC.target.linux-mips64.mk
new file mode 100644
index 00000000..f25e9984
--- /dev/null
+++ b/modules/iSAC.target.linux-mips64.mk
@@ -0,0 +1,301 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_iSAC_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/arith_routines.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/arith_routines_hist.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/arith_routines_logist.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/bandwidth_estimator.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/crc.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/decode.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/decode_bwe.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/encode.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/encode_lpc_swb.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/entropy_coding.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/fft.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/filter_functions.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/filterbank_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/intialize.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/isac.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/filterbanks.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/pitch_lag_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/lattice.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/lpc_gain_swb_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/lpc_analysis.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb12_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb16_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/lpc_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/pitch_estimator.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/pitch_filter.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/pitch_gain_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/spectrum_ar_model_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/main/source/transform.c
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_iSAC_gyp
+
+# Alias gyp target name.
+.PHONY: iSAC
+iSAC: third_party_webrtc_modules_iSAC_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/iSAC.target.linux-x86.mk b/modules/iSAC.target.linux-x86.mk
index e7061b05..9a4fc483 100644
--- a/modules/iSAC.target.linux-x86.mk
+++ b/modules/iSAC.target.linux-x86.mk
@@ -108,11 +108,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -125,6 +127,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -220,11 +223,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -237,6 +242,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iSAC.target.linux-x86_64.mk b/modules/iSAC.target.linux-x86_64.mk
index e93fea67..b939b4aa 100644
--- a/modules/iSAC.target.linux-x86_64.mk
+++ b/modules/iSAC.target.linux-x86_64.mk
@@ -107,11 +107,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -124,6 +126,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -218,11 +221,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -235,6 +240,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iSACFix.target.darwin-arm.mk b/modules/iSACFix.target.darwin-arm.mk
index cc5dd244..e9d8ccc9 100644
--- a/modules/iSACFix.target.darwin-arm.mk
+++ b/modules/iSACFix.target.darwin-arm.mk
@@ -113,11 +113,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -133,6 +135,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -235,11 +238,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -255,6 +260,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iSACFix.target.darwin-arm64.mk b/modules/iSACFix.target.darwin-arm64.mk
index d3ccea5f..c690ae69 100644
--- a/modules/iSACFix.target.darwin-arm64.mk
+++ b/modules/iSACFix.target.darwin-arm64.mk
@@ -102,11 +102,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -115,10 +117,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -209,11 +213,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -222,10 +228,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iSACFix.target.darwin-mips.mk b/modules/iSACFix.target.darwin-mips.mk
index 200ea4ff..639671d3 100644
--- a/modules/iSACFix.target.darwin-mips.mk
+++ b/modules/iSACFix.target.darwin-mips.mk
@@ -110,11 +110,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -129,6 +131,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -225,11 +228,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -244,6 +249,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iSACFix.target.darwin-mips64.mk b/modules/iSACFix.target.darwin-mips64.mk
new file mode 100644
index 00000000..61251daf
--- /dev/null
+++ b/modules/iSACFix.target.darwin-mips64.mk
@@ -0,0 +1,303 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_iSACFix_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/arith_routines.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/arith_routines_hist.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/arith_routines_logist.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/decode.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/decode_bwe.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/decode_plc.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/encode.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/entropy_coding.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/fft.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/filterbank_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/filterbanks.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/filters.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/initialize.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/isacfix.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/lattice.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/lattice_c.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/lpc_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_estimator_c.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_filter.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_filter_c.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_gain_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_lag_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/spectrum_ar_model_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/transform.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/transform_tables.c
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/fix/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/fix/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_iSACFix_gyp
+
+# Alias gyp target name.
+.PHONY: iSACFix
+iSACFix: third_party_webrtc_modules_iSACFix_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/iSACFix.target.darwin-x86.mk b/modules/iSACFix.target.darwin-x86.mk
index 090a0226..c90c54ff 100644
--- a/modules/iSACFix.target.darwin-x86.mk
+++ b/modules/iSACFix.target.darwin-x86.mk
@@ -108,11 +108,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -125,6 +127,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -221,11 +224,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -238,6 +243,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iSACFix.target.darwin-x86_64.mk b/modules/iSACFix.target.darwin-x86_64.mk
index e82859c8..76d2293e 100644
--- a/modules/iSACFix.target.darwin-x86_64.mk
+++ b/modules/iSACFix.target.darwin-x86_64.mk
@@ -107,11 +107,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -124,6 +126,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -219,11 +222,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -236,6 +241,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iSACFix.target.linux-arm.mk b/modules/iSACFix.target.linux-arm.mk
index cc5dd244..e9d8ccc9 100644
--- a/modules/iSACFix.target.linux-arm.mk
+++ b/modules/iSACFix.target.linux-arm.mk
@@ -113,11 +113,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -133,6 +135,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -235,11 +238,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -255,6 +260,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iSACFix.target.linux-arm64.mk b/modules/iSACFix.target.linux-arm64.mk
index d3ccea5f..c690ae69 100644
--- a/modules/iSACFix.target.linux-arm64.mk
+++ b/modules/iSACFix.target.linux-arm64.mk
@@ -102,11 +102,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -115,10 +117,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -209,11 +213,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -222,10 +228,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iSACFix.target.linux-mips.mk b/modules/iSACFix.target.linux-mips.mk
index 200ea4ff..639671d3 100644
--- a/modules/iSACFix.target.linux-mips.mk
+++ b/modules/iSACFix.target.linux-mips.mk
@@ -110,11 +110,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -129,6 +131,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -225,11 +228,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -244,6 +249,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iSACFix.target.linux-mips64.mk b/modules/iSACFix.target.linux-mips64.mk
new file mode 100644
index 00000000..61251daf
--- /dev/null
+++ b/modules/iSACFix.target.linux-mips64.mk
@@ -0,0 +1,303 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_iSACFix_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/arith_routines.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/arith_routines_hist.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/arith_routines_logist.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/decode.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/decode_bwe.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/decode_plc.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/encode.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/entropy_coding.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/fft.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/filterbank_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/filterbanks.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/filters.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/initialize.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/isacfix.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/lattice.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/lattice_c.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/lpc_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_estimator_c.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_filter.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_filter_c.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_gain_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_lag_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/spectrum_ar_model_tables.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/transform.c \
+ third_party/webrtc/modules/audio_coding/codecs/isac/fix/source/transform_tables.c
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/fix/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/fix/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_iSACFix_gyp
+
+# Alias gyp target name.
+.PHONY: iSACFix
+iSACFix: third_party_webrtc_modules_iSACFix_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/iSACFix.target.linux-x86.mk b/modules/iSACFix.target.linux-x86.mk
index 090a0226..c90c54ff 100644
--- a/modules/iSACFix.target.linux-x86.mk
+++ b/modules/iSACFix.target.linux-x86.mk
@@ -108,11 +108,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -125,6 +127,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -221,11 +224,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -238,6 +243,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/iSACFix.target.linux-x86_64.mk b/modules/iSACFix.target.linux-x86_64.mk
index e82859c8..76d2293e 100644
--- a/modules/iSACFix.target.linux-x86_64.mk
+++ b/modules/iSACFix.target.linux-x86_64.mk
@@ -107,11 +107,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -124,6 +126,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -219,11 +222,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -236,6 +241,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/isac_neon.target.darwin-arm.mk b/modules/isac_neon.target.darwin-arm.mk
index c496a915..32608695 100644
--- a/modules/isac_neon.target.darwin-arm.mk
+++ b/modules/isac_neon.target.darwin-arm.mk
@@ -93,11 +93,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -113,6 +115,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -215,11 +218,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -235,6 +240,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/isac_neon.target.linux-arm.mk b/modules/isac_neon.target.linux-arm.mk
index c496a915..32608695 100644
--- a/modules/isac_neon.target.linux-arm.mk
+++ b/modules/isac_neon.target.linux-arm.mk
@@ -93,11 +93,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -113,6 +115,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -215,11 +218,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -235,6 +240,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/media_file.target.darwin-arm.mk b/modules/media_file.target.darwin-arm.mk
index 6a78abc3..d1c8ad6a 100644
--- a/modules/media_file.target.darwin-arm.mk
+++ b/modules/media_file.target.darwin-arm.mk
@@ -89,11 +89,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -109,6 +111,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -208,11 +211,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -228,6 +233,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/media_file.target.darwin-arm64.mk b/modules/media_file.target.darwin-arm64.mk
index 9ebbee89..7b61e3a1 100644
--- a/modules/media_file.target.darwin-arm64.mk
+++ b/modules/media_file.target.darwin-arm64.mk
@@ -78,11 +78,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -91,10 +93,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -182,11 +186,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -195,10 +201,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/media_file.target.darwin-mips.mk b/modules/media_file.target.darwin-mips.mk
index 342bf045..96f821a2 100644
--- a/modules/media_file.target.darwin-mips.mk
+++ b/modules/media_file.target.darwin-mips.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -102,6 +104,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -195,11 +198,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -214,6 +219,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/media_file.target.darwin-mips64.mk b/modules/media_file.target.darwin-mips64.mk
new file mode 100644
index 00000000..0f13b293
--- /dev/null
+++ b/modules/media_file.target.darwin-mips64.mk
@@ -0,0 +1,273 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_media_file_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/media_file/source/avi_file.cc \
+ third_party/webrtc/modules/media_file/source/media_file_impl.cc \
+ third_party/webrtc/modules/media_file/source/media_file_utility.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/media_file/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/media_file/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_media_file_gyp
+
+# Alias gyp target name.
+.PHONY: media_file
+media_file: third_party_webrtc_modules_media_file_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/media_file.target.darwin-x86.mk b/modules/media_file.target.darwin-x86.mk
index 1967f137..b0a9f516 100644
--- a/modules/media_file.target.darwin-x86.mk
+++ b/modules/media_file.target.darwin-x86.mk
@@ -84,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -194,11 +197,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -211,6 +216,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/media_file.target.darwin-x86_64.mk b/modules/media_file.target.darwin-x86_64.mk
index a486b79b..5486ac62 100644
--- a/modules/media_file.target.darwin-x86_64.mk
+++ b/modules/media_file.target.darwin-x86_64.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -192,11 +195,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -209,6 +214,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/media_file.target.linux-arm.mk b/modules/media_file.target.linux-arm.mk
index 6a78abc3..d1c8ad6a 100644
--- a/modules/media_file.target.linux-arm.mk
+++ b/modules/media_file.target.linux-arm.mk
@@ -89,11 +89,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -109,6 +111,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -208,11 +211,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -228,6 +233,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/media_file.target.linux-arm64.mk b/modules/media_file.target.linux-arm64.mk
index 9ebbee89..7b61e3a1 100644
--- a/modules/media_file.target.linux-arm64.mk
+++ b/modules/media_file.target.linux-arm64.mk
@@ -78,11 +78,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -91,10 +93,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -182,11 +186,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -195,10 +201,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/media_file.target.linux-mips.mk b/modules/media_file.target.linux-mips.mk
index 342bf045..96f821a2 100644
--- a/modules/media_file.target.linux-mips.mk
+++ b/modules/media_file.target.linux-mips.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -102,6 +104,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -195,11 +198,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -214,6 +219,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/media_file.target.linux-mips64.mk b/modules/media_file.target.linux-mips64.mk
new file mode 100644
index 00000000..0f13b293
--- /dev/null
+++ b/modules/media_file.target.linux-mips64.mk
@@ -0,0 +1,273 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_media_file_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/media_file/source/avi_file.cc \
+ third_party/webrtc/modules/media_file/source/media_file_impl.cc \
+ third_party/webrtc/modules/media_file/source/media_file_utility.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/media_file/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/media_file/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_media_file_gyp
+
+# Alias gyp target name.
+.PHONY: media_file
+media_file: third_party_webrtc_modules_media_file_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/media_file.target.linux-x86.mk b/modules/media_file.target.linux-x86.mk
index 1967f137..b0a9f516 100644
--- a/modules/media_file.target.linux-x86.mk
+++ b/modules/media_file.target.linux-x86.mk
@@ -84,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -194,11 +197,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -211,6 +216,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/media_file.target.linux-x86_64.mk b/modules/media_file.target.linux-x86_64.mk
index a486b79b..5486ac62 100644
--- a/modules/media_file.target.linux-x86_64.mk
+++ b/modules/media_file.target.linux-x86_64.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -192,11 +195,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -209,6 +214,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/modules.gyp b/modules/modules.gyp
index 9650e66d..3caf41f9 100644
--- a/modules/modules.gyp
+++ b/modules/modules.gyp
@@ -95,11 +95,13 @@
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
'<(webrtc_root)/common_audio/common_audio.gyp:common_audio',
+ '<(webrtc_root)/modules/modules.gyp:video_capture_module_impl',
'<(webrtc_root)/modules/video_coding/codecs/vp8/vp8.gyp:webrtc_vp8',
+ '<(webrtc_root)/modules/video_coding/codecs/vp9/vp9.gyp:webrtc_vp9',
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
- '<(webrtc_root)/test/test.gyp:test_support_main',
'<(webrtc_root)/test/test.gyp:frame_generator',
- '<(webrtc_root)/test/test.gyp:rtcp_packet_parser',
+ '<(webrtc_root)/test/test.gyp:rtp_test_utils',
+ '<(webrtc_root)/test/test.gyp:test_support_main',
],
'sources': [
'audio_coding/main/acm2/acm_opus_unittest.cc',
@@ -179,6 +181,7 @@
'desktop_capture/win/cursor_unittest_resources.rc',
'media_file/source/media_file_unittest.cc',
'module_common_types_unittest.cc',
+ 'pacing/bitrate_prober_unittest.cc',
'pacing/paced_sender_unittest.cc',
'remote_bitrate_estimator/bwe_simulations.cc',
'remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h',
@@ -211,6 +214,7 @@
'rtp_rtcp/source/rtcp_packet_unittest.cc',
'rtp_rtcp/source/rtcp_receiver_unittest.cc',
'rtp_rtcp/source/rtcp_sender_unittest.cc',
+ 'rtp_rtcp/source/rtcp_utility_unittest.cc',
'rtp_rtcp/source/rtp_fec_unittest.cc',
'rtp_rtcp/source/rtp_format_h264_unittest.cc',
'rtp_rtcp/source/rtp_format_vp8_unittest.cc',
@@ -323,6 +327,7 @@
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(webrtc_root)/common_video/common_video.gyp:common_video',
'<(webrtc_root)/modules/video_coding/codecs/vp8/vp8.gyp:webrtc_vp8',
+ '<(webrtc_root)/modules/video_coding/codecs/vp9/vp9.gyp:webrtc_vp9',
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
'<(webrtc_root)/test/metrics.gyp:metrics',
'<(webrtc_root)/test/test.gyp:test_support',
@@ -394,7 +399,6 @@
],
'includes': [
'../build/isolate.gypi',
- 'modules_tests.isolate',
],
'sources': [
'modules_tests.isolate',
@@ -408,7 +412,6 @@
],
'includes': [
'../build/isolate.gypi',
- 'modules_unittests.isolate',
],
'sources': [
'modules_unittests.isolate',
diff --git a/modules/modules_tests.isolate b/modules/modules_tests.isolate
index e5055f0d..c29c65b7 100644
--- a/modules/modules_tests.isolate
+++ b/modules/modules_tests.isolate
@@ -9,7 +9,7 @@
'conditions': [
['OS=="android"', {
'variables': {
- 'isolate_dependency_untracked': [
+ 'files': [
'<(DEPTH)/data/',
'<(DEPTH)/resources/',
],
@@ -21,7 +21,7 @@
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/modules_tests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'<(DEPTH)/DEPS',
'<(DEPTH)/resources/audio_coding/testfile32kHz.pcm',
'<(DEPTH)/resources/audio_coding/teststereo32kHz.pcm',
@@ -30,9 +30,6 @@
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/modules_tests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_untracked': [
- '<(DEPTH)/tools/swarming_client/',
- ],
},
}],
],
diff --git a/modules/modules_unittests.isolate b/modules/modules_unittests.isolate
index 09ace1c1..967ff32f 100644
--- a/modules/modules_unittests.isolate
+++ b/modules/modules_unittests.isolate
@@ -9,16 +9,10 @@
'conditions': [
['OS=="android"', {
'variables': {
- 'isolate_dependency_untracked': [
+ 'files': [
'<(DEPTH)/data/',
'<(DEPTH)/resources/',
],
- 'isolate_dependency_tracked': [
- '<(DEPTH)/resources/short_mixed_mono_48.dat',
- '<(DEPTH)/resources/short_mixed_mono_48.pcm',
- '<(DEPTH)/resources/short_mixed_stereo_48.dat',
- '<(DEPTH)/resources/short_mixed_stereo_48.pcm',
- ],
},
}],
['OS=="linux" or OS=="mac" or OS=="win"', {
@@ -27,7 +21,7 @@
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/modules_unittests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'<(DEPTH)/DEPS',
'<(DEPTH)/data/audio_processing/output_data_float.pb',
'<(DEPTH)/data/voice_engine/audio_tiny48.wav',
@@ -105,9 +99,6 @@
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/modules_unittests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_untracked': [
- '<(DEPTH)/tools/swarming_client/',
- ],
},
}],
],
diff --git a/modules/neteq.target.darwin-arm.mk b/modules/neteq.target.darwin-arm.mk
index 4ff035c6..7400e1ef 100644
--- a/modules/neteq.target.darwin-arm.mk
+++ b/modules/neteq.target.darwin-arm.mk
@@ -119,11 +119,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -140,6 +142,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -251,11 +254,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -272,6 +277,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/neteq.target.darwin-arm64.mk b/modules/neteq.target.darwin-arm64.mk
index 62eb70e9..d2f26cde 100644
--- a/modules/neteq.target.darwin-arm64.mk
+++ b/modules/neteq.target.darwin-arm64.mk
@@ -108,11 +108,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -121,11 +123,13 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -225,11 +229,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -238,11 +244,13 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/neteq.target.darwin-mips.mk b/modules/neteq.target.darwin-mips.mk
index 61110cc6..6028d0cc 100644
--- a/modules/neteq.target.darwin-mips.mk
+++ b/modules/neteq.target.darwin-mips.mk
@@ -113,11 +113,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -133,6 +135,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -238,11 +241,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -258,6 +263,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/neteq.target.darwin-mips64.mk b/modules/neteq.target.darwin-mips64.mk
new file mode 100644
index 00000000..44be3d66
--- /dev/null
+++ b/modules/neteq.target.darwin-mips64.mk
@@ -0,0 +1,329 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_neteq_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/neteq/accelerate.cc \
+ third_party/webrtc/modules/audio_coding/neteq/audio_classifier.cc \
+ third_party/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc \
+ third_party/webrtc/modules/audio_coding/neteq/audio_decoder.cc \
+ third_party/webrtc/modules/audio_coding/neteq/audio_multi_vector.cc \
+ third_party/webrtc/modules/audio_coding/neteq/audio_vector.cc \
+ third_party/webrtc/modules/audio_coding/neteq/background_noise.cc \
+ third_party/webrtc/modules/audio_coding/neteq/buffer_level_filter.cc \
+ third_party/webrtc/modules/audio_coding/neteq/comfort_noise.cc \
+ third_party/webrtc/modules/audio_coding/neteq/decision_logic.cc \
+ third_party/webrtc/modules/audio_coding/neteq/decision_logic_fax.cc \
+ third_party/webrtc/modules/audio_coding/neteq/decision_logic_normal.cc \
+ third_party/webrtc/modules/audio_coding/neteq/decoder_database.cc \
+ third_party/webrtc/modules/audio_coding/neteq/delay_manager.cc \
+ third_party/webrtc/modules/audio_coding/neteq/delay_peak_detector.cc \
+ third_party/webrtc/modules/audio_coding/neteq/dsp_helper.cc \
+ third_party/webrtc/modules/audio_coding/neteq/dtmf_buffer.cc \
+ third_party/webrtc/modules/audio_coding/neteq/dtmf_tone_generator.cc \
+ third_party/webrtc/modules/audio_coding/neteq/expand.cc \
+ third_party/webrtc/modules/audio_coding/neteq/merge.cc \
+ third_party/webrtc/modules/audio_coding/neteq/neteq_impl.cc \
+ third_party/webrtc/modules/audio_coding/neteq/neteq.cc \
+ third_party/webrtc/modules/audio_coding/neteq/statistics_calculator.cc \
+ third_party/webrtc/modules/audio_coding/neteq/normal.cc \
+ third_party/webrtc/modules/audio_coding/neteq/packet_buffer.cc \
+ third_party/webrtc/modules/audio_coding/neteq/payload_splitter.cc \
+ third_party/webrtc/modules/audio_coding/neteq/post_decode_vad.cc \
+ third_party/webrtc/modules/audio_coding/neteq/preemptive_expand.cc \
+ third_party/webrtc/modules/audio_coding/neteq/random_vector.cc \
+ third_party/webrtc/modules/audio_coding/neteq/rtcp.cc \
+ third_party/webrtc/modules/audio_coding/neteq/sync_buffer.cc \
+ third_party/webrtc/modules/audio_coding/neteq/timestamp_scaler.cc \
+ third_party/webrtc/modules/audio_coding/neteq/time_stretch.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/opus/src/celt \
+ $(LOCAL_PATH)/third_party/opus/src/src \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g711/include \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g722/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/pcm16b/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/ilbc/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/fix/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/cng/include \
+ $(LOCAL_PATH)/third_party/opus/src/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/opus/src/celt \
+ $(LOCAL_PATH)/third_party/opus/src/src \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g711/include \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g722/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/pcm16b/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/ilbc/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/fix/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/cng/include \
+ $(LOCAL_PATH)/third_party/opus/src/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_neteq_gyp
+
+# Alias gyp target name.
+.PHONY: neteq
+neteq: third_party_webrtc_modules_neteq_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/neteq.target.darwin-x86.mk b/modules/neteq.target.darwin-x86.mk
index d0da44f3..22eef0be 100644
--- a/modules/neteq.target.darwin-x86.mk
+++ b/modules/neteq.target.darwin-x86.mk
@@ -114,11 +114,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -132,6 +134,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -237,11 +240,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -255,6 +260,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/neteq.target.darwin-x86_64.mk b/modules/neteq.target.darwin-x86_64.mk
index 631a8bd4..7c412bbe 100644
--- a/modules/neteq.target.darwin-x86_64.mk
+++ b/modules/neteq.target.darwin-x86_64.mk
@@ -113,11 +113,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -131,6 +133,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -235,11 +238,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -253,6 +258,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/neteq.target.linux-arm.mk b/modules/neteq.target.linux-arm.mk
index 4ff035c6..7400e1ef 100644
--- a/modules/neteq.target.linux-arm.mk
+++ b/modules/neteq.target.linux-arm.mk
@@ -119,11 +119,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -140,6 +142,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -251,11 +254,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -272,6 +277,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/neteq.target.linux-arm64.mk b/modules/neteq.target.linux-arm64.mk
index 62eb70e9..d2f26cde 100644
--- a/modules/neteq.target.linux-arm64.mk
+++ b/modules/neteq.target.linux-arm64.mk
@@ -108,11 +108,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -121,11 +123,13 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -225,11 +229,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -238,11 +244,13 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/neteq.target.linux-mips.mk b/modules/neteq.target.linux-mips.mk
index 61110cc6..6028d0cc 100644
--- a/modules/neteq.target.linux-mips.mk
+++ b/modules/neteq.target.linux-mips.mk
@@ -113,11 +113,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -133,6 +135,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -238,11 +241,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -258,6 +263,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/neteq.target.linux-mips64.mk b/modules/neteq.target.linux-mips64.mk
new file mode 100644
index 00000000..44be3d66
--- /dev/null
+++ b/modules/neteq.target.linux-mips64.mk
@@ -0,0 +1,329 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_neteq_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/neteq/accelerate.cc \
+ third_party/webrtc/modules/audio_coding/neteq/audio_classifier.cc \
+ third_party/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc \
+ third_party/webrtc/modules/audio_coding/neteq/audio_decoder.cc \
+ third_party/webrtc/modules/audio_coding/neteq/audio_multi_vector.cc \
+ third_party/webrtc/modules/audio_coding/neteq/audio_vector.cc \
+ third_party/webrtc/modules/audio_coding/neteq/background_noise.cc \
+ third_party/webrtc/modules/audio_coding/neteq/buffer_level_filter.cc \
+ third_party/webrtc/modules/audio_coding/neteq/comfort_noise.cc \
+ third_party/webrtc/modules/audio_coding/neteq/decision_logic.cc \
+ third_party/webrtc/modules/audio_coding/neteq/decision_logic_fax.cc \
+ third_party/webrtc/modules/audio_coding/neteq/decision_logic_normal.cc \
+ third_party/webrtc/modules/audio_coding/neteq/decoder_database.cc \
+ third_party/webrtc/modules/audio_coding/neteq/delay_manager.cc \
+ third_party/webrtc/modules/audio_coding/neteq/delay_peak_detector.cc \
+ third_party/webrtc/modules/audio_coding/neteq/dsp_helper.cc \
+ third_party/webrtc/modules/audio_coding/neteq/dtmf_buffer.cc \
+ third_party/webrtc/modules/audio_coding/neteq/dtmf_tone_generator.cc \
+ third_party/webrtc/modules/audio_coding/neteq/expand.cc \
+ third_party/webrtc/modules/audio_coding/neteq/merge.cc \
+ third_party/webrtc/modules/audio_coding/neteq/neteq_impl.cc \
+ third_party/webrtc/modules/audio_coding/neteq/neteq.cc \
+ third_party/webrtc/modules/audio_coding/neteq/statistics_calculator.cc \
+ third_party/webrtc/modules/audio_coding/neteq/normal.cc \
+ third_party/webrtc/modules/audio_coding/neteq/packet_buffer.cc \
+ third_party/webrtc/modules/audio_coding/neteq/payload_splitter.cc \
+ third_party/webrtc/modules/audio_coding/neteq/post_decode_vad.cc \
+ third_party/webrtc/modules/audio_coding/neteq/preemptive_expand.cc \
+ third_party/webrtc/modules/audio_coding/neteq/random_vector.cc \
+ third_party/webrtc/modules/audio_coding/neteq/rtcp.cc \
+ third_party/webrtc/modules/audio_coding/neteq/sync_buffer.cc \
+ third_party/webrtc/modules/audio_coding/neteq/timestamp_scaler.cc \
+ third_party/webrtc/modules/audio_coding/neteq/time_stretch.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/opus/src/celt \
+ $(LOCAL_PATH)/third_party/opus/src/src \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g711/include \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g722/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/pcm16b/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/ilbc/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/fix/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/cng/include \
+ $(LOCAL_PATH)/third_party/opus/src/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/opus/src/celt \
+ $(LOCAL_PATH)/third_party/opus/src/src \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g711/include \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/g722/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/pcm16b/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/ilbc/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/isac/fix/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/codecs/cng/include \
+ $(LOCAL_PATH)/third_party/opus/src/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_neteq_gyp
+
+# Alias gyp target name.
+.PHONY: neteq
+neteq: third_party_webrtc_modules_neteq_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/neteq.target.linux-x86.mk b/modules/neteq.target.linux-x86.mk
index d0da44f3..22eef0be 100644
--- a/modules/neteq.target.linux-x86.mk
+++ b/modules/neteq.target.linux-x86.mk
@@ -114,11 +114,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -132,6 +134,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -237,11 +240,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -255,6 +260,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/neteq.target.linux-x86_64.mk b/modules/neteq.target.linux-x86_64.mk
index 631a8bd4..7c412bbe 100644
--- a/modules/neteq.target.linux-x86_64.mk
+++ b/modules/neteq.target.linux-x86_64.mk
@@ -113,11 +113,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -131,6 +133,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -235,11 +238,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -253,6 +258,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_CODEC_OPUS' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/paced_sender.target.darwin-arm.mk b/modules/paced_sender.target.darwin-arm.mk
index 4c6cb676..4e335d78 100644
--- a/modules/paced_sender.target.darwin-arm.mk
+++ b/modules/paced_sender.target.darwin-arm.mk
@@ -24,6 +24,7 @@ LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/pacing/bitrate_prober.cc \
third_party/webrtc/modules/pacing/paced_sender.cc
@@ -87,11 +88,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +110,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -204,11 +208,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -224,6 +230,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/paced_sender.target.darwin-arm64.mk b/modules/paced_sender.target.darwin-arm64.mk
index ea0eb7b4..47599476 100644
--- a/modules/paced_sender.target.darwin-arm64.mk
+++ b/modules/paced_sender.target.darwin-arm64.mk
@@ -24,6 +24,7 @@ LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/pacing/bitrate_prober.cc \
third_party/webrtc/modules/pacing/paced_sender.cc
@@ -76,11 +77,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -89,10 +92,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -178,11 +183,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -191,10 +198,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/paced_sender.target.darwin-mips.mk b/modules/paced_sender.target.darwin-mips.mk
index 9a3c2d80..6dab91ab 100644
--- a/modules/paced_sender.target.darwin-mips.mk
+++ b/modules/paced_sender.target.darwin-mips.mk
@@ -24,6 +24,7 @@ LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/pacing/bitrate_prober.cc \
third_party/webrtc/modules/pacing/paced_sender.cc
@@ -81,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +195,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -210,6 +216,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/paced_sender.target.darwin-mips64.mk b/modules/paced_sender.target.darwin-mips64.mk
new file mode 100644
index 00000000..62477c3a
--- /dev/null
+++ b/modules/paced_sender.target.darwin-mips64.mk
@@ -0,0 +1,268 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_paced_sender_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/pacing/bitrate_prober.cc \
+ third_party/webrtc/modules/pacing/paced_sender.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_paced_sender_gyp
+
+# Alias gyp target name.
+.PHONY: paced_sender
+paced_sender: third_party_webrtc_modules_paced_sender_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/paced_sender.target.darwin-x86.mk b/modules/paced_sender.target.darwin-x86.mk
index 2a90a58e..7e392bb3 100644
--- a/modules/paced_sender.target.darwin-x86.mk
+++ b/modules/paced_sender.target.darwin-x86.mk
@@ -24,6 +24,7 @@ LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/pacing/bitrate_prober.cc \
third_party/webrtc/modules/pacing/paced_sender.cc
@@ -82,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -190,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -207,6 +213,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/paced_sender.target.darwin-x86_64.mk b/modules/paced_sender.target.darwin-x86_64.mk
index b7269cb4..6a9b5633 100644
--- a/modules/paced_sender.target.darwin-x86_64.mk
+++ b/modules/paced_sender.target.darwin-x86_64.mk
@@ -24,6 +24,7 @@ LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/pacing/bitrate_prober.cc \
third_party/webrtc/modules/pacing/paced_sender.cc
@@ -81,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -188,11 +192,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -205,6 +211,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/paced_sender.target.linux-arm.mk b/modules/paced_sender.target.linux-arm.mk
index 4c6cb676..4e335d78 100644
--- a/modules/paced_sender.target.linux-arm.mk
+++ b/modules/paced_sender.target.linux-arm.mk
@@ -24,6 +24,7 @@ LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/pacing/bitrate_prober.cc \
third_party/webrtc/modules/pacing/paced_sender.cc
@@ -87,11 +88,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +110,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -204,11 +208,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -224,6 +230,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/paced_sender.target.linux-arm64.mk b/modules/paced_sender.target.linux-arm64.mk
index ea0eb7b4..47599476 100644
--- a/modules/paced_sender.target.linux-arm64.mk
+++ b/modules/paced_sender.target.linux-arm64.mk
@@ -24,6 +24,7 @@ LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/pacing/bitrate_prober.cc \
third_party/webrtc/modules/pacing/paced_sender.cc
@@ -76,11 +77,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -89,10 +92,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -178,11 +183,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -191,10 +198,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/paced_sender.target.linux-mips.mk b/modules/paced_sender.target.linux-mips.mk
index 9a3c2d80..6dab91ab 100644
--- a/modules/paced_sender.target.linux-mips.mk
+++ b/modules/paced_sender.target.linux-mips.mk
@@ -24,6 +24,7 @@ LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/pacing/bitrate_prober.cc \
third_party/webrtc/modules/pacing/paced_sender.cc
@@ -81,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +195,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -210,6 +216,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/paced_sender.target.linux-mips64.mk b/modules/paced_sender.target.linux-mips64.mk
new file mode 100644
index 00000000..62477c3a
--- /dev/null
+++ b/modules/paced_sender.target.linux-mips64.mk
@@ -0,0 +1,268 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_paced_sender_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/pacing/bitrate_prober.cc \
+ third_party/webrtc/modules/pacing/paced_sender.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_paced_sender_gyp
+
+# Alias gyp target name.
+.PHONY: paced_sender
+paced_sender: third_party_webrtc_modules_paced_sender_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/paced_sender.target.linux-x86.mk b/modules/paced_sender.target.linux-x86.mk
index 2a90a58e..7e392bb3 100644
--- a/modules/paced_sender.target.linux-x86.mk
+++ b/modules/paced_sender.target.linux-x86.mk
@@ -24,6 +24,7 @@ LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/pacing/bitrate_prober.cc \
third_party/webrtc/modules/pacing/paced_sender.cc
@@ -82,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -190,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -207,6 +213,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/paced_sender.target.linux-x86_64.mk b/modules/paced_sender.target.linux-x86_64.mk
index b7269cb4..6a9b5633 100644
--- a/modules/paced_sender.target.linux-x86_64.mk
+++ b/modules/paced_sender.target.linux-x86_64.mk
@@ -24,6 +24,7 @@ LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/pacing/bitrate_prober.cc \
third_party/webrtc/modules/pacing/paced_sender.cc
@@ -81,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -188,11 +192,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -205,6 +211,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/pacing/BUILD.gn b/modules/pacing/BUILD.gn
index 58a73aea..aa44b0da 100644
--- a/modules/pacing/BUILD.gn
+++ b/modules/pacing/BUILD.gn
@@ -9,6 +9,8 @@
source_set("pacing") {
sources = [
"include/paced_sender.h",
+ "bitrate_prober.cc",
+ "bitrate_prober.h",
"paced_sender.cc",
]
diff --git a/modules/pacing/bitrate_prober.cc b/modules/pacing/bitrate_prober.cc
new file mode 100644
index 00000000..04e71c5c
--- /dev/null
+++ b/modules/pacing/bitrate_prober.cc
@@ -0,0 +1,120 @@
+/*
+ * 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 "webrtc/modules/pacing/bitrate_prober.h"
+
+#include <assert.h>
+#include <limits>
+#include <sstream>
+
+#include "webrtc/system_wrappers/interface/logging.h"
+
+namespace webrtc {
+
+namespace {
+int ComputeDeltaFromBitrate(size_t packet_size, int bitrate_bps) {
+ assert(bitrate_bps > 0);
+ // Compute the time delta needed to send packet_size bytes at bitrate_bps
+ // bps. Result is in milliseconds.
+ return static_cast<int>(1000ll * static_cast<int64_t>(packet_size) * 8ll /
+ bitrate_bps);
+}
+} // namespace
+
+BitrateProber::BitrateProber()
+ : probing_state_(kDisabled),
+ packet_size_last_send_(0),
+ time_last_send_ms_(-1) {
+}
+
+void BitrateProber::SetEnabled(bool enable) {
+ if (enable) {
+ if (probing_state_ == kDisabled) {
+ probing_state_ = kAllowedToProbe;
+ LOG(LS_INFO) << "Initial bandwidth probing enabled";
+ }
+ } else {
+ probing_state_ = kDisabled;
+ LOG(LS_INFO) << "Initial bandwidth probing disabled";
+ }
+}
+
+bool BitrateProber::IsProbing() const {
+ return probing_state_ == kProbing;
+}
+
+void BitrateProber::MaybeInitializeProbe(int bitrate_bps) {
+ if (probing_state_ != kAllowedToProbe)
+ return;
+ probe_bitrates_.clear();
+ // Max number of packets used for probing.
+ const int kMaxProbeLength = 15;
+ const int kMaxNumProbes = 3;
+ const int kPacketsPerProbe = kMaxProbeLength / kMaxNumProbes;
+ const float kProbeBitrateMultipliers[kMaxNumProbes] = {2.5, 4, 6};
+ int bitrates_bps[kMaxNumProbes];
+ std::stringstream bitrate_log;
+ bitrate_log << "Start probing for bandwidth, bitrates:";
+ for (int i = 0; i < kMaxNumProbes; ++i) {
+ bitrates_bps[i] = kProbeBitrateMultipliers[i] * bitrate_bps;
+ bitrate_log << " " << bitrates_bps[i];
+ for (int j = 0; j < kPacketsPerProbe; ++j)
+ probe_bitrates_.push_back(bitrates_bps[i]);
+ }
+ bitrate_log << ", num packets: " << probe_bitrates_.size();
+ LOG(LS_INFO) << bitrate_log.str().c_str();
+ probing_state_ = kProbing;
+}
+
+int BitrateProber::TimeUntilNextProbe(int64_t now_ms) {
+ if (probing_state_ != kDisabled && probe_bitrates_.empty()) {
+ probing_state_ = kWait;
+ }
+ if (probe_bitrates_.empty()) {
+ // No probe started, or waiting for next probe.
+ return std::numeric_limits<int>::max();
+ }
+ int64_t elapsed_time_ms = now_ms - time_last_send_ms_;
+ // We will send the first probe packet immediately if no packet has been
+ // sent before.
+ int time_until_probe_ms = 0;
+ if (packet_size_last_send_ > 0 && probing_state_ == kProbing) {
+ int next_delta_ms = ComputeDeltaFromBitrate(packet_size_last_send_,
+ probe_bitrates_.front());
+ time_until_probe_ms = next_delta_ms - elapsed_time_ms;
+ // There is no point in trying to probe with less than 1 ms between packets
+ // as it essentially means trying to probe at infinite bandwidth.
+ const int kMinProbeDeltaMs = 1;
+ // If we have waited more than 3 ms for a new packet to probe with we will
+ // consider this probing session over.
+ const int kMaxProbeDelayMs = 3;
+ if (next_delta_ms < kMinProbeDeltaMs ||
+ time_until_probe_ms < -kMaxProbeDelayMs) {
+ // We currently disable probing after the first probe, as we only want
+ // to probe at the beginning of a connection. We should set this to
+ // kWait if we later want to probe periodically.
+ probing_state_ = kWait;
+ LOG(LS_INFO) << "Next delta too small, stop probing.";
+ time_until_probe_ms = 0;
+ }
+ }
+ return time_until_probe_ms;
+}
+
+void BitrateProber::PacketSent(int64_t now_ms, size_t packet_size) {
+ assert(packet_size > 0);
+ packet_size_last_send_ = packet_size;
+ time_last_send_ms_ = now_ms;
+ if (probing_state_ != kProbing)
+ return;
+ if (!probe_bitrates_.empty())
+ probe_bitrates_.pop_front();
+}
+} // namespace webrtc
diff --git a/modules/pacing/bitrate_prober.h b/modules/pacing/bitrate_prober.h
new file mode 100644
index 00000000..04a85805
--- /dev/null
+++ b/modules/pacing/bitrate_prober.h
@@ -0,0 +1,57 @@
+/*
+ * 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 WEBRTC_MODULES_PACING_BITRATE_PROBER_H_
+#define WEBRTC_MODULES_PACING_BITRATE_PROBER_H_
+
+#include <cstddef>
+#include <list>
+
+#include "webrtc/typedefs.h"
+
+namespace webrtc {
+
+// Note that this class isn't thread-safe by itself and therefore relies
+// on being protected by the caller.
+class BitrateProber {
+ public:
+ BitrateProber();
+
+ void SetEnabled(bool enable);
+
+ // Returns true if the prober is in a probing session, i.e., it currently
+ // wants packets to be sent out according to the time returned by
+ // TimeUntilNextProbe().
+ bool IsProbing() const;
+
+ // Initializes a new probing session if the prober is allowed to probe.
+ void MaybeInitializeProbe(int bitrate_bps);
+
+ // Returns the number of milliseconds until the next packet should be sent to
+ // get accurate probing.
+ int TimeUntilNextProbe(int64_t now_ms);
+
+ // Called to report to the prober that a packet has been sent, which helps the
+ // prober know when to move to the next packet in a probe.
+ void PacketSent(int64_t now_ms, size_t packet_size);
+
+ private:
+ enum ProbingState { kDisabled, kAllowedToProbe, kProbing, kWait };
+
+ ProbingState probing_state_;
+ // Probe bitrate per packet. These are used to compute the delta relative to
+ // the previous probe packet based on the size and time when that packet was
+ // sent.
+ std::list<int> probe_bitrates_;
+ size_t packet_size_last_send_;
+ int64_t time_last_send_ms_;
+};
+} // namespace webrtc
+#endif // WEBRTC_MODULES_PACING_BITRATE_PROBER_H_
diff --git a/modules/pacing/bitrate_prober_unittest.cc b/modules/pacing/bitrate_prober_unittest.cc
new file mode 100644
index 00000000..15b1cc58
--- /dev/null
+++ b/modules/pacing/bitrate_prober_unittest.cc
@@ -0,0 +1,57 @@
+/*
+ * 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 <limits>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/modules/pacing/bitrate_prober.h"
+
+namespace webrtc {
+
+TEST(BitrateProberTest, VerifyStatesAndTimeBetweenProbes) {
+ BitrateProber prober;
+ EXPECT_FALSE(prober.IsProbing());
+ int64_t now_ms = 0;
+ EXPECT_EQ(std::numeric_limits<int>::max(), prober.TimeUntilNextProbe(now_ms));
+
+ prober.SetEnabled(true);
+ EXPECT_FALSE(prober.IsProbing());
+
+ prober.MaybeInitializeProbe(300000);
+ EXPECT_TRUE(prober.IsProbing());
+
+ EXPECT_EQ(0, prober.TimeUntilNextProbe(now_ms));
+ prober.PacketSent(now_ms, 1000);
+
+ for (int i = 0; i < 4; ++i) {
+ EXPECT_EQ(10, prober.TimeUntilNextProbe(now_ms));
+ now_ms += 5;
+ EXPECT_EQ(5, prober.TimeUntilNextProbe(now_ms));
+ now_ms += 5;
+ EXPECT_EQ(0, prober.TimeUntilNextProbe(now_ms));
+ prober.PacketSent(now_ms, 1000);
+ }
+ for (int i = 0; i < 5; ++i) {
+ EXPECT_EQ(6, prober.TimeUntilNextProbe(now_ms));
+ now_ms += 6;
+ EXPECT_EQ(0, prober.TimeUntilNextProbe(now_ms));
+ prober.PacketSent(now_ms, 1000);
+ }
+ for (int i = 0; i < 5; ++i) {
+ EXPECT_EQ(4, prober.TimeUntilNextProbe(now_ms));
+ now_ms += 4;
+ EXPECT_EQ(0, prober.TimeUntilNextProbe(now_ms));
+ prober.PacketSent(now_ms, 1000);
+ }
+
+ EXPECT_EQ(std::numeric_limits<int>::max(), prober.TimeUntilNextProbe(now_ms));
+ EXPECT_FALSE(prober.IsProbing());
+}
+} // namespace webrtc
diff --git a/modules/pacing/include/mock/mock_paced_sender.h b/modules/pacing/include/mock/mock_paced_sender.h
index 6600a929..0c9e354d 100644
--- a/modules/pacing/include/mock/mock_paced_sender.h
+++ b/modules/pacing/include/mock/mock_paced_sender.h
@@ -22,7 +22,7 @@ namespace webrtc {
class MockPacedSender : public PacedSender {
public:
- MockPacedSender() : PacedSender(Clock::GetRealTimeClock(), NULL, 0, 0) {}
+ MockPacedSender() : PacedSender(Clock::GetRealTimeClock(), NULL, 0, 0, 0) {}
MOCK_METHOD6(SendPacket, bool(Priority priority,
uint32_t ssrc,
uint16_t sequence_number,
diff --git a/modules/pacing/include/paced_sender.h b/modules/pacing/include/paced_sender.h
index 14a3a3d4..d7efb8ea 100644
--- a/modules/pacing/include/paced_sender.h
+++ b/modules/pacing/include/paced_sender.h
@@ -8,8 +8,8 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#ifndef WEBRTC_MODULES_PACED_SENDER_H_
-#define WEBRTC_MODULES_PACED_SENDER_H_
+#ifndef WEBRTC_MODULES_PACING_INCLUDE_PACED_SENDER_H_
+#define WEBRTC_MODULES_PACING_INCLUDE_PACED_SENDER_H_
#include <list>
#include <set>
@@ -20,13 +20,14 @@
#include "webrtc/typedefs.h"
namespace webrtc {
+class BitrateProber;
class Clock;
class CriticalSectionWrapper;
namespace paced_sender {
class IntervalBudget;
struct Packet;
-class PacketList;
+class PacketQueue;
} // namespace paced_sender
class PacedSender : public Module {
@@ -67,7 +68,10 @@ class PacedSender : public Module {
// overshoots from the encoder.
static const float kDefaultPaceMultiplier;
- PacedSender(Clock* clock, Callback* callback, int max_bitrate_kbps,
+ PacedSender(Clock* clock,
+ Callback* callback,
+ int bitrate_kbps,
+ int max_bitrate_kbps,
int min_bitrate_kbps);
virtual ~PacedSender();
@@ -83,9 +87,14 @@ class PacedSender : public Module {
// Resume sending packets.
void Resume();
- // Set target bitrates for the pacer. Padding packets will be utilized to
- // reach |min_bitrate| unless enough media packets are available.
- void UpdateBitrate(int max_bitrate_kbps, int min_bitrate_kbps);
+ // Set target bitrates for the pacer.
+ // We will pace out bursts of packets at a bitrate of |max_bitrate_kbps|.
+ // |bitrate_kbps| is our estimate of what we are allowed to send on average.
+ // Padding packets will be utilized to reach |min_bitrate| unless enough media
+ // packets are available.
+ void UpdateBitrate(int bitrate_kbps,
+ int max_bitrate_kbps,
+ int min_bitrate_kbps);
// Returns true if we send the packet now, else it will add the packet
// information to the queue and call TimeToSendPacket when it's time to send.
@@ -96,13 +105,15 @@ class PacedSender : public Module {
int bytes,
bool retransmission);
- // Sets the max length of the pacer queue in milliseconds.
- // A negative queue size is interpreted as infinite.
- virtual void set_max_queue_length_ms(int max_queue_length_ms);
-
// Returns the time since the oldest queued packet was enqueued.
virtual int QueueInMs() const;
+ virtual size_t QueueSizePackets() const;
+
+ // Returns the number of milliseconds it will take to send the current
+ // packets in the queue, given the current size and bitrate, ignoring prio.
+ virtual int ExpectedQueueTimeMs() const;
+
// Returns the number of milliseconds until the module want a worker thread
// to call Process.
virtual int32_t TimeUntilNextProcess() OVERRIDE;
@@ -110,25 +121,17 @@ class PacedSender : public Module {
// Process any pending packets in the queue(s).
virtual int32_t Process() OVERRIDE;
- private:
- // Return true if next packet in line should be transmitted.
- // Return packet list that contains the next packet.
- bool ShouldSendNextPacket(paced_sender::PacketList** packet_list)
- EXCLUSIVE_LOCKS_REQUIRED(critsect_);
-
- // Local helper function to GetNextPacket.
- paced_sender::Packet GetNextPacketFromList(paced_sender::PacketList* packets)
- EXCLUSIVE_LOCKS_REQUIRED(critsect_);
-
- bool SendPacketFromList(paced_sender::PacketList* packet_list)
- EXCLUSIVE_LOCKS_REQUIRED(critsect_);
+ protected:
+ virtual bool ProbingExperimentIsEnabled() const;
+ private:
// Updates the number of bytes that can be sent for the next time interval.
void UpdateBytesPerInterval(uint32_t delta_time_in_ms)
EXCLUSIVE_LOCKS_REQUIRED(critsect_);
- // Updates the buffers with the number of bytes that we sent.
- void UpdateMediaBytesSent(int num_bytes) EXCLUSIVE_LOCKS_REQUIRED(critsect_);
+ bool SendPacket(const paced_sender::Packet& packet)
+ EXCLUSIVE_LOCKS_REQUIRED(critsect_);
+ void SendPadding(int padding_needed) EXCLUSIVE_LOCKS_REQUIRED(critsect_);
Clock* const clock_;
Callback* const callback_;
@@ -136,7 +139,6 @@ class PacedSender : public Module {
scoped_ptr<CriticalSectionWrapper> critsect_;
bool enabled_ GUARDED_BY(critsect_);
bool paused_ GUARDED_BY(critsect_);
- int max_queue_length_ms_ GUARDED_BY(critsect_);
// This is the media budget, keeping track of how many bits of media
// we can pace out during the current interval.
scoped_ptr<paced_sender::IntervalBudget> media_budget_ GUARDED_BY(critsect_);
@@ -146,17 +148,13 @@ class PacedSender : public Module {
scoped_ptr<paced_sender::IntervalBudget> padding_budget_
GUARDED_BY(critsect_);
+ scoped_ptr<BitrateProber> prober_ GUARDED_BY(critsect_);
+ int bitrate_bps_ GUARDED_BY(critsect_);
+
int64_t time_last_update_us_ GUARDED_BY(critsect_);
- int64_t time_last_send_us_ GUARDED_BY(critsect_);
- int64_t capture_time_ms_last_queued_ GUARDED_BY(critsect_);
- int64_t capture_time_ms_last_sent_ GUARDED_BY(critsect_);
- scoped_ptr<paced_sender::PacketList> high_priority_packets_
- GUARDED_BY(critsect_);
- scoped_ptr<paced_sender::PacketList> normal_priority_packets_
- GUARDED_BY(critsect_);
- scoped_ptr<paced_sender::PacketList> low_priority_packets_
- GUARDED_BY(critsect_);
+ scoped_ptr<paced_sender::PacketQueue> packets_ GUARDED_BY(critsect_);
+ uint64_t packet_counter_ GUARDED_BY(critsect_);
};
} // namespace webrtc
-#endif // WEBRTC_MODULES_PACED_SENDER_H_
+#endif // WEBRTC_MODULES_PACING_INCLUDE_PACED_SENDER_H_
diff --git a/modules/pacing/paced_sender.cc b/modules/pacing/paced_sender.cc
index 6204a9a0..a071ffcc 100644
--- a/modules/pacing/paced_sender.cc
+++ b/modules/pacing/paced_sender.cc
@@ -13,11 +13,15 @@
#include <assert.h>
#include <map>
+#include <queue>
#include <set>
#include "webrtc/modules/interface/module_common_types.h"
+#include "webrtc/modules/pacing/bitrate_prober.h"
#include "webrtc/system_wrappers/interface/clock.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
+#include "webrtc/system_wrappers/interface/field_trial.h"
+#include "webrtc/system_wrappers/interface/logging.h"
#include "webrtc/system_wrappers/interface/trace_event.h"
namespace {
@@ -28,69 +32,140 @@ const int kMinPacketLimitMs = 5;
// time.
const int kMaxIntervalTimeMs = 30;
-// Max time that the first packet in the queue can sit in the queue if no
-// packets are sent, regardless of buffer state. In practice only in effect at
-// low bitrates (less than 320 kbits/s).
-const int kMaxQueueTimeWithoutSendingUs = 30000;
-
} // namespace
namespace webrtc {
namespace paced_sender {
struct Packet {
- Packet(uint32_t ssrc,
+ Packet(PacedSender::Priority priority,
+ uint32_t ssrc,
uint16_t seq_number,
int64_t capture_time_ms,
int64_t enqueue_time_ms,
int length_in_bytes,
- bool retransmission)
- : ssrc(ssrc),
+ bool retransmission,
+ uint64_t enqueue_order)
+ : priority(priority),
+ ssrc(ssrc),
sequence_number(seq_number),
capture_time_ms(capture_time_ms),
enqueue_time_ms(enqueue_time_ms),
bytes(length_in_bytes),
- retransmission(retransmission) {}
+ retransmission(retransmission),
+ enqueue_order(enqueue_order) {}
+
+ PacedSender::Priority priority;
uint32_t ssrc;
uint16_t sequence_number;
int64_t capture_time_ms;
int64_t enqueue_time_ms;
int bytes;
bool retransmission;
+ uint64_t enqueue_order;
+ std::list<Packet>::iterator this_it;
};
-// STL list style class which prevents duplicates in the list.
-class PacketList {
+// Used by priority queue to sort packets.
+struct Comparator {
+ bool operator()(const Packet* first, const Packet* second) {
+ // Highest prio = 0.
+ if (first->priority != second->priority)
+ return first->priority > second->priority;
+
+ // Retransmissions go first.
+ if (second->retransmission && !first->retransmission)
+ return true;
+
+ // Older frames have higher prio.
+ if (first->capture_time_ms != second->capture_time_ms)
+ return first->capture_time_ms > second->capture_time_ms;
+
+ return first->enqueue_order > second->enqueue_order;
+ }
+};
+
+// Class encapsulating a priority queue with some extensions.
+class PacketQueue {
public:
- PacketList() {};
+ PacketQueue() : bytes_(0) {}
+ virtual ~PacketQueue() {}
+
+ void Push(const Packet& packet) {
+ if (!AddToDupeSet(packet))
+ return;
+
+ // Store packet in list, use pointers in priority queue for cheaper moves.
+ // Packets have a handle to its own iterator in the list, for easy removal
+ // when popping from queue.
+ packet_list_.push_front(packet);
+ std::list<Packet>::iterator it = packet_list_.begin();
+ it->this_it = it; // Handle for direct removal from list.
+ prio_queue_.push(&(*it)); // Pointer into list.
+ bytes_ += packet.bytes;
+ }
- bool empty() const {
- return packet_list_.empty();
+ const Packet& BeginPop() {
+ const Packet& packet = *prio_queue_.top();
+ prio_queue_.pop();
+ return packet;
}
- Packet front() const {
- return packet_list_.front();
+ void CancelPop(const Packet& packet) { prio_queue_.push(&(*packet.this_it)); }
+
+ void FinalizePop(const Packet& packet) {
+ RemoveFromDupeSet(packet);
+ bytes_ -= packet.bytes;
+ packet_list_.erase(packet.this_it);
}
- void pop_front() {
- Packet& packet = packet_list_.front();
- uint16_t sequence_number = packet.sequence_number;
- uint32_t ssrc = packet.ssrc;
- packet_list_.pop_front();
- sequence_number_set_[ssrc].erase(sequence_number);
+ bool Empty() const { return prio_queue_.empty(); }
+
+ size_t SizeInPackets() const { return prio_queue_.size(); }
+
+ uint32_t SizeInBytes() const { return bytes_; }
+
+ int64_t OldestEnqueueTime() const {
+ std::list<Packet>::const_reverse_iterator it = packet_list_.rbegin();
+ if (it == packet_list_.rend())
+ return 0;
+ return it->enqueue_time_ms;
}
- void push_back(const Packet& packet) {
- if (sequence_number_set_[packet.ssrc].find(packet.sequence_number) ==
- sequence_number_set_[packet.ssrc].end()) {
- // Don't insert duplicates.
- packet_list_.push_back(packet);
- sequence_number_set_[packet.ssrc].insert(packet.sequence_number);
+ private:
+ // Try to add a packet to the set of ssrc/seqno identifiers currently in the
+ // queue. Return true if inserted, false if this is a duplicate.
+ bool AddToDupeSet(const Packet& packet) {
+ SsrcSeqNoMap::iterator it = dupe_map_.find(packet.ssrc);
+ if (it == dupe_map_.end()) {
+ // First for this ssrc, just insert.
+ dupe_map_[packet.ssrc].insert(packet.sequence_number);
+ return true;
}
+
+ // Insert returns a pair, where second is a bool set to true if new element.
+ return it->second.insert(packet.sequence_number).second;
}
- private:
+ void RemoveFromDupeSet(const Packet& packet) {
+ SsrcSeqNoMap::iterator it = dupe_map_.find(packet.ssrc);
+ assert(it != dupe_map_.end());
+ it->second.erase(packet.sequence_number);
+ if (it->second.empty()) {
+ dupe_map_.erase(it);
+ }
+ }
+
+ // List of packets, in the order the were enqueued. Since dequeueing may
+ // occur out of order, use list instead of vector.
std::list<Packet> packet_list_;
- std::map<uint32_t, std::set<uint16_t> > sequence_number_set_;
+ // Priority queue of the packets, sorted according to Comparator.
+ // Use pointers into list, to avoid moving whole struct within heap.
+ std::priority_queue<Packet*, std::vector<Packet*>, Comparator> prio_queue_;
+ // Total number of bytes in the queue.
+ uint64_t bytes_;
+ // Map<ssrc, set<seq_no> >, for checking duplicates.
+ typedef std::map<uint32_t, std::set<uint16_t> > SsrcSeqNoMap;
+ SsrcSeqNoMap dupe_map_;
};
class IntervalBudget {
@@ -121,6 +196,8 @@ class IntervalBudget {
int bytes_remaining() const { return bytes_remaining_; }
+ int target_rate_kbps() const { return target_rate_kbps_; }
+
private:
int target_rate_kbps_;
int bytes_remaining_;
@@ -131,6 +208,7 @@ const float PacedSender::kDefaultPaceMultiplier = 2.5f;
PacedSender::PacedSender(Clock* clock,
Callback* callback,
+ int bitrate_kbps,
int max_bitrate_kbps,
int min_bitrate_kbps)
: clock_(clock),
@@ -138,15 +216,13 @@ PacedSender::PacedSender(Clock* clock,
critsect_(CriticalSectionWrapper::CreateCriticalSection()),
enabled_(true),
paused_(false),
- max_queue_length_ms_(kDefaultMaxQueueLengthMs),
media_budget_(new paced_sender::IntervalBudget(max_bitrate_kbps)),
padding_budget_(new paced_sender::IntervalBudget(min_bitrate_kbps)),
+ prober_(new BitrateProber()),
+ bitrate_bps_(1000 * bitrate_kbps),
time_last_update_us_(clock->TimeInMicroseconds()),
- capture_time_ms_last_queued_(0),
- capture_time_ms_last_sent_(0),
- high_priority_packets_(new paced_sender::PacketList),
- normal_priority_packets_(new paced_sender::PacketList),
- low_priority_packets_(new paced_sender::PacketList) {
+ packets_(new paced_sender::PacketQueue()),
+ packet_counter_(0) {
UpdateBytesPerInterval(kMinPacketLimitMs);
}
@@ -172,11 +248,13 @@ bool PacedSender::Enabled() const {
return enabled_;
}
-void PacedSender::UpdateBitrate(int max_bitrate_kbps,
+void PacedSender::UpdateBitrate(int bitrate_kbps,
+ int max_bitrate_kbps,
int min_bitrate_kbps) {
CriticalSectionScoped cs(critsect_.get());
media_budget_->set_target_rate_kbps(max_bitrate_kbps);
padding_budget_->set_target_rate_kbps(min_bitrate_kbps);
+ bitrate_bps_ = 1000 * bitrate_kbps;
}
bool PacedSender::SendPacket(Priority priority, uint32_t ssrc,
@@ -187,69 +265,51 @@ bool PacedSender::SendPacket(Priority priority, uint32_t ssrc,
if (!enabled_) {
return true; // We can send now.
}
+ // Enable probing if the probing experiment is enabled.
+ if (!prober_->IsProbing() && ProbingExperimentIsEnabled()) {
+ prober_->SetEnabled(true);
+ }
+ prober_->MaybeInitializeProbe(bitrate_bps_);
+
if (capture_time_ms < 0) {
capture_time_ms = clock_->TimeInMilliseconds();
}
- if (priority != kHighPriority &&
- capture_time_ms > capture_time_ms_last_queued_) {
- capture_time_ms_last_queued_ = capture_time_ms;
- TRACE_EVENT_ASYNC_BEGIN1("webrtc_rtp", "PacedSend", capture_time_ms,
- "capture_time_ms", capture_time_ms);
- }
- paced_sender::PacketList* packet_list = NULL;
- switch (priority) {
- case kHighPriority:
- packet_list = high_priority_packets_.get();
- break;
- case kNormalPriority:
- packet_list = normal_priority_packets_.get();
- break;
- case kLowPriority:
- packet_list = low_priority_packets_.get();
- break;
- }
- packet_list->push_back(paced_sender::Packet(ssrc,
- sequence_number,
- capture_time_ms,
- clock_->TimeInMilliseconds(),
- bytes,
- retransmission));
+
+ packets_->Push(paced_sender::Packet(
+ priority, ssrc, sequence_number, capture_time_ms,
+ clock_->TimeInMilliseconds(), bytes, retransmission, packet_counter_++));
return false;
}
-void PacedSender::set_max_queue_length_ms(int max_queue_length_ms) {
+int PacedSender::ExpectedQueueTimeMs() const {
CriticalSectionScoped cs(critsect_.get());
- max_queue_length_ms_ = max_queue_length_ms;
+ int target_rate = media_budget_->target_rate_kbps();
+ assert(target_rate > 0);
+ return packets_->SizeInBytes() * 8 / target_rate;
+}
+
+size_t PacedSender::QueueSizePackets() const {
+ CriticalSectionScoped cs(critsect_.get());
+ return packets_->SizeInPackets();
}
int PacedSender::QueueInMs() const {
CriticalSectionScoped cs(critsect_.get());
- int64_t now_ms = clock_->TimeInMilliseconds();
- int64_t oldest_packet_enqueue_time = now_ms;
- if (!high_priority_packets_->empty()) {
- oldest_packet_enqueue_time =
- std::min(oldest_packet_enqueue_time,
- high_priority_packets_->front().enqueue_time_ms);
- }
- if (!normal_priority_packets_->empty()) {
- oldest_packet_enqueue_time =
- std::min(oldest_packet_enqueue_time,
- normal_priority_packets_->front().enqueue_time_ms);
- }
- if (!low_priority_packets_->empty()) {
- oldest_packet_enqueue_time =
- std::min(oldest_packet_enqueue_time,
- low_priority_packets_->front().enqueue_time_ms);
- }
- return now_ms - oldest_packet_enqueue_time;
+
+ int64_t oldest_packet = packets_->OldestEnqueueTime();
+ if (oldest_packet == 0)
+ return 0;
+
+ return clock_->TimeInMilliseconds() - oldest_packet;
}
int32_t PacedSender::TimeUntilNextProcess() {
CriticalSectionScoped cs(critsect_.get());
- int64_t elapsed_time_ms = (clock_->TimeInMicroseconds() -
- time_last_update_us_ + 500) / 1000;
- if (elapsed_time_ms <= 0) {
- return kMinPacketLimitMs;
+ int64_t elapsed_time_us = clock_->TimeInMicroseconds() - time_last_update_us_;
+ int elapsed_time_ms = static_cast<int>((elapsed_time_us + 500) / 1000);
+ if (prober_->IsProbing()) {
+ int next_probe = prober_->TimeUntilNextProbe(clock_->TimeInMilliseconds());
+ return next_probe;
}
if (elapsed_time_ms >= kMinPacketLimitMs) {
return 0;
@@ -270,122 +330,70 @@ int32_t PacedSender::Process() {
uint32_t delta_time_ms = std::min(kMaxIntervalTimeMs, elapsed_time_ms);
UpdateBytesPerInterval(delta_time_ms);
}
- paced_sender::PacketList* packet_list;
- while (ShouldSendNextPacket(&packet_list)) {
- if (!SendPacketFromList(packet_list))
+
+ while (!packets_->Empty()) {
+ if (media_budget_->bytes_remaining() <= 0 && !prober_->IsProbing())
+ return 0;
+
+ // Since we need to release the lock in order to send, we first pop the
+ // element from the priority queue but keep it in storage, so that we can
+ // reinsert it if send fails.
+ const paced_sender::Packet& packet = packets_->BeginPop();
+ if (SendPacket(packet)) {
+ // Send succeeded, remove it from the queue.
+ packets_->FinalizePop(packet);
+ if (prober_->IsProbing())
+ return 0;
+ } else {
+ // Send failed, put it back into the queue.
+ packets_->CancelPop(packet);
return 0;
+ }
}
- if (high_priority_packets_->empty() &&
- normal_priority_packets_->empty() &&
- low_priority_packets_->empty() &&
- padding_budget_->bytes_remaining() > 0) {
- int padding_needed = padding_budget_->bytes_remaining();
- critsect_->Leave();
- int bytes_sent = callback_->TimeToSendPadding(padding_needed);
- critsect_->Enter();
- media_budget_->UseBudget(bytes_sent);
- padding_budget_->UseBudget(bytes_sent);
+
+ int padding_needed = padding_budget_->bytes_remaining();
+ if (padding_needed > 0) {
+ SendPadding(padding_needed);
}
}
return 0;
}
-bool PacedSender::SendPacketFromList(paced_sender::PacketList* packet_list)
- EXCLUSIVE_LOCKS_REQUIRED(critsect_.get()) {
- paced_sender::Packet packet = GetNextPacketFromList(packet_list);
+bool PacedSender::SendPacket(const paced_sender::Packet& packet) {
critsect_->Leave();
-
const bool success = callback_->TimeToSendPacket(packet.ssrc,
packet.sequence_number,
packet.capture_time_ms,
packet.retransmission);
critsect_->Enter();
- // If packet cannot be sent then keep it in packet list and exit early.
- // There's no need to send more packets.
- if (!success) {
- return false;
- }
- packet_list->pop_front();
- const bool last_packet =
- packet_list->empty() ||
- packet_list->front().capture_time_ms > packet.capture_time_ms;
- if (packet_list != high_priority_packets_.get()) {
- if (packet.capture_time_ms > capture_time_ms_last_sent_) {
- capture_time_ms_last_sent_ = packet.capture_time_ms;
- } else if (packet.capture_time_ms == capture_time_ms_last_sent_ &&
- last_packet) {
- TRACE_EVENT_ASYNC_END0("webrtc_rtp", "PacedSend", packet.capture_time_ms);
- }
+
+ if (success) {
+ // Update media bytes sent.
+ prober_->PacketSent(clock_->TimeInMilliseconds(), packet.bytes);
+ media_budget_->UseBudget(packet.bytes);
+ padding_budget_->UseBudget(packet.bytes);
}
- return true;
-}
-void PacedSender::UpdateBytesPerInterval(uint32_t delta_time_ms) {
- media_budget_->IncreaseBudget(delta_time_ms);
- padding_budget_->IncreaseBudget(delta_time_ms);
+ return success;
}
-bool PacedSender::ShouldSendNextPacket(paced_sender::PacketList** packet_list) {
- *packet_list = NULL;
- if (media_budget_->bytes_remaining() <= 0) {
- // All bytes consumed for this interval.
- // Check if we have not sent in a too long time.
- if (clock_->TimeInMicroseconds() - time_last_send_us_ >
- kMaxQueueTimeWithoutSendingUs) {
- if (!high_priority_packets_->empty()) {
- *packet_list = high_priority_packets_.get();
- return true;
- }
- if (!normal_priority_packets_->empty()) {
- *packet_list = normal_priority_packets_.get();
- return true;
- }
- }
- // Send any old packets to avoid queuing for too long.
- if (max_queue_length_ms_ >= 0 && QueueInMs() > max_queue_length_ms_) {
- int64_t high_priority_capture_time = -1;
- if (!high_priority_packets_->empty()) {
- high_priority_capture_time =
- high_priority_packets_->front().capture_time_ms;
- *packet_list = high_priority_packets_.get();
- }
- if (!normal_priority_packets_->empty() &&
- (high_priority_capture_time == -1 ||
- high_priority_capture_time >
- normal_priority_packets_->front().capture_time_ms)) {
- *packet_list = normal_priority_packets_.get();
- }
- if (*packet_list)
- return true;
- }
- return false;
- }
- if (!high_priority_packets_->empty()) {
- *packet_list = high_priority_packets_.get();
- return true;
- }
- if (!normal_priority_packets_->empty()) {
- *packet_list = normal_priority_packets_.get();
- return true;
- }
- if (!low_priority_packets_->empty()) {
- *packet_list = low_priority_packets_.get();
- return true;
- }
- return false;
-}
+void PacedSender::SendPadding(int padding_needed) {
+ critsect_->Leave();
+ int bytes_sent = callback_->TimeToSendPadding(padding_needed);
+ critsect_->Enter();
-paced_sender::Packet PacedSender::GetNextPacketFromList(
- paced_sender::PacketList* packets) {
- paced_sender::Packet packet = packets->front();
- UpdateMediaBytesSent(packet.bytes);
- return packet;
+ // Update padding bytes sent.
+ media_budget_->UseBudget(bytes_sent);
+ padding_budget_->UseBudget(bytes_sent);
}
-void PacedSender::UpdateMediaBytesSent(int num_bytes) {
- time_last_send_us_ = clock_->TimeInMicroseconds();
- media_budget_->UseBudget(num_bytes);
- padding_budget_->UseBudget(num_bytes);
+void PacedSender::UpdateBytesPerInterval(uint32_t delta_time_ms) {
+ media_budget_->IncreaseBudget(delta_time_ms);
+ padding_budget_->IncreaseBudget(delta_time_ms);
}
+bool PacedSender::ProbingExperimentIsEnabled() const {
+ return webrtc::field_trial::FindFullName("WebRTC-BitrateProbing") ==
+ "Enabled";
+}
} // namespace webrtc
diff --git a/modules/pacing/paced_sender_unittest.cc b/modules/pacing/paced_sender_unittest.cc
index 14dcdbc5..34787d16 100644
--- a/modules/pacing/paced_sender_unittest.cc
+++ b/modules/pacing/paced_sender_unittest.cc
@@ -8,9 +8,10 @@
* be found in the AUTHORS file in the root of the source tree.
*/
+#include <list>
+
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-
#include "webrtc/modules/pacing/include/paced_sender.h"
#include "webrtc/system_wrappers/interface/clock.h"
@@ -26,8 +27,10 @@ static const float kPaceMultiplier = 1.5f;
class MockPacedSenderCallback : public PacedSender::Callback {
public:
MOCK_METHOD4(TimeToSendPacket,
- bool(uint32_t ssrc, uint16_t sequence_number, int64_t capture_time_ms,
- bool retransmission));
+ bool(uint32_t ssrc,
+ uint16_t sequence_number,
+ int64_t capture_time_ms,
+ bool retransmission));
MOCK_METHOD1(TimeToSendPadding,
int(int bytes));
};
@@ -36,8 +39,10 @@ class PacedSenderPadding : public PacedSender::Callback {
public:
PacedSenderPadding() : padding_sent_(0) {}
- bool TimeToSendPacket(uint32_t ssrc, uint16_t sequence_number,
- int64_t capture_time_ms, bool retransmission) {
+ bool TimeToSendPacket(uint32_t ssrc,
+ uint16_t sequence_number,
+ int64_t capture_time_ms,
+ bool retransmission) {
return true;
}
@@ -54,24 +59,67 @@ class PacedSenderPadding : public PacedSender::Callback {
int padding_sent_;
};
+class PacedSenderProbing : public PacedSender::Callback {
+ public:
+ PacedSenderProbing(const std::list<int>& expected_deltas, Clock* clock)
+ : prev_packet_time_ms_(-1),
+ expected_deltas_(expected_deltas),
+ packets_sent_(0),
+ clock_(clock) {}
+
+ bool TimeToSendPacket(uint32_t ssrc,
+ uint16_t sequence_number,
+ int64_t capture_time_ms,
+ bool retransmission) {
+ ++packets_sent_;
+ EXPECT_FALSE(expected_deltas_.empty());
+ if (expected_deltas_.empty())
+ return false;
+ int64_t now_ms = clock_->TimeInMilliseconds();
+ if (prev_packet_time_ms_ >= 0) {
+ EXPECT_EQ(expected_deltas_.front(), now_ms - prev_packet_time_ms_);
+ expected_deltas_.pop_front();
+ }
+ prev_packet_time_ms_ = now_ms;
+ return true;
+ }
+
+ int TimeToSendPadding(int bytes) {
+ EXPECT_TRUE(false);
+ return bytes;
+ }
+
+ int packets_sent() const { return packets_sent_; }
+
+ private:
+ int64_t prev_packet_time_ms_;
+ std::list<int> expected_deltas_;
+ int packets_sent_;
+ Clock* clock_;
+};
+
class PacedSenderTest : public ::testing::Test {
protected:
PacedSenderTest() : clock_(123456) {
srand(0);
// Need to initialize PacedSender after we initialize clock.
- send_bucket_.reset(
- new PacedSender(
- &clock_, &callback_, kPaceMultiplier * kTargetBitrate, 0));
+ send_bucket_.reset(new PacedSender(&clock_,
+ &callback_,
+ kTargetBitrate,
+ kPaceMultiplier * kTargetBitrate,
+ 0));
}
void SendAndExpectPacket(PacedSender::Priority priority,
- uint32_t ssrc, uint16_t sequence_number,
- int64_t capture_time_ms, int size,
+ uint32_t ssrc,
+ uint16_t sequence_number,
+ int64_t capture_time_ms,
+ int size,
bool retransmission) {
EXPECT_FALSE(send_bucket_->SendPacket(priority, ssrc,
sequence_number, capture_time_ms, size, retransmission));
- EXPECT_CALL(callback_, TimeToSendPacket(
- ssrc, sequence_number, capture_time_ms, false))
+ EXPECT_CALL(callback_,
+ TimeToSendPacket(ssrc, sequence_number, capture_time_ms, false))
.Times(1)
.WillRepeatedly(Return(true));
}
@@ -85,12 +133,24 @@ TEST_F(PacedSenderTest, QueuePacket) {
uint32_t ssrc = 12345;
uint16_t sequence_number = 1234;
// Due to the multiplicative factor we can send 3 packets not 2 packets.
- SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
- clock_.TimeInMilliseconds(), 250, false);
- SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
- clock_.TimeInMilliseconds(), 250, false);
- SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
- clock_.TimeInMilliseconds(), 250, false);
+ SendAndExpectPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ clock_.TimeInMilliseconds(),
+ 250,
+ false);
+ SendAndExpectPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ clock_.TimeInMilliseconds(),
+ 250,
+ false);
+ SendAndExpectPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ clock_.TimeInMilliseconds(),
+ 250,
+ false);
int64_t queued_packet_timestamp = clock_.TimeInMilliseconds();
EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc,
sequence_number, queued_packet_timestamp, 250, false));
@@ -101,16 +161,25 @@ TEST_F(PacedSenderTest, QueuePacket) {
EXPECT_EQ(1, send_bucket_->TimeUntilNextProcess());
clock_.AdvanceTimeMilliseconds(1);
EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
- EXPECT_CALL(callback_, TimeToSendPacket(
- ssrc, sequence_number++, queued_packet_timestamp, false))
+ EXPECT_CALL(
+ callback_,
+ TimeToSendPacket(ssrc, sequence_number++, queued_packet_timestamp, false))
.Times(1)
.WillRepeatedly(Return(true));
send_bucket_->Process();
sequence_number++;
- SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
- clock_.TimeInMilliseconds(), 250, false);
- SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
- clock_.TimeInMilliseconds(), 250, false);
+ SendAndExpectPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ clock_.TimeInMilliseconds(),
+ 250,
+ false);
+ SendAndExpectPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ clock_.TimeInMilliseconds(),
+ 250,
+ false);
EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc,
sequence_number++, clock_.TimeInMilliseconds(), 250, false));
send_bucket_->Process();
@@ -122,8 +191,12 @@ TEST_F(PacedSenderTest, PaceQueuedPackets) {
// Due to the multiplicative factor we can send 3 packets not 2 packets.
for (int i = 0; i < 3; ++i) {
- SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
- clock_.TimeInMilliseconds(), 250, false);
+ SendAndExpectPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ clock_.TimeInMilliseconds(),
+ 250,
+ false);
}
for (int j = 0; j < 30; ++j) {
EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc,
@@ -134,8 +207,7 @@ TEST_F(PacedSenderTest, PaceQueuedPackets) {
for (int k = 0; k < 10; ++k) {
EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
clock_.AdvanceTimeMilliseconds(5);
- EXPECT_CALL(callback_,
- TimeToSendPacket(ssrc, _, _, false))
+ EXPECT_CALL(callback_, TimeToSendPacket(ssrc, _, _, false))
.Times(3)
.WillRepeatedly(Return(true));
EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
@@ -145,12 +217,24 @@ TEST_F(PacedSenderTest, PaceQueuedPackets) {
clock_.AdvanceTimeMilliseconds(5);
EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
EXPECT_EQ(0, send_bucket_->Process());
- SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
- clock_.TimeInMilliseconds(), 250, false);
- SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
- clock_.TimeInMilliseconds(), 250, false);
- SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
- clock_.TimeInMilliseconds(), 250, false);
+ SendAndExpectPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ clock_.TimeInMilliseconds(),
+ 250,
+ false);
+ SendAndExpectPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ clock_.TimeInMilliseconds(),
+ 250,
+ false);
+ SendAndExpectPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ clock_.TimeInMilliseconds(),
+ 250,
+ false);
EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc,
sequence_number, clock_.TimeInMilliseconds(), 250, false));
send_bucket_->Process();
@@ -163,8 +247,12 @@ TEST_F(PacedSenderTest, PaceQueuedPacketsWithDuplicates) {
// Due to the multiplicative factor we can send 3 packets not 2 packets.
for (int i = 0; i < 3; ++i) {
- SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
- clock_.TimeInMilliseconds(), 250, false);
+ SendAndExpectPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ clock_.TimeInMilliseconds(),
+ 250,
+ false);
}
queued_sequence_number = sequence_number;
@@ -182,9 +270,8 @@ TEST_F(PacedSenderTest, PaceQueuedPacketsWithDuplicates) {
clock_.AdvanceTimeMilliseconds(5);
for (int i = 0; i < 3; ++i) {
- EXPECT_CALL(callback_, TimeToSendPacket(ssrc, queued_sequence_number++,
- _,
- false))
+ EXPECT_CALL(callback_,
+ TimeToSendPacket(ssrc, queued_sequence_number++, _, false))
.Times(1)
.WillRepeatedly(Return(true));
}
@@ -195,12 +282,24 @@ TEST_F(PacedSenderTest, PaceQueuedPacketsWithDuplicates) {
clock_.AdvanceTimeMilliseconds(5);
EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
EXPECT_EQ(0, send_bucket_->Process());
- SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
- clock_.TimeInMilliseconds(), 250, false);
- SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
- clock_.TimeInMilliseconds(), 250, false);
- SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
- clock_.TimeInMilliseconds(), 250, false);
+ SendAndExpectPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ clock_.TimeInMilliseconds(),
+ 250,
+ false);
+ SendAndExpectPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ clock_.TimeInMilliseconds(),
+ 250,
+ false);
+ SendAndExpectPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ clock_.TimeInMilliseconds(),
+ 250,
+ false);
EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc,
sequence_number++, clock_.TimeInMilliseconds(), 250, false));
send_bucket_->Process();
@@ -233,14 +332,27 @@ TEST_F(PacedSenderTest, Padding) {
uint32_t ssrc = 12345;
uint16_t sequence_number = 1234;
- send_bucket_->UpdateBitrate(kPaceMultiplier * kTargetBitrate, kTargetBitrate);
+ send_bucket_->UpdateBitrate(
+ kTargetBitrate, kPaceMultiplier * kTargetBitrate, kTargetBitrate);
// Due to the multiplicative factor we can send 3 packets not 2 packets.
- SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
- clock_.TimeInMilliseconds(), 250, false);
- SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
- clock_.TimeInMilliseconds(), 250, false);
- SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
- clock_.TimeInMilliseconds(), 250, false);
+ SendAndExpectPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ clock_.TimeInMilliseconds(),
+ 250,
+ false);
+ SendAndExpectPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ clock_.TimeInMilliseconds(),
+ 250,
+ false);
+ SendAndExpectPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ clock_.TimeInMilliseconds(),
+ 250,
+ false);
// No padding is expected since we have sent too much already.
EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
@@ -259,7 +371,8 @@ TEST_F(PacedSenderTest, Padding) {
TEST_F(PacedSenderTest, NoPaddingWhenDisabled) {
send_bucket_->SetStatus(false);
- send_bucket_->UpdateBitrate(kPaceMultiplier * kTargetBitrate, kTargetBitrate);
+ send_bucket_->UpdateBitrate(
+ kTargetBitrate, kPaceMultiplier * kTargetBitrate, kTargetBitrate);
// No padding is expected since the pacer is disabled.
EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
@@ -279,11 +392,16 @@ TEST_F(PacedSenderTest, VerifyPaddingUpToBitrate) {
int64_t capture_time_ms = 56789;
const int kTimeStep = 5;
const int64_t kBitrateWindow = 100;
- send_bucket_->UpdateBitrate(kPaceMultiplier * kTargetBitrate, kTargetBitrate);
+ send_bucket_->UpdateBitrate(
+ kTargetBitrate, kPaceMultiplier * kTargetBitrate, kTargetBitrate);
int64_t start_time = clock_.TimeInMilliseconds();
while (clock_.TimeInMilliseconds() - start_time < kBitrateWindow) {
- SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
- capture_time_ms, 250, false);
+ SendAndExpectPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ capture_time_ms,
+ 250,
+ false);
clock_.AdvanceTimeMilliseconds(kTimeStep);
EXPECT_CALL(callback_, TimeToSendPadding(250)).Times(1).
WillOnce(Return(250));
@@ -298,9 +416,10 @@ TEST_F(PacedSenderTest, VerifyAverageBitrateVaryingMediaPayload) {
const int kTimeStep = 5;
const int64_t kBitrateWindow = 10000;
PacedSenderPadding callback;
- send_bucket_.reset(
- new PacedSender(&clock_, &callback, kPaceMultiplier * kTargetBitrate, 0));
- send_bucket_->UpdateBitrate(kPaceMultiplier * kTargetBitrate, kTargetBitrate);
+ send_bucket_.reset(new PacedSender(
+ &clock_, &callback, kTargetBitrate, kPaceMultiplier * kTargetBitrate, 0));
+ send_bucket_->UpdateBitrate(
+ kTargetBitrate, kPaceMultiplier * kTargetBitrate, kTargetBitrate);
int64_t start_time = clock_.TimeInMilliseconds();
int media_bytes = 0;
while (clock_.TimeInMilliseconds() - start_time < kBitrateWindow) {
@@ -324,12 +443,24 @@ TEST_F(PacedSenderTest, Priority) {
int64_t capture_time_ms_low_priority = 1234567;
// Due to the multiplicative factor we can send 3 packets not 2 packets.
- SendAndExpectPacket(PacedSender::kLowPriority, ssrc, sequence_number++,
- capture_time_ms, 250, false);
- SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
- capture_time_ms, 250, false);
- SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
- capture_time_ms, 250, false);
+ SendAndExpectPacket(PacedSender::kLowPriority,
+ ssrc,
+ sequence_number++,
+ capture_time_ms,
+ 250,
+ false);
+ SendAndExpectPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ capture_time_ms,
+ 250,
+ false);
+ SendAndExpectPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ capture_time_ms,
+ 250,
+ false);
send_bucket_->Process();
// Expect normal and low priority to be queued and high to pass through.
@@ -354,8 +485,9 @@ TEST_F(PacedSenderTest, Priority) {
EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
EXPECT_EQ(0, send_bucket_->Process());
- EXPECT_CALL(callback_, TimeToSendPacket(
- ssrc_low_priority, _, capture_time_ms_low_priority, false))
+ EXPECT_CALL(callback_,
+ TimeToSendPacket(
+ ssrc_low_priority, _, capture_time_ms_low_priority, false))
.Times(1)
.WillRepeatedly(Return(true));
@@ -374,12 +506,24 @@ TEST_F(PacedSenderTest, Pause) {
EXPECT_EQ(0, send_bucket_->QueueInMs());
// Due to the multiplicative factor we can send 3 packets not 2 packets.
- SendAndExpectPacket(PacedSender::kLowPriority, ssrc, sequence_number++,
- capture_time_ms, 250, false);
- SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
- capture_time_ms, 250, false);
- SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
- capture_time_ms, 250, false);
+ SendAndExpectPacket(PacedSender::kLowPriority,
+ ssrc,
+ sequence_number++,
+ capture_time_ms,
+ 250,
+ false);
+ SendAndExpectPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ capture_time_ms,
+ 250,
+ false);
+ SendAndExpectPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ capture_time_ms,
+ 250,
+ false);
send_bucket_->Process();
send_bucket_->Pause();
@@ -423,8 +567,7 @@ TEST_F(PacedSenderTest, Pause) {
EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
EXPECT_EQ(0, send_bucket_->Process());
- EXPECT_CALL(
- callback_, TimeToSendPacket(_, _, second_capture_time_ms, false))
+ EXPECT_CALL(callback_, TimeToSendPacket(_, _, second_capture_time_ms, false))
.Times(1)
.WillRepeatedly(Return(true));
EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
@@ -457,8 +600,8 @@ TEST_F(PacedSenderTest, ResendPacket) {
EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms,
send_bucket_->QueueInMs());
// Fails to send first packet so only one call.
- EXPECT_CALL(callback_, TimeToSendPacket(
- ssrc, sequence_number, capture_time_ms, false))
+ EXPECT_CALL(callback_,
+ TimeToSendPacket(ssrc, sequence_number, capture_time_ms, false))
.Times(1)
.WillOnce(Return(false));
clock_.AdvanceTimeMilliseconds(10000);
@@ -469,12 +612,13 @@ TEST_F(PacedSenderTest, ResendPacket) {
send_bucket_->QueueInMs());
// Fails to send second packet.
- EXPECT_CALL(callback_, TimeToSendPacket(
- ssrc, sequence_number, capture_time_ms, false))
+ EXPECT_CALL(callback_,
+ TimeToSendPacket(ssrc, sequence_number, capture_time_ms, false))
.Times(1)
.WillOnce(Return(true));
- EXPECT_CALL(callback_, TimeToSendPacket(
- ssrc, sequence_number + 1, capture_time_ms + 1, false))
+ EXPECT_CALL(
+ callback_,
+ TimeToSendPacket(ssrc, sequence_number + 1, capture_time_ms + 1, false))
.Times(1)
.WillOnce(Return(false));
clock_.AdvanceTimeMilliseconds(10000);
@@ -485,8 +629,9 @@ TEST_F(PacedSenderTest, ResendPacket) {
send_bucket_->QueueInMs());
// Send second packet and queue becomes empty.
- EXPECT_CALL(callback_, TimeToSendPacket(
- ssrc, sequence_number + 1, capture_time_ms + 1, false))
+ EXPECT_CALL(
+ callback_,
+ TimeToSendPacket(ssrc, sequence_number + 1, capture_time_ms + 1, false))
.Times(1)
.WillOnce(Return(true));
clock_.AdvanceTimeMilliseconds(10000);
@@ -494,34 +639,40 @@ TEST_F(PacedSenderTest, ResendPacket) {
EXPECT_EQ(0, send_bucket_->QueueInMs());
}
-TEST_F(PacedSenderTest, MaxQueueLength) {
+TEST_F(PacedSenderTest, ExpectedQueueTimeMs) {
uint32_t ssrc = 12346;
uint16_t sequence_number = 1234;
- EXPECT_EQ(0, send_bucket_->QueueInMs());
+ const int32_t kNumPackets = 60;
+ const int32_t kPacketSize = 1200;
+ const int32_t kMaxBitrate = kPaceMultiplier * 30;
+ EXPECT_EQ(0, send_bucket_->ExpectedQueueTimeMs());
- send_bucket_->UpdateBitrate(kPaceMultiplier * 30, 0);
- for (int i = 0; i < 30; ++i) {
- SendAndExpectPacket(PacedSender::kNormalPriority,
- ssrc,
- sequence_number++,
- clock_.TimeInMilliseconds(),
- 1200,
- false);
+ send_bucket_->UpdateBitrate(30, kMaxBitrate, 0);
+ for (int i = 0; i < kNumPackets; ++i) {
+ SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
+ clock_.TimeInMilliseconds(), kPacketSize, false);
}
- clock_.AdvanceTimeMilliseconds(2001);
- SendAndExpectPacket(PacedSender::kNormalPriority,
- ssrc,
- sequence_number++,
- clock_.TimeInMilliseconds(),
- 1200,
- false);
- EXPECT_EQ(2001, send_bucket_->QueueInMs());
- send_bucket_->Process();
- EXPECT_EQ(0, send_bucket_->QueueInMs());
- clock_.AdvanceTimeMilliseconds(31);
+ // Queue in ms = 1000 * (bytes in queue) / (kbit per second * 1000 / 8)
+ int32_t queue_in_ms = kNumPackets * kPacketSize * 8 / kMaxBitrate;
+ EXPECT_EQ(queue_in_ms, send_bucket_->ExpectedQueueTimeMs());
+
+ int64_t time_start = clock_.TimeInMilliseconds();
+ while (send_bucket_->QueueSizePackets() > 0) {
+ int time_until_process = send_bucket_->TimeUntilNextProcess();
+ if (time_until_process <= 0) {
+ send_bucket_->Process();
+ } else {
+ clock_.AdvanceTimeMilliseconds(time_until_process);
+ }
+ }
+ int64_t duration = clock_.TimeInMilliseconds() - time_start;
- send_bucket_->Process();
+ EXPECT_EQ(0, send_bucket_->ExpectedQueueTimeMs());
+
+ // Allow for aliasing, duration should be in [expected(n - 1), expected(n)].
+ EXPECT_LE(duration, queue_in_ms);
+ EXPECT_GE(duration, queue_in_ms - (kPacketSize * 8 / kMaxBitrate));
}
TEST_F(PacedSenderTest, QueueTimeGrowsOverTime) {
@@ -529,7 +680,7 @@ TEST_F(PacedSenderTest, QueueTimeGrowsOverTime) {
uint16_t sequence_number = 1234;
EXPECT_EQ(0, send_bucket_->QueueInMs());
- send_bucket_->UpdateBitrate(kPaceMultiplier * 30, 0);
+ send_bucket_->UpdateBitrate(30, kPaceMultiplier * 30, 0);
SendAndExpectPacket(PacedSender::kNormalPriority,
ssrc,
sequence_number,
@@ -542,5 +693,130 @@ TEST_F(PacedSenderTest, QueueTimeGrowsOverTime) {
send_bucket_->Process();
EXPECT_EQ(0, send_bucket_->QueueInMs());
}
+
+class ProbingPacedSender : public PacedSender {
+ public:
+ ProbingPacedSender(Clock* clock,
+ Callback* callback,
+ int bitrate_kbps,
+ int max_bitrate_kbps,
+ int min_bitrate_kbps)
+ : PacedSender(clock,
+ callback,
+ bitrate_kbps,
+ max_bitrate_kbps,
+ min_bitrate_kbps) {}
+
+ virtual bool ProbingExperimentIsEnabled() const OVERRIDE { return true; }
+};
+
+TEST_F(PacedSenderTest, ProbingWithInitialFrame) {
+ const int kNumPackets = 15;
+ const int kPacketSize = 1200;
+ const int kInitialBitrateKbps = 300;
+ uint32_t ssrc = 12346;
+ uint16_t sequence_number = 1234;
+ const int expected_deltas[kNumPackets - 1] = {
+ 12, 12, 12, 12, 8, 8, 8, 8, 8, 5, 5, 5, 5, 5};
+ std::list<int> expected_deltas_list(expected_deltas,
+ expected_deltas + kNumPackets - 1);
+ PacedSenderProbing callback(expected_deltas_list, &clock_);
+ send_bucket_.reset(
+ new ProbingPacedSender(&clock_,
+ &callback,
+ kInitialBitrateKbps,
+ kPaceMultiplier * kInitialBitrateKbps,
+ 0));
+ for (int i = 0; i < kNumPackets; ++i) {
+ EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority,
+ ssrc,
+ sequence_number++,
+ clock_.TimeInMilliseconds(),
+ kPacketSize,
+ false));
+ }
+ while (callback.packets_sent() < kNumPackets) {
+ int time_until_process = send_bucket_->TimeUntilNextProcess();
+ if (time_until_process <= 0) {
+ send_bucket_->Process();
+ } else {
+ clock_.AdvanceTimeMilliseconds(time_until_process);
+ }
+ }
+}
+
+TEST_F(PacedSenderTest, PriorityInversion) {
+ uint32_t ssrc = 12346;
+ uint16_t sequence_number = 1234;
+ const int32_t kPacketSize = 1200;
+
+ EXPECT_FALSE(send_bucket_->SendPacket(
+ PacedSender::kHighPriority, ssrc, sequence_number + 3,
+ clock_.TimeInMilliseconds() + 33, kPacketSize, true));
+
+ EXPECT_FALSE(send_bucket_->SendPacket(
+ PacedSender::kHighPriority, ssrc, sequence_number + 2,
+ clock_.TimeInMilliseconds() + 33, kPacketSize, true));
+
+ EXPECT_FALSE(send_bucket_->SendPacket(
+ PacedSender::kHighPriority, ssrc, sequence_number,
+ clock_.TimeInMilliseconds(), kPacketSize, true));
+
+ EXPECT_FALSE(send_bucket_->SendPacket(
+ PacedSender::kHighPriority, ssrc, sequence_number + 1,
+ clock_.TimeInMilliseconds(), kPacketSize, true));
+
+ // Packets from earlier frames should be sent first.
+ {
+ ::testing::InSequence sequence;
+ EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number,
+ clock_.TimeInMilliseconds(), true))
+ .WillOnce(Return(true));
+ EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number + 1,
+ clock_.TimeInMilliseconds(), true))
+ .WillOnce(Return(true));
+ EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number + 3,
+ clock_.TimeInMilliseconds() + 33,
+ true)).WillOnce(Return(true));
+ EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number + 2,
+ clock_.TimeInMilliseconds() + 33,
+ true)).WillOnce(Return(true));
+
+ while (send_bucket_->QueueSizePackets() > 0) {
+ int time_until_process = send_bucket_->TimeUntilNextProcess();
+ if (time_until_process <= 0) {
+ send_bucket_->Process();
+ } else {
+ clock_.AdvanceTimeMilliseconds(time_until_process);
+ }
+ }
+ }
+}
+
+TEST_F(PacedSenderTest, PaddingOveruse) {
+ uint32_t ssrc = 12346;
+ uint16_t sequence_number = 1234;
+ const int32_t kPacketSize = 1200;
+
+ // Min bitrate 0 => no padding, padding budget will stay at 0.
+ send_bucket_->UpdateBitrate(60, 90, 0);
+ SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
+ clock_.TimeInMilliseconds(), kPacketSize, false);
+ send_bucket_->Process();
+
+ // Add 30kbit padding. When increasing budget, media budget will increase from
+ // negative (overuse) while padding budget will increase form 0.
+ clock_.AdvanceTimeMilliseconds(5);
+ send_bucket_->UpdateBitrate(60, 90, 30);
+
+ EXPECT_FALSE(send_bucket_->SendPacket(
+ PacedSender::kHighPriority, ssrc, sequence_number++,
+ clock_.TimeInMilliseconds(), kPacketSize, false));
+
+ // Don't send padding if queue is non-empty, even if padding budget > 0.
+ EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
+ send_bucket_->Process();
+}
+
} // namespace test
} // namespace webrtc
diff --git a/modules/pacing/pacing.gypi b/modules/pacing/pacing.gypi
index 07b43380..36684508 100644
--- a/modules/pacing/pacing.gypi
+++ b/modules/pacing/pacing.gypi
@@ -16,6 +16,8 @@
],
'sources': [
'include/paced_sender.h',
+ 'bitrate_prober.cc',
+ 'bitrate_prober.h',
'paced_sender.cc',
],
},
diff --git a/modules/remote_bitrate_estimator.target.darwin-arm.mk b/modules/remote_bitrate_estimator.target.darwin-arm.mk
index 97d1c162..280e6cb2 100644
--- a/modules/remote_bitrate_estimator.target.darwin-arm.mk
+++ b/modules/remote_bitrate_estimator.target.darwin-arm.mk
@@ -87,11 +87,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +109,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -204,11 +207,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -224,6 +229,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/remote_bitrate_estimator.target.darwin-arm64.mk b/modules/remote_bitrate_estimator.target.darwin-arm64.mk
index c91d9df7..5799e0b7 100644
--- a/modules/remote_bitrate_estimator.target.darwin-arm64.mk
+++ b/modules/remote_bitrate_estimator.target.darwin-arm64.mk
@@ -76,11 +76,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -89,10 +91,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -178,11 +182,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -191,10 +197,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/remote_bitrate_estimator.target.darwin-mips.mk b/modules/remote_bitrate_estimator.target.darwin-mips.mk
index ece0f75b..15b6a88d 100644
--- a/modules/remote_bitrate_estimator.target.darwin-mips.mk
+++ b/modules/remote_bitrate_estimator.target.darwin-mips.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -210,6 +215,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/remote_bitrate_estimator.target.darwin-mips64.mk b/modules/remote_bitrate_estimator.target.darwin-mips64.mk
new file mode 100644
index 00000000..84282955
--- /dev/null
+++ b/modules/remote_bitrate_estimator.target.darwin-mips64.mk
@@ -0,0 +1,267 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_remote_bitrate_estimator_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/remote_bitrate_estimator/rate_statistics.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_remote_bitrate_estimator_gyp
+
+# Alias gyp target name.
+.PHONY: remote_bitrate_estimator
+remote_bitrate_estimator: third_party_webrtc_modules_remote_bitrate_estimator_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/remote_bitrate_estimator.target.darwin-x86.mk b/modules/remote_bitrate_estimator.target.darwin-x86.mk
index ab826c63..88819ca5 100644
--- a/modules/remote_bitrate_estimator.target.darwin-x86.mk
+++ b/modules/remote_bitrate_estimator.target.darwin-x86.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -190,11 +193,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -207,6 +212,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/remote_bitrate_estimator.target.darwin-x86_64.mk b/modules/remote_bitrate_estimator.target.darwin-x86_64.mk
index 42925142..5a0d24e9 100644
--- a/modules/remote_bitrate_estimator.target.darwin-x86_64.mk
+++ b/modules/remote_bitrate_estimator.target.darwin-x86_64.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,6 +100,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -188,11 +191,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -205,6 +210,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/remote_bitrate_estimator.target.linux-arm.mk b/modules/remote_bitrate_estimator.target.linux-arm.mk
index 97d1c162..280e6cb2 100644
--- a/modules/remote_bitrate_estimator.target.linux-arm.mk
+++ b/modules/remote_bitrate_estimator.target.linux-arm.mk
@@ -87,11 +87,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +109,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -204,11 +207,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -224,6 +229,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/remote_bitrate_estimator.target.linux-arm64.mk b/modules/remote_bitrate_estimator.target.linux-arm64.mk
index c91d9df7..5799e0b7 100644
--- a/modules/remote_bitrate_estimator.target.linux-arm64.mk
+++ b/modules/remote_bitrate_estimator.target.linux-arm64.mk
@@ -76,11 +76,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -89,10 +91,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -178,11 +182,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -191,10 +197,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/remote_bitrate_estimator.target.linux-mips.mk b/modules/remote_bitrate_estimator.target.linux-mips.mk
index ece0f75b..15b6a88d 100644
--- a/modules/remote_bitrate_estimator.target.linux-mips.mk
+++ b/modules/remote_bitrate_estimator.target.linux-mips.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -210,6 +215,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/remote_bitrate_estimator.target.linux-mips64.mk b/modules/remote_bitrate_estimator.target.linux-mips64.mk
new file mode 100644
index 00000000..84282955
--- /dev/null
+++ b/modules/remote_bitrate_estimator.target.linux-mips64.mk
@@ -0,0 +1,267 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_remote_bitrate_estimator_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/remote_bitrate_estimator/rate_statistics.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_remote_bitrate_estimator_gyp
+
+# Alias gyp target name.
+.PHONY: remote_bitrate_estimator
+remote_bitrate_estimator: third_party_webrtc_modules_remote_bitrate_estimator_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/remote_bitrate_estimator.target.linux-x86.mk b/modules/remote_bitrate_estimator.target.linux-x86.mk
index ab826c63..88819ca5 100644
--- a/modules/remote_bitrate_estimator.target.linux-x86.mk
+++ b/modules/remote_bitrate_estimator.target.linux-x86.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -190,11 +193,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -207,6 +212,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/remote_bitrate_estimator.target.linux-x86_64.mk b/modules/remote_bitrate_estimator.target.linux-x86_64.mk
index 42925142..5a0d24e9 100644
--- a/modules/remote_bitrate_estimator.target.linux-x86_64.mk
+++ b/modules/remote_bitrate_estimator.target.linux-x86_64.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,6 +100,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -188,11 +191,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -205,6 +210,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/remote_bitrate_estimator/bwe_simulations.cc b/modules/remote_bitrate_estimator/bwe_simulations.cc
index 142de871..f47984c6 100644
--- a/modules/remote_bitrate_estimator/bwe_simulations.cc
+++ b/modules/remote_bitrate_estimator/bwe_simulations.cc
@@ -98,7 +98,7 @@ TEST_P(BweSimulation, Choke1000kbps500kbps1000kbps) {
TEST_P(BweSimulation, PacerChoke1000kbps500kbps1000kbps) {
VerboseLogging(true);
- AdaptiveVideoSender source(0, NULL, 30, 300, 0, 0);
+ PeriodicKeyFrameSender source(0, NULL, 30, 300, 0, 0, 1000);
PacedVideoSender sender(this, 300, &source);
ChokeFilter filter(this);
RateCounterFilter counter(this, "receiver_input");
@@ -111,9 +111,20 @@ TEST_P(BweSimulation, PacerChoke1000kbps500kbps1000kbps) {
RunFor(60 * 1000);
}
+TEST_P(BweSimulation, PacerChoke10000kbps) {
+ VerboseLogging(true);
+ PeriodicKeyFrameSender source(0, NULL, 30, 300, 0, 0, 0);
+ PacedVideoSender sender(this, 300, &source);
+ ChokeFilter filter(this);
+ RateCounterFilter counter(this, "receiver_input");
+ filter.SetCapacity(10000);
+ filter.SetMaxDelay(500);
+ RunFor(60 * 1000);
+}
+
TEST_P(BweSimulation, PacerChoke200kbps30kbps200kbps) {
VerboseLogging(true);
- AdaptiveVideoSender source(0, NULL, 30, 300, 0, 0);
+ PeriodicKeyFrameSender source(0, NULL, 30, 300, 0, 0, 1000);
PacedVideoSender sender(this, 300, &source);
ChokeFilter filter(this);
RateCounterFilter counter(this, "receiver_input");
@@ -151,6 +162,18 @@ TEST_P(BweSimulation, GoogleWifiTrace3Mbps) {
RunFor(300 * 1000);
}
+TEST_P(BweSimulation, PacerGoogleWifiTrace3Mbps) {
+ VerboseLogging(true);
+ PeriodicKeyFrameSender source(0, NULL, 30, 300, 0, 0, 1000);
+ PacedVideoSender sender(this, 300, &source);
+ RateCounterFilter counter1(this, "sender_output");
+ TraceBasedDeliveryFilter filter(this, "link_capacity");
+ filter.SetMaxDelay(500);
+ RateCounterFilter counter2(this, "receiver_input");
+ ASSERT_TRUE(filter.Init(test::ResourcePath("google-wifi-3mbps", "rx")));
+ RunFor(300 * 1000);
+}
+
class MultiFlowBweSimulation : public BweSimulation {
public:
MultiFlowBweSimulation() : BweSimulation() {}
diff --git a/modules/remote_bitrate_estimator/rbe_components.target.darwin-arm.mk b/modules/remote_bitrate_estimator/rbe_components.target.darwin-arm.mk
index 10d22051..fea03722 100644
--- a/modules/remote_bitrate_estimator/rbe_components.target.darwin-arm.mk
+++ b/modules/remote_bitrate_estimator/rbe_components.target.darwin-arm.mk
@@ -85,11 +85,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -105,6 +107,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -197,11 +200,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -217,6 +222,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/remote_bitrate_estimator/rbe_components.target.darwin-arm64.mk b/modules/remote_bitrate_estimator/rbe_components.target.darwin-arm64.mk
index b4922017..12d98bb9 100644
--- a/modules/remote_bitrate_estimator/rbe_components.target.darwin-arm64.mk
+++ b/modules/remote_bitrate_estimator/rbe_components.target.darwin-arm64.mk
@@ -74,11 +74,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -87,10 +89,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -171,11 +175,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -184,10 +190,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/remote_bitrate_estimator/rbe_components.target.darwin-mips.mk b/modules/remote_bitrate_estimator/rbe_components.target.darwin-mips.mk
index a6c42f8b..6360bf8a 100644
--- a/modules/remote_bitrate_estimator/rbe_components.target.darwin-mips.mk
+++ b/modules/remote_bitrate_estimator/rbe_components.target.darwin-mips.mk
@@ -78,11 +78,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -97,6 +99,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -182,11 +185,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -201,6 +206,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/remote_bitrate_estimator/rbe_components.target.darwin-mips64.mk b/modules/remote_bitrate_estimator/rbe_components.target.darwin-mips64.mk
new file mode 100644
index 00000000..28ee7441
--- /dev/null
+++ b/modules/remote_bitrate_estimator/rbe_components.target.darwin-mips64.mk
@@ -0,0 +1,259 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_remote_bitrate_estimator_rbe_components_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/remote_bitrate_estimator/overuse_detector.cc \
+ third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc \
+ third_party/webrtc/modules/remote_bitrate_estimator/remote_rate_control.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_remote_bitrate_estimator_rbe_components_gyp
+
+# Alias gyp target name.
+.PHONY: rbe_components
+rbe_components: third_party_webrtc_modules_remote_bitrate_estimator_rbe_components_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/remote_bitrate_estimator/rbe_components.target.darwin-x86.mk b/modules/remote_bitrate_estimator/rbe_components.target.darwin-x86.mk
index 2a4bcc53..ff78cbec 100644
--- a/modules/remote_bitrate_estimator/rbe_components.target.darwin-x86.mk
+++ b/modules/remote_bitrate_estimator/rbe_components.target.darwin-x86.mk
@@ -80,11 +80,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -97,6 +99,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -183,11 +186,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -200,6 +205,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/remote_bitrate_estimator/rbe_components.target.darwin-x86_64.mk b/modules/remote_bitrate_estimator/rbe_components.target.darwin-x86_64.mk
index eafe4b2f..3f840c95 100644
--- a/modules/remote_bitrate_estimator/rbe_components.target.darwin-x86_64.mk
+++ b/modules/remote_bitrate_estimator/rbe_components.target.darwin-x86_64.mk
@@ -79,11 +79,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -96,6 +98,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -181,11 +184,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -198,6 +203,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/remote_bitrate_estimator/rbe_components.target.linux-arm.mk b/modules/remote_bitrate_estimator/rbe_components.target.linux-arm.mk
index 10d22051..fea03722 100644
--- a/modules/remote_bitrate_estimator/rbe_components.target.linux-arm.mk
+++ b/modules/remote_bitrate_estimator/rbe_components.target.linux-arm.mk
@@ -85,11 +85,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -105,6 +107,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -197,11 +200,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -217,6 +222,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/remote_bitrate_estimator/rbe_components.target.linux-arm64.mk b/modules/remote_bitrate_estimator/rbe_components.target.linux-arm64.mk
index b4922017..12d98bb9 100644
--- a/modules/remote_bitrate_estimator/rbe_components.target.linux-arm64.mk
+++ b/modules/remote_bitrate_estimator/rbe_components.target.linux-arm64.mk
@@ -74,11 +74,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -87,10 +89,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -171,11 +175,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -184,10 +190,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/remote_bitrate_estimator/rbe_components.target.linux-mips.mk b/modules/remote_bitrate_estimator/rbe_components.target.linux-mips.mk
index a6c42f8b..6360bf8a 100644
--- a/modules/remote_bitrate_estimator/rbe_components.target.linux-mips.mk
+++ b/modules/remote_bitrate_estimator/rbe_components.target.linux-mips.mk
@@ -78,11 +78,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -97,6 +99,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -182,11 +185,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -201,6 +206,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/remote_bitrate_estimator/rbe_components.target.linux-mips64.mk b/modules/remote_bitrate_estimator/rbe_components.target.linux-mips64.mk
new file mode 100644
index 00000000..28ee7441
--- /dev/null
+++ b/modules/remote_bitrate_estimator/rbe_components.target.linux-mips64.mk
@@ -0,0 +1,259 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_remote_bitrate_estimator_rbe_components_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/remote_bitrate_estimator/overuse_detector.cc \
+ third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc \
+ third_party/webrtc/modules/remote_bitrate_estimator/remote_rate_control.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_remote_bitrate_estimator_rbe_components_gyp
+
+# Alias gyp target name.
+.PHONY: rbe_components
+rbe_components: third_party_webrtc_modules_remote_bitrate_estimator_rbe_components_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/remote_bitrate_estimator/rbe_components.target.linux-x86.mk b/modules/remote_bitrate_estimator/rbe_components.target.linux-x86.mk
index 2a4bcc53..ff78cbec 100644
--- a/modules/remote_bitrate_estimator/rbe_components.target.linux-x86.mk
+++ b/modules/remote_bitrate_estimator/rbe_components.target.linux-x86.mk
@@ -80,11 +80,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -97,6 +99,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -183,11 +186,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -200,6 +205,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/remote_bitrate_estimator/rbe_components.target.linux-x86_64.mk b/modules/remote_bitrate_estimator/rbe_components.target.linux-x86_64.mk
index eafe4b2f..3f840c95 100644
--- a/modules/remote_bitrate_estimator/rbe_components.target.linux-x86_64.mk
+++ b/modules/remote_bitrate_estimator/rbe_components.target.linux-x86_64.mk
@@ -79,11 +79,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -96,6 +98,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -181,11 +184,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -198,6 +203,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi b/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi
index f290a34c..f88a16a2 100644
--- a/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi
+++ b/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi
@@ -45,7 +45,7 @@
],
'dependencies': [
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
- '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default',
+ '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers_default',
'bwe_tools_util',
'rtp_rtcp',
],
@@ -68,7 +68,7 @@
],
'dependencies': [
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
- '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default',
+ '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers_default',
'bwe_tools_util',
'rtp_rtcp',
],
diff --git a/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc b/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc
index f67c7f34..08ba49d4 100644
--- a/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc
+++ b/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc
@@ -40,45 +40,45 @@ TEST_F(RemoteBitrateEstimatorSingleTest, RateIncreaseReordering) {
}
TEST_F(RemoteBitrateEstimatorSingleTest, RateIncreaseRtpTimestamps) {
- RateIncreaseRtpTimestampsTestHelper();
+ RateIncreaseRtpTimestampsTestHelper(1621);
}
// Verify that the time it takes for the estimator to reduce the bitrate when
// the capacity is tightened stays the same.
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropOneStream) {
- CapacityDropTestHelper(1, false, 956214, 367);
+ CapacityDropTestHelper(1, false, 367);
}
// Verify that the time it takes for the estimator to reduce the bitrate when
// the capacity is tightened stays the same. This test also verifies that we
// handle wrap-arounds in this scenario.
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropOneStreamWrap) {
- CapacityDropTestHelper(1, true, 956214, 367);
+ CapacityDropTestHelper(1, true, 367);
}
// Verify that the time it takes for the estimator to reduce the bitrate when
// the capacity is tightened stays the same. This test also verifies that we
// handle wrap-arounds in this scenario. This is a multi-stream test.
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropTwoStreamsWrap) {
- CapacityDropTestHelper(2, true, 927088, 267);
+ CapacityDropTestHelper(2, true, 267);
}
// Verify that the time it takes for the estimator to reduce the bitrate when
// the capacity is tightened stays the same. This test also verifies that we
// handle wrap-arounds in this scenario. This is a multi-stream test.
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropThreeStreamsWrap) {
- CapacityDropTestHelper(3, true, 920944, 333);
+ CapacityDropTestHelper(3, true, 333);
}
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropThirteenStreamsWrap) {
- CapacityDropTestHelper(13, true, 938944, 300);
+ CapacityDropTestHelper(13, true, 300);
}
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropNineteenStreamsWrap) {
- CapacityDropTestHelper(19, true, 926718, 300);
+ CapacityDropTestHelper(19, true, 300);
}
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropThirtyStreamsWrap) {
- CapacityDropTestHelper(30, true, 927016, 300);
+ CapacityDropTestHelper(30, true, 300);
}
} // namespace webrtc
diff --git a/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.cc b/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.cc
index 1b38a1ea..4f9e16c8 100644
--- a/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.cc
+++ b/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.cc
@@ -14,7 +14,7 @@
namespace webrtc {
-enum { kMtu = 1200 };
+enum { kMtu = 1200, kAcceptedBitrateErrorBps = 50000u };
namespace testing {
@@ -225,6 +225,7 @@ void RemoteBitrateEstimatorTest::IncomingPacket(uint32_t ssrc,
memset(&header, 0, sizeof(header));
header.ssrc = ssrc;
header.timestamp = rtp_timestamp;
+ header.extension.hasAbsoluteSendTime = true;
header.extension.absoluteSendTime = absolute_send_time;
bitrate_estimator_->IncomingPacket(arrival_time + kArrivalTimeClockOffsetMs,
payload_size, header);
@@ -340,7 +341,7 @@ void RemoteBitrateEstimatorTest::InitialBehaviorTestHelper(
EXPECT_TRUE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
ASSERT_EQ(1u, ssrcs.size());
EXPECT_EQ(kDefaultSsrc, ssrcs.front());
- EXPECT_EQ(expected_converge_bitrate, bitrate_bps);
+ EXPECT_NEAR(expected_converge_bitrate, bitrate_bps, kAcceptedBitrateErrorBps);
EXPECT_TRUE(bitrate_observer_->updated());
bitrate_observer_->Reset();
EXPECT_EQ(bitrate_observer_->latest_bitrate(), bitrate_bps);
@@ -372,7 +373,9 @@ void RemoteBitrateEstimatorTest::RateIncreaseReorderingTestHelper(
}
bitrate_estimator_->Process();
EXPECT_TRUE(bitrate_observer_->updated());
- EXPECT_EQ(expected_bitrate_bps, bitrate_observer_->latest_bitrate());
+ EXPECT_NEAR(expected_bitrate_bps,
+ bitrate_observer_->latest_bitrate(),
+ kAcceptedBitrateErrorBps);
for (int i = 0; i < 10; ++i) {
clock_.AdvanceTimeMilliseconds(2 * kFrameIntervalMs);
timestamp += 2 * 90 * kFrameIntervalMs;
@@ -387,15 +390,17 @@ void RemoteBitrateEstimatorTest::RateIncreaseReorderingTestHelper(
}
bitrate_estimator_->Process();
EXPECT_TRUE(bitrate_observer_->updated());
- EXPECT_EQ(expected_bitrate_bps, bitrate_observer_->latest_bitrate());
+ EXPECT_NEAR(expected_bitrate_bps,
+ bitrate_observer_->latest_bitrate(),
+ kAcceptedBitrateErrorBps);
}
// Make sure we initially increase the bitrate as expected.
-void RemoteBitrateEstimatorTest::RateIncreaseRtpTimestampsTestHelper() {
+void RemoteBitrateEstimatorTest::RateIncreaseRtpTimestampsTestHelper(
+ int expected_iterations) {
// This threshold corresponds approximately to increasing linearly with
// bitrate(i) = 1.04 * bitrate(i-1) + 1000
// until bitrate(i) > 500000, with bitrate(1) ~= 30000.
- const int kExpectedIterations = 1621;
unsigned int bitrate_bps = 30000;
int iterations = 0;
AddDefaultStream();
@@ -412,15 +417,14 @@ void RemoteBitrateEstimatorTest::RateIncreaseRtpTimestampsTestHelper() {
bitrate_observer_->Reset();
}
++iterations;
- ASSERT_LE(iterations, kExpectedIterations);
+ ASSERT_LE(iterations, expected_iterations);
}
- ASSERT_EQ(kExpectedIterations, iterations);
+ ASSERT_EQ(expected_iterations, iterations);
}
void RemoteBitrateEstimatorTest::CapacityDropTestHelper(
int number_of_streams,
bool wrap_time_stamp,
- unsigned int expected_converge_bitrate,
unsigned int expected_bitrate_drop_delta) {
const int kFramerate = 30;
const int kStartBitrate = 900e3;
@@ -430,14 +434,11 @@ void RemoteBitrateEstimatorTest::CapacityDropTestHelper(
const unsigned int kReducedCapacityBps = 500e3;
int steady_state_time = 0;
- int expected_overuse_start_time = 0;
if (number_of_streams <= 1) {
steady_state_time = 10;
- expected_overuse_start_time = 10000;
AddDefaultStream();
} else {
steady_state_time = 8 * number_of_streams;
- expected_overuse_start_time = 8000;
int bitrate_sum = 0;
int kBitrateDenom = number_of_streams * (number_of_streams - 1);
for (int i = 0; i < number_of_streams; i++) {
@@ -471,13 +472,12 @@ void RemoteBitrateEstimatorTest::CapacityDropTestHelper(
kMinExpectedBitrate,
kMaxExpectedBitrate,
kInitialCapacityBps);
- EXPECT_EQ(expected_converge_bitrate, bitrate_bps);
+ EXPECT_NEAR(kInitialCapacityBps, bitrate_bps, 100000u);
bitrate_observer_->Reset();
// Reduce the capacity and verify the decrease time.
stream_generator_->set_capacity_bps(kReducedCapacityBps);
int64_t overuse_start_time = clock_.TimeInMilliseconds();
- EXPECT_EQ(expected_overuse_start_time, overuse_start_time);
int64_t bitrate_drop_time = -1;
for (int i = 0; i < 100 * number_of_streams; ++i) {
GenerateAndProcessFrame(kDefaultSsrc, bitrate_bps);
diff --git a/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h b/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h
index 1d748c57..2ef2f45c 100644
--- a/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h
+++ b/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h
@@ -191,10 +191,9 @@ class RemoteBitrateEstimatorTest : public ::testing::Test {
void InitialBehaviorTestHelper(unsigned int expected_converge_bitrate);
void RateIncreaseReorderingTestHelper(unsigned int expected_bitrate);
- void RateIncreaseRtpTimestampsTestHelper();
+ void RateIncreaseRtpTimestampsTestHelper(int expected_iterations);
void CapacityDropTestHelper(int number_of_streams,
bool wrap_time_stamp,
- unsigned int expected_converge_bitrate,
unsigned int expected_bitrate_drop_delta);
static const unsigned int kDefaultSsrc;
diff --git a/modules/remote_bitrate_estimator/test/bwe_test_framework.cc b/modules/remote_bitrate_estimator/test/bwe_test_framework.cc
index 194db4d3..f7a7197e 100644
--- a/modules/remote_bitrate_estimator/test/bwe_test_framework.cc
+++ b/modules/remote_bitrate_estimator/test/bwe_test_framework.cc
@@ -155,6 +155,7 @@ void Packet::set_send_time_us(int64_t send_time_us) {
}
void Packet::SetAbsSendTimeMs(int64_t abs_send_time_ms) {
+ header_.extension.hasAbsoluteSendTime = true;
header_.extension.absoluteSendTime = ((static_cast<int64_t>(abs_send_time_ms *
(1 << 18)) + 500) / 1000) & 0x00fffffful;
}
@@ -543,8 +544,11 @@ PacketSender::PacketSender(PacketProcessorListener* listener,
}
-VideoSender::VideoSender(int flow_id, PacketProcessorListener* listener,
- float fps, uint32_t kbps, uint32_t ssrc,
+VideoSender::VideoSender(int flow_id,
+ PacketProcessorListener* listener,
+ float fps,
+ uint32_t kbps,
+ uint32_t ssrc,
float first_frame_offset)
: PacketSender(listener, FlowIds(1, flow_id)),
kMaxPayloadSizeBytes(1200),
@@ -566,6 +570,15 @@ uint32_t VideoSender::GetCapacityKbps() const {
return (bytes_per_second_ * 8) / 1000;
}
+uint32_t VideoSender::NextFrameSize() {
+ return frame_size_bytes_;
+}
+
+uint32_t VideoSender::NextPacketSize(uint32_t frame_size,
+ uint32_t remaining_payload) {
+ return std::min(kMaxPayloadSizeBytes, remaining_payload);
+}
+
void VideoSender::RunFor(int64_t time_ms, Packets* in_out) {
assert(in_out);
now_ms_ += time_ms;
@@ -580,10 +593,12 @@ void VideoSender::RunFor(int64_t time_ms, Packets* in_out) {
// one packet, we will see a number of equally sized packets followed by
// one smaller at the tail.
int64_t send_time_us = next_frame_ms_ * 1000.0;
- uint32_t payload_size = frame_size_bytes_;
+ uint32_t frame_size = NextFrameSize();
+ uint32_t payload_size = frame_size;
+
while (payload_size > 0) {
++prototype_header_.sequenceNumber;
- uint32_t size = std::min(kMaxPayloadSizeBytes, payload_size);
+ uint32_t size = NextPacketSize(frame_size, payload_size);
new_packets.push_back(Packet(flow_ids()[0], send_time_us, size,
prototype_header_));
new_packets.back().SetAbsSendTimeMs(next_frame_ms_);
@@ -601,13 +616,69 @@ AdaptiveVideoSender::AdaptiveVideoSender(int flow_id,
uint32_t kbps,
uint32_t ssrc,
float first_frame_offset)
- : VideoSender(flow_id, listener, fps, kbps, ssrc, first_frame_offset) {}
+ : VideoSender(flow_id, listener, fps, kbps, ssrc, first_frame_offset) {
+}
void AdaptiveVideoSender::GiveFeedback(const PacketSender::Feedback& feedback) {
- bytes_per_second_ = feedback.estimated_bps / 8;
+ bytes_per_second_ = std::min(feedback.estimated_bps / 8, 2500000u / 8);
frame_size_bytes_ = (bytes_per_second_ * frame_period_ms_ + 500) / 1000;
}
+PeriodicKeyFrameSender::PeriodicKeyFrameSender(
+ int flow_id,
+ PacketProcessorListener* listener,
+ float fps,
+ uint32_t kbps,
+ uint32_t ssrc,
+ float first_frame_offset,
+ int key_frame_interval)
+ : AdaptiveVideoSender(flow_id,
+ listener,
+ fps,
+ kbps,
+ ssrc,
+ first_frame_offset),
+ key_frame_interval_(key_frame_interval),
+ frame_counter_(0),
+ compensation_bytes_(0),
+ compensation_per_frame_(0) {
+}
+
+uint32_t PeriodicKeyFrameSender::NextFrameSize() {
+ uint32_t payload_size = frame_size_bytes_;
+ if (frame_counter_ == 0) {
+ payload_size = kMaxPayloadSizeBytes * 12;
+ compensation_bytes_ = 4 * frame_size_bytes_;
+ compensation_per_frame_ = compensation_bytes_ / 30;
+ } else if (key_frame_interval_ > 0 &&
+ (frame_counter_ % key_frame_interval_ == 0)) {
+ payload_size *= 5;
+ compensation_bytes_ = payload_size - frame_size_bytes_;
+ compensation_per_frame_ = compensation_bytes_ / 30;
+ } else if (compensation_bytes_ > 0) {
+ if (compensation_per_frame_ > static_cast<int>(payload_size)) {
+ // Skip this frame.
+ compensation_bytes_ -= payload_size;
+ payload_size = 0;
+ } else {
+ payload_size -= compensation_per_frame_;
+ compensation_bytes_ -= compensation_per_frame_;
+ }
+ }
+ if (compensation_bytes_ < 0)
+ compensation_bytes_ = 0;
+ ++frame_counter_;
+ return payload_size;
+}
+
+uint32_t PeriodicKeyFrameSender::NextPacketSize(uint32_t frame_size,
+ uint32_t remaining_payload) {
+ uint32_t fragments =
+ (frame_size + (kMaxPayloadSizeBytes - 1)) / kMaxPayloadSizeBytes;
+ uint32_t avg_size = (frame_size + fragments - 1) / fragments;
+ return std::min(avg_size, remaining_payload);
+}
+
PacedVideoSender::PacedVideoSender(PacketProcessorListener* listener,
uint32_t kbps,
AdaptiveVideoSender* source)
@@ -617,22 +688,40 @@ PacedVideoSender::PacedVideoSender(PacketProcessorListener* listener,
: PacketSender(listener, source->flow_ids()),
clock_(0),
start_of_run_ms_(0),
- pacer_(&clock_, this, PacedSender::kDefaultPaceMultiplier * kbps, 0),
- source_(source) {}
+ pacer_(&clock_, this, kbps, PacedSender::kDefaultPaceMultiplier* kbps, 0),
+ source_(source) {
+}
void PacedVideoSender::RunFor(int64_t time_ms, Packets* in_out) {
start_of_run_ms_ = clock_.TimeInMilliseconds();
Packets generated_packets;
source_->RunFor(time_ms, &generated_packets);
- Packets::iterator it = generated_packets.begin();
// Run process periodically to allow the packets to be paced out.
- const int kProcessIntervalMs = 10;
- for (int64_t current_time = 0; current_time < time_ms;
- current_time += kProcessIntervalMs) {
- int64_t end_of_interval_us =
- 1000 * (clock_.TimeInMilliseconds() + kProcessIntervalMs);
- while (it != generated_packets.end() &&
- end_of_interval_us >= it->send_time_us()) {
+ int64_t end_time_ms = clock_.TimeInMilliseconds() + time_ms;
+ Packets::iterator it = generated_packets.begin();
+ while (clock_.TimeInMilliseconds() <= end_time_ms) {
+ int time_until_process_ms = pacer_.TimeUntilNextProcess();
+ if (time_until_process_ms < 0)
+ time_until_process_ms = 0;
+ int time_until_packet_ms = time_ms;
+ if (it != generated_packets.end())
+ time_until_packet_ms =
+ (it->send_time_us() + 500) / 1000 - clock_.TimeInMilliseconds();
+ assert(time_until_packet_ms >= 0);
+ int time_until_next_event_ms = time_until_packet_ms;
+ if (time_until_process_ms < time_until_packet_ms &&
+ pacer_.QueueSizePackets() > 0)
+ time_until_next_event_ms = time_until_process_ms;
+
+ if (clock_.TimeInMilliseconds() + time_until_next_event_ms > end_time_ms) {
+ clock_.AdvanceTimeMilliseconds(end_time_ms - clock_.TimeInMilliseconds());
+ break;
+ }
+ clock_.AdvanceTimeMilliseconds(time_until_next_event_ms);
+ if (time_until_process_ms < time_until_packet_ms) {
+ // Time to process.
+ pacer_.Process();
+ } else {
// Time to send next packet to pacer.
pacer_.SendPacket(PacedSender::kNormalPriority,
it->header().ssrc,
@@ -641,16 +730,14 @@ void PacedVideoSender::RunFor(int64_t time_ms, Packets* in_out) {
it->payload_size(),
false);
pacer_queue_.push_back(*it);
- const size_t kMaxPacerQueueSize = 1000;
+ const size_t kMaxPacerQueueSize = 10000;
if (pacer_queue_.size() > kMaxPacerQueueSize) {
pacer_queue_.pop_front();
}
++it;
}
- clock_.AdvanceTimeMilliseconds(kProcessIntervalMs);
- pacer_.Process();
}
- QueuePackets(in_out, (start_of_run_ms_ + time_ms) * 1000);
+ QueuePackets(in_out, end_time_ms * 1000);
}
void PacedVideoSender::QueuePackets(Packets* batch,
@@ -673,7 +760,9 @@ void PacedVideoSender::QueuePackets(Packets* batch,
void PacedVideoSender::GiveFeedback(const PacketSender::Feedback& feedback) {
source_->GiveFeedback(feedback);
pacer_.UpdateBitrate(
- PacedSender::kDefaultPaceMultiplier * feedback.estimated_bps / 1000, 0);
+ feedback.estimated_bps / 1000,
+ PacedSender::kDefaultPaceMultiplier * feedback.estimated_bps / 1000,
+ 0);
}
bool PacedVideoSender::TimeToSendPacket(uint32_t ssrc,
@@ -686,7 +775,7 @@ bool PacedVideoSender::TimeToSendPacket(uint32_t ssrc,
int64_t pace_out_time_ms = clock_.TimeInMilliseconds();
// Make sure a packet is never paced out earlier than when it was put into
// the pacer.
- assert(1000 * pace_out_time_ms >= it->send_time_us());
+ assert(pace_out_time_ms >= (it->send_time_us() + 500) / 1000);
it->SetAbsSendTimeMs(pace_out_time_ms);
it->set_send_time_us(1000 * pace_out_time_ms);
queue_.push_back(*it);
diff --git a/modules/remote_bitrate_estimator/test/bwe_test_framework.h b/modules/remote_bitrate_estimator/test/bwe_test_framework.h
index 0ab3b5f9..60981976 100644
--- a/modules/remote_bitrate_estimator/test/bwe_test_framework.h
+++ b/modules/remote_bitrate_estimator/test/bwe_test_framework.h
@@ -387,8 +387,12 @@ class PacketSender : public PacketProcessor {
class VideoSender : public PacketSender {
public:
- VideoSender(int flow_id, PacketProcessorListener* listener, float fps,
- uint32_t kbps, uint32_t ssrc, float first_frame_offset);
+ VideoSender(int flow_id,
+ PacketProcessorListener* listener,
+ float fps,
+ uint32_t kbps,
+ uint32_t ssrc,
+ float first_frame_offset);
virtual ~VideoSender() {}
uint32_t max_payload_size_bytes() const { return kMaxPayloadSizeBytes; }
@@ -399,6 +403,10 @@ class VideoSender : public PacketSender {
virtual void RunFor(int64_t time_ms, Packets* in_out) OVERRIDE;
protected:
+ virtual uint32_t NextFrameSize();
+ virtual uint32_t NextPacketSize(uint32_t frame_size,
+ uint32_t remaining_payload);
+
const uint32_t kMaxPayloadSizeBytes;
const uint32_t kTimestampBase;
const double frame_period_ms_;
@@ -427,6 +435,30 @@ class AdaptiveVideoSender : public VideoSender {
DISALLOW_IMPLICIT_CONSTRUCTORS(AdaptiveVideoSender);
};
+class PeriodicKeyFrameSender : public AdaptiveVideoSender {
+ public:
+ PeriodicKeyFrameSender(int flow_id,
+ PacketProcessorListener* listener,
+ float fps,
+ uint32_t kbps,
+ uint32_t ssrc,
+ float first_frame_offset,
+ int key_frame_interval);
+ virtual ~PeriodicKeyFrameSender() {}
+
+ protected:
+ virtual uint32_t NextFrameSize() OVERRIDE;
+ virtual uint32_t NextPacketSize(uint32_t frame_size,
+ uint32_t remaining_payload) OVERRIDE;
+
+ private:
+ int key_frame_interval_;
+ uint32_t frame_counter_;
+ int compensation_bytes_;
+ int compensation_per_frame_;
+ DISALLOW_IMPLICIT_CONSTRUCTORS(PeriodicKeyFrameSender);
+};
+
class PacedVideoSender : public PacketSender, public PacedSender::Callback {
public:
PacedVideoSender(PacketProcessorListener* listener,
@@ -445,12 +477,28 @@ class PacedVideoSender : public PacketSender, public PacedSender::Callback {
virtual int TimeToSendPadding(int bytes) OVERRIDE;
private:
+ class ProbingPacedSender : public PacedSender {
+ public:
+ ProbingPacedSender(Clock* clock,
+ Callback* callback,
+ int bitrate_kbps,
+ int max_bitrate_kbps,
+ int min_bitrate_kbps)
+ : PacedSender(clock,
+ callback,
+ bitrate_kbps,
+ max_bitrate_kbps,
+ min_bitrate_kbps) {}
+
+ virtual bool ProbingExperimentIsEnabled() const OVERRIDE { return true; }
+ };
+
void QueuePackets(Packets* batch, int64_t end_of_batch_time_us);
static const int64_t kInitialTimeMs = 0;
SimulatedClock clock_;
int64_t start_of_run_ms_;
- PacedSender pacer_;
+ ProbingPacedSender pacer_;
Packets pacer_queue_;
Packets queue_;
AdaptiveVideoSender* source_;
diff --git a/modules/rtp_rtcp.target.darwin-arm.mk b/modules/rtp_rtcp.target.darwin-arm.mk
index 03d2054b..0b6d5b2b 100644
--- a/modules/rtp_rtcp.target.darwin-arm.mk
+++ b/modules/rtp_rtcp.target.darwin-arm.mk
@@ -119,11 +119,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -139,6 +141,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -236,11 +239,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -256,6 +261,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/rtp_rtcp.target.darwin-arm64.mk b/modules/rtp_rtcp.target.darwin-arm64.mk
index c17344d4..0369ec37 100644
--- a/modules/rtp_rtcp.target.darwin-arm64.mk
+++ b/modules/rtp_rtcp.target.darwin-arm64.mk
@@ -108,11 +108,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -121,10 +123,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -210,11 +214,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -223,10 +229,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/rtp_rtcp.target.darwin-mips.mk b/modules/rtp_rtcp.target.darwin-mips.mk
index 9cead139..addcbf40 100644
--- a/modules/rtp_rtcp.target.darwin-mips.mk
+++ b/modules/rtp_rtcp.target.darwin-mips.mk
@@ -113,11 +113,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -132,6 +134,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -223,11 +226,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -242,6 +247,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/rtp_rtcp.target.darwin-mips64.mk b/modules/rtp_rtcp.target.darwin-mips64.mk
new file mode 100644
index 00000000..8fd5536c
--- /dev/null
+++ b/modules/rtp_rtcp.target.darwin-mips64.mk
@@ -0,0 +1,299 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_rtp_rtcp_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/rtp_rtcp/source/bitrate.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/fec_receiver_impl.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/receive_statistics_impl.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_header_parser.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_header_extension.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_sender.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_utility.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/ssrc_database.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/tmmbr_help.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/dtmf_queue.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/producer_fec.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_packet_history.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_payload_registry.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_receiver_video.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_format.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_format_h264.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_format_vp8.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_rtp_rtcp_gyp
+
+# Alias gyp target name.
+.PHONY: rtp_rtcp
+rtp_rtcp: third_party_webrtc_modules_rtp_rtcp_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/rtp_rtcp.target.darwin-x86.mk b/modules/rtp_rtcp.target.darwin-x86.mk
index 640347fe..afad3a59 100644
--- a/modules/rtp_rtcp.target.darwin-x86.mk
+++ b/modules/rtp_rtcp.target.darwin-x86.mk
@@ -114,11 +114,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -131,6 +133,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -222,11 +225,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -239,6 +244,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/rtp_rtcp.target.darwin-x86_64.mk b/modules/rtp_rtcp.target.darwin-x86_64.mk
index 85a9b7aa..fca9b24b 100644
--- a/modules/rtp_rtcp.target.darwin-x86_64.mk
+++ b/modules/rtp_rtcp.target.darwin-x86_64.mk
@@ -113,11 +113,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -130,6 +132,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -220,11 +223,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -237,6 +242,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/rtp_rtcp.target.linux-arm.mk b/modules/rtp_rtcp.target.linux-arm.mk
index 03d2054b..0b6d5b2b 100644
--- a/modules/rtp_rtcp.target.linux-arm.mk
+++ b/modules/rtp_rtcp.target.linux-arm.mk
@@ -119,11 +119,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -139,6 +141,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -236,11 +239,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -256,6 +261,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/rtp_rtcp.target.linux-arm64.mk b/modules/rtp_rtcp.target.linux-arm64.mk
index c17344d4..0369ec37 100644
--- a/modules/rtp_rtcp.target.linux-arm64.mk
+++ b/modules/rtp_rtcp.target.linux-arm64.mk
@@ -108,11 +108,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -121,10 +123,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -210,11 +214,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -223,10 +229,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/rtp_rtcp.target.linux-mips.mk b/modules/rtp_rtcp.target.linux-mips.mk
index 9cead139..addcbf40 100644
--- a/modules/rtp_rtcp.target.linux-mips.mk
+++ b/modules/rtp_rtcp.target.linux-mips.mk
@@ -113,11 +113,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -132,6 +134,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -223,11 +226,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -242,6 +247,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/rtp_rtcp.target.linux-mips64.mk b/modules/rtp_rtcp.target.linux-mips64.mk
new file mode 100644
index 00000000..8fd5536c
--- /dev/null
+++ b/modules/rtp_rtcp.target.linux-mips64.mk
@@ -0,0 +1,299 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_rtp_rtcp_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/rtp_rtcp/source/bitrate.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/fec_receiver_impl.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/receive_statistics_impl.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/remote_ntp_time_estimator.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_header_parser.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtcp_packet.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_header_extension.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_sender.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_utility.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/ssrc_database.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/tmmbr_help.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/dtmf_queue.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/producer_fec.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_packet_history.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_payload_registry.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_receiver_video.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_format.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_format_h264.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_format_vp8.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.cc \
+ third_party/webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_rtp_rtcp_gyp
+
+# Alias gyp target name.
+.PHONY: rtp_rtcp
+rtp_rtcp: third_party_webrtc_modules_rtp_rtcp_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/rtp_rtcp.target.linux-x86.mk b/modules/rtp_rtcp.target.linux-x86.mk
index 640347fe..afad3a59 100644
--- a/modules/rtp_rtcp.target.linux-x86.mk
+++ b/modules/rtp_rtcp.target.linux-x86.mk
@@ -114,11 +114,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -131,6 +133,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -222,11 +225,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -239,6 +244,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/rtp_rtcp.target.linux-x86_64.mk b/modules/rtp_rtcp.target.linux-x86_64.mk
index 85a9b7aa..fca9b24b 100644
--- a/modules/rtp_rtcp.target.linux-x86_64.mk
+++ b/modules/rtp_rtcp.target.linux-x86_64.mk
@@ -113,11 +113,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -130,6 +132,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -220,11 +223,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -237,6 +242,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/rtp_rtcp/source/rtcp_receiver.cc b/modules/rtp_rtcp/source/rtcp_receiver.cc
index a9343145..1d1e2916 100644
--- a/modules/rtp_rtcp/source/rtcp_receiver.cc
+++ b/modules/rtp_rtcp/source/rtcp_receiver.cc
@@ -833,6 +833,8 @@ RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
++packet_type_counter_.nack_packets;
+ packet_type_counter_.nack_requests = nack_stats_.requests();
+ packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
}
}
@@ -842,6 +844,7 @@ RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
RTCPPacketInformation& rtcpPacketInformation)
{
rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
+ nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID);
uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
if(bitMask)
@@ -851,6 +854,7 @@ RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
if(bitMask & 0x01)
{
rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
+ nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID + i);
}
bitMask = bitMask >>1;
}
diff --git a/modules/rtp_rtcp/source/rtcp_receiver.h b/modules/rtp_rtcp/source/rtcp_receiver.h
index 84eb24c7..087722c4 100644
--- a/modules/rtp_rtcp/source/rtcp_receiver.h
+++ b/modules/rtp_rtcp/source/rtcp_receiver.h
@@ -270,6 +270,8 @@ protected:
RtcpStatisticsCallback* stats_callback_;
RtcpPacketTypeCounter packet_type_counter_;
+
+ RTCPUtility::NackStats nack_stats_;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_RECEIVER_H_
diff --git a/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
index b3a9d093..2a615734 100644
--- a/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
@@ -592,13 +592,6 @@ TEST_F(RtcpReceiverTest, InjectXrPacketWithUnknownReportBlock) {
EXPECT_FALSE(rtcp_packet_info_.xr_dlrr_item);
}
-TEST(RtcpUtilityTest, MidNtp) {
- const uint32_t kNtpSec = 0x12345678;
- const uint32_t kNtpFrac = 0x23456789;
- const uint32_t kNtpMid = 0x56782345;
- EXPECT_EQ(kNtpMid, RTCPUtility::MidNtp(kNtpSec, kNtpFrac));
-}
-
TEST_F(RtcpReceiverTest, TestXrRrRttInitiallyFalse) {
uint16_t rtt_ms;
EXPECT_FALSE(rtcp_receiver_->GetAndResetXrRrRtt(&rtt_ms));
diff --git a/modules/rtp_rtcp/source/rtcp_sender.cc b/modules/rtp_rtcp/source/rtcp_sender.cc
index 1edbee43..afe80195 100644
--- a/modules/rtp_rtcp/source/rtcp_sender.cc
+++ b/modules/rtp_rtcp/source/rtcp_sender.cc
@@ -1354,7 +1354,6 @@ RTCPSender::BuildNACK(uint8_t* rtcpbuffer,
RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC);
pos += 4;
- NACKStringBuilder stringBuilder;
// Build NACK bitmasks and write them to the RTCP message.
// The nack list should be sorted and not contain duplicates if one
// wants to build the smallest rtcp nack packet.
@@ -1363,13 +1362,11 @@ RTCPSender::BuildNACK(uint8_t* rtcpbuffer,
(IP_PACKET_SIZE - pos) / 4);
int i = 0;
while (i < nackSize && numOfNackFields < maxNackFields) {
- stringBuilder.PushNACK(nackList[i]);
uint16_t nack = nackList[i++];
uint16_t bitmask = 0;
while (i < nackSize) {
int shift = static_cast<uint16_t>(nackList[i] - nack) - 1;
if (shift >= 0 && shift <= 15) {
- stringBuilder.PushNACK(nackList[i]);
bitmask |= (1 << shift);
++i;
} else {
@@ -1384,11 +1381,21 @@ RTCPSender::BuildNACK(uint8_t* rtcpbuffer,
pos += 2;
numOfNackFields++;
}
+ rtcpbuffer[nackSizePos] = static_cast<uint8_t>(2 + numOfNackFields);
+
if (i != nackSize) {
- LOG(LS_WARNING) << "Nack list to large for one packet.";
+ LOG(LS_WARNING) << "Nack list too large for one packet.";
+ }
+
+ // Report stats.
+ NACKStringBuilder stringBuilder;
+ for (int idx = 0; idx < i; ++idx) {
+ stringBuilder.PushNACK(nackList[idx]);
+ nack_stats_.ReportRequest(nackList[idx]);
}
- rtcpbuffer[nackSizePos] = static_cast<uint8_t>(2 + numOfNackFields);
*nackString = stringBuilder.GetResult();
+ packet_type_counter_.nack_requests = nack_stats_.requests();
+ packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
return 0;
}
diff --git a/modules/rtp_rtcp/source/rtcp_sender.h b/modules/rtp_rtcp/source/rtcp_sender.h
index c0b8ebdb..06c373b6 100644
--- a/modules/rtp_rtcp/source/rtcp_sender.h
+++ b/modules/rtp_rtcp/source/rtcp_sender.h
@@ -360,6 +360,8 @@ private:
RtcpPacketTypeCounter packet_type_counter_
GUARDED_BY(_criticalSectionRTCPSender);
+
+ RTCPUtility::NackStats nack_stats_ GUARDED_BY(_criticalSectionRTCPSender);
};
} // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtcp_utility.cc b/modules/rtp_rtcp/source/rtcp_utility.cc
index 9acab735..04233896 100644
--- a/modules/rtp_rtcp/source/rtcp_utility.cc
+++ b/modules/rtp_rtcp/source/rtcp_utility.cc
@@ -17,6 +17,23 @@
namespace webrtc {
namespace RTCPUtility {
+
+NackStats::NackStats()
+ : max_sequence_number_(0),
+ requests_(0),
+ unique_requests_(0) {}
+
+NackStats::~NackStats() {}
+
+void NackStats::ReportRequest(uint16_t sequence_number) {
+ if (requests_ == 0 ||
+ webrtc::IsNewerSequenceNumber(sequence_number, max_sequence_number_)) {
+ max_sequence_number_ = sequence_number;
+ ++unique_requests_;
+ }
+ ++requests_;
+}
+
uint32_t MidNtp(uint32_t ntp_sec, uint32_t ntp_frac) {
return (ntp_sec << 16) + (ntp_frac >> 16);
} // end RTCPUtility
diff --git a/modules/rtp_rtcp/source/rtcp_utility.h b/modules/rtp_rtcp/source/rtcp_utility.h
index f0867a75..804e8b94 100644
--- a/modules/rtp_rtcp/source/rtcp_utility.h
+++ b/modules/rtp_rtcp/source/rtcp_utility.h
@@ -19,6 +19,29 @@
namespace webrtc {
namespace RTCPUtility {
+
+class NackStats {
+ public:
+ NackStats();
+ ~NackStats();
+
+ // Updates stats with requested sequence number.
+ // This function should be called for each NACK request to calculate the
+ // number of unique NACKed RTP packets.
+ void ReportRequest(uint16_t sequence_number);
+
+ // Gets the number of NACKed RTP packets.
+ uint32_t requests() const { return requests_; }
+
+ // Gets the number of unique NACKed RTP packets.
+ uint32_t unique_requests() const { return unique_requests_; }
+
+ private:
+ uint16_t max_sequence_number_;
+ uint32_t requests_;
+ uint32_t unique_requests_;
+};
+
uint32_t MidNtp(uint32_t ntp_sec, uint32_t ntp_frac);
// CNAME
diff --git a/modules/rtp_rtcp/source/rtcp_utility_unittest.cc b/modules/rtp_rtcp/source/rtcp_utility_unittest.cc
new file mode 100644
index 00000000..275b007b
--- /dev/null
+++ b/modules/rtp_rtcp/source/rtcp_utility_unittest.cc
@@ -0,0 +1,72 @@
+/*
+ * 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 "testing/gtest/include/gtest/gtest.h"
+
+#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
+
+namespace webrtc {
+
+TEST(RtcpUtilityTest, MidNtp) {
+ const uint32_t kNtpSec = 0x12345678;
+ const uint32_t kNtpFrac = 0x23456789;
+ const uint32_t kNtpMid = 0x56782345;
+ EXPECT_EQ(kNtpMid, RTCPUtility::MidNtp(kNtpSec, kNtpFrac));
+}
+
+TEST(RtcpUtilityTest, NackRequests) {
+ RTCPUtility::NackStats stats;
+ EXPECT_EQ(0U, stats.unique_requests());
+ EXPECT_EQ(0U, stats.requests());
+ stats.ReportRequest(10);
+ EXPECT_EQ(1U, stats.unique_requests());
+ EXPECT_EQ(1U, stats.requests());
+
+ stats.ReportRequest(10);
+ EXPECT_EQ(1U, stats.unique_requests());
+ stats.ReportRequest(11);
+ EXPECT_EQ(2U, stats.unique_requests());
+
+ stats.ReportRequest(11);
+ EXPECT_EQ(2U, stats.unique_requests());
+ stats.ReportRequest(13);
+ EXPECT_EQ(3U, stats.unique_requests());
+
+ stats.ReportRequest(11);
+ EXPECT_EQ(3U, stats.unique_requests());
+ EXPECT_EQ(6U, stats.requests());
+}
+
+TEST(RtcpUtilityTest, NackRequestsWithWrap) {
+ RTCPUtility::NackStats stats;
+ stats.ReportRequest(65534);
+ EXPECT_EQ(1U, stats.unique_requests());
+
+ stats.ReportRequest(65534);
+ EXPECT_EQ(1U, stats.unique_requests());
+ stats.ReportRequest(65535);
+ EXPECT_EQ(2U, stats.unique_requests());
+
+ stats.ReportRequest(65535);
+ EXPECT_EQ(2U, stats.unique_requests());
+ stats.ReportRequest(0);
+ EXPECT_EQ(3U, stats.unique_requests());
+
+ stats.ReportRequest(65535);
+ EXPECT_EQ(3U, stats.unique_requests());
+ stats.ReportRequest(0);
+ EXPECT_EQ(3U, stats.unique_requests());
+ stats.ReportRequest(1);
+ EXPECT_EQ(4U, stats.unique_requests());
+ EXPECT_EQ(8U, stats.requests());
+}
+
+} // namespace webrtc
+
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
index 4868b71f..24ff227a 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
@@ -18,8 +18,10 @@
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
#include "webrtc/system_wrappers/interface/scoped_vector.h"
+#include "webrtc/test/rtcp_packet_parser.h"
using ::testing::_;
+using ::testing::ElementsAre;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SaveArg;
@@ -76,6 +78,10 @@ class SendTransport : public Transport,
return len;
}
virtual int SendRTCPPacket(int /*ch*/, const void *data, int len) OVERRIDE {
+ test::RtcpPacketParser parser;
+ parser.Parse(static_cast<const uint8_t*>(data), len);
+ last_nack_list_ = parser.nack_item()->last_nack_list();
+
if (clock_) {
clock_->AdvanceTimeMilliseconds(delay_ms_);
}
@@ -89,6 +95,7 @@ class SendTransport : public Transport,
uint32_t delay_ms_;
int rtp_packets_sent_;
RTPHeader last_rtp_header_;
+ std::vector<uint16_t> last_nack_list_;
};
class RtpRtcpModule {
@@ -129,6 +136,9 @@ class RtpRtcpModule {
uint16_t LastRtpSequenceNumber() {
return transport_.last_rtp_header_.sequenceNumber;
}
+ std::vector<uint16_t> LastNackListSent() {
+ return transport_.last_nack_list_;
+ }
};
} // namespace
@@ -344,6 +354,46 @@ TEST_F(RtpRtcpImplTest, RtcpPacketTypeCounter_FirAndPli) {
EXPECT_EQ(1U, sender_.RtcpReceived().pli_packets);
}
+TEST_F(RtpRtcpImplTest, UniqueNackRequests) {
+ receiver_.transport_.SimulateNetworkDelay(0, &clock_);
+ EXPECT_EQ(0U, receiver_.RtcpSent().nack_packets);
+ EXPECT_EQ(0U, receiver_.RtcpSent().nack_requests);
+ EXPECT_EQ(0U, receiver_.RtcpSent().unique_nack_requests);
+ EXPECT_EQ(0, receiver_.RtcpSent().UniqueNackRequestsInPercent());
+
+ // Receive module sends NACK request.
+ const uint16_t kNackLength = 4;
+ uint16_t nack_list[kNackLength] = {10, 11, 13, 18};
+ EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list, kNackLength));
+ EXPECT_EQ(1U, receiver_.RtcpSent().nack_packets);
+ EXPECT_EQ(4U, receiver_.RtcpSent().nack_requests);
+ EXPECT_EQ(4U, receiver_.RtcpSent().unique_nack_requests);
+ EXPECT_THAT(receiver_.LastNackListSent(), ElementsAre(10, 11, 13, 18));
+
+ // Send module receives the request.
+ EXPECT_EQ(1U, sender_.RtcpReceived().nack_packets);
+ EXPECT_EQ(4U, sender_.RtcpReceived().nack_requests);
+ EXPECT_EQ(4U, sender_.RtcpReceived().unique_nack_requests);
+ EXPECT_EQ(100, sender_.RtcpReceived().UniqueNackRequestsInPercent());
+
+ // Receive module sends new request with duplicated packets.
+ const int kStartupRttMs = 100;
+ clock_.AdvanceTimeMilliseconds(kStartupRttMs + 1);
+ const uint16_t kNackLength2 = 4;
+ uint16_t nack_list2[kNackLength2] = {11, 18, 20, 21};
+ EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list2, kNackLength2));
+ EXPECT_EQ(2U, receiver_.RtcpSent().nack_packets);
+ EXPECT_EQ(8U, receiver_.RtcpSent().nack_requests);
+ EXPECT_EQ(6U, receiver_.RtcpSent().unique_nack_requests);
+ EXPECT_THAT(receiver_.LastNackListSent(), ElementsAre(11, 18, 20, 21));
+
+ // Send module receives the request.
+ EXPECT_EQ(2U, sender_.RtcpReceived().nack_packets);
+ EXPECT_EQ(8U, sender_.RtcpReceived().nack_requests);
+ EXPECT_EQ(6U, sender_.RtcpReceived().unique_nack_requests);
+ EXPECT_EQ(75, sender_.RtcpReceived().UniqueNackRequestsInPercent());
+}
+
class RtpSendingTestTransport : public Transport {
public:
void ResetCounters() { bytes_received_.clear(); }
diff --git a/modules/rtp_rtcp/source/rtp_sender.cc b/modules/rtp_rtcp/source/rtp_sender.cc
index f544db21..0438b9f7 100644
--- a/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/modules/rtp_rtcp/source/rtp_sender.cc
@@ -50,12 +50,17 @@ RTPSender::RTPSender(const int32_t id,
FrameCountObserver* frame_count_observer,
SendSideDelayObserver* send_side_delay_observer)
: clock_(clock),
+ // TODO(holmer): Remove this conversion when we remove the use of
+ // TickTime.
+ clock_delta_ms_(clock_->TimeInMilliseconds() -
+ TickTime::MillisecondTimestamp()),
bitrate_sent_(clock, this),
id_(id),
audio_configured_(audio),
audio_(NULL),
video_(NULL),
paced_sender_(paced_sender),
+ last_capture_time_ms_sent_(0),
send_critsect_(CriticalSectionWrapper::CreateCriticalSection()),
transport_(transport),
sending_media_(true), // Default to sending media.
@@ -622,15 +627,10 @@ int32_t RTPSender::ReSendPacket(uint16_t packet_id, uint32_t min_resend_time) {
}
// Convert from TickTime to Clock since capture_time_ms is based on
// TickTime.
- // TODO(holmer): Remove this conversion when we remove the use of TickTime.
- int64_t clock_delta_ms = clock_->TimeInMilliseconds() -
- TickTime::MillisecondTimestamp();
- if (!paced_sender_->SendPacket(PacedSender::kHighPriority,
- header.ssrc,
- header.sequenceNumber,
- capture_time_ms + clock_delta_ms,
- length - header.headerLength,
- true)) {
+ int64_t corrected_capture_tims_ms = capture_time_ms + clock_delta_ms_;
+ if (!paced_sender_->SendPacket(
+ PacedSender::kHighPriority, header.ssrc, header.sequenceNumber,
+ corrected_capture_tims_ms, length - header.headerLength, true)) {
// We can't send the packet right now.
// We will be called when it is time.
return length;
@@ -819,6 +819,10 @@ bool RTPSender::PrepareAndSendPacket(uint8_t* buffer,
RtpUtility::RtpHeaderParser rtp_parser(buffer, length);
RTPHeader rtp_header;
rtp_parser.Parse(rtp_header);
+ if (!is_retransmit && rtp_header.markerBit) {
+ TRACE_EVENT_ASYNC_END0("webrtc_rtp", "PacedSend", capture_time_ms);
+ }
+
TRACE_EVENT_INSTANT2("webrtc_rtp", "PrepareAndSendPacket",
"timestamp", rtp_header.timestamp,
"seqnum", rtp_header.sequenceNumber);
@@ -937,12 +941,18 @@ int32_t RTPSender::SendToNetwork(
}
if (paced_sender_ && storage != kDontStore) {
- int64_t clock_delta_ms = clock_->TimeInMilliseconds() -
- TickTime::MillisecondTimestamp();
+ // Correct offset between implementations of millisecond time stamps in
+ // TickTime and Clock.
+ int64_t corrected_time_ms = capture_time_ms + clock_delta_ms_;
if (!paced_sender_->SendPacket(priority, rtp_header.ssrc,
- rtp_header.sequenceNumber,
- capture_time_ms + clock_delta_ms,
+ rtp_header.sequenceNumber, corrected_time_ms,
payload_length, false)) {
+ if (last_capture_time_ms_sent_ == 0 ||
+ corrected_time_ms > last_capture_time_ms_sent_) {
+ last_capture_time_ms_sent_ = corrected_time_ms;
+ TRACE_EVENT_ASYNC_BEGIN1("webrtc_rtp", "PacedSend", corrected_time_ms,
+ "capture_time_ms", corrected_time_ms);
+ }
// We can't send the packet right now.
// We will be called when it is time.
return 0;
@@ -954,7 +964,6 @@ int32_t RTPSender::SendToNetwork(
uint32_t length = payload_length + rtp_header_length;
if (!SendPacketToNetwork(buffer, length))
return -1;
- assert(payload_length - rtp_header.paddingLength > 0);
{
CriticalSectionScoped lock(send_critsect_);
media_has_been_sent_ = true;
diff --git a/modules/rtp_rtcp/source/rtp_sender.h b/modules/rtp_rtcp/source/rtp_sender.h
index b2f2e0c4..780baa1f 100644
--- a/modules/rtp_rtcp/source/rtp_sender.h
+++ b/modules/rtp_rtcp/source/rtp_sender.h
@@ -336,6 +336,7 @@ class RTPSender : public RTPSenderInterface, public Bitrate::Observer {
bool IsFecPacket(const uint8_t* buffer, const RTPHeader& header) const;
Clock* clock_;
+ int64_t clock_delta_ms_;
Bitrate bitrate_sent_;
int32_t id_;
@@ -344,6 +345,7 @@ class RTPSender : public RTPSenderInterface, public Bitrate::Observer {
RTPSenderVideo *video_;
PacedSender *paced_sender_;
+ int64_t last_capture_time_ms_sent_;
CriticalSectionWrapper *send_critsect_;
Transport *transport_;
diff --git a/modules/video_capture/android/java/src/org/webrtc/videoengine/VideoCaptureAndroid.java b/modules/video_capture/android/java/src/org/webrtc/videoengine/VideoCaptureAndroid.java
index 926b350e..2ebf911f 100644
--- a/modules/video_capture/android/java/src/org/webrtc/videoengine/VideoCaptureAndroid.java
+++ b/modules/video_capture/android/java/src/org/webrtc/videoengine/VideoCaptureAndroid.java
@@ -11,11 +11,13 @@
package org.webrtc.videoengine;
import java.io.IOException;
+import java.util.List;
import java.util.concurrent.Exchanger;
import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
+import android.hardware.Camera.Parameters;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera;
import android.opengl.GLES11Ext;
@@ -58,6 +60,7 @@ public class VideoCaptureAndroid implements PreviewCallback, Callback {
private double averageDurationMs;
private long lastCaptureTimeMs;
private int frameCount;
+ private int frameDropRatio;
// Requests future capturers to send their frames to |localPreview| directly.
public static void setLocalPreview(SurfaceHolder localPreview) {
@@ -169,8 +172,40 @@ public class VideoCaptureAndroid implements PreviewCallback, Callback {
if (parameters.isVideoStabilizationSupported()) {
parameters.setVideoStabilization(true);
}
+ parameters.setPictureSize(width, height);
parameters.setPreviewSize(width, height);
+
+ // Check if requested fps range is supported by camera,
+ // otherwise calculate frame drop ratio.
+ List<int[]> supportedFpsRanges = parameters.getSupportedPreviewFpsRange();
+ frameDropRatio = Integer.MAX_VALUE;
+ for (int i = 0; i < supportedFpsRanges.size(); i++) {
+ int[] range = supportedFpsRanges.get(i);
+ if (range[Parameters.PREVIEW_FPS_MIN_INDEX] == min_mfps &&
+ range[Parameters.PREVIEW_FPS_MAX_INDEX] == max_mfps) {
+ frameDropRatio = 1;
+ break;
+ }
+ if (range[Parameters.PREVIEW_FPS_MIN_INDEX] % min_mfps == 0 &&
+ range[Parameters.PREVIEW_FPS_MAX_INDEX] % max_mfps == 0) {
+ int dropRatio = range[Parameters.PREVIEW_FPS_MAX_INDEX] / max_mfps;
+ frameDropRatio = Math.min(dropRatio, frameDropRatio);
+ }
+ }
+ if (frameDropRatio == Integer.MAX_VALUE) {
+ Log.e(TAG, "Can not find camera fps range");
+ error = new RuntimeException("Can not find camera fps range");
+ exchange(result, false);
+ return;
+ }
+ if (frameDropRatio > 1) {
+ Log.d(TAG, "Frame dropper is enabled. Ratio: " + frameDropRatio);
+ }
+ min_mfps *= frameDropRatio;
+ max_mfps *= frameDropRatio;
+ Log.d(TAG, "Camera preview mfps range: " + min_mfps + " - " + max_mfps);
parameters.setPreviewFpsRange(min_mfps, max_mfps);
+
int format = ImageFormat.NV21;
parameters.setPreviewFormat(format);
camera.setParameters(parameters);
@@ -180,7 +215,7 @@ public class VideoCaptureAndroid implements PreviewCallback, Callback {
}
camera.setPreviewCallbackWithBuffer(this);
frameCount = 0;
- averageDurationMs = 1000 / max_mfps;
+ averageDurationMs = 1000000.0f / (max_mfps / frameDropRatio);
camera.startPreview();
exchange(result, true);
return;
@@ -296,8 +331,13 @@ public class VideoCaptureAndroid implements PreviewCallback, Callback {
throw new RuntimeException("Unexpected camera in callback!");
}
frameCount++;
+ // Check if frame needs to be dropped.
+ if ((frameDropRatio > 1) && (frameCount % frameDropRatio) > 0) {
+ camera.addCallbackBuffer(data);
+ return;
+ }
long captureTimeMs = SystemClock.elapsedRealtime();
- if (frameCount > 1) {
+ if (frameCount > frameDropRatio) {
double durationMs = captureTimeMs - lastCaptureTimeMs;
averageDurationMs = 0.9 * averageDurationMs + 0.1 * durationMs;
if ((frameCount % 30) == 0) {
diff --git a/modules/video_capture/android/java/src/org/webrtc/videoengine/VideoCaptureDeviceInfoAndroid.java b/modules/video_capture/android/java/src/org/webrtc/videoengine/VideoCaptureDeviceInfoAndroid.java
index fe207ca3..4b0089b1 100644
--- a/modules/video_capture/android/java/src/org/webrtc/videoengine/VideoCaptureDeviceInfoAndroid.java
+++ b/modules/video_capture/android/java/src/org/webrtc/videoengine/VideoCaptureDeviceInfoAndroid.java
@@ -75,6 +75,36 @@ public class VideoCaptureDeviceInfoAndroid {
sizes.put(size);
}
+ boolean is30fpsRange = false;
+ boolean is15fpsRange = false;
+ // If there is constant 30 fps mode, but no 15 fps - add 15 fps
+ // mode to the list of supported ranges. Frame drop will be done
+ // in software.
+ for (int[] range : supportedFpsRanges) {
+ if (range[Parameters.PREVIEW_FPS_MIN_INDEX] == 30000 &&
+ range[Parameters.PREVIEW_FPS_MAX_INDEX] == 30000) {
+ is30fpsRange = true;
+ }
+ if (range[Parameters.PREVIEW_FPS_MIN_INDEX] == 15000 &&
+ range[Parameters.PREVIEW_FPS_MAX_INDEX] == 15000) {
+ is15fpsRange = true;
+ }
+ }
+ if (is30fpsRange && !is15fpsRange) {
+ Log.d(TAG, "Adding 15 fps support");
+ int[] newRange = new int [Parameters.PREVIEW_FPS_MAX_INDEX + 1];
+ newRange[Parameters.PREVIEW_FPS_MIN_INDEX] = 15000;
+ newRange[Parameters.PREVIEW_FPS_MAX_INDEX] = 15000;
+ for (int j = 0; j < supportedFpsRanges.size(); j++ ) {
+ int[] range = supportedFpsRanges.get(j);
+ if (range[Parameters.PREVIEW_FPS_MAX_INDEX] >
+ newRange[Parameters.PREVIEW_FPS_MAX_INDEX]) {
+ supportedFpsRanges.add(j, newRange);
+ break;
+ }
+ }
+ }
+
JSONArray mfpsRanges = new JSONArray();
for (int[] range : supportedFpsRanges) {
JSONObject mfpsRange = new JSONObject();
diff --git a/modules/video_capture/video_capture.gypi b/modules/video_capture/video_capture.gypi
index 888d7727..22b8e02c 100644
--- a/modules/video_capture/video_capture.gypi
+++ b/modules/video_capture/video_capture.gypi
@@ -161,7 +161,7 @@
'type': '<(gtest_target_type)',
'dependencies': [
'video_capture_module',
- 'video_capture_module_internal_impl',
+ 'video_capture_module_internal_impl',
'webrtc_utility',
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
'<(DEPTH)/testing/gtest.gyp:gtest',
@@ -192,13 +192,13 @@
'dependencies': [
'<(DEPTH)/testing/android/native_test.gyp:native_test_native_code',
],
- # Need to disable error due to the line in
- # base/android/jni_android.h triggering it:
- # const BASE_EXPORT jobject GetApplicationContext()
- # error: type qualifiers ignored on function return type
- 'cflags': [
- '-Wno-ignored-qualifiers',
- ],
+ # Need to disable error due to the line in
+ # base/android/jni_android.h triggering it:
+ # const BASE_EXPORT jobject GetApplicationContext()
+ # error: type qualifiers ignored on function return type
+ 'cflags': [
+ '-Wno-ignored-qualifiers',
+ ],
}],
['OS=="mac"', {
'dependencies': [
@@ -243,7 +243,6 @@
],
'includes': [
'../../build/isolate.gypi',
- 'video_capture_tests.isolate',
],
'sources': [
'video_capture_tests.isolate',
diff --git a/modules/video_capture/video_capture_tests.isolate b/modules/video_capture/video_capture_tests.isolate
index 57dd6673..be104376 100644
--- a/modules/video_capture/video_capture_tests.isolate
+++ b/modules/video_capture/video_capture_tests.isolate
@@ -9,7 +9,7 @@
'conditions': [
['OS=="android"', {
'variables': {
- 'isolate_dependency_untracked': [
+ 'files': [
'<(DEPTH)/data/',
'<(DEPTH)/resources/',
],
@@ -21,13 +21,10 @@
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/video_capture_tests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/video_capture_tests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_untracked': [
- '<(DEPTH)/tools/swarming_client/',
- ],
},
}],
],
diff --git a/modules/video_capture_module.target.darwin-arm.mk b/modules/video_capture_module.target.darwin-arm.mk
index d007c5dd..8aac8041 100644
--- a/modules/video_capture_module.target.darwin-arm.mk
+++ b/modules/video_capture_module.target.darwin-arm.mk
@@ -89,11 +89,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -109,6 +111,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -208,11 +211,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -228,6 +233,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_capture_module.target.darwin-arm64.mk b/modules/video_capture_module.target.darwin-arm64.mk
index 5afb9486..372bca54 100644
--- a/modules/video_capture_module.target.darwin-arm64.mk
+++ b/modules/video_capture_module.target.darwin-arm64.mk
@@ -78,11 +78,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -91,10 +93,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -182,11 +186,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -195,10 +201,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_capture_module.target.darwin-mips.mk b/modules/video_capture_module.target.darwin-mips.mk
index 960b8fa1..afe1d564 100644
--- a/modules/video_capture_module.target.darwin-mips.mk
+++ b/modules/video_capture_module.target.darwin-mips.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -102,6 +104,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -195,11 +198,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -214,6 +219,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_capture_module.target.darwin-mips64.mk b/modules/video_capture_module.target.darwin-mips64.mk
new file mode 100644
index 00000000..5b80915c
--- /dev/null
+++ b/modules/video_capture_module.target.darwin-mips64.mk
@@ -0,0 +1,273 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_capture_module_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_capture/device_info_impl.cc \
+ third_party/webrtc/modules/video_capture/video_capture_factory.cc \
+ third_party/webrtc/modules/video_capture/video_capture_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_capture_module_gyp
+
+# Alias gyp target name.
+.PHONY: video_capture_module
+video_capture_module: third_party_webrtc_modules_video_capture_module_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_capture_module.target.darwin-x86.mk b/modules/video_capture_module.target.darwin-x86.mk
index 3d673808..702cc352 100644
--- a/modules/video_capture_module.target.darwin-x86.mk
+++ b/modules/video_capture_module.target.darwin-x86.mk
@@ -84,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -194,11 +197,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -211,6 +216,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_capture_module.target.darwin-x86_64.mk b/modules/video_capture_module.target.darwin-x86_64.mk
index 127814ee..01a7bef5 100644
--- a/modules/video_capture_module.target.darwin-x86_64.mk
+++ b/modules/video_capture_module.target.darwin-x86_64.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -192,11 +195,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -209,6 +214,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_capture_module.target.linux-arm.mk b/modules/video_capture_module.target.linux-arm.mk
index d007c5dd..8aac8041 100644
--- a/modules/video_capture_module.target.linux-arm.mk
+++ b/modules/video_capture_module.target.linux-arm.mk
@@ -89,11 +89,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -109,6 +111,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -208,11 +211,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -228,6 +233,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_capture_module.target.linux-arm64.mk b/modules/video_capture_module.target.linux-arm64.mk
index 5afb9486..372bca54 100644
--- a/modules/video_capture_module.target.linux-arm64.mk
+++ b/modules/video_capture_module.target.linux-arm64.mk
@@ -78,11 +78,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -91,10 +93,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -182,11 +186,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -195,10 +201,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_capture_module.target.linux-mips.mk b/modules/video_capture_module.target.linux-mips.mk
index 960b8fa1..afe1d564 100644
--- a/modules/video_capture_module.target.linux-mips.mk
+++ b/modules/video_capture_module.target.linux-mips.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -102,6 +104,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -195,11 +198,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -214,6 +219,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_capture_module.target.linux-mips64.mk b/modules/video_capture_module.target.linux-mips64.mk
new file mode 100644
index 00000000..5b80915c
--- /dev/null
+++ b/modules/video_capture_module.target.linux-mips64.mk
@@ -0,0 +1,273 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_capture_module_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_capture/device_info_impl.cc \
+ third_party/webrtc/modules/video_capture/video_capture_factory.cc \
+ third_party/webrtc/modules/video_capture/video_capture_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_capture_module_gyp
+
+# Alias gyp target name.
+.PHONY: video_capture_module
+video_capture_module: third_party_webrtc_modules_video_capture_module_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_capture_module.target.linux-x86.mk b/modules/video_capture_module.target.linux-x86.mk
index 3d673808..702cc352 100644
--- a/modules/video_capture_module.target.linux-x86.mk
+++ b/modules/video_capture_module.target.linux-x86.mk
@@ -84,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -194,11 +197,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -211,6 +216,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_capture_module.target.linux-x86_64.mk b/modules/video_capture_module.target.linux-x86_64.mk
index 127814ee..01a7bef5 100644
--- a/modules/video_capture_module.target.linux-x86_64.mk
+++ b/modules/video_capture_module.target.linux-x86_64.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -192,11 +195,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -209,6 +214,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_capture_module_impl.target.darwin-arm.mk b/modules/video_capture_module_impl.target.darwin-arm.mk
index 1df21a9c..7e0df19e 100644
--- a/modules/video_capture_module_impl.target.darwin-arm.mk
+++ b/modules/video_capture_module_impl.target.darwin-arm.mk
@@ -88,11 +88,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -108,6 +110,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -204,11 +207,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -224,6 +229,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_capture_module_impl.target.darwin-arm64.mk b/modules/video_capture_module_impl.target.darwin-arm64.mk
index 758069c2..b67e56ad 100644
--- a/modules/video_capture_module_impl.target.darwin-arm64.mk
+++ b/modules/video_capture_module_impl.target.darwin-arm64.mk
@@ -77,11 +77,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -90,10 +92,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -178,11 +182,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -191,10 +197,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_capture_module_impl.target.darwin-mips.mk b/modules/video_capture_module_impl.target.darwin-mips.mk
index 5611034f..265e3bc5 100644
--- a/modules/video_capture_module_impl.target.darwin-mips.mk
+++ b/modules/video_capture_module_impl.target.darwin-mips.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -210,6 +215,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_capture_module_impl.target.darwin-mips64.mk b/modules/video_capture_module_impl.target.darwin-mips64.mk
new file mode 100644
index 00000000..01552459
--- /dev/null
+++ b/modules/video_capture_module_impl.target.darwin-mips64.mk
@@ -0,0 +1,266 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_capture_module_impl_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_capture/external/device_info_external.cc \
+ third_party/webrtc/modules/video_capture/external/video_capture_external.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_capture_module_impl_gyp
+
+# Alias gyp target name.
+.PHONY: video_capture_module_impl
+video_capture_module_impl: third_party_webrtc_modules_video_capture_module_impl_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_capture_module_impl.target.darwin-x86.mk b/modules/video_capture_module_impl.target.darwin-x86.mk
index 35ddb503..52a6a516 100644
--- a/modules/video_capture_module_impl.target.darwin-x86.mk
+++ b/modules/video_capture_module_impl.target.darwin-x86.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -190,11 +193,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -207,6 +212,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_capture_module_impl.target.darwin-x86_64.mk b/modules/video_capture_module_impl.target.darwin-x86_64.mk
index 671273cc..7e4d529a 100644
--- a/modules/video_capture_module_impl.target.darwin-x86_64.mk
+++ b/modules/video_capture_module_impl.target.darwin-x86_64.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -188,11 +191,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -205,6 +210,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_capture_module_impl.target.linux-arm.mk b/modules/video_capture_module_impl.target.linux-arm.mk
index 1df21a9c..7e0df19e 100644
--- a/modules/video_capture_module_impl.target.linux-arm.mk
+++ b/modules/video_capture_module_impl.target.linux-arm.mk
@@ -88,11 +88,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -108,6 +110,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -204,11 +207,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -224,6 +229,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_capture_module_impl.target.linux-arm64.mk b/modules/video_capture_module_impl.target.linux-arm64.mk
index 758069c2..b67e56ad 100644
--- a/modules/video_capture_module_impl.target.linux-arm64.mk
+++ b/modules/video_capture_module_impl.target.linux-arm64.mk
@@ -77,11 +77,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -90,10 +92,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -178,11 +182,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -191,10 +197,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_capture_module_impl.target.linux-mips.mk b/modules/video_capture_module_impl.target.linux-mips.mk
index 5611034f..265e3bc5 100644
--- a/modules/video_capture_module_impl.target.linux-mips.mk
+++ b/modules/video_capture_module_impl.target.linux-mips.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -210,6 +215,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_capture_module_impl.target.linux-mips64.mk b/modules/video_capture_module_impl.target.linux-mips64.mk
new file mode 100644
index 00000000..01552459
--- /dev/null
+++ b/modules/video_capture_module_impl.target.linux-mips64.mk
@@ -0,0 +1,266 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_capture_module_impl_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_capture/external/device_info_external.cc \
+ third_party/webrtc/modules/video_capture/external/video_capture_external.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_capture_module_impl_gyp
+
+# Alias gyp target name.
+.PHONY: video_capture_module_impl
+video_capture_module_impl: third_party_webrtc_modules_video_capture_module_impl_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_capture_module_impl.target.linux-x86.mk b/modules/video_capture_module_impl.target.linux-x86.mk
index 35ddb503..52a6a516 100644
--- a/modules/video_capture_module_impl.target.linux-x86.mk
+++ b/modules/video_capture_module_impl.target.linux-x86.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -190,11 +193,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -207,6 +212,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_capture_module_impl.target.linux-x86_64.mk b/modules/video_capture_module_impl.target.linux-x86_64.mk
index 671273cc..7e4d529a 100644
--- a/modules/video_capture_module_impl.target.linux-x86_64.mk
+++ b/modules/video_capture_module_impl.target.linux-x86_64.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -188,11 +191,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -205,6 +210,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn
index 07e7afc0..706e9d99 100644
--- a/modules/video_coding/BUILD.gn
+++ b/modules/video_coding/BUILD.gn
@@ -77,6 +77,7 @@ source_set("video_coding") {
":video_coding_utility",
":webrtc_i420",
":webrtc_vp8",
+ ":webrtc_vp9",
"../../common_video",
"../../system_wrappers",
]
@@ -159,3 +160,35 @@ source_set("webrtc_vp8") {
]
}
}
+
+source_set("webrtc_vp9") {
+ sources = [
+ "codecs/vp9/include/vp9.h",
+ "codecs/vp9/vp9_impl.cc",
+ "codecs/vp9/vp9_impl.h",
+ ]
+
+ configs += [ "../..:common_config" ]
+ public_configs = [ "../..:common_inherited_config" ]
+
+ if (is_clang) {
+ # Suppress warnings from Chrome's Clang plugins.
+ # See http://code.google.com/p/webrtc/issues/detail?id=163 for details.
+ configs -= [ "//build/config/clang:find_bad_constructs" ]
+ }
+
+ # TODO(kjellander): Remove once libvpx has changed it's libvpx_config to be
+ # in direct_dependent_configs.
+ configs += [ "//third_party/libvpx:libvpx_config" ]
+
+ deps = [
+ ":video_coding_utility",
+ "../../common_video",
+ "../../system_wrappers",
+ ]
+ if (rtc_build_libvpx) {
+ deps += [
+ "//third_party/libvpx",
+ ]
+ }
+}
diff --git a/modules/video_coding/codecs/interface/video_codec_interface.h b/modules/video_coding/codecs/interface/video_codec_interface.h
index 82bcd26d..da72febb 100644
--- a/modules/video_coding/codecs/interface/video_codec_interface.h
+++ b/modules/video_coding/codecs/interface/video_codec_interface.h
@@ -18,6 +18,7 @@
#include "webrtc/modules/interface/module_common_types.h"
#include "webrtc/modules/video_coding/codecs/interface/video_error_codes.h"
#include "webrtc/typedefs.h"
+#include "webrtc/video_decoder.h"
#include "webrtc/video_encoder.h"
namespace webrtc
@@ -41,6 +42,19 @@ struct CodecSpecificInfoVP8 {
int8_t keyIdx; // Negative value to skip keyIdx.
};
+struct CodecSpecificInfoVP9 {
+ bool hasReceivedSLI;
+ uint8_t pictureIdSLI;
+ bool hasReceivedRPSI;
+ uint64_t pictureIdRPSI;
+ int16_t pictureId; // Negative value to skip pictureId.
+ bool nonReference;
+ uint8_t temporalIdx;
+ bool layerSync;
+ int tl0PicIdx; // Negative value to skip tl0PicIdx.
+ int8_t keyIdx; // Negative value to skip keyIdx.
+};
+
struct CodecSpecificInfoGeneric {
uint8_t simulcast_idx;
};
@@ -50,6 +64,7 @@ struct CodecSpecificInfoH264 {};
union CodecSpecificInfoUnion {
CodecSpecificInfoGeneric generic;
CodecSpecificInfoVP8 VP8;
+ CodecSpecificInfoVP9 VP9;
CodecSpecificInfoH264 H264;
};
@@ -62,96 +77,6 @@ struct CodecSpecificInfo
CodecSpecificInfoUnion codecSpecific;
};
-class DecodedImageCallback
-{
-public:
- virtual ~DecodedImageCallback() {};
-
- // Callback function which is called when an image has been decoded.
- //
- // Input:
- // - decodedImage : The decoded image.
- //
- // Return value : 0 if OK, < 0 otherwise.
- virtual int32_t Decoded(I420VideoFrame& decodedImage) = 0;
-
- virtual int32_t ReceivedDecodedReferenceFrame(const uint64_t pictureId) {return -1;}
-
- virtual int32_t ReceivedDecodedFrame(const uint64_t pictureId) {return -1;}
-};
-
-class VideoDecoder
-{
-public:
- virtual ~VideoDecoder() {};
-
- // Initialize the decoder with the information from the VideoCodec.
- //
- // Input:
- // - inst : Codec settings
- // - numberOfCores : Number of cores available for the decoder
- //
- // Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise.
- virtual int32_t InitDecode(const VideoCodec* codecSettings, int32_t numberOfCores) = 0;
-
- // Decode encoded image (as a part of a video stream). The decoded image
- // will be returned to the user through the decode complete callback.
- //
- // Input:
- // - inputImage : Encoded image to be decoded
- // - missingFrames : True if one or more frames have been lost
- // since the previous decode call.
- // - fragmentation : Specifies where the encoded frame can be
- // split into separate fragments. The meaning
- // of fragment is codec specific, but often
- // means that each fragment is decodable by
- // itself.
- // - codecSpecificInfo : Pointer to codec specific data
- // - renderTimeMs : System time to render in milliseconds. Only
- // used by decoders with internal rendering.
- //
- // Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise.
- virtual int32_t
- Decode(const EncodedImage& inputImage,
- bool missingFrames,
- const RTPFragmentationHeader* fragmentation,
- const CodecSpecificInfo* codecSpecificInfo = NULL,
- int64_t renderTimeMs = -1) = 0;
-
- // Register an decode complete callback object.
- //
- // Input:
- // - callback : Callback object which handles decoded images.
- //
- // Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise.
- virtual int32_t RegisterDecodeCompleteCallback(DecodedImageCallback* callback) = 0;
-
- // Free decoder memory.
- //
- // Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise.
- virtual int32_t Release() = 0;
-
- // Reset decoder state and prepare for a new call.
- //
- // Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise.
- virtual int32_t Reset() = 0;
-
- // Codec configuration data sent out-of-band, i.e. in SIP call setup
- //
- // Input/Output:
- // - buffer : Buffer pointer to the configuration data
- // - size : The size of the configuration data in
- // bytes
- //
- // Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise.
- virtual int32_t SetCodecConfigParameters(const uint8_t* /*buffer*/, int32_t /*size*/) { return WEBRTC_VIDEO_CODEC_ERROR; }
-
- // Create a copy of the codec and its internal state.
- //
- // Return value : A copy of the instance if OK, NULL otherwise.
- virtual VideoDecoder* Copy() { return NULL; }
-};
-
} // namespace webrtc
#endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_INTERFACE_VIDEO_CODEC_INTERFACE_H
diff --git a/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc b/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc
index bd4a563f..73f774d6 100644
--- a/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc
+++ b/modules/video_coding/codecs/test/videoprocessor_integrationtest.cc
@@ -16,6 +16,7 @@
#include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h"
#include "webrtc/modules/video_coding/codecs/test/videoprocessor.h"
#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
+#include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
#include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h"
#include "webrtc/modules/video_coding/main/interface/video_coding.h"
#include "webrtc/test/testsupport/fileutils.h"
@@ -37,6 +38,7 @@ const int kBaseKeyFrameInterval = 3000;
// Codec and network settings.
struct CodecConfigPars {
+ VideoCodecType codec_type;
float packet_loss;
int num_temporal_layers;
int key_frame_interval;
@@ -136,6 +138,7 @@ class VideoProcessorIntegrationTest: public testing::Test {
float start_bitrate_;
// Codec and network settings.
+ VideoCodecType codec_type_;
float packet_loss_;
int num_temporal_layers_;
int key_frame_interval_;
@@ -149,8 +152,15 @@ class VideoProcessorIntegrationTest: public testing::Test {
virtual ~VideoProcessorIntegrationTest() {}
void SetUpCodecConfig() {
- encoder_ = VP8Encoder::Create();
- decoder_ = VP8Decoder::Create();
+ if (codec_type_ == kVideoCodecVP8) {
+ encoder_ = VP8Encoder::Create();
+ decoder_ = VP8Decoder::Create();
+ VideoCodingModule::Codec(kVideoCodecVP8, &codec_settings_);
+ } else if (codec_type_ == kVideoCodecVP9) {
+ encoder_ = VP9Encoder::Create();
+ decoder_ = VP9Decoder::Create();
+ VideoCodingModule::Codec(kVideoCodecVP9, &codec_settings_);
+ }
// CIF is currently used for all tests below.
// Setup the TestConfig struct for processing of a clip in CIF resolution.
@@ -169,26 +179,42 @@ class VideoProcessorIntegrationTest: public testing::Test {
config_.keyframe_interval = key_frame_interval_;
config_.networking_config.packet_loss_probability = packet_loss_;
- // Get a codec configuration struct and configure it.
- VideoCodingModule::Codec(kVideoCodecVP8, &codec_settings_);
+ // Configure codec settings.
config_.codec_settings = &codec_settings_;
config_.codec_settings->startBitrate = start_bitrate_;
config_.codec_settings->width = kCIFWidth;
config_.codec_settings->height = kCIFHeight;
- // These features may be set depending on the test.
- config_.codec_settings->codecSpecific.VP8.errorConcealmentOn =
- error_concealment_on_;
- config_.codec_settings->codecSpecific.VP8.denoisingOn =
- denoising_on_;
- config_.codec_settings->codecSpecific.VP8.numberOfTemporalLayers =
- num_temporal_layers_;
- config_.codec_settings->codecSpecific.VP8.frameDroppingOn =
- frame_dropper_on_;
- config_.codec_settings->codecSpecific.VP8.automaticResizeOn =
- spatial_resize_on_;
- config_.codec_settings->codecSpecific.VP8.keyFrameInterval =
- kBaseKeyFrameInterval;
+ // These features may be set depending on the test.
+ switch (config_.codec_settings->codecType) {
+ case kVideoCodecVP8:
+ config_.codec_settings->codecSpecific.VP8.errorConcealmentOn =
+ error_concealment_on_;
+ config_.codec_settings->codecSpecific.VP8.denoisingOn =
+ denoising_on_;
+ config_.codec_settings->codecSpecific.VP8.numberOfTemporalLayers =
+ num_temporal_layers_;
+ config_.codec_settings->codecSpecific.VP8.frameDroppingOn =
+ frame_dropper_on_;
+ config_.codec_settings->codecSpecific.VP8.automaticResizeOn =
+ spatial_resize_on_;
+ config_.codec_settings->codecSpecific.VP8.keyFrameInterval =
+ kBaseKeyFrameInterval;
+ break;
+ case kVideoCodecVP9:
+ config_.codec_settings->codecSpecific.VP9.denoisingOn =
+ denoising_on_;
+ config_.codec_settings->codecSpecific.VP9.numberOfTemporalLayers =
+ num_temporal_layers_;
+ config_.codec_settings->codecSpecific.VP9.frameDroppingOn =
+ frame_dropper_on_;
+ config_.codec_settings->codecSpecific.VP9.keyFrameInterval =
+ kBaseKeyFrameInterval;
+ break;
+ default:
+ assert(false);
+ break;
+ }
frame_reader_ =
new webrtc::test::FrameReaderImpl(config_.input_filename,
config_.frame_length_in_bytes);
@@ -405,6 +431,7 @@ class VideoProcessorIntegrationTest: public testing::Test {
CodecConfigPars process,
RateControlMetrics* rc_metrics) {
// Codec/config settings.
+ codec_type_ = process.codec_type;
start_bitrate_ = rate_profile.target_bit_rate[0];
packet_loss_ = process.packet_loss;
key_frame_interval_ = process.key_frame_interval;
@@ -514,6 +541,7 @@ void SetRateProfilePars(RateProfile* rate_profile,
}
void SetCodecParameters(CodecConfigPars* process_settings,
+ VideoCodecType codec_type,
float packet_loss,
int key_frame_interval,
int num_temporal_layers,
@@ -521,6 +549,7 @@ void SetCodecParameters(CodecConfigPars* process_settings,
bool denoising_on,
bool frame_dropper_on,
bool spatial_resize_on) {
+ process_settings->codec_type = codec_type;
process_settings->packet_loss = packet_loss;
process_settings->key_frame_interval = key_frame_interval;
process_settings->num_temporal_layers = num_temporal_layers,
@@ -560,7 +589,126 @@ void SetRateControlMetrics(RateControlMetrics* rc_metrics,
rc_metrics[update_index].num_spatial_resizes = num_spatial_resizes;
}
-// Run with no packet loss and fixed bitrate. Quality should be very high.
+// VP9: Run with no packet loss and fixed bitrate. Quality should be very high.
+// One key frame (first frame only) in sequence. Setting |key_frame_interval|
+// to -1 below means no periodic key frames in test.
+TEST_F(VideoProcessorIntegrationTest, Process0PercentPacketLossVP9) {
+ // Bitrate and frame rate profile.
+ RateProfile rate_profile;
+ SetRateProfilePars(&rate_profile, 0, 500, 30, 0);
+ rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1;
+ rate_profile.num_frames = kNbrFramesShort;
+ // Codec/network settings.
+ CodecConfigPars process_settings;
+ SetCodecParameters(&process_settings, kVideoCodecVP9, 0.0f, -1, 1, false,
+ false, true, false);
+ // Metrics for expected quality.
+ QualityMetrics quality_metrics;
+ SetQualityMetrics(&quality_metrics, 37.5, 36.0, 0.94, 0.93);
+ // Metrics for rate control.
+ RateControlMetrics rc_metrics[1];
+ SetRateControlMetrics(rc_metrics, 0, 0, 40, 20, 10, 15, 0);
+ ProcessFramesAndVerify(quality_metrics,
+ rate_profile,
+ process_settings,
+ rc_metrics);
+}
+
+// VP9: Run with 5% packet loss and fixed bitrate. Quality should be a bit
+// lower. One key frame (first frame only) in sequence.
+TEST_F(VideoProcessorIntegrationTest, Process5PercentPacketLossVP9) {
+ // Bitrate and frame rate profile.
+ RateProfile rate_profile;
+ SetRateProfilePars(&rate_profile, 0, 500, 30, 0);
+ rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1;
+ rate_profile.num_frames = kNbrFramesShort;
+ // Codec/network settings.
+ CodecConfigPars process_settings;
+ SetCodecParameters(&process_settings, kVideoCodecVP9, 0.05f, -1, 1, false,
+ false, true, false);
+ // Metrics for expected quality.
+ QualityMetrics quality_metrics;
+ SetQualityMetrics(&quality_metrics, 17.0, 15.0, 0.45, 0.38);
+ // Metrics for rate control.
+ RateControlMetrics rc_metrics[1];
+ SetRateControlMetrics(rc_metrics, 0, 0, 40, 20, 10, 15, 0);
+ ProcessFramesAndVerify(quality_metrics,
+ rate_profile,
+ process_settings,
+ rc_metrics);
+}
+
+
+// VP9: Run with no packet loss, with varying bitrate (3 rate updates):
+// low to high to medium. Check that quality and encoder response to the new
+// target rate/per-frame bandwidth (for each rate update) is within limits.
+// One key frame (first frame only) in sequence.
+TEST_F(VideoProcessorIntegrationTest, ProcessNoLossChangeBitRateVP9) {
+ // Bitrate and frame rate profile.
+ RateProfile rate_profile;
+ SetRateProfilePars(&rate_profile, 0, 200, 30, 0);
+ SetRateProfilePars(&rate_profile, 1, 800, 30, 100);
+ SetRateProfilePars(&rate_profile, 2, 500, 30, 200);
+ rate_profile.frame_index_rate_update[3] = kNbrFramesLong + 1;
+ rate_profile.num_frames = kNbrFramesLong;
+ // Codec/network settings.
+ CodecConfigPars process_settings;
+ SetCodecParameters(&process_settings, kVideoCodecVP9, 0.0f, -1, 1, false,
+ false, true, false);
+ // Metrics for expected quality.
+ QualityMetrics quality_metrics;
+ SetQualityMetrics(&quality_metrics, 36.0, 32.0, 0.90, 0.85);
+ // Metrics for rate control.
+ RateControlMetrics rc_metrics[3];
+ SetRateControlMetrics(rc_metrics, 0, 0, 30, 20, 20, 20, 0);
+ SetRateControlMetrics(rc_metrics, 1, 2, 0, 20, 20, 60, 0);
+ SetRateControlMetrics(rc_metrics, 2, 0, 0, 20, 20, 30, 0);
+ ProcessFramesAndVerify(quality_metrics,
+ rate_profile,
+ process_settings,
+ rc_metrics);
+}
+
+// VP9: Run with no packet loss, with an update (decrease) in frame rate.
+// Lower frame rate means higher per-frame-bandwidth, so easier to encode.
+// At the low bitrate in this test, this means better rate control after the
+// update(s) to lower frame rate. So expect less frame drops, and max values
+// for the rate control metrics can be lower. One key frame (first frame only).
+// Note: quality after update should be higher but we currently compute quality
+// metrics averaged over whole sequence run.
+TEST_F(VideoProcessorIntegrationTest,
+ ProcessNoLossChangeFrameRateFrameDropVP9) {
+ config_.networking_config.packet_loss_probability = 0;
+ // Bitrate and frame rate profile.
+ RateProfile rate_profile;
+ SetRateProfilePars(&rate_profile, 0, 50, 24, 0);
+ SetRateProfilePars(&rate_profile, 1, 50, 15, 100);
+ SetRateProfilePars(&rate_profile, 2, 50, 10, 200);
+ rate_profile.frame_index_rate_update[3] = kNbrFramesLong + 1;
+ rate_profile.num_frames = kNbrFramesLong;
+ // Codec/network settings.
+ CodecConfigPars process_settings;
+ SetCodecParameters(&process_settings, kVideoCodecVP9, 0.0f, -1, 1, false,
+ false, true, false);
+ // Metrics for expected quality.
+ QualityMetrics quality_metrics;
+ SetQualityMetrics(&quality_metrics, 30.0, 18.0, 0.80, 0.40);
+ // Metrics for rate control.
+ RateControlMetrics rc_metrics[3];
+ SetRateControlMetrics(rc_metrics, 0, 35, 55, 70, 15, 40, 0);
+ SetRateControlMetrics(rc_metrics, 1, 15, 0, 50, 10, 30, 0);
+ SetRateControlMetrics(rc_metrics, 2, 5, 0, 38, 10, 30, 0);
+ ProcessFramesAndVerify(quality_metrics,
+ rate_profile,
+ process_settings,
+ rc_metrics);
+}
+
+
+// TODO(marpan): Add temporal layer test for VP9, once changes are in
+// vp9 wrapper for this.
+
+// VP8: Run with no packet loss and fixed bitrate. Quality should be very high.
// One key frame (first frame only) in sequence. Setting |key_frame_interval|
// to -1 below means no periodic key frames in test.
TEST_F(VideoProcessorIntegrationTest, ProcessZeroPacketLoss) {
@@ -571,7 +719,8 @@ TEST_F(VideoProcessorIntegrationTest, ProcessZeroPacketLoss) {
rate_profile.num_frames = kNbrFramesShort;
// Codec/network settings.
CodecConfigPars process_settings;
- SetCodecParameters(&process_settings, 0.0f, -1, 1, false, true, true, false);
+ SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, -1, 1, false,
+ true, true, false);
// Metrics for expected quality.
QualityMetrics quality_metrics;
SetQualityMetrics(&quality_metrics, 34.95, 33.0, 0.90, 0.89);
@@ -584,8 +733,8 @@ TEST_F(VideoProcessorIntegrationTest, ProcessZeroPacketLoss) {
rc_metrics);
}
-// Run with 5% packet loss and fixed bitrate. Quality should be a bit lower.
-// One key frame (first frame only) in sequence.
+// VP8: Run with 5% packet loss and fixed bitrate. Quality should be a bit
+// lower. One key frame (first frame only) in sequence.
TEST_F(VideoProcessorIntegrationTest, Process5PercentPacketLoss) {
// Bitrate and frame rate profile.
RateProfile rate_profile;
@@ -594,7 +743,8 @@ TEST_F(VideoProcessorIntegrationTest, Process5PercentPacketLoss) {
rate_profile.num_frames = kNbrFramesShort;
// Codec/network settings.
CodecConfigPars process_settings;
- SetCodecParameters(&process_settings, 0.05f, -1, 1, false, true, true, false);
+ SetCodecParameters(&process_settings, kVideoCodecVP8, 0.05f, -1, 1, false,
+ true, true, false);
// Metrics for expected quality.
QualityMetrics quality_metrics;
SetQualityMetrics(&quality_metrics, 20.0, 16.0, 0.60, 0.40);
@@ -607,7 +757,7 @@ TEST_F(VideoProcessorIntegrationTest, Process5PercentPacketLoss) {
rc_metrics);
}
-// Run with 10% packet loss and fixed bitrate. Quality should be even lower.
+// VP8: Run with 10% packet loss and fixed bitrate. Quality should be lower.
// One key frame (first frame only) in sequence.
TEST_F(VideoProcessorIntegrationTest, Process10PercentPacketLoss) {
// Bitrate and frame rate profile.
@@ -617,7 +767,8 @@ TEST_F(VideoProcessorIntegrationTest, Process10PercentPacketLoss) {
rate_profile.num_frames = kNbrFramesShort;
// Codec/network settings.
CodecConfigPars process_settings;
- SetCodecParameters(&process_settings, 0.1f, -1, 1, false, true, true, false);
+ SetCodecParameters(&process_settings, kVideoCodecVP8, 0.1f, -1, 1, false,
+ true, true, false);
// Metrics for expected quality.
QualityMetrics quality_metrics;
SetQualityMetrics(&quality_metrics, 19.0, 16.0, 0.50, 0.35);
@@ -639,12 +790,12 @@ TEST_F(VideoProcessorIntegrationTest, Process10PercentPacketLoss) {
// disabled on Android. Some quality parameter in the above test has been
// adjusted to also pass for |cpu_speed| <= 12.
-// Run with no packet loss, with varying bitrate (3 rate updates):
+// VP8: Run with no packet loss, with varying bitrate (3 rate updates):
// low to high to medium. Check that quality and encoder response to the new
// target rate/per-frame bandwidth (for each rate update) is within limits.
// One key frame (first frame only) in sequence.
TEST_F(VideoProcessorIntegrationTest,
- DISABLED_ON_ANDROID(ProcessNoLossChangeBitRate)) {
+ DISABLED_ON_ANDROID(ProcessNoLossChangeBitRateVP8)) {
// Bitrate and frame rate profile.
RateProfile rate_profile;
SetRateProfilePars(&rate_profile, 0, 200, 30, 0);
@@ -654,7 +805,8 @@ TEST_F(VideoProcessorIntegrationTest,
rate_profile.num_frames = kNbrFramesLong;
// Codec/network settings.
CodecConfigPars process_settings;
- SetCodecParameters(&process_settings, 0.0f, -1, 1, false, true, true, false);
+ SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, -1, 1, false,
+ true, true, false);
// Metrics for expected quality.
QualityMetrics quality_metrics;
SetQualityMetrics(&quality_metrics, 34.0, 32.0, 0.85, 0.80);
@@ -669,15 +821,15 @@ TEST_F(VideoProcessorIntegrationTest,
rc_metrics);
}
-// Run with no packet loss, with an update (decrease) in frame rate.
+// VP8: Run with no packet loss, with an update (decrease) in frame rate.
// Lower frame rate means higher per-frame-bandwidth, so easier to encode.
// At the bitrate in this test, this means better rate control after the
// update(s) to lower frame rate. So expect less frame drops, and max values
// for the rate control metrics can be lower. One key frame (first frame only).
// Note: quality after update should be higher but we currently compute quality
-// metrics avergaed over whole sequence run.
+// metrics averaged over whole sequence run.
TEST_F(VideoProcessorIntegrationTest,
- DISABLED_ON_ANDROID(ProcessNoLossChangeFrameRateFrameDrop)) {
+ DISABLED_ON_ANDROID(ProcessNoLossChangeFrameRateFrameDropVP8)) {
config_.networking_config.packet_loss_probability = 0;
// Bitrate and frame rate profile.
RateProfile rate_profile;
@@ -688,7 +840,8 @@ TEST_F(VideoProcessorIntegrationTest,
rate_profile.num_frames = kNbrFramesLong;
// Codec/network settings.
CodecConfigPars process_settings;
- SetCodecParameters(&process_settings, 0.0f, -1, 1, false, true, true, false);
+ SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, -1, 1, false,
+ true, true, false);
// Metrics for expected quality.
QualityMetrics quality_metrics;
SetQualityMetrics(&quality_metrics, 31.0, 22.0, 0.80, 0.65);
@@ -706,7 +859,7 @@ TEST_F(VideoProcessorIntegrationTest,
// Run with no packet loss, at low bitrate. During this time we should've
// resized once.
TEST_F(VideoProcessorIntegrationTest,
- DISABLED_ON_ANDROID(ProcessNoLossSpatialResizeFrameDrop)) {
+ DISABLED_ON_ANDROID(ProcessNoLossSpatialResizeFrameDropVP8)) {
config_.networking_config.packet_loss_probability = 0;
// Bitrate and frame rate profile.
RateProfile rate_profile;
@@ -715,8 +868,8 @@ TEST_F(VideoProcessorIntegrationTest,
rate_profile.num_frames = kNbrFramesLong;
// Codec/network settings.
CodecConfigPars process_settings;
- SetCodecParameters(
- &process_settings, 0.0f, kNbrFramesLong, 1, false, true, true, true);
+ SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, kNbrFramesLong,
+ 1, false, true, true, true);
// Metrics for expected quality.
QualityMetrics quality_metrics;
SetQualityMetrics(&quality_metrics, 25.0, 15.0, 0.70, 0.40);
@@ -729,13 +882,13 @@ TEST_F(VideoProcessorIntegrationTest,
rc_metrics);
}
-// Run with no packet loss, with 3 temporal layers, with a rate update in the
-// middle of the sequence. The max values for the frame size mismatch and
+// VP8: Run with no packet loss, with 3 temporal layers, with a rate update in
+// the middle of the sequence. The max values for the frame size mismatch and
// encoding rate mismatch are applied to each layer.
// No dropped frames in this test, and internal spatial resizer is off.
// One key frame (first frame only) in sequence, so no spatial resizing.
TEST_F(VideoProcessorIntegrationTest,
- DISABLED_ON_ANDROID(ProcessNoLossTemporalLayers)) {
+ DISABLED_ON_ANDROID(ProcessNoLossTemporalLayersVP8)) {
config_.networking_config.packet_loss_probability = 0;
// Bitrate and frame rate profile.
RateProfile rate_profile;
@@ -745,7 +898,8 @@ TEST_F(VideoProcessorIntegrationTest,
rate_profile.num_frames = kNbrFramesLong;
// Codec/network settings.
CodecConfigPars process_settings;
- SetCodecParameters(&process_settings, 0.0f, -1, 3, false, true, true, false);
+ SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, -1, 3, false,
+ true, true, false);
// Metrics for expected quality.
QualityMetrics quality_metrics;
SetQualityMetrics(&quality_metrics, 32.5, 30.0, 0.85, 0.80);
diff --git a/modules/video_coding/codecs/tools/video_codecs_tools.gypi b/modules/video_coding/codecs/tools/video_codecs_tools.gypi
index 8f15b285..3e77a5be 100644
--- a/modules/video_coding/codecs/tools/video_codecs_tools.gypi
+++ b/modules/video_coding/codecs/tools/video_codecs_tools.gypi
@@ -17,7 +17,7 @@
'video_codecs_test_framework',
'webrtc_video_coding',
'<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
- '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default',
+ '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers_default',
'<(webrtc_root)/test/metrics.gyp:metrics',
'<(webrtc_vp8_dir)/vp8.gyp:webrtc_vp8',
],
diff --git a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
index 3cc8bc33..5e0bfc82 100644
--- a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
+++ b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
@@ -192,7 +192,13 @@ class TestVp8Impl : public ::testing::Test {
VideoCodec codec_inst_;
};
+// Disabled on MemorySanitizer as it's breaking on generic libvpx.
+// https://code.google.com/p/webrtc/issues/detail?id=3904
+#if defined(MEMORY_SANITIZER)
+TEST_F(TestVp8Impl, DISABLED_BaseUnitTest) {
+#else
TEST_F(TestVp8Impl, DISABLED_ON_ANDROID(BaseUnitTest)) {
+#endif
// TODO(mikhal): Remove dependency. Move all test code here.
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
UnitTest unittest;
diff --git a/modules/video_coding/codecs/vp8/vp8_impl.h b/modules/video_coding/codecs/vp8/vp8_impl.h
index 08ce3c91..fec53d53 100644
--- a/modules/video_coding/codecs/vp8/vp8_impl.h
+++ b/modules/video_coding/codecs/vp8/vp8_impl.h
@@ -35,73 +35,20 @@ class VP8EncoderImpl : public VP8Encoder {
virtual ~VP8EncoderImpl();
- // Free encoder memory.
- //
- // Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise.
virtual int Release();
- // Initialize the encoder with the information from the codecSettings
- //
- // Input:
- // - codec_settings : Codec settings
- // - 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_LEVEL_EXCEEDED
- // WEBRTC_VIDEO_CODEC_MEMORY
- // WEBRTC_VIDEO_CODEC_ERROR
virtual int InitEncode(const VideoCodec* codec_settings,
int number_of_cores,
uint32_t max_payload_size);
- // Encode an I420 image (as a part of a video stream). The encoded image
- // will be returned to the user through the encode complete callback.
- //
- // Input:
- // - input_image : 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
- // WEBRTC_VIDEO_CODEC_TIMEOUT
-
virtual int Encode(const I420VideoFrame& input_image,
const CodecSpecificInfo* codec_specific_info,
const std::vector<VideoFrameType>* frame_types);
- // 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 int RegisterEncodeCompleteCallback(EncodedImageCallback* callback);
- // Inform the encoder of the new packet loss rate and the round-trip time of
- // the network.
- //
- // - packet_loss : Fraction lost
- // (loss rate in percent = 100 * packetLoss / 255)
- // - rtt : Round-trip time in milliseconds
- // Return value : WEBRTC_VIDEO_CODEC_OK if OK
- // <0 - Errors: WEBRTC_VIDEO_CODEC_ERROR
- //
virtual int SetChannelParameters(uint32_t packet_loss, int rtt);
- // Inform the encoder about the new target bit rate.
- //
- // - new_bitrate_kbit : New target bit rate
- // - frame_rate : The target frame rate
- //
- // Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise.
virtual int SetRates(uint32_t new_bitrate_kbit, uint32_t frame_rate);
private:
@@ -150,61 +97,20 @@ class VP8DecoderImpl : public VP8Decoder {
virtual ~VP8DecoderImpl();
- // Initialize the decoder.
- //
- // Return value : WEBRTC_VIDEO_CODEC_OK.
- // <0 - Errors:
- // WEBRTC_VIDEO_CODEC_ERROR
virtual int InitDecode(const VideoCodec* inst, int number_of_cores);
- // Decode encoded image (as a part of a video stream). The decoded image
- // will be returned to the user through the decode complete callback.
- //
- // Input:
- // - input_image : Encoded image to be decoded
- // - missing_frames : True if one or more frames have been lost
- // since the previous decode call.
- // - fragmentation : Specifies the start and length of each VP8
- // partition.
- // - codec_specific_info : pointer to specific codec data
- // - render_time_ms : Render time in Ms
- //
- // Return value : WEBRTC_VIDEO_CODEC_OK if OK
- // <0 - Errors:
- // WEBRTC_VIDEO_CODEC_ERROR
- // WEBRTC_VIDEO_CODEC_ERR_PARAMETER
virtual int Decode(const EncodedImage& input_image,
bool missing_frames,
const RTPFragmentationHeader* fragmentation,
const CodecSpecificInfo* codec_specific_info,
int64_t /*render_time_ms*/);
- // Register a decode complete callback object.
- //
- // Input:
- // - callback : Callback object which handles decoded images.
- //
- // Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise.
virtual int RegisterDecodeCompleteCallback(DecodedImageCallback* callback);
- // Free decoder memory.
- //
- // Return value : WEBRTC_VIDEO_CODEC_OK if OK
- // <0 - Errors:
- // WEBRTC_VIDEO_CODEC_ERROR
virtual int Release();
- // Reset decoder state and prepare for a new call.
- //
- // Return value : WEBRTC_VIDEO_CODEC_OK.
- // <0 - Errors:
- // WEBRTC_VIDEO_CODEC_UNINITIALIZED
- // WEBRTC_VIDEO_CODEC_ERROR
virtual int Reset();
- // Create a copy of the codec and its internal state.
- //
- // Return value : A copy of the instance if OK, NULL otherwise.
virtual VideoDecoder* Copy();
private:
diff --git a/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-arm.mk b/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-arm.mk
index 79bb0c7d..04f686da 100644
--- a/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-arm.mk
+++ b/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-arm.mk
@@ -87,11 +87,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +109,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -203,11 +206,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -223,6 +228,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-arm64.mk b/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-arm64.mk
index 268ec13f..9e6c52e1 100644
--- a/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-arm64.mk
+++ b/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-arm64.mk
@@ -76,11 +76,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -89,10 +91,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -177,11 +181,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -190,10 +196,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-mips.mk b/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-mips.mk
index 1b8eab86..9af54f96 100644
--- a/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-mips.mk
+++ b/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-mips.mk
@@ -80,11 +80,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -188,11 +191,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -207,6 +212,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-mips64.mk b/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-mips64.mk
new file mode 100644
index 00000000..8ca243dd
--- /dev/null
+++ b/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-mips64.mk
@@ -0,0 +1,269 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_coding_codecs_vp8_webrtc_vp8_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_coding/codecs/vp8/reference_picture_selection.cc \
+ third_party/webrtc/modules/video_coding/codecs/vp8/vp8_factory.cc \
+ third_party/webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc \
+ third_party/webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.cc \
+ third_party/webrtc/modules/video_coding/codecs/vp8/realtime_temporal_layers.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_coding_codecs_vp8_webrtc_vp8_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_vp8
+webrtc_vp8: third_party_webrtc_modules_video_coding_codecs_vp8_webrtc_vp8_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-x86.mk b/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-x86.mk
index 1b4923aa..6d28f751 100644
--- a/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-x86.mk
+++ b/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-x86.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -189,11 +192,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -206,6 +211,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-x86_64.mk b/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-x86_64.mk
index c0fe3e06..e85d60c7 100644
--- a/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-x86_64.mk
+++ b/modules/video_coding/codecs/vp8/webrtc_vp8.target.darwin-x86_64.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,6 +100,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -187,11 +190,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -204,6 +209,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-arm.mk b/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-arm.mk
index 79bb0c7d..04f686da 100644
--- a/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-arm.mk
+++ b/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-arm.mk
@@ -87,11 +87,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +109,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -203,11 +206,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -223,6 +228,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-arm64.mk b/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-arm64.mk
index 268ec13f..9e6c52e1 100644
--- a/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-arm64.mk
+++ b/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-arm64.mk
@@ -76,11 +76,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -89,10 +91,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -177,11 +181,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -190,10 +196,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-mips.mk b/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-mips.mk
index 1b8eab86..9af54f96 100644
--- a/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-mips.mk
+++ b/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-mips.mk
@@ -80,11 +80,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -188,11 +191,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -207,6 +212,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-mips64.mk b/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-mips64.mk
new file mode 100644
index 00000000..8ca243dd
--- /dev/null
+++ b/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-mips64.mk
@@ -0,0 +1,269 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_coding_codecs_vp8_webrtc_vp8_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_coding/codecs/vp8/reference_picture_selection.cc \
+ third_party/webrtc/modules/video_coding/codecs/vp8/vp8_factory.cc \
+ third_party/webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc \
+ third_party/webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.cc \
+ third_party/webrtc/modules/video_coding/codecs/vp8/realtime_temporal_layers.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_coding_codecs_vp8_webrtc_vp8_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_vp8
+webrtc_vp8: third_party_webrtc_modules_video_coding_codecs_vp8_webrtc_vp8_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-x86.mk b/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-x86.mk
index 1b4923aa..6d28f751 100644
--- a/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-x86.mk
+++ b/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-x86.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -189,11 +192,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -206,6 +211,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-x86_64.mk b/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-x86_64.mk
index c0fe3e06..e85d60c7 100644
--- a/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-x86_64.mk
+++ b/modules/video_coding/codecs/vp8/webrtc_vp8.target.linux-x86_64.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,6 +100,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -187,11 +190,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -204,6 +209,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_coding/codecs/vp9/include/vp9.h b/modules/video_coding/codecs/vp9/include/vp9.h
new file mode 100644
index 00000000..cd77f72d
--- /dev/null
+++ b/modules/video_coding/codecs/vp9/include/vp9.h
@@ -0,0 +1,35 @@
+/*
+ * 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 WEBRTC_MODULES_VIDEO_CODING_CODECS_VP9_INCLUDE_VP9_H_
+#define WEBRTC_MODULES_VIDEO_CODING_CODECS_VP9_INCLUDE_VP9_H_
+
+#include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
+
+namespace webrtc {
+
+class VP9Encoder : public VideoEncoder {
+ public:
+ static VP9Encoder* Create();
+
+ virtual ~VP9Encoder() {}
+};
+
+
+class VP9Decoder : public VideoDecoder {
+ public:
+ static VP9Decoder* Create();
+
+ virtual ~VP9Decoder() {}
+};
+} // namespace webrtc
+
+#endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_VP9_INCLUDE_VP9_H_
diff --git a/modules/video_coding/codecs/vp9/vp9.gyp b/modules/video_coding/codecs/vp9/vp9.gyp
new file mode 100644
index 00000000..2bd46feb
--- /dev/null
+++ b/modules/video_coding/codecs/vp9/vp9.gyp
@@ -0,0 +1,36 @@
+# 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.
+
+{
+ 'includes': [
+ '../../../../build/common.gypi',
+ ],
+ 'targets': [
+ {
+ 'target_name': 'webrtc_vp9',
+ 'type': 'static_library',
+ 'dependencies': [
+ '<(webrtc_root)/common_video/common_video.gyp:common_video',
+ '<(webrtc_root)/modules/video_coding/utility/video_coding_utility.gyp:video_coding_utility',
+ '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
+ ],
+ 'conditions': [
+ ['build_libvpx==1', {
+ 'dependencies': [
+ '<(DEPTH)/third_party/libvpx/libvpx.gyp:libvpx',
+ ],
+ }],
+ ],
+ 'sources': [
+ 'include/vp9.h',
+ 'vp9_impl.cc',
+ 'vp9_impl.h',
+ ],
+ },
+ ],
+}
diff --git a/modules/video_coding/codecs/vp9/vp9_impl.cc b/modules/video_coding/codecs/vp9/vp9_impl.cc
new file mode 100644
index 00000000..33f11a37
--- /dev/null
+++ b/modules/video_coding/codecs/vp9/vp9_impl.cc
@@ -0,0 +1,487 @@
+/*
+ * 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 "webrtc/modules/video_coding/codecs/vp9/vp9_impl.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <vector>
+
+#include "vpx/vpx_encoder.h"
+#include "vpx/vpx_decoder.h"
+#include "vpx/vp8cx.h"
+#include "vpx/vp8dx.h"
+
+#include "webrtc/common.h"
+#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
+#include "webrtc/modules/interface/module_common_types.h"
+#include "webrtc/system_wrappers/interface/tick_util.h"
+#include "webrtc/system_wrappers/interface/trace_event.h"
+
+namespace webrtc {
+
+VP9Encoder* VP9Encoder::Create() {
+ return new VP9EncoderImpl();
+}
+
+VP9EncoderImpl::VP9EncoderImpl()
+ : encoded_image_(),
+ encoded_complete_callback_(NULL),
+ inited_(false),
+ timestamp_(0),
+ picture_id_(0),
+ cpu_speed_(3),
+ rc_max_intra_target_(0),
+ encoder_(NULL),
+ config_(NULL),
+ raw_(NULL) {
+ memset(&codec_, 0, sizeof(codec_));
+ uint32_t seed = static_cast<uint32_t>(TickTime::MillisecondTimestamp());
+ srand(seed);
+}
+
+VP9EncoderImpl::~VP9EncoderImpl() {
+ Release();
+}
+
+int VP9EncoderImpl::Release() {
+ if (encoded_image_._buffer != NULL) {
+ delete [] encoded_image_._buffer;
+ encoded_image_._buffer = NULL;
+ }
+ if (encoder_ != NULL) {
+ if (vpx_codec_destroy(encoder_)) {
+ return WEBRTC_VIDEO_CODEC_MEMORY;
+ }
+ delete encoder_;
+ encoder_ = NULL;
+ }
+ if (config_ != NULL) {
+ delete config_;
+ config_ = NULL;
+ }
+ if (raw_ != NULL) {
+ vpx_img_free(raw_);
+ raw_ = NULL;
+ }
+ inited_ = false;
+ return WEBRTC_VIDEO_CODEC_OK;
+}
+
+int VP9EncoderImpl::SetRates(uint32_t new_bitrate_kbit,
+ uint32_t new_framerate) {
+ if (!inited_) {
+ return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
+ }
+ if (encoder_->err) {
+ return WEBRTC_VIDEO_CODEC_ERROR;
+ }
+ if (new_framerate < 1) {
+ return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
+ }
+ // Update bit rate
+ if (codec_.maxBitrate > 0 && new_bitrate_kbit > codec_.maxBitrate) {
+ new_bitrate_kbit = codec_.maxBitrate;
+ }
+ config_->rc_target_bitrate = new_bitrate_kbit;
+ codec_.maxFramerate = new_framerate;
+ // Update encoder context
+ if (vpx_codec_enc_config_set(encoder_, config_)) {
+ return WEBRTC_VIDEO_CODEC_ERROR;
+ }
+ return WEBRTC_VIDEO_CODEC_OK;
+}
+
+int VP9EncoderImpl::InitEncode(const VideoCodec* inst,
+ int number_of_cores,
+ uint32_t /*max_payload_size*/) {
+ if (inst == NULL) {
+ return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
+ }
+ if (inst->maxFramerate < 1) {
+ return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
+ }
+ // Allow zero to represent an unspecified maxBitRate
+ if (inst->maxBitrate > 0 && inst->startBitrate > inst->maxBitrate) {
+ return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
+ }
+ if (inst->width < 1 || inst->height < 1) {
+ return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
+ }
+ if (number_of_cores < 1) {
+ return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
+ }
+ int retVal = Release();
+ if (retVal < 0) {
+ return retVal;
+ }
+ if (encoder_ == NULL) {
+ encoder_ = new vpx_codec_ctx_t;
+ }
+ if (config_ == NULL) {
+ config_ = new vpx_codec_enc_cfg_t;
+ }
+ timestamp_ = 0;
+ if (&codec_ != inst) {
+ codec_ = *inst;
+ }
+ // Random start 16 bits is enough.
+ picture_id_ = static_cast<uint16_t>(rand()) & 0x7FFF;
+ // Allocate memory for encoded image
+ if (encoded_image_._buffer != NULL) {
+ delete [] encoded_image_._buffer;
+ }
+ encoded_image_._size = CalcBufferSize(kI420, codec_.width, codec_.height);
+ encoded_image_._buffer = new uint8_t[encoded_image_._size];
+ encoded_image_._completeFrame = true;
+ // Creating a wrapper to the image - setting image data to NULL. Actual
+ // pointer will be set in encode. Setting align to 1, as it is meaningless
+ // (actual memory is not allocated).
+ raw_ = vpx_img_wrap(NULL, VPX_IMG_FMT_I420, codec_.width, codec_.height,
+ 1, NULL);
+ // Populate encoder configuration with default values.
+ if (vpx_codec_enc_config_default(vpx_codec_vp9_cx(), config_, 0)) {
+ return WEBRTC_VIDEO_CODEC_ERROR;
+ }
+ config_->g_w = codec_.width;
+ config_->g_h = codec_.height;
+ config_->rc_target_bitrate = inst->startBitrate; // in kbit/s
+ config_->g_error_resilient = 1;
+ // Setting the time base of the codec.
+ config_->g_timebase.num = 1;
+ config_->g_timebase.den = 90000;
+ config_->g_lag_in_frames = 0; // 0- no frame lagging
+ config_->g_threads = 1;
+ // Rate control settings.
+ config_->rc_dropframe_thresh = inst->codecSpecific.VP9.frameDroppingOn ?
+ 30 : 0;
+ config_->rc_end_usage = VPX_CBR;
+ config_->g_pass = VPX_RC_ONE_PASS;
+ config_->rc_min_quantizer = 2;
+ config_->rc_max_quantizer = 56;
+ config_->rc_undershoot_pct = 50;
+ config_->rc_overshoot_pct = 50;
+ config_->rc_buf_initial_sz = 500;
+ config_->rc_buf_optimal_sz = 600;
+ config_->rc_buf_sz = 1000;
+ // Set the maximum target size of any key-frame.
+ rc_max_intra_target_ = MaxIntraTarget(config_->rc_buf_optimal_sz);
+ if (inst->codecSpecific.VP9.keyFrameInterval > 0) {
+ config_->kf_mode = VPX_KF_AUTO;
+ config_->kf_max_dist = inst->codecSpecific.VP9.keyFrameInterval;
+ } else {
+ config_->kf_mode = VPX_KF_DISABLED;
+ }
+ return InitAndSetControlSettings(inst);
+}
+
+int VP9EncoderImpl::InitAndSetControlSettings(const VideoCodec* inst) {
+ if (vpx_codec_enc_init(encoder_, vpx_codec_vp9_cx(), config_, 0)) {
+ return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
+ }
+ // Only positive speeds, currently: 0 - 7.
+ // O means slowest/best quality, 7 means fastest/lowest quality.
+ // TODO(marpan): Speeds 5-7 are speed settings for real-time mode, on desktop.
+ // Currently set to 5, update to 6 (for faster encoding) after some subjective
+ // quality tests.
+ cpu_speed_ = 5;
+ // Note: some of these codec controls still use "VP8" in the control name.
+ // TODO(marpan): Update this in the next/future libvpx version.
+ vpx_codec_control(encoder_, VP8E_SET_CPUUSED, cpu_speed_);
+ vpx_codec_control(encoder_, VP8E_SET_MAX_INTRA_BITRATE_PCT,
+ rc_max_intra_target_);
+ vpx_codec_control(encoder_, VP9E_SET_AQ_MODE,
+ inst->codecSpecific.VP9.adaptiveQpMode ? 3 : 0);
+ // TODO(marpan): Enable in future libvpx roll: waiting for SSE2 optimization.
+// #if !defined(WEBRTC_ARCH_ARM)
+ // vpx_codec_control(encoder_, VP9E_SET_NOISE_SENSITIVITY,
+ // inst->codecSpecific.VP9.denoisingOn ? 1 : 0);
+// #endif
+ inited_ = true;
+ return WEBRTC_VIDEO_CODEC_OK;
+}
+
+uint32_t VP9EncoderImpl::MaxIntraTarget(uint32_t optimal_buffer_size) {
+ // Set max to the optimal buffer level (normalized by target BR),
+ // and scaled by a scale_par.
+ // Max target size = scale_par * optimal_buffer_size * targetBR[Kbps].
+ // This value is presented in percentage of perFrameBw:
+ // perFrameBw = targetBR[Kbps] * 1000 / framerate.
+ // The target in % is as follows:
+ float scale_par = 0.5;
+ uint32_t target_pct =
+ optimal_buffer_size * scale_par * codec_.maxFramerate / 10;
+ // Don't go below 3 times the per frame bandwidth.
+ const uint32_t min_intra_size = 300;
+ return (target_pct < min_intra_size) ? min_intra_size: target_pct;
+}
+
+int VP9EncoderImpl::Encode(const I420VideoFrame& input_image,
+ const CodecSpecificInfo* codec_specific_info,
+ const std::vector<VideoFrameType>* frame_types) {
+ if (!inited_) {
+ return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
+ }
+ if (input_image.IsZeroSize()) {
+ return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
+ }
+ if (encoded_complete_callback_ == NULL) {
+ return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
+ }
+ VideoFrameType frame_type = kDeltaFrame;
+ // We only support one stream at the moment.
+ if (frame_types && frame_types->size() > 0) {
+ frame_type = (*frame_types)[0];
+ }
+ // Image in vpx_image_t format.
+ // Input image is const. VPX's raw image is not defined as const.
+ raw_->planes[VPX_PLANE_Y] = const_cast<uint8_t*>(input_image.buffer(kYPlane));
+ raw_->planes[VPX_PLANE_U] = const_cast<uint8_t*>(input_image.buffer(kUPlane));
+ raw_->planes[VPX_PLANE_V] = const_cast<uint8_t*>(input_image.buffer(kVPlane));
+ raw_->stride[VPX_PLANE_Y] = input_image.stride(kYPlane);
+ raw_->stride[VPX_PLANE_U] = input_image.stride(kUPlane);
+ raw_->stride[VPX_PLANE_V] = input_image.stride(kVPlane);
+
+ int flags = 0;
+ bool send_keyframe = (frame_type == kKeyFrame);
+ if (send_keyframe) {
+ // Key frame request from caller.
+ flags = VPX_EFLAG_FORCE_KF;
+ }
+ assert(codec_.maxFramerate > 0);
+ uint32_t duration = 90000 / codec_.maxFramerate;
+ if (vpx_codec_encode(encoder_, raw_, timestamp_, duration, flags,
+ VPX_DL_REALTIME)) {
+ return WEBRTC_VIDEO_CODEC_ERROR;
+ }
+ timestamp_ += duration;
+ return GetEncodedPartitions(input_image);
+}
+
+void VP9EncoderImpl::PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
+ const vpx_codec_cx_pkt& pkt,
+ uint32_t timestamp) {
+ assert(codec_specific != NULL);
+ codec_specific->codecType = kVideoCodecVP9;
+ CodecSpecificInfoVP9 *vp9_info = &(codec_specific->codecSpecific.VP9);
+ vp9_info->pictureId = picture_id_;
+ vp9_info->keyIdx = kNoKeyIdx;
+ vp9_info->nonReference = (pkt.data.frame.flags & VPX_FRAME_IS_DROPPABLE) != 0;
+ // TODO(marpan): Temporal layers are supported in the current VP9 version,
+ // but for now use 1 temporal layer encoding. Will update this when temporal
+ // layer support for VP9 is added in webrtc.
+ vp9_info->temporalIdx = kNoTemporalIdx;
+ vp9_info->layerSync = false;
+ vp9_info->tl0PicIdx = kNoTl0PicIdx;
+ picture_id_ = (picture_id_ + 1) & 0x7FFF;
+}
+
+int VP9EncoderImpl::GetEncodedPartitions(const I420VideoFrame& input_image) {
+ vpx_codec_iter_t iter = NULL;
+ encoded_image_._length = 0;
+ encoded_image_._frameType = kDeltaFrame;
+ RTPFragmentationHeader frag_info;
+ // Note: no data partitioning in VP9, so 1 partition only. We keep this
+ // fragmentation data for now, until VP9 packetizer is implemented.
+ frag_info.VerifyAndAllocateFragmentationHeader(1);
+ int part_idx = 0;
+ CodecSpecificInfo codec_specific;
+ const vpx_codec_cx_pkt_t *pkt = NULL;
+ while ((pkt = vpx_codec_get_cx_data(encoder_, &iter)) != NULL) {
+ switch (pkt->kind) {
+ case VPX_CODEC_CX_FRAME_PKT: {
+ memcpy(&encoded_image_._buffer[encoded_image_._length],
+ pkt->data.frame.buf,
+ pkt->data.frame.sz);
+ frag_info.fragmentationOffset[part_idx] = encoded_image_._length;
+ frag_info.fragmentationLength[part_idx] =
+ static_cast<uint32_t>(pkt->data.frame.sz);
+ frag_info.fragmentationPlType[part_idx] = 0;
+ frag_info.fragmentationTimeDiff[part_idx] = 0;
+ encoded_image_._length += static_cast<uint32_t>(pkt->data.frame.sz);
+ assert(encoded_image_._length <= encoded_image_._size);
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ // End of frame.
+ if ((pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT) == 0) {
+ // Check if encoded frame is a key frame.
+ if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) {
+ encoded_image_._frameType = kKeyFrame;
+ }
+ PopulateCodecSpecific(&codec_specific, *pkt, input_image.timestamp());
+ break;
+ }
+ }
+ if (encoded_image_._length > 0) {
+ TRACE_COUNTER1("webrtc", "EncodedFrameSize", encoded_image_._length);
+ encoded_image_._timeStamp = input_image.timestamp();
+ encoded_image_.capture_time_ms_ = input_image.render_time_ms();
+ encoded_image_._encodedHeight = raw_->d_h;
+ encoded_image_._encodedWidth = raw_->d_w;
+ encoded_complete_callback_->Encoded(encoded_image_, &codec_specific,
+ &frag_info);
+ }
+ return WEBRTC_VIDEO_CODEC_OK;
+}
+
+int VP9EncoderImpl::SetChannelParameters(uint32_t packet_loss, int rtt) {
+ return WEBRTC_VIDEO_CODEC_OK;
+}
+
+int VP9EncoderImpl::RegisterEncodeCompleteCallback(
+ EncodedImageCallback* callback) {
+ encoded_complete_callback_ = callback;
+ return WEBRTC_VIDEO_CODEC_OK;
+}
+
+VP9Decoder* VP9Decoder::Create() {
+ return new VP9DecoderImpl();
+}
+
+VP9DecoderImpl::VP9DecoderImpl()
+ : decode_complete_callback_(NULL),
+ inited_(false),
+ decoder_(NULL),
+ key_frame_required_(true) {
+ memset(&codec_, 0, sizeof(codec_));
+}
+
+VP9DecoderImpl::~VP9DecoderImpl() {
+ inited_ = true; // in order to do the actual release
+ Release();
+}
+
+int VP9DecoderImpl::Reset() {
+ if (!inited_) {
+ return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
+ }
+ InitDecode(&codec_, 1);
+ return WEBRTC_VIDEO_CODEC_OK;
+}
+
+int VP9DecoderImpl::InitDecode(const VideoCodec* inst, int number_of_cores) {
+ if (inst == NULL) {
+ return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
+ }
+ int ret_val = Release();
+ if (ret_val < 0) {
+ return ret_val;
+ }
+ if (decoder_ == NULL) {
+ decoder_ = new vpx_dec_ctx_t;
+ }
+ vpx_codec_dec_cfg_t cfg;
+ // Setting number of threads to a constant value (1)
+ cfg.threads = 1;
+ cfg.h = cfg.w = 0; // set after decode
+ vpx_codec_flags_t flags = 0;
+ if (vpx_codec_dec_init(decoder_, vpx_codec_vp9_dx(), &cfg, flags)) {
+ return WEBRTC_VIDEO_CODEC_MEMORY;
+ }
+ if (&codec_ != inst) {
+ // Save VideoCodec instance for later; mainly for duplicating the decoder.
+ codec_ = *inst;
+ }
+ inited_ = true;
+ // Always start with a complete key frame.
+ key_frame_required_ = true;
+ return WEBRTC_VIDEO_CODEC_OK;
+}
+
+int VP9DecoderImpl::Decode(const EncodedImage& input_image,
+ bool missing_frames,
+ const RTPFragmentationHeader* fragmentation,
+ const CodecSpecificInfo* codec_specific_info,
+ int64_t /*render_time_ms*/) {
+ if (!inited_) {
+ return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
+ }
+ if (decode_complete_callback_ == NULL) {
+ return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
+ }
+ // Always start with a complete key frame.
+ if (key_frame_required_) {
+ if (input_image._frameType != kKeyFrame)
+ return WEBRTC_VIDEO_CODEC_ERROR;
+ // We have a key frame - is it complete?
+ if (input_image._completeFrame) {
+ key_frame_required_ = false;
+ } else {
+ return WEBRTC_VIDEO_CODEC_ERROR;
+ }
+ }
+ vpx_codec_iter_t iter = NULL;
+ vpx_image_t* img;
+ uint8_t* buffer = input_image._buffer;
+ if (input_image._length == 0) {
+ buffer = NULL; // Triggers full frame concealment.
+ }
+ if (vpx_codec_decode(decoder_,
+ buffer,
+ input_image._length,
+ 0,
+ VPX_DL_REALTIME)) {
+ return WEBRTC_VIDEO_CODEC_ERROR;
+ }
+ img = vpx_codec_get_frame(decoder_, &iter);
+ int ret = ReturnFrame(img, input_image._timeStamp);
+ if (ret != 0) {
+ return ret;
+ }
+ return WEBRTC_VIDEO_CODEC_OK;
+}
+
+int VP9DecoderImpl::ReturnFrame(const vpx_image_t* img, uint32_t timestamp) {
+ if (img == NULL) {
+ // Decoder OK and NULL image => No show frame.
+ return WEBRTC_VIDEO_CODEC_NO_OUTPUT;
+ }
+ int half_height = (img->d_h + 1) / 2;
+ int size_y = img->stride[VPX_PLANE_Y] * img->d_h;
+ int size_u = img->stride[VPX_PLANE_U] * half_height;
+ int size_v = img->stride[VPX_PLANE_V] * half_height;
+ decoded_image_.CreateFrame(size_y, img->planes[VPX_PLANE_Y],
+ size_u, img->planes[VPX_PLANE_U],
+ size_v, img->planes[VPX_PLANE_V],
+ img->d_w, img->d_h,
+ img->stride[VPX_PLANE_Y],
+ img->stride[VPX_PLANE_U],
+ img->stride[VPX_PLANE_V]);
+ decoded_image_.set_timestamp(timestamp);
+ int ret = decode_complete_callback_->Decoded(decoded_image_);
+ if (ret != 0)
+ return ret;
+ return WEBRTC_VIDEO_CODEC_OK;
+}
+
+int VP9DecoderImpl::RegisterDecodeCompleteCallback(
+ DecodedImageCallback* callback) {
+ decode_complete_callback_ = callback;
+ return WEBRTC_VIDEO_CODEC_OK;
+}
+
+int VP9DecoderImpl::Release() {
+ if (decoder_ != NULL) {
+ if (vpx_codec_destroy(decoder_)) {
+ return WEBRTC_VIDEO_CODEC_MEMORY;
+ }
+ delete decoder_;
+ decoder_ = NULL;
+ }
+ inited_ = false;
+ return WEBRTC_VIDEO_CODEC_OK;
+}
+} // namespace webrtc
diff --git a/modules/video_coding/codecs/vp9/vp9_impl.h b/modules/video_coding/codecs/vp9/vp9_impl.h
new file mode 100644
index 00000000..94788db5
--- /dev/null
+++ b/modules/video_coding/codecs/vp9/vp9_impl.h
@@ -0,0 +1,115 @@
+/*
+ * 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 WEBRTC_MODULES_VIDEO_CODING_CODECS_VP9_IMPL_H_
+#define WEBRTC_MODULES_VIDEO_CODING_CODECS_VP9_IMPL_H_
+
+#include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
+
+// VPX forward declaration
+typedef struct vpx_codec_ctx vpx_codec_ctx_t;
+typedef struct vpx_codec_ctx vpx_dec_ctx_t;
+typedef struct vpx_codec_enc_cfg vpx_codec_enc_cfg_t;
+typedef struct vpx_image vpx_image_t;
+typedef struct vpx_ref_frame vpx_ref_frame_t;
+struct vpx_codec_cx_pkt;
+
+namespace webrtc {
+
+class VP9EncoderImpl : public VP9Encoder {
+ public:
+ VP9EncoderImpl();
+
+ virtual ~VP9EncoderImpl();
+
+ virtual int Release() OVERRIDE;
+
+ virtual int InitEncode(const VideoCodec* codec_settings,
+ int number_of_cores,
+ uint32_t max_payload_size) OVERRIDE;
+
+ virtual int Encode(const I420VideoFrame& input_image,
+ const CodecSpecificInfo* codec_specific_info,
+ const std::vector<VideoFrameType>* frame_types) OVERRIDE;
+
+ virtual int RegisterEncodeCompleteCallback(EncodedImageCallback* callback)
+ OVERRIDE;
+
+ virtual int SetChannelParameters(uint32_t packet_loss, int rtt) OVERRIDE;
+
+ virtual int SetRates(uint32_t new_bitrate_kbit, uint32_t frame_rate) OVERRIDE;
+
+ private:
+ // Call encoder initialize function and set control settings.
+ int InitAndSetControlSettings(const VideoCodec* inst);
+
+ void PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
+ const vpx_codec_cx_pkt& pkt,
+ uint32_t timestamp);
+
+ int GetEncodedPartitions(const I420VideoFrame& input_image);
+
+ // Determine maximum target for Intra frames
+ //
+ // Input:
+ // - optimal_buffer_size : Optimal buffer size
+ // Return Value : Max target size for Intra frames represented as
+ // percentage of the per frame bandwidth
+ uint32_t MaxIntraTarget(uint32_t optimal_buffer_size);
+
+ EncodedImage encoded_image_;
+ EncodedImageCallback* encoded_complete_callback_;
+ VideoCodec codec_;
+ bool inited_;
+ int64_t timestamp_;
+ uint16_t picture_id_;
+ int cpu_speed_;
+ uint32_t rc_max_intra_target_;
+ vpx_codec_ctx_t* encoder_;
+ vpx_codec_enc_cfg_t* config_;
+ vpx_image_t* raw_;
+};
+
+
+class VP9DecoderImpl : public VP9Decoder {
+ public:
+ VP9DecoderImpl();
+
+ virtual ~VP9DecoderImpl();
+
+ virtual int InitDecode(const VideoCodec* inst, int number_of_cores) OVERRIDE;
+
+ virtual int Decode(const EncodedImage& input_image,
+ bool missing_frames,
+ const RTPFragmentationHeader* fragmentation,
+ const CodecSpecificInfo* codec_specific_info,
+ int64_t /*render_time_ms*/) OVERRIDE;
+
+ virtual int RegisterDecodeCompleteCallback(DecodedImageCallback* callback)
+ OVERRIDE;
+
+ virtual int Release() OVERRIDE;
+
+ virtual int Reset() OVERRIDE;
+
+ private:
+ int ReturnFrame(const vpx_image_t* img, uint32_t timeStamp);
+
+ I420VideoFrame decoded_image_;
+ DecodedImageCallback* decode_complete_callback_;
+ bool inited_;
+ vpx_dec_ctx_t* decoder_;
+ VideoCodec codec_;
+ bool key_frame_required_;
+};
+} // namespace webrtc
+
+#endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_VP9_IMPL_H_
diff --git a/modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-arm.mk b/modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-arm.mk
new file mode 100644
index 00000000..f40975e3
--- /dev/null
+++ b/modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-arm.mk
@@ -0,0 +1,287 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-tree-sra \
+ -fno-caller-saves \
+ -Wno-psabi \
+ -fno-partial-inlining \
+ -fno-early-inlining \
+ -fno-tree-copy-prop \
+ -fno-tree-loop-optimize \
+ -fno-move-loop-invariants \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
+ '-DWEBRTC_ARCH_ARM_V7' \
+ '-DWEBRTC_DETECT_ARM_NEON' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-abi \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-tree-sra \
+ -fno-caller-saves \
+ -Wno-psabi \
+ -fno-partial-inlining \
+ -fno-early-inlining \
+ -fno-tree-copy-prop \
+ -fno-tree-loop-optimize \
+ -fno-move-loop-invariants \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
+ '-DWEBRTC_ARCH_ARM_V7' \
+ '-DWEBRTC_DETECT_ARM_NEON' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-abi \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_vp9
+webrtc_vp9: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-arm64.mk b/modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-arm64.mk
new file mode 100644
index 00000000..0adfcfa3
--- /dev/null
+++ b/modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-arm64.mk
@@ -0,0 +1,259 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_vp9
+webrtc_vp9: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-mips.mk b/modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-mips.mk
new file mode 100644
index 00000000..56334af9
--- /dev/null
+++ b/modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-mips.mk
@@ -0,0 +1,271 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -mhard-float \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DMIPS32_LE' \
+ '-DMIPS_FPU_LE' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -mhard-float \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DMIPS32_LE' \
+ '-DMIPS_FPU_LE' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_vp9
+webrtc_vp9: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-mips64.mk b/modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-mips64.mk
new file mode 100644
index 00000000..e752cbc3
--- /dev/null
+++ b/modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-mips64.mk
@@ -0,0 +1,265 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_vp9
+webrtc_vp9: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-x86.mk b/modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-x86.mk
new file mode 100644
index 00000000..3eba9b18
--- /dev/null
+++ b/modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-x86.mk
@@ -0,0 +1,269 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -msse2 \
+ -mfpmath=sse \
+ -mmmx \
+ -m32 \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -msse2 \
+ -mfpmath=sse \
+ -mmmx \
+ -m32 \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -fno-stack-protector \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_vp9
+webrtc_vp9: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-x86_64.mk b/modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-x86_64.mk
new file mode 100644
index 00000000..ee8824ce
--- /dev/null
+++ b/modules/video_coding/codecs/vp9/webrtc_vp9.target.darwin-x86_64.mk
@@ -0,0 +1,267 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -m64 \
+ -march=x86-64 \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -m64 \
+ -march=x86-64 \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_vp9
+webrtc_vp9: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-arm.mk b/modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-arm.mk
new file mode 100644
index 00000000..f40975e3
--- /dev/null
+++ b/modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-arm.mk
@@ -0,0 +1,287 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-tree-sra \
+ -fno-caller-saves \
+ -Wno-psabi \
+ -fno-partial-inlining \
+ -fno-early-inlining \
+ -fno-tree-copy-prop \
+ -fno-tree-loop-optimize \
+ -fno-move-loop-invariants \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
+ '-DWEBRTC_ARCH_ARM_V7' \
+ '-DWEBRTC_DETECT_ARM_NEON' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-abi \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-tree-sra \
+ -fno-caller-saves \
+ -Wno-psabi \
+ -fno-partial-inlining \
+ -fno-early-inlining \
+ -fno-tree-copy-prop \
+ -fno-tree-loop-optimize \
+ -fno-move-loop-invariants \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
+ '-DWEBRTC_ARCH_ARM_V7' \
+ '-DWEBRTC_DETECT_ARM_NEON' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-abi \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_vp9
+webrtc_vp9: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-arm64.mk b/modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-arm64.mk
new file mode 100644
index 00000000..0adfcfa3
--- /dev/null
+++ b/modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-arm64.mk
@@ -0,0 +1,259 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_vp9
+webrtc_vp9: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-mips.mk b/modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-mips.mk
new file mode 100644
index 00000000..56334af9
--- /dev/null
+++ b/modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-mips.mk
@@ -0,0 +1,271 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -mhard-float \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DMIPS32_LE' \
+ '-DMIPS_FPU_LE' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -mhard-float \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DMIPS32_LE' \
+ '-DMIPS_FPU_LE' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_vp9
+webrtc_vp9: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-mips64.mk b/modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-mips64.mk
new file mode 100644
index 00000000..e752cbc3
--- /dev/null
+++ b/modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-mips64.mk
@@ -0,0 +1,265 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_vp9
+webrtc_vp9: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-x86.mk b/modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-x86.mk
new file mode 100644
index 00000000..3eba9b18
--- /dev/null
+++ b/modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-x86.mk
@@ -0,0 +1,269 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -msse2 \
+ -mfpmath=sse \
+ -mmmx \
+ -m32 \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -fno-stack-protector \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -msse2 \
+ -mfpmath=sse \
+ -mmmx \
+ -m32 \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -fno-stack-protector \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_vp9
+webrtc_vp9: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-x86_64.mk b/modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-x86_64.mk
new file mode 100644
index 00000000..ee8824ce
--- /dev/null
+++ b/modules/video_coding/codecs/vp9/webrtc_vp9.target.linux-x86_64.mk
@@ -0,0 +1,267 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -m64 \
+ -march=x86-64 \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ -Werror \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -m64 \
+ -march=x86-64 \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface \
+ $(LOCAL_PATH)/third_party/libvpx/source/libvpx
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_vp9
+webrtc_vp9: third_party_webrtc_modules_video_coding_codecs_vp9_webrtc_vp9_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_coding/main/interface/video_coding_defines.h b/modules/video_coding/main/interface/video_coding_defines.h
index c5f93cb1..efdc41b4 100644
--- a/modules/video_coding/main/interface/video_coding_defines.h
+++ b/modules/video_coding/main/interface/video_coding_defines.h
@@ -39,9 +39,12 @@ namespace webrtc {
#define VCM_RED_PAYLOAD_TYPE 96
#define VCM_ULPFEC_PAYLOAD_TYPE 97
#define VCM_VP8_PAYLOAD_TYPE 100
+#define VCM_VP9_PAYLOAD_TYPE 101
#define VCM_I420_PAYLOAD_TYPE 124
#define VCM_H264_PAYLOAD_TYPE 127
+enum { kDefaultStartBitrateKbps = 300 };
+
enum VCMVideoProtection {
kProtectionNack, // Both send-side and receive-side
kProtectionNackSender, // Send-side only
diff --git a/modules/video_coding/main/source/codec_database.cc b/modules/video_coding/main/source/codec_database.cc
index cd8f9d35..2fc92461 100644
--- a/modules/video_coding/main/source/codec_database.cc
+++ b/modules/video_coding/main/source/codec_database.cc
@@ -19,6 +19,9 @@
#ifdef VIDEOCODEC_VP8
#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
#endif
+#ifdef VIDEOCODEC_VP9
+#include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
+#endif
#include "webrtc/modules/video_coding/main/source/internal_defines.h"
#include "webrtc/system_wrappers/interface/logging.h"
@@ -39,6 +42,20 @@ VideoCodecVP8 VideoEncoder::GetDefaultVp8Settings() {
return vp8_settings;
}
+VideoCodecVP9 VideoEncoder::GetDefaultVp9Settings() {
+ VideoCodecVP9 vp9_settings;
+ memset(&vp9_settings, 0, sizeof(vp9_settings));
+
+ vp9_settings.resilience = 1;
+ vp9_settings.numberOfTemporalLayers = 1;
+ vp9_settings.denoisingOn = false;
+ vp9_settings.frameDroppingOn = true;
+ vp9_settings.keyFrameInterval = 3000;
+ vp9_settings.adaptiveQpMode = true;
+
+ return vp9_settings;
+}
+
VideoCodecH264 VideoEncoder::GetDefaultH264Settings() {
VideoCodecH264 h264_settings;
memset(&h264_settings, 0, sizeof(h264_settings));
@@ -114,7 +131,7 @@ bool VCMCodecDataBase::Codec(int list_id,
settings->codecType = kVideoCodecVP8;
// 96 to 127 dynamic payload types for video codecs.
settings->plType = VCM_VP8_PAYLOAD_TYPE;
- settings->startBitrate = 100;
+ settings->startBitrate = kDefaultStartBitrateKbps;
settings->minBitrate = VCM_MIN_BITRATE;
settings->maxBitrate = 0;
settings->maxFramerate = VCM_DEFAULT_FRAME_RATE;
@@ -126,13 +143,31 @@ bool VCMCodecDataBase::Codec(int list_id,
return true;
}
#endif
+#ifdef VIDEOCODEC_VP9
+ case VCM_VP9_IDX: {
+ strncpy(settings->plName, "VP9", 4);
+ settings->codecType = kVideoCodecVP9;
+ // 96 to 127 dynamic payload types for video codecs.
+ settings->plType = VCM_VP9_PAYLOAD_TYPE;
+ settings->startBitrate = 100;
+ settings->minBitrate = VCM_MIN_BITRATE;
+ settings->maxBitrate = 0;
+ settings->maxFramerate = VCM_DEFAULT_FRAME_RATE;
+ settings->width = VCM_DEFAULT_CODEC_WIDTH;
+ settings->height = VCM_DEFAULT_CODEC_HEIGHT;
+ settings->numberOfSimulcastStreams = 0;
+ settings->qpMax = 56;
+ settings->codecSpecific.VP9 = VideoEncoder::GetDefaultVp9Settings();
+ return true;
+ }
+#endif
#ifdef VIDEOCODEC_H264
case VCM_H264_IDX: {
strncpy(settings->plName, "H264", 5);
settings->codecType = kVideoCodecH264;
// 96 to 127 dynamic payload types for video codecs.
settings->plType = VCM_H264_PAYLOAD_TYPE;
- settings->startBitrate = 100;
+ settings->startBitrate = kDefaultStartBitrateKbps;
settings->minBitrate = VCM_MIN_BITRATE;
settings->maxBitrate = 0;
settings->maxFramerate = VCM_DEFAULT_FRAME_RATE;
@@ -362,6 +397,13 @@ bool VCMCodecDataBase::RequiresEncoderReset(const VideoCodec& new_send_codec) {
return true;
}
break;
+ case kVideoCodecVP9:
+ if (memcmp(&new_send_codec.codecSpecific.VP9,
+ &send_codec_.codecSpecific.VP9,
+ sizeof(new_send_codec.codecSpecific.VP9)) != 0) {
+ return true;
+ }
+ break;
case kVideoCodecH264:
if (memcmp(&new_send_codec.codecSpecific.H264,
&send_codec_.codecSpecific.H264,
@@ -635,6 +677,10 @@ VCMGenericEncoder* VCMCodecDataBase::CreateEncoder(
case kVideoCodecVP8:
return new VCMGenericEncoder(*(VP8Encoder::Create()));
#endif
+#ifdef VIDEOCODEC_VP9
+ case kVideoCodecVP9:
+ return new VCMGenericEncoder(*(VP9Encoder::Create()));
+#endif
#ifdef VIDEOCODEC_I420
case kVideoCodecI420:
return new VCMGenericEncoder(*(new I420Encoder));
@@ -662,6 +708,10 @@ VCMGenericDecoder* VCMCodecDataBase::CreateDecoder(VideoCodecType type) const {
case kVideoCodecVP8:
return new VCMGenericDecoder(*(VP8Decoder::Create()));
#endif
+#ifdef VIDEOCODEC_VP9
+ case kVideoCodecVP9:
+ return new VCMGenericDecoder(*(VP9Decoder::Create()));
+#endif
#ifdef VIDEOCODEC_I420
case kVideoCodecI420:
return new VCMGenericDecoder(*(new I420Decoder));
diff --git a/modules/video_coding/main/source/internal_defines.h b/modules/video_coding/main/source/internal_defines.h
index ef42c628..adc940f2 100644
--- a/modules/video_coding/main/source/internal_defines.h
+++ b/modules/video_coding/main/source/internal_defines.h
@@ -39,10 +39,15 @@ inline uint32_t MaskWord64ToUWord32(int64_t w64)
#else
#define VCM_VP8_IDX VCM_NO_CODEC_IDX
#endif
+#ifdef VIDEOCODEC_VP9
+ #define VCM_VP9_IDX (VCM_VP8_IDX + 1)
+#else
+ #define VCM_VP9_IDX VCM_VP8_IDX
+#endif
#ifdef VIDEOCODEC_H264
- #define VCM_H264_IDX (VCM_VP8_IDX + 1)
+ #define VCM_H264_IDX (VCM_VP9_IDX + 1)
#else
- #define VCM_H264_IDX VCM_VP8_IDX
+ #define VCM_H264_IDX VCM_VP9_IDX
#endif
#ifdef VIDEOCODEC_I420
#define VCM_I420_IDX (VCM_H264_IDX + 1)
diff --git a/modules/video_coding/main/source/jitter_buffer.cc b/modules/video_coding/main/source/jitter_buffer.cc
index d09fccd9..e3a4a8a7 100644
--- a/modules/video_coding/main/source/jitter_buffer.cc
+++ b/modules/video_coding/main/source/jitter_buffer.cc
@@ -25,6 +25,7 @@
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/event_wrapper.h"
#include "webrtc/system_wrappers/interface/logging.h"
+#include "webrtc/system_wrappers/interface/metrics.h"
#include "webrtc/system_wrappers/interface/trace_event.h"
namespace webrtc {
@@ -143,6 +144,8 @@ VCMJitterBuffer::VCMJitterBuffer(Clock* clock, EventFactory* event_factory)
drop_count_(0),
num_consecutive_old_frames_(0),
num_consecutive_old_packets_(0),
+ num_packets_(0),
+ num_duplicated_packets_(0),
num_discarded_packets_(0),
jitter_estimate_(clock),
inter_frame_delay_(clock_->TimeInMilliseconds()),
@@ -190,6 +193,8 @@ void VCMJitterBuffer::CopyFrom(const VCMJitterBuffer& rhs) {
drop_count_ = rhs.drop_count_;
num_consecutive_old_frames_ = rhs.num_consecutive_old_frames_;
num_consecutive_old_packets_ = rhs.num_consecutive_old_packets_;
+ num_packets_ = rhs.num_packets_;
+ num_duplicated_packets_ = rhs.num_duplicated_packets_;
num_discarded_packets_ = rhs.num_discarded_packets_;
jitter_estimate_ = rhs.jitter_estimate_;
inter_frame_delay_ = rhs.inter_frame_delay_;
@@ -238,6 +243,15 @@ void VCMJitterBuffer::CopyFrames(FrameList* to_list,
}
}
+void VCMJitterBuffer::UpdateHistograms() {
+ if (num_packets_ > 0) {
+ RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.DiscardedPacketsInPercent",
+ num_discarded_packets_ * 100 / num_packets_);
+ RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.DuplicatedPacketsInPercent",
+ num_duplicated_packets_ * 100 / num_packets_);
+ }
+}
+
void VCMJitterBuffer::Start() {
CriticalSectionScoped cs(crit_sect_);
running_ = true;
@@ -250,6 +264,8 @@ void VCMJitterBuffer::Start() {
num_consecutive_old_frames_ = 0;
num_consecutive_old_packets_ = 0;
+ num_packets_ = 0;
+ num_duplicated_packets_ = 0;
num_discarded_packets_ = 0;
// Start in a non-signaled state.
@@ -265,6 +281,7 @@ void VCMJitterBuffer::Start() {
void VCMJitterBuffer::Stop() {
crit_sect_->Enter();
+ UpdateHistograms();
running_ = false;
last_decoded_state_.Reset();
free_frames_.clear();
@@ -313,6 +330,16 @@ std::map<FrameType, uint32_t> VCMJitterBuffer::FrameStatistics() const {
return receive_statistics_;
}
+int VCMJitterBuffer::num_packets() const {
+ CriticalSectionScoped cs(crit_sect_);
+ return num_packets_;
+}
+
+int VCMJitterBuffer::num_duplicated_packets() const {
+ CriticalSectionScoped cs(crit_sect_);
+ return num_duplicated_packets_;
+}
+
int VCMJitterBuffer::num_discarded_packets() const {
CriticalSectionScoped cs(crit_sect_);
return num_discarded_packets_;
@@ -543,6 +570,7 @@ void VCMJitterBuffer::ReleaseFrame(VCMEncodedFrame* frame) {
// Gets frame to use for this timestamp. If no match, get empty frame.
VCMFrameBufferEnum VCMJitterBuffer::GetFrame(const VCMPacket& packet,
VCMFrameBuffer** frame) {
+ ++num_packets_;
// Does this packet belong to an old frame?
if (last_decoded_state_.IsOldPacket(&packet)) {
// Account only for media packets.
@@ -747,6 +775,7 @@ VCMFrameBufferEnum VCMJitterBuffer::InsertPacket(const VCMPacket& packet,
case kNoError:
case kOutOfBoundsPacket:
case kDuplicatePacket: {
+ ++num_duplicated_packets_;
break;
}
case kFlushIndicator:
diff --git a/modules/video_coding/main/source/jitter_buffer.h b/modules/video_coding/main/source/jitter_buffer.h
index 6ed9cfb8..182b80b4 100644
--- a/modules/video_coding/main/source/jitter_buffer.h
+++ b/modules/video_coding/main/source/jitter_buffer.h
@@ -103,6 +103,12 @@ class VCMJitterBuffer {
// won't be able to decode them.
int num_not_decodable_packets() const;
+ // Gets number of packets received.
+ int num_packets() const;
+
+ // Gets number of duplicated packets received.
+ int num_duplicated_packets() const;
+
// Gets number of packets discarded by the jitter buffer.
int num_discarded_packets() const;
@@ -271,6 +277,8 @@ class VCMJitterBuffer {
uint16_t EstimatedLowSequenceNumber(const VCMFrameBuffer& frame) const;
+ void UpdateHistograms();
+
Clock* clock_;
// If we are running (have started) or not.
bool running_;
@@ -303,6 +311,10 @@ class VCMJitterBuffer {
int num_consecutive_old_frames_;
// Number of packets in a row that have been too old.
int num_consecutive_old_packets_;
+ // Number of packets received.
+ int num_packets_;
+ // Number of duplicated packets received.
+ int num_duplicated_packets_;
// Number of packets discarded by the jitter buffer.
int num_discarded_packets_;
diff --git a/modules/video_coding/main/source/jitter_buffer_unittest.cc b/modules/video_coding/main/source/jitter_buffer_unittest.cc
index 0490658b..899a3eec 100644
--- a/modules/video_coding/main/source/jitter_buffer_unittest.cc
+++ b/modules/video_coding/main/source/jitter_buffer_unittest.cc
@@ -512,6 +512,8 @@ TEST_F(TestBasicJitterBuffer, DuplicatePackets) {
packet_->markerBit = false;
packet_->seqNum = seq_num_;
packet_->timestamp = timestamp_;
+ EXPECT_EQ(0, jitter_buffer_->num_packets());
+ EXPECT_EQ(0, jitter_buffer_->num_duplicated_packets());
bool retransmitted = false;
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
@@ -520,6 +522,8 @@ TEST_F(TestBasicJitterBuffer, DuplicatePackets) {
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
EXPECT_TRUE(frame_out == NULL);
+ EXPECT_EQ(1, jitter_buffer_->num_packets());
+ EXPECT_EQ(0, jitter_buffer_->num_duplicated_packets());
packet_->isFirstPacket = false;
packet_->markerBit = true;
@@ -527,6 +531,8 @@ TEST_F(TestBasicJitterBuffer, DuplicatePackets) {
// Insert a packet into a frame.
EXPECT_EQ(kDuplicatePacket, jitter_buffer_->InsertPacket(*packet_,
&retransmitted));
+ EXPECT_EQ(2, jitter_buffer_->num_packets());
+ EXPECT_EQ(1, jitter_buffer_->num_duplicated_packets());
seq_num_++;
packet_->seqNum = seq_num_;
@@ -539,6 +545,8 @@ TEST_F(TestBasicJitterBuffer, DuplicatePackets) {
CheckOutFrame(frame_out, 2 * size_, false);
EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
+ EXPECT_EQ(3, jitter_buffer_->num_packets());
+ EXPECT_EQ(1, jitter_buffer_->num_duplicated_packets());
}
TEST_F(TestBasicJitterBuffer, H264InsertStartCode) {
diff --git a/modules/video_coding/main/source/video_coding.gypi b/modules/video_coding/main/source/video_coding.gypi
index f19a5855..02c5a5c0 100644
--- a/modules/video_coding/main/source/video_coding.gypi
+++ b/modules/video_coding/main/source/video_coding.gypi
@@ -17,6 +17,7 @@
'<(webrtc_root)/modules/video_coding/utility/video_coding_utility.gyp:video_coding_utility',
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
'<(webrtc_vp8_dir)/vp8.gyp:webrtc_vp8',
+ '<(webrtc_vp9_dir)/vp9.gyp:webrtc_vp9',
],
'sources': [
# interfaces
diff --git a/modules/video_coding/main/source/video_coding_impl.h b/modules/video_coding/main/source/video_coding_impl.h
index 5b3fe2eb..ac7a1f4b 100644
--- a/modules/video_coding/main/source/video_coding_impl.h
+++ b/modules/video_coding/main/source/video_coding_impl.h
@@ -186,7 +186,8 @@ class VideoReceiver {
void RegisterPreDecodeImageCallback(EncodedImageCallback* observer);
protected:
- int32_t Decode(const webrtc::VCMEncodedFrame& frame);
+ int32_t Decode(const webrtc::VCMEncodedFrame& frame)
+ EXCLUSIVE_LOCKS_REQUIRED(_receiveCritSect);
int32_t RequestKeyFrame();
int32_t RequestSliceLossIndication(const uint64_t pictureID) const;
int32_t NackList(uint16_t* nackList, uint16_t* size);
@@ -230,7 +231,7 @@ class VideoReceiver {
size_t max_nack_list_size_ GUARDED_BY(process_crit_sect_);
EncodedImageCallback* pre_decode_image_callback_ GUARDED_BY(_receiveCritSect);
- VCMCodecDataBase _codecDataBase;
+ VCMCodecDataBase _codecDataBase GUARDED_BY(_receiveCritSect);
VCMProcessTimer _receiveStatsTimer;
VCMProcessTimer _retransmissionTimer;
VCMProcessTimer _keyRequestTimer;
diff --git a/modules/video_coding/main/source/video_coding_test.gypi b/modules/video_coding/main/source/video_coding_test.gypi
index 64cb6024..0c5641d7 100644
--- a/modules/video_coding/main/source/video_coding_test.gypi
+++ b/modules/video_coding/main/source/video_coding_test.gypi
@@ -20,7 +20,7 @@
'<(webrtc_root)/test/test.gyp:test_support',
'<(webrtc_root)/test/metrics.gyp:metrics',
'<(webrtc_root)/common_video/common_video.gyp:common_video',
- '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default',
+ '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers_default',
'<(webrtc_root)/test/webrtc_test_common.gyp:webrtc_test_common',
],
'sources': [
diff --git a/modules/video_coding/main/source/video_receiver.cc b/modules/video_coding/main/source/video_receiver.cc
index 0b561249..a8de28bb 100644
--- a/modules/video_coding/main/source/video_receiver.cc
+++ b/modules/video_coding/main/source/video_receiver.cc
@@ -280,11 +280,11 @@ int32_t VideoReceiver::InitializeReceiver() {
if (ret < 0) {
return ret;
}
- _codecDataBase.ResetReceiver();
- _timing.Reset();
{
CriticalSectionScoped receive_cs(_receiveCritSect);
+ _codecDataBase.ResetReceiver();
+ _timing.Reset();
_receiverInited = true;
}
@@ -369,6 +369,7 @@ int VideoReceiver::RegisterRenderBufferSizeCallback(
// Should be called as often as possible to get the most out of the decoder.
int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) {
int64_t nextRenderTimeMs;
+ bool supports_render_scheduling;
{
CriticalSectionScoped cs(_receiveCritSect);
if (!_receiverInited) {
@@ -377,6 +378,7 @@ int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) {
if (!_codecDataBase.DecoderRegistered()) {
return VCM_NO_CODEC_REGISTERED;
}
+ supports_render_scheduling = _codecDataBase.SupportsRenderScheduling();
}
const bool dualReceiverEnabledNotReceiving = (
@@ -385,7 +387,7 @@ int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) {
VCMEncodedFrame* frame =
_receiver.FrameForDecoding(maxWaitTimeMs,
nextRenderTimeMs,
- _codecDataBase.SupportsRenderScheduling(),
+ supports_render_scheduling,
&_dualReceiver);
if (dualReceiverEnabledNotReceiving && _dualReceiver.State() == kReceiving) {
diff --git a/modules/video_coding/main/test/normal_test.cc b/modules/video_coding/main/test/normal_test.cc
index f23682bd..815c3acc 100644
--- a/modules/video_coding/main/test/normal_test.cc
+++ b/modules/video_coding/main/test/normal_test.cc
@@ -101,6 +101,9 @@ VCMNTEncodeCompleteCallback::SendData(
rtpInfo.type.Video.codecHeader.VP8.pictureId =
videoHdr->codecHeader.VP8.pictureId;
break;
+ case kVideoCodecVP9:
+ // Leave for now, until we add kRtpVideoVp9 to RTP.
+ break;
default:
assert(false);
return -1;
diff --git a/modules/video_coding/main/test/test_callbacks.cc b/modules/video_coding/main/test/test_callbacks.cc
index 710a06ea..d68f9949 100644
--- a/modules/video_coding/main/test/test_callbacks.cc
+++ b/modules/video_coding/main/test/test_callbacks.cc
@@ -82,6 +82,9 @@ VCMEncodeCompleteCallback::SendData(
rtpInfo.type.Video.codecHeader.VP8.pictureId =
videoHdr->codecHeader.VP8.pictureId;
break;
+ case webrtc::kRtpVideoGeneric:
+ // Leave for now, until we add kRtpVideoVp9 to RTP.
+ break;
default:
assert(false);
return -1;
diff --git a/modules/video_coding/main/test/test_util.cc b/modules/video_coding/main/test/test_util.cc
index 09ad9916..d2b8f8c7 100644
--- a/modules/video_coding/main/test/test_util.cc
+++ b/modules/video_coding/main/test/test_util.cc
@@ -151,6 +151,7 @@ webrtc::RtpVideoCodecTypes ConvertCodecType(const char* plname) {
if (strncmp(plname,"VP8" , 3) == 0) {
return webrtc::kRtpVideoVp8;
} else {
- return webrtc::kRtpVideoNone; // Default value
+ // Default value.
+ return webrtc::kRtpVideoGeneric;
}
}
diff --git a/modules/video_coding/main/test/tester_main.cc b/modules/video_coding/main/test/tester_main.cc
index bf17ab27..874fa9e7 100644
--- a/modules/video_coding/main/test/tester_main.cc
+++ b/modules/video_coding/main/test/tester_main.cc
@@ -63,6 +63,8 @@ int ParseArguments(CmdArgs& args) {
args.codecName = FLAGS_codec;
if (args.codecName == "VP8") {
args.codecType = kVideoCodecVP8;
+ } else if (args.codecName == "VP9") {
+ args.codecType = kVideoCodecVP9;
} else if (args.codecName == "I420") {
args.codecType = kVideoCodecI420;
} else {
diff --git a/modules/video_coding/utility/video_coding_utility.target.darwin-arm.mk b/modules/video_coding/utility/video_coding_utility.target.darwin-arm.mk
index 13e70ada..9e107923 100644
--- a/modules/video_coding/utility/video_coding_utility.target.darwin-arm.mk
+++ b/modules/video_coding/utility/video_coding_utility.target.darwin-arm.mk
@@ -84,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -104,6 +106,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -197,11 +200,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -217,6 +222,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_coding/utility/video_coding_utility.target.darwin-arm64.mk b/modules/video_coding/utility/video_coding_utility.target.darwin-arm64.mk
index dc5453d8..26c7a494 100644
--- a/modules/video_coding/utility/video_coding_utility.target.darwin-arm64.mk
+++ b/modules/video_coding/utility/video_coding_utility.target.darwin-arm64.mk
@@ -73,11 +73,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -86,10 +88,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -171,11 +175,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -184,10 +190,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_coding/utility/video_coding_utility.target.darwin-mips.mk b/modules/video_coding/utility/video_coding_utility.target.darwin-mips.mk
index d6975665..e6367b72 100644
--- a/modules/video_coding/utility/video_coding_utility.target.darwin-mips.mk
+++ b/modules/video_coding/utility/video_coding_utility.target.darwin-mips.mk
@@ -77,11 +77,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -96,6 +98,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -182,11 +185,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -201,6 +206,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_coding/utility/video_coding_utility.target.darwin-mips64.mk b/modules/video_coding/utility/video_coding_utility.target.darwin-mips64.mk
new file mode 100644
index 00000000..71941bc0
--- /dev/null
+++ b/modules/video_coding/utility/video_coding_utility.target.darwin-mips64.mk
@@ -0,0 +1,260 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_coding_utility_video_coding_utility_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_coding/utility/frame_dropper.cc \
+ third_party/webrtc/modules/video_coding/utility/quality_scaler.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_coding_utility_video_coding_utility_gyp
+
+# Alias gyp target name.
+.PHONY: video_coding_utility
+video_coding_utility: third_party_webrtc_modules_video_coding_utility_video_coding_utility_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_coding/utility/video_coding_utility.target.darwin-x86.mk b/modules/video_coding/utility/video_coding_utility.target.darwin-x86.mk
index 13bc1cc0..b423cb28 100644
--- a/modules/video_coding/utility/video_coding_utility.target.darwin-x86.mk
+++ b/modules/video_coding/utility/video_coding_utility.target.darwin-x86.mk
@@ -79,11 +79,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -96,6 +98,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -183,11 +186,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -200,6 +205,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_coding/utility/video_coding_utility.target.darwin-x86_64.mk b/modules/video_coding/utility/video_coding_utility.target.darwin-x86_64.mk
index 9a820817..17043fc9 100644
--- a/modules/video_coding/utility/video_coding_utility.target.darwin-x86_64.mk
+++ b/modules/video_coding/utility/video_coding_utility.target.darwin-x86_64.mk
@@ -78,11 +78,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -95,6 +97,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -181,11 +184,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -198,6 +203,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_coding/utility/video_coding_utility.target.linux-arm.mk b/modules/video_coding/utility/video_coding_utility.target.linux-arm.mk
index 13e70ada..9e107923 100644
--- a/modules/video_coding/utility/video_coding_utility.target.linux-arm.mk
+++ b/modules/video_coding/utility/video_coding_utility.target.linux-arm.mk
@@ -84,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -104,6 +106,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -197,11 +200,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -217,6 +222,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_coding/utility/video_coding_utility.target.linux-arm64.mk b/modules/video_coding/utility/video_coding_utility.target.linux-arm64.mk
index dc5453d8..26c7a494 100644
--- a/modules/video_coding/utility/video_coding_utility.target.linux-arm64.mk
+++ b/modules/video_coding/utility/video_coding_utility.target.linux-arm64.mk
@@ -73,11 +73,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -86,10 +88,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -171,11 +175,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -184,10 +190,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_coding/utility/video_coding_utility.target.linux-mips.mk b/modules/video_coding/utility/video_coding_utility.target.linux-mips.mk
index d6975665..e6367b72 100644
--- a/modules/video_coding/utility/video_coding_utility.target.linux-mips.mk
+++ b/modules/video_coding/utility/video_coding_utility.target.linux-mips.mk
@@ -77,11 +77,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -96,6 +98,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -182,11 +185,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -201,6 +206,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_coding/utility/video_coding_utility.target.linux-mips64.mk b/modules/video_coding/utility/video_coding_utility.target.linux-mips64.mk
new file mode 100644
index 00000000..71941bc0
--- /dev/null
+++ b/modules/video_coding/utility/video_coding_utility.target.linux-mips64.mk
@@ -0,0 +1,260 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_coding_utility_video_coding_utility_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_coding/utility/frame_dropper.cc \
+ third_party/webrtc/modules/video_coding/utility/quality_scaler.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_coding_utility_video_coding_utility_gyp
+
+# Alias gyp target name.
+.PHONY: video_coding_utility
+video_coding_utility: third_party_webrtc_modules_video_coding_utility_video_coding_utility_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_coding/utility/video_coding_utility.target.linux-x86.mk b/modules/video_coding/utility/video_coding_utility.target.linux-x86.mk
index 13bc1cc0..b423cb28 100644
--- a/modules/video_coding/utility/video_coding_utility.target.linux-x86.mk
+++ b/modules/video_coding/utility/video_coding_utility.target.linux-x86.mk
@@ -79,11 +79,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -96,6 +98,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -183,11 +186,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -200,6 +205,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_coding/utility/video_coding_utility.target.linux-x86_64.mk b/modules/video_coding/utility/video_coding_utility.target.linux-x86_64.mk
index 9a820817..17043fc9 100644
--- a/modules/video_coding/utility/video_coding_utility.target.linux-x86_64.mk
+++ b/modules/video_coding/utility/video_coding_utility.target.linux-x86_64.mk
@@ -78,11 +78,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -95,6 +97,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -181,11 +184,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -198,6 +203,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_processing.target.darwin-arm.mk b/modules/video_processing.target.darwin-arm.mk
index df41d78b..aa673834 100644
--- a/modules/video_processing.target.darwin-arm.mk
+++ b/modules/video_processing.target.darwin-arm.mk
@@ -95,11 +95,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -115,6 +117,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -217,11 +220,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -237,6 +242,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_processing.target.darwin-arm64.mk b/modules/video_processing.target.darwin-arm64.mk
index b0ac65b9..603e1665 100644
--- a/modules/video_processing.target.darwin-arm64.mk
+++ b/modules/video_processing.target.darwin-arm64.mk
@@ -84,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -97,10 +99,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +195,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -204,10 +210,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_processing.target.darwin-mips.mk b/modules/video_processing.target.darwin-mips.mk
index aef54e0e..0c380a27 100644
--- a/modules/video_processing.target.darwin-mips.mk
+++ b/modules/video_processing.target.darwin-mips.mk
@@ -89,11 +89,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -108,6 +110,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -204,11 +207,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -223,6 +228,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_processing.target.darwin-mips64.mk b/modules/video_processing.target.darwin-mips64.mk
new file mode 100644
index 00000000..03b57c97
--- /dev/null
+++ b/modules/video_processing.target.darwin-mips64.mk
@@ -0,0 +1,285 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_processing_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_processing/main/source/brighten.cc \
+ third_party/webrtc/modules/video_processing/main/source/brightness_detection.cc \
+ third_party/webrtc/modules/video_processing/main/source/color_enhancement.cc \
+ third_party/webrtc/modules/video_processing/main/source/content_analysis.cc \
+ third_party/webrtc/modules/video_processing/main/source/deflickering.cc \
+ third_party/webrtc/modules/video_processing/main/source/frame_preprocessor.cc \
+ third_party/webrtc/modules/video_processing/main/source/spatial_resampler.cc \
+ third_party/webrtc/modules/video_processing/main/source/video_decimator.cc \
+ third_party/webrtc/modules/video_processing/main/source/video_processing_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_processing_gyp
+
+# Alias gyp target name.
+.PHONY: video_processing
+video_processing: third_party_webrtc_modules_video_processing_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_processing.target.darwin-x86.mk b/modules/video_processing.target.darwin-x86.mk
index bc7a8990..be7e37c4 100644
--- a/modules/video_processing.target.darwin-x86.mk
+++ b/modules/video_processing.target.darwin-x86.mk
@@ -90,11 +90,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +109,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -203,11 +206,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -220,6 +225,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_processing.target.darwin-x86_64.mk b/modules/video_processing.target.darwin-x86_64.mk
index a9851a47..fed3f29a 100644
--- a/modules/video_processing.target.darwin-x86_64.mk
+++ b/modules/video_processing.target.darwin-x86_64.mk
@@ -89,11 +89,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -106,6 +108,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -201,11 +204,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -218,6 +223,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_processing.target.linux-arm.mk b/modules/video_processing.target.linux-arm.mk
index df41d78b..aa673834 100644
--- a/modules/video_processing.target.linux-arm.mk
+++ b/modules/video_processing.target.linux-arm.mk
@@ -95,11 +95,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -115,6 +117,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -217,11 +220,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -237,6 +242,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_processing.target.linux-arm64.mk b/modules/video_processing.target.linux-arm64.mk
index b0ac65b9..603e1665 100644
--- a/modules/video_processing.target.linux-arm64.mk
+++ b/modules/video_processing.target.linux-arm64.mk
@@ -84,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -97,10 +99,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +195,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -204,10 +210,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_processing.target.linux-mips.mk b/modules/video_processing.target.linux-mips.mk
index aef54e0e..0c380a27 100644
--- a/modules/video_processing.target.linux-mips.mk
+++ b/modules/video_processing.target.linux-mips.mk
@@ -89,11 +89,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -108,6 +110,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -204,11 +207,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -223,6 +228,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_processing.target.linux-mips64.mk b/modules/video_processing.target.linux-mips64.mk
new file mode 100644
index 00000000..03b57c97
--- /dev/null
+++ b/modules/video_processing.target.linux-mips64.mk
@@ -0,0 +1,285 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_processing_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_processing/main/source/brighten.cc \
+ third_party/webrtc/modules/video_processing/main/source/brightness_detection.cc \
+ third_party/webrtc/modules/video_processing/main/source/color_enhancement.cc \
+ third_party/webrtc/modules/video_processing/main/source/content_analysis.cc \
+ third_party/webrtc/modules/video_processing/main/source/deflickering.cc \
+ third_party/webrtc/modules/video_processing/main/source/frame_preprocessor.cc \
+ third_party/webrtc/modules/video_processing/main/source/spatial_resampler.cc \
+ third_party/webrtc/modules/video_processing/main/source/video_decimator.cc \
+ third_party/webrtc/modules/video_processing/main/source/video_processing_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_processing_gyp
+
+# Alias gyp target name.
+.PHONY: video_processing
+video_processing: third_party_webrtc_modules_video_processing_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_processing.target.linux-x86.mk b/modules/video_processing.target.linux-x86.mk
index bc7a8990..be7e37c4 100644
--- a/modules/video_processing.target.linux-x86.mk
+++ b/modules/video_processing.target.linux-x86.mk
@@ -90,11 +90,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +109,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -203,11 +206,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -220,6 +225,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_processing.target.linux-x86_64.mk b/modules/video_processing.target.linux-x86_64.mk
index a9851a47..fed3f29a 100644
--- a/modules/video_processing.target.linux-x86_64.mk
+++ b/modules/video_processing.target.linux-x86_64.mk
@@ -89,11 +89,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -106,6 +108,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -201,11 +204,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -218,6 +223,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_processing_sse2.target.darwin-x86.mk b/modules/video_processing_sse2.target.darwin-x86.mk
index bb8623f8..863c65d8 100644
--- a/modules/video_processing_sse2.target.darwin-x86.mk
+++ b/modules/video_processing_sse2.target.darwin-x86.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -208,6 +213,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_processing_sse2.target.darwin-x86_64.mk b/modules/video_processing_sse2.target.darwin-x86_64.mk
index a0a6b1ee..2bb01c28 100644
--- a/modules/video_processing_sse2.target.darwin-x86_64.mk
+++ b/modules/video_processing_sse2.target.darwin-x86_64.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -189,11 +192,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -206,6 +211,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_processing_sse2.target.linux-x86.mk b/modules/video_processing_sse2.target.linux-x86.mk
index bb8623f8..863c65d8 100644
--- a/modules/video_processing_sse2.target.linux-x86.mk
+++ b/modules/video_processing_sse2.target.linux-x86.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -208,6 +213,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_processing_sse2.target.linux-x86_64.mk b/modules/video_processing_sse2.target.linux-x86_64.mk
index a0a6b1ee..2bb01c28 100644
--- a/modules/video_processing_sse2.target.linux-x86_64.mk
+++ b/modules/video_processing_sse2.target.linux-x86_64.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -189,11 +192,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -206,6 +211,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_render/incoming_video_stream.cc b/modules/video_render/incoming_video_stream.cc
index 71f30c38..1770569e 100644
--- a/modules/video_render/incoming_video_stream.cc
+++ b/modules/video_render/incoming_video_stream.cc
@@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include "webrtc/modules/video_render//incoming_video_stream.h"
+#include "webrtc/modules/video_render/incoming_video_stream.h"
#include <assert.h>
@@ -22,7 +22,7 @@
#endif
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
-#include "webrtc/modules/video_render//video_render_frames.h"
+#include "webrtc/modules/video_render/video_render_frames.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/event_wrapper.h"
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
diff --git a/modules/video_render/video_render.gypi b/modules/video_render/video_render.gypi
index 5db851d9..38a77985 100644
--- a/modules/video_render/video_render.gypi
+++ b/modules/video_render/video_render.gypi
@@ -205,7 +205,6 @@
],
'includes': [
'../../build/isolate.gypi',
- 'video_render_tests.isolate',
],
'sources': [
'video_render_tests.isolate',
diff --git a/modules/video_render/video_render_tests.isolate b/modules/video_render/video_render_tests.isolate
index 15c80141..12bfecf9 100644
--- a/modules/video_render/video_render_tests.isolate
+++ b/modules/video_render/video_render_tests.isolate
@@ -9,7 +9,7 @@
'conditions': [
['OS=="android"', {
'variables': {
- 'isolate_dependency_untracked': [
+ 'files': [
'<(DEPTH)/data/',
'<(DEPTH)/resources/',
],
@@ -21,13 +21,10 @@
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/video_render_tests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/video_render_tests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_untracked': [
- '<(DEPTH)/tools/swarming_client/',
- ],
},
}],
],
diff --git a/modules/video_render_module.target.darwin-arm.mk b/modules/video_render_module.target.darwin-arm.mk
index 5dada0f3..4899832b 100644
--- a/modules/video_render_module.target.darwin-arm.mk
+++ b/modules/video_render_module.target.darwin-arm.mk
@@ -89,11 +89,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -109,6 +111,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -208,11 +211,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -228,6 +233,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_render_module.target.darwin-arm64.mk b/modules/video_render_module.target.darwin-arm64.mk
index 0a91cbef..a5e3a505 100644
--- a/modules/video_render_module.target.darwin-arm64.mk
+++ b/modules/video_render_module.target.darwin-arm64.mk
@@ -78,11 +78,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -91,10 +93,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -182,11 +186,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -195,10 +201,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_render_module.target.darwin-mips.mk b/modules/video_render_module.target.darwin-mips.mk
index 4417e7ee..ea672a79 100644
--- a/modules/video_render_module.target.darwin-mips.mk
+++ b/modules/video_render_module.target.darwin-mips.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -102,6 +104,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -195,11 +198,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -214,6 +219,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_render_module.target.darwin-mips64.mk b/modules/video_render_module.target.darwin-mips64.mk
new file mode 100644
index 00000000..a2a89140
--- /dev/null
+++ b/modules/video_render_module.target.darwin-mips64.mk
@@ -0,0 +1,273 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_render_module_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_render/external/video_render_external_impl.cc \
+ third_party/webrtc/modules/video_render/incoming_video_stream.cc \
+ third_party/webrtc/modules/video_render/video_render_frames.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_render_module_gyp
+
+# Alias gyp target name.
+.PHONY: video_render_module
+video_render_module: third_party_webrtc_modules_video_render_module_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_render_module.target.darwin-x86.mk b/modules/video_render_module.target.darwin-x86.mk
index 243df8f3..16e78e29 100644
--- a/modules/video_render_module.target.darwin-x86.mk
+++ b/modules/video_render_module.target.darwin-x86.mk
@@ -84,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -194,11 +197,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -211,6 +216,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_render_module.target.darwin-x86_64.mk b/modules/video_render_module.target.darwin-x86_64.mk
index 23e262da..e91a36f3 100644
--- a/modules/video_render_module.target.darwin-x86_64.mk
+++ b/modules/video_render_module.target.darwin-x86_64.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -192,11 +195,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -209,6 +214,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_render_module.target.linux-arm.mk b/modules/video_render_module.target.linux-arm.mk
index 5dada0f3..4899832b 100644
--- a/modules/video_render_module.target.linux-arm.mk
+++ b/modules/video_render_module.target.linux-arm.mk
@@ -89,11 +89,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -109,6 +111,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -208,11 +211,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -228,6 +233,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_render_module.target.linux-arm64.mk b/modules/video_render_module.target.linux-arm64.mk
index 0a91cbef..a5e3a505 100644
--- a/modules/video_render_module.target.linux-arm64.mk
+++ b/modules/video_render_module.target.linux-arm64.mk
@@ -78,11 +78,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -91,10 +93,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -182,11 +186,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -195,10 +201,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_render_module.target.linux-mips.mk b/modules/video_render_module.target.linux-mips.mk
index 4417e7ee..ea672a79 100644
--- a/modules/video_render_module.target.linux-mips.mk
+++ b/modules/video_render_module.target.linux-mips.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -102,6 +104,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -195,11 +198,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -214,6 +219,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_render_module.target.linux-mips64.mk b/modules/video_render_module.target.linux-mips64.mk
new file mode 100644
index 00000000..a2a89140
--- /dev/null
+++ b/modules/video_render_module.target.linux-mips64.mk
@@ -0,0 +1,273 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_render_module_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_render/external/video_render_external_impl.cc \
+ third_party/webrtc/modules/video_render/incoming_video_stream.cc \
+ third_party/webrtc/modules/video_render/video_render_frames.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_render_module_gyp
+
+# Alias gyp target name.
+.PHONY: video_render_module
+video_render_module: third_party_webrtc_modules_video_render_module_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_render_module.target.linux-x86.mk b/modules/video_render_module.target.linux-x86.mk
index 243df8f3..16e78e29 100644
--- a/modules/video_render_module.target.linux-x86.mk
+++ b/modules/video_render_module.target.linux-x86.mk
@@ -84,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -194,11 +197,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -211,6 +216,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_render_module.target.linux-x86_64.mk b/modules/video_render_module.target.linux-x86_64.mk
index 23e262da..e91a36f3 100644
--- a/modules/video_render_module.target.linux-x86_64.mk
+++ b/modules/video_render_module.target.linux-x86_64.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -192,11 +195,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -209,6 +214,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_render_module_impl.target.darwin-arm.mk b/modules/video_render_module_impl.target.darwin-arm.mk
index 5bc5ef67..4b35778b 100644
--- a/modules/video_render_module_impl.target.darwin-arm.mk
+++ b/modules/video_render_module_impl.target.darwin-arm.mk
@@ -87,11 +87,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +109,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -203,11 +206,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -223,6 +228,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_render_module_impl.target.darwin-arm64.mk b/modules/video_render_module_impl.target.darwin-arm64.mk
index dfd5ba2c..b4b299ca 100644
--- a/modules/video_render_module_impl.target.darwin-arm64.mk
+++ b/modules/video_render_module_impl.target.darwin-arm64.mk
@@ -76,11 +76,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -89,10 +91,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -177,11 +181,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -190,10 +196,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_render_module_impl.target.darwin-mips.mk b/modules/video_render_module_impl.target.darwin-mips.mk
index 81e7db71..7bf2537e 100644
--- a/modules/video_render_module_impl.target.darwin-mips.mk
+++ b/modules/video_render_module_impl.target.darwin-mips.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -190,11 +193,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -209,6 +214,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_render_module_impl.target.darwin-mips64.mk b/modules/video_render_module_impl.target.darwin-mips64.mk
new file mode 100644
index 00000000..de890a7a
--- /dev/null
+++ b/modules/video_render_module_impl.target.darwin-mips64.mk
@@ -0,0 +1,265 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_render_module_impl_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_render/video_render_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_render_module_impl_gyp
+
+# Alias gyp target name.
+.PHONY: video_render_module_impl
+video_render_module_impl: third_party_webrtc_modules_video_render_module_impl_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_render_module_impl.target.darwin-x86.mk b/modules/video_render_module_impl.target.darwin-x86.mk
index ff6157d5..7b19afe9 100644
--- a/modules/video_render_module_impl.target.darwin-x86.mk
+++ b/modules/video_render_module_impl.target.darwin-x86.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -189,11 +192,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -206,6 +211,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_render_module_impl.target.darwin-x86_64.mk b/modules/video_render_module_impl.target.darwin-x86_64.mk
index 93074eb5..3b8d5fd5 100644
--- a/modules/video_render_module_impl.target.darwin-x86_64.mk
+++ b/modules/video_render_module_impl.target.darwin-x86_64.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,6 +100,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -187,11 +190,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -204,6 +209,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_render_module_impl.target.linux-arm.mk b/modules/video_render_module_impl.target.linux-arm.mk
index 5bc5ef67..4b35778b 100644
--- a/modules/video_render_module_impl.target.linux-arm.mk
+++ b/modules/video_render_module_impl.target.linux-arm.mk
@@ -87,11 +87,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +109,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -203,11 +206,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -223,6 +228,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_render_module_impl.target.linux-arm64.mk b/modules/video_render_module_impl.target.linux-arm64.mk
index dfd5ba2c..b4b299ca 100644
--- a/modules/video_render_module_impl.target.linux-arm64.mk
+++ b/modules/video_render_module_impl.target.linux-arm64.mk
@@ -76,11 +76,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -89,10 +91,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -177,11 +181,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -190,10 +196,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_render_module_impl.target.linux-mips.mk b/modules/video_render_module_impl.target.linux-mips.mk
index 81e7db71..7bf2537e 100644
--- a/modules/video_render_module_impl.target.linux-mips.mk
+++ b/modules/video_render_module_impl.target.linux-mips.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -190,11 +193,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -209,6 +214,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_render_module_impl.target.linux-mips64.mk b/modules/video_render_module_impl.target.linux-mips64.mk
new file mode 100644
index 00000000..de890a7a
--- /dev/null
+++ b/modules/video_render_module_impl.target.linux-mips64.mk
@@ -0,0 +1,265 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_video_render_module_impl_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_render/video_render_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_video_render_module_impl_gyp
+
+# Alias gyp target name.
+.PHONY: video_render_module_impl
+video_render_module_impl: third_party_webrtc_modules_video_render_module_impl_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/video_render_module_impl.target.linux-x86.mk b/modules/video_render_module_impl.target.linux-x86.mk
index ff6157d5..7b19afe9 100644
--- a/modules/video_render_module_impl.target.linux-x86.mk
+++ b/modules/video_render_module_impl.target.linux-x86.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -189,11 +192,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -206,6 +211,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/video_render_module_impl.target.linux-x86_64.mk b/modules/video_render_module_impl.target.linux-x86_64.mk
index 93074eb5..3b8d5fd5 100644
--- a/modules/video_render_module_impl.target.linux-x86_64.mk
+++ b/modules/video_render_module_impl.target.linux-x86_64.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,6 +100,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -187,11 +190,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -204,6 +209,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_i420.target.darwin-arm.mk b/modules/webrtc_i420.target.darwin-arm.mk
index 3ba9f72c..a8903e45 100644
--- a/modules/webrtc_i420.target.darwin-arm.mk
+++ b/modules/webrtc_i420.target.darwin-arm.mk
@@ -87,11 +87,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +109,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -204,11 +207,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -224,6 +229,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_i420.target.darwin-arm64.mk b/modules/webrtc_i420.target.darwin-arm64.mk
index 3719cfd8..a38e7bdb 100644
--- a/modules/webrtc_i420.target.darwin-arm64.mk
+++ b/modules/webrtc_i420.target.darwin-arm64.mk
@@ -76,11 +76,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -89,10 +91,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -178,11 +182,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -191,10 +197,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_i420.target.darwin-mips.mk b/modules/webrtc_i420.target.darwin-mips.mk
index b7a937bf..dba3d278 100644
--- a/modules/webrtc_i420.target.darwin-mips.mk
+++ b/modules/webrtc_i420.target.darwin-mips.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -210,6 +215,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_i420.target.darwin-mips64.mk b/modules/webrtc_i420.target.darwin-mips64.mk
new file mode 100644
index 00000000..29caed72
--- /dev/null
+++ b/modules/webrtc_i420.target.darwin-mips64.mk
@@ -0,0 +1,267 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_webrtc_i420_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_coding/codecs/i420/main/source/i420.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_webrtc_i420_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_i420
+webrtc_i420: third_party_webrtc_modules_webrtc_i420_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/webrtc_i420.target.darwin-x86.mk b/modules/webrtc_i420.target.darwin-x86.mk
index 7ca1aa4e..2792e219 100644
--- a/modules/webrtc_i420.target.darwin-x86.mk
+++ b/modules/webrtc_i420.target.darwin-x86.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -190,11 +193,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -207,6 +212,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_i420.target.darwin-x86_64.mk b/modules/webrtc_i420.target.darwin-x86_64.mk
index 39edf254..4397a0c4 100644
--- a/modules/webrtc_i420.target.darwin-x86_64.mk
+++ b/modules/webrtc_i420.target.darwin-x86_64.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,6 +100,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -188,11 +191,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -205,6 +210,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_i420.target.linux-arm.mk b/modules/webrtc_i420.target.linux-arm.mk
index 3ba9f72c..a8903e45 100644
--- a/modules/webrtc_i420.target.linux-arm.mk
+++ b/modules/webrtc_i420.target.linux-arm.mk
@@ -87,11 +87,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +109,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -204,11 +207,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -224,6 +229,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_i420.target.linux-arm64.mk b/modules/webrtc_i420.target.linux-arm64.mk
index 3719cfd8..a38e7bdb 100644
--- a/modules/webrtc_i420.target.linux-arm64.mk
+++ b/modules/webrtc_i420.target.linux-arm64.mk
@@ -76,11 +76,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -89,10 +91,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -178,11 +182,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -191,10 +197,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_i420.target.linux-mips.mk b/modules/webrtc_i420.target.linux-mips.mk
index b7a937bf..dba3d278 100644
--- a/modules/webrtc_i420.target.linux-mips.mk
+++ b/modules/webrtc_i420.target.linux-mips.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +194,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -210,6 +215,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_i420.target.linux-mips64.mk b/modules/webrtc_i420.target.linux-mips64.mk
new file mode 100644
index 00000000..29caed72
--- /dev/null
+++ b/modules/webrtc_i420.target.linux-mips64.mk
@@ -0,0 +1,267 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_webrtc_i420_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_coding/codecs/i420/main/source/i420.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_webrtc_i420_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_i420
+webrtc_i420: third_party_webrtc_modules_webrtc_i420_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/webrtc_i420.target.linux-x86.mk b/modules/webrtc_i420.target.linux-x86.mk
index 7ca1aa4e..2792e219 100644
--- a/modules/webrtc_i420.target.linux-x86.mk
+++ b/modules/webrtc_i420.target.linux-x86.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -190,11 +193,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -207,6 +212,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_i420.target.linux-x86_64.mk b/modules/webrtc_i420.target.linux-x86_64.mk
index 39edf254..4397a0c4 100644
--- a/modules/webrtc_i420.target.linux-x86_64.mk
+++ b/modules/webrtc_i420.target.linux-x86_64.mk
@@ -81,11 +81,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,6 +100,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -188,11 +191,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -205,6 +210,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_opus.target.darwin-arm.mk b/modules/webrtc_opus.target.darwin-arm.mk
index 035ca971..59323d36 100644
--- a/modules/webrtc_opus.target.darwin-arm.mk
+++ b/modules/webrtc_opus.target.darwin-arm.mk
@@ -18,11 +18,13 @@ GYP_GENERATED_OUTPUTS :=
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+LOCAL_CPP_EXTENSION := .cc
LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc \
third_party/webrtc/modules/audio_coding/codecs/opus/opus_interface.c
@@ -86,11 +88,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -106,6 +110,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -204,11 +209,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -224,6 +231,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_opus.target.darwin-arm64.mk b/modules/webrtc_opus.target.darwin-arm64.mk
index 7282504b..585e781d 100644
--- a/modules/webrtc_opus.target.darwin-arm64.mk
+++ b/modules/webrtc_opus.target.darwin-arm64.mk
@@ -18,11 +18,13 @@ GYP_GENERATED_OUTPUTS :=
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+LOCAL_CPP_EXTENSION := .cc
LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc \
third_party/webrtc/modules/audio_coding/codecs/opus/opus_interface.c
@@ -75,11 +77,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -88,10 +92,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -178,11 +184,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -191,10 +199,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_opus.target.darwin-mips.mk b/modules/webrtc_opus.target.darwin-mips.mk
index 27a6f002..e58c3e83 100644
--- a/modules/webrtc_opus.target.darwin-mips.mk
+++ b/modules/webrtc_opus.target.darwin-mips.mk
@@ -18,11 +18,13 @@ GYP_GENERATED_OUTPUTS :=
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+LOCAL_CPP_EXTENSION := .cc
LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc \
third_party/webrtc/modules/audio_coding/codecs/opus/opus_interface.c
@@ -80,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +196,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -210,6 +217,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_opus.target.darwin-mips64.mk b/modules/webrtc_opus.target.darwin-mips64.mk
new file mode 100644
index 00000000..284ce734
--- /dev/null
+++ b/modules/webrtc_opus.target.darwin-mips64.mk
@@ -0,0 +1,270 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_webrtc_opus_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc \
+ third_party/webrtc/modules/audio_coding/codecs/opus/opus_interface.c
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/opus/src/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/opus/src/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_webrtc_opus_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_opus
+webrtc_opus: third_party_webrtc_modules_webrtc_opus_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/webrtc_opus.target.darwin-x86.mk b/modules/webrtc_opus.target.darwin-x86.mk
index 475a30a7..bc4258ef 100644
--- a/modules/webrtc_opus.target.darwin-x86.mk
+++ b/modules/webrtc_opus.target.darwin-x86.mk
@@ -18,11 +18,13 @@ GYP_GENERATED_OUTPUTS :=
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+LOCAL_CPP_EXTENSION := .cc
LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc \
third_party/webrtc/modules/audio_coding/codecs/opus/opus_interface.c
@@ -81,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -190,11 +195,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -207,6 +214,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_opus.target.darwin-x86_64.mk b/modules/webrtc_opus.target.darwin-x86_64.mk
index 1fa557c3..01f2af32 100644
--- a/modules/webrtc_opus.target.darwin-x86_64.mk
+++ b/modules/webrtc_opus.target.darwin-x86_64.mk
@@ -18,11 +18,13 @@ GYP_GENERATED_OUTPUTS :=
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+LOCAL_CPP_EXTENSION := .cc
LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc \
third_party/webrtc/modules/audio_coding/codecs/opus/opus_interface.c
@@ -80,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -97,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -188,11 +193,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -205,6 +212,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_opus.target.linux-arm.mk b/modules/webrtc_opus.target.linux-arm.mk
index 035ca971..59323d36 100644
--- a/modules/webrtc_opus.target.linux-arm.mk
+++ b/modules/webrtc_opus.target.linux-arm.mk
@@ -18,11 +18,13 @@ GYP_GENERATED_OUTPUTS :=
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+LOCAL_CPP_EXTENSION := .cc
LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc \
third_party/webrtc/modules/audio_coding/codecs/opus/opus_interface.c
@@ -86,11 +88,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -106,6 +110,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -204,11 +209,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -224,6 +231,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_opus.target.linux-arm64.mk b/modules/webrtc_opus.target.linux-arm64.mk
index 7282504b..585e781d 100644
--- a/modules/webrtc_opus.target.linux-arm64.mk
+++ b/modules/webrtc_opus.target.linux-arm64.mk
@@ -18,11 +18,13 @@ GYP_GENERATED_OUTPUTS :=
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+LOCAL_CPP_EXTENSION := .cc
LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc \
third_party/webrtc/modules/audio_coding/codecs/opus/opus_interface.c
@@ -75,11 +77,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -88,10 +92,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -178,11 +184,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -191,10 +199,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_opus.target.linux-mips.mk b/modules/webrtc_opus.target.linux-mips.mk
index 27a6f002..e58c3e83 100644
--- a/modules/webrtc_opus.target.linux-mips.mk
+++ b/modules/webrtc_opus.target.linux-mips.mk
@@ -18,11 +18,13 @@ GYP_GENERATED_OUTPUTS :=
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+LOCAL_CPP_EXTENSION := .cc
LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc \
third_party/webrtc/modules/audio_coding/codecs/opus/opus_interface.c
@@ -80,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -99,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -191,11 +196,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -210,6 +217,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_opus.target.linux-mips64.mk b/modules/webrtc_opus.target.linux-mips64.mk
new file mode 100644
index 00000000..284ce734
--- /dev/null
+++ b/modules/webrtc_opus.target.linux-mips64.mk
@@ -0,0 +1,270 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_webrtc_opus_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc \
+ third_party/webrtc/modules/audio_coding/codecs/opus/opus_interface.c
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/opus/src/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/opus/src/include
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_webrtc_opus_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_opus
+webrtc_opus: third_party_webrtc_modules_webrtc_opus_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/webrtc_opus.target.linux-x86.mk b/modules/webrtc_opus.target.linux-x86.mk
index 475a30a7..bc4258ef 100644
--- a/modules/webrtc_opus.target.linux-x86.mk
+++ b/modules/webrtc_opus.target.linux-x86.mk
@@ -18,11 +18,13 @@ GYP_GENERATED_OUTPUTS :=
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+LOCAL_CPP_EXTENSION := .cc
LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc \
third_party/webrtc/modules/audio_coding/codecs/opus/opus_interface.c
@@ -81,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -190,11 +195,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -207,6 +214,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_opus.target.linux-x86_64.mk b/modules/webrtc_opus.target.linux-x86_64.mk
index 1fa557c3..01f2af32 100644
--- a/modules/webrtc_opus.target.linux-x86_64.mk
+++ b/modules/webrtc_opus.target.linux-x86_64.mk
@@ -18,11 +18,13 @@ GYP_GENERATED_OUTPUTS :=
# Make sure our deps and generated files are built first.
LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+LOCAL_CPP_EXTENSION := .cc
LOCAL_GENERATED_SOURCES :=
GYP_COPIED_SOURCE_ORIGIN_DIRS :=
LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc \
third_party/webrtc/modules/audio_coding/codecs/opus/opus_interface.c
@@ -80,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -97,6 +101,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -188,11 +193,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -205,6 +212,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_utility.target.darwin-arm.mk b/modules/webrtc_utility.target.darwin-arm.mk
index db720034..44fd9c87 100644
--- a/modules/webrtc_utility.target.darwin-arm.mk
+++ b/modules/webrtc_utility.target.darwin-arm.mk
@@ -96,11 +96,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -116,6 +118,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -220,11 +223,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -240,6 +245,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_utility.target.darwin-arm64.mk b/modules/webrtc_utility.target.darwin-arm64.mk
index 1613ed90..d4c70e73 100644
--- a/modules/webrtc_utility.target.darwin-arm64.mk
+++ b/modules/webrtc_utility.target.darwin-arm64.mk
@@ -85,11 +85,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,10 +100,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -194,11 +198,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -207,10 +213,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_utility.target.darwin-mips.mk b/modules/webrtc_utility.target.darwin-mips.mk
index 6a674908..261b9e24 100644
--- a/modules/webrtc_utility.target.darwin-mips.mk
+++ b/modules/webrtc_utility.target.darwin-mips.mk
@@ -90,11 +90,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -109,6 +111,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -207,11 +210,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -226,6 +231,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_utility.target.darwin-mips64.mk b/modules/webrtc_utility.target.darwin-mips64.mk
new file mode 100644
index 00000000..b318dd83
--- /dev/null
+++ b/modules/webrtc_utility.target.darwin-mips64.mk
@@ -0,0 +1,290 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_webrtc_utility_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/utility/source/audio_frame_operations.cc \
+ third_party/webrtc/modules/utility/source/coder.cc \
+ third_party/webrtc/modules/utility/source/file_player_impl.cc \
+ third_party/webrtc/modules/utility/source/file_recorder_impl.cc \
+ third_party/webrtc/modules/utility/source/helpers_android.cc \
+ third_party/webrtc/modules/utility/source/process_thread_impl.cc \
+ third_party/webrtc/modules/utility/source/rtp_dump_impl.cc \
+ third_party/webrtc/modules/utility/source/frame_scaler.cc \
+ third_party/webrtc/modules/utility/source/video_coder.cc \
+ third_party/webrtc/modules/utility/source/video_frames_queue.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/modules/media_file/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/modules/media_file/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_webrtc_utility_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_utility
+webrtc_utility: third_party_webrtc_modules_webrtc_utility_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/webrtc_utility.target.darwin-x86.mk b/modules/webrtc_utility.target.darwin-x86.mk
index f7c7ebc7..dda42910 100644
--- a/modules/webrtc_utility.target.darwin-x86.mk
+++ b/modules/webrtc_utility.target.darwin-x86.mk
@@ -91,11 +91,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -108,6 +110,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -206,11 +209,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -223,6 +228,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_utility.target.darwin-x86_64.mk b/modules/webrtc_utility.target.darwin-x86_64.mk
index c679d4c8..8934fe83 100644
--- a/modules/webrtc_utility.target.darwin-x86_64.mk
+++ b/modules/webrtc_utility.target.darwin-x86_64.mk
@@ -90,11 +90,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +109,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -204,11 +207,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -221,6 +226,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_utility.target.linux-arm.mk b/modules/webrtc_utility.target.linux-arm.mk
index db720034..44fd9c87 100644
--- a/modules/webrtc_utility.target.linux-arm.mk
+++ b/modules/webrtc_utility.target.linux-arm.mk
@@ -96,11 +96,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -116,6 +118,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -220,11 +223,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -240,6 +245,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_utility.target.linux-arm64.mk b/modules/webrtc_utility.target.linux-arm64.mk
index 1613ed90..d4c70e73 100644
--- a/modules/webrtc_utility.target.linux-arm64.mk
+++ b/modules/webrtc_utility.target.linux-arm64.mk
@@ -85,11 +85,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -98,10 +100,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -194,11 +198,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -207,10 +213,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_utility.target.linux-mips.mk b/modules/webrtc_utility.target.linux-mips.mk
index 6a674908..261b9e24 100644
--- a/modules/webrtc_utility.target.linux-mips.mk
+++ b/modules/webrtc_utility.target.linux-mips.mk
@@ -90,11 +90,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -109,6 +111,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -207,11 +210,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -226,6 +231,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_utility.target.linux-mips64.mk b/modules/webrtc_utility.target.linux-mips64.mk
new file mode 100644
index 00000000..b318dd83
--- /dev/null
+++ b/modules/webrtc_utility.target.linux-mips64.mk
@@ -0,0 +1,290 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_webrtc_utility_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/utility/source/audio_frame_operations.cc \
+ third_party/webrtc/modules/utility/source/coder.cc \
+ third_party/webrtc/modules/utility/source/file_player_impl.cc \
+ third_party/webrtc/modules/utility/source/file_recorder_impl.cc \
+ third_party/webrtc/modules/utility/source/helpers_android.cc \
+ third_party/webrtc/modules/utility/source/process_thread_impl.cc \
+ third_party/webrtc/modules/utility/source/rtp_dump_impl.cc \
+ third_party/webrtc/modules/utility/source/frame_scaler.cc \
+ third_party/webrtc/modules/utility/source/video_coder.cc \
+ third_party/webrtc/modules/utility/source/video_frames_queue.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/modules/media_file/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/modules/media_file/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_webrtc_utility_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_utility
+webrtc_utility: third_party_webrtc_modules_webrtc_utility_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/webrtc_utility.target.linux-x86.mk b/modules/webrtc_utility.target.linux-x86.mk
index f7c7ebc7..dda42910 100644
--- a/modules/webrtc_utility.target.linux-x86.mk
+++ b/modules/webrtc_utility.target.linux-x86.mk
@@ -91,11 +91,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -108,6 +110,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -206,11 +209,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -223,6 +228,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_utility.target.linux-x86_64.mk b/modules/webrtc_utility.target.linux-x86_64.mk
index c679d4c8..8934fe83 100644
--- a/modules/webrtc_utility.target.linux-x86_64.mk
+++ b/modules/webrtc_utility.target.linux-x86_64.mk
@@ -90,11 +90,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -107,6 +109,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -204,11 +207,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -221,6 +226,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_video_coding.target.darwin-arm.mk b/modules/webrtc_video_coding.target.darwin-arm.mk
index 9beb0566..357b2fa5 100644
--- a/modules/webrtc_video_coding.target.darwin-arm.mk
+++ b/modules/webrtc_video_coding.target.darwin-arm.mk
@@ -109,11 +109,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -129,6 +131,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -228,11 +231,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -248,6 +253,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_video_coding.target.darwin-arm64.mk b/modules/webrtc_video_coding.target.darwin-arm64.mk
index 6cc9aece..e686d78c 100644
--- a/modules/webrtc_video_coding.target.darwin-arm64.mk
+++ b/modules/webrtc_video_coding.target.darwin-arm64.mk
@@ -98,11 +98,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -111,10 +113,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -202,11 +206,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -215,10 +221,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_video_coding.target.darwin-mips.mk b/modules/webrtc_video_coding.target.darwin-mips.mk
index f121d0be..11689c17 100644
--- a/modules/webrtc_video_coding.target.darwin-mips.mk
+++ b/modules/webrtc_video_coding.target.darwin-mips.mk
@@ -103,11 +103,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -122,6 +124,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -215,11 +218,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -234,6 +239,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_video_coding.target.darwin-mips64.mk b/modules/webrtc_video_coding.target.darwin-mips64.mk
new file mode 100644
index 00000000..837f9131
--- /dev/null
+++ b/modules/webrtc_video_coding.target.darwin-mips64.mk
@@ -0,0 +1,293 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_webrtc_video_coding_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_coding/main/source/codec_database.cc \
+ third_party/webrtc/modules/video_coding/main/source/codec_timer.cc \
+ third_party/webrtc/modules/video_coding/main/source/content_metrics_processing.cc \
+ third_party/webrtc/modules/video_coding/main/source/decoding_state.cc \
+ third_party/webrtc/modules/video_coding/main/source/encoded_frame.cc \
+ third_party/webrtc/modules/video_coding/main/source/frame_buffer.cc \
+ third_party/webrtc/modules/video_coding/main/source/generic_decoder.cc \
+ third_party/webrtc/modules/video_coding/main/source/generic_encoder.cc \
+ third_party/webrtc/modules/video_coding/main/source/inter_frame_delay.cc \
+ third_party/webrtc/modules/video_coding/main/source/jitter_buffer.cc \
+ third_party/webrtc/modules/video_coding/main/source/jitter_estimator.cc \
+ third_party/webrtc/modules/video_coding/main/source/media_opt_util.cc \
+ third_party/webrtc/modules/video_coding/main/source/media_optimization.cc \
+ third_party/webrtc/modules/video_coding/main/source/packet.cc \
+ third_party/webrtc/modules/video_coding/main/source/qm_select.cc \
+ third_party/webrtc/modules/video_coding/main/source/receiver.cc \
+ third_party/webrtc/modules/video_coding/main/source/rtt_filter.cc \
+ third_party/webrtc/modules/video_coding/main/source/session_info.cc \
+ third_party/webrtc/modules/video_coding/main/source/timestamp_map.cc \
+ third_party/webrtc/modules/video_coding/main/source/timing.cc \
+ third_party/webrtc/modules/video_coding/main/source/video_coding_impl.cc \
+ third_party/webrtc/modules/video_coding/main/source/video_sender.cc \
+ third_party/webrtc/modules/video_coding/main/source/video_receiver.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_webrtc_video_coding_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_video_coding
+webrtc_video_coding: third_party_webrtc_modules_webrtc_video_coding_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/webrtc_video_coding.target.darwin-x86.mk b/modules/webrtc_video_coding.target.darwin-x86.mk
index 272271da..8f08b512 100644
--- a/modules/webrtc_video_coding.target.darwin-x86.mk
+++ b/modules/webrtc_video_coding.target.darwin-x86.mk
@@ -104,11 +104,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -121,6 +123,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -214,11 +217,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -231,6 +236,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_video_coding.target.darwin-x86_64.mk b/modules/webrtc_video_coding.target.darwin-x86_64.mk
index b6dea834..b4732d85 100644
--- a/modules/webrtc_video_coding.target.darwin-x86_64.mk
+++ b/modules/webrtc_video_coding.target.darwin-x86_64.mk
@@ -103,11 +103,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -120,6 +122,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -212,11 +215,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -229,6 +234,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_video_coding.target.linux-arm.mk b/modules/webrtc_video_coding.target.linux-arm.mk
index 9beb0566..357b2fa5 100644
--- a/modules/webrtc_video_coding.target.linux-arm.mk
+++ b/modules/webrtc_video_coding.target.linux-arm.mk
@@ -109,11 +109,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -129,6 +131,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -228,11 +231,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -248,6 +253,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_video_coding.target.linux-arm64.mk b/modules/webrtc_video_coding.target.linux-arm64.mk
index 6cc9aece..e686d78c 100644
--- a/modules/webrtc_video_coding.target.linux-arm64.mk
+++ b/modules/webrtc_video_coding.target.linux-arm64.mk
@@ -98,11 +98,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -111,10 +113,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -202,11 +206,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -215,10 +221,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_video_coding.target.linux-mips.mk b/modules/webrtc_video_coding.target.linux-mips.mk
index f121d0be..11689c17 100644
--- a/modules/webrtc_video_coding.target.linux-mips.mk
+++ b/modules/webrtc_video_coding.target.linux-mips.mk
@@ -103,11 +103,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -122,6 +124,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -215,11 +218,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -234,6 +239,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_video_coding.target.linux-mips64.mk b/modules/webrtc_video_coding.target.linux-mips64.mk
new file mode 100644
index 00000000..837f9131
--- /dev/null
+++ b/modules/webrtc_video_coding.target.linux-mips64.mk
@@ -0,0 +1,293 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_modules_webrtc_video_coding_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/modules/video_coding/main/source/codec_database.cc \
+ third_party/webrtc/modules/video_coding/main/source/codec_timer.cc \
+ third_party/webrtc/modules/video_coding/main/source/content_metrics_processing.cc \
+ third_party/webrtc/modules/video_coding/main/source/decoding_state.cc \
+ third_party/webrtc/modules/video_coding/main/source/encoded_frame.cc \
+ third_party/webrtc/modules/video_coding/main/source/frame_buffer.cc \
+ third_party/webrtc/modules/video_coding/main/source/generic_decoder.cc \
+ third_party/webrtc/modules/video_coding/main/source/generic_encoder.cc \
+ third_party/webrtc/modules/video_coding/main/source/inter_frame_delay.cc \
+ third_party/webrtc/modules/video_coding/main/source/jitter_buffer.cc \
+ third_party/webrtc/modules/video_coding/main/source/jitter_estimator.cc \
+ third_party/webrtc/modules/video_coding/main/source/media_opt_util.cc \
+ third_party/webrtc/modules/video_coding/main/source/media_optimization.cc \
+ third_party/webrtc/modules/video_coding/main/source/packet.cc \
+ third_party/webrtc/modules/video_coding/main/source/qm_select.cc \
+ third_party/webrtc/modules/video_coding/main/source/receiver.cc \
+ third_party/webrtc/modules/video_coding/main/source/rtt_filter.cc \
+ third_party/webrtc/modules/video_coding/main/source/session_info.cc \
+ third_party/webrtc/modules/video_coding/main/source/timestamp_map.cc \
+ third_party/webrtc/modules/video_coding/main/source/timing.cc \
+ third_party/webrtc/modules/video_coding/main/source/video_coding_impl.cc \
+ third_party/webrtc/modules/video_coding/main/source/video_sender.cc \
+ third_party/webrtc/modules/video_coding/main/source/video_receiver.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_modules_webrtc_video_coding_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_video_coding
+webrtc_video_coding: third_party_webrtc_modules_webrtc_video_coding_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/modules/webrtc_video_coding.target.linux-x86.mk b/modules/webrtc_video_coding.target.linux-x86.mk
index 272271da..8f08b512 100644
--- a/modules/webrtc_video_coding.target.linux-x86.mk
+++ b/modules/webrtc_video_coding.target.linux-x86.mk
@@ -104,11 +104,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -121,6 +123,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -214,11 +217,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -231,6 +236,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/modules/webrtc_video_coding.target.linux-x86_64.mk b/modules/webrtc_video_coding.target.linux-x86_64.mk
index b6dea834..b4732d85 100644
--- a/modules/webrtc_video_coding.target.linux-x86_64.mk
+++ b/modules/webrtc_video_coding.target.linux-x86_64.mk
@@ -103,11 +103,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -120,6 +122,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -212,11 +215,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -229,6 +234,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/p2p/OWNERS b/p2p/OWNERS
new file mode 100644
index 00000000..1a24a6a8
--- /dev/null
+++ b/p2p/OWNERS
@@ -0,0 +1,13 @@
+henrika@webrtc.org
+henrike@webrtc.org
+henrikg@webrtc.org
+hta@webrtc.org
+jiayl@webrtc.org
+juberti@webrtc.org
+mflodman@webrtc.org
+perkj@webrtc.org
+pthatcher@webrtc.org
+sergeyu@chromium.org
+tommi@webrtc.org
+
+per-file BUILD.gn=kjellander@webrtc.org
diff --git a/p2p/base/asyncstuntcpsocket.cc b/p2p/base/asyncstuntcpsocket.cc
new file mode 100644
index 00000000..2b1b6935
--- /dev/null
+++ b/p2p/base/asyncstuntcpsocket.cc
@@ -0,0 +1,153 @@
+/*
+ * Copyright 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.
+ */
+
+#include "webrtc/p2p/base/asyncstuntcpsocket.h"
+
+#include <string.h>
+
+#include "webrtc/p2p/base/stun.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/logging.h"
+
+namespace cricket {
+
+static const size_t kMaxPacketSize = 64 * 1024;
+
+typedef uint16 PacketLength;
+static const size_t kPacketLenSize = sizeof(PacketLength);
+static const size_t kPacketLenOffset = 2;
+static const size_t kBufSize = kMaxPacketSize + kStunHeaderSize;
+static const size_t kTurnChannelDataHdrSize = 4;
+
+inline bool IsStunMessage(uint16 msg_type) {
+ // The first two bits of a channel data message are 0b01.
+ return (msg_type & 0xC000) ? false : true;
+}
+
+// AsyncStunTCPSocket
+// Binds and connects |socket| and creates AsyncTCPSocket for
+// it. Takes ownership of |socket|. Returns NULL if bind() or
+// connect() fail (|socket| is destroyed in that case).
+AsyncStunTCPSocket* AsyncStunTCPSocket::Create(
+ rtc::AsyncSocket* socket,
+ const rtc::SocketAddress& bind_address,
+ const rtc::SocketAddress& remote_address) {
+ return new AsyncStunTCPSocket(AsyncTCPSocketBase::ConnectSocket(
+ socket, bind_address, remote_address), false);
+}
+
+AsyncStunTCPSocket::AsyncStunTCPSocket(
+ rtc::AsyncSocket* socket, bool listen)
+ : rtc::AsyncTCPSocketBase(socket, listen, kBufSize) {
+}
+
+int AsyncStunTCPSocket::Send(const void *pv, size_t cb,
+ const rtc::PacketOptions& options) {
+ if (cb > kBufSize || cb < kPacketLenSize + kPacketLenOffset) {
+ SetError(EMSGSIZE);
+ return -1;
+ }
+
+ // If we are blocking on send, then silently drop this packet
+ if (!IsOutBufferEmpty())
+ return static_cast<int>(cb);
+
+ int pad_bytes;
+ size_t expected_pkt_len = GetExpectedLength(pv, cb, &pad_bytes);
+
+ // Accepts only complete STUN/ChannelData packets.
+ if (cb != expected_pkt_len)
+ return -1;
+
+ AppendToOutBuffer(pv, cb);
+
+ ASSERT(pad_bytes < 4);
+ char padding[4] = {0};
+ AppendToOutBuffer(padding, pad_bytes);
+
+ int res = FlushOutBuffer();
+ if (res <= 0) {
+ // drop packet if we made no progress
+ ClearOutBuffer();
+ return res;
+ }
+
+ // We claim to have sent the whole thing, even if we only sent partial
+ return static_cast<int>(cb);
+}
+
+void AsyncStunTCPSocket::ProcessInput(char* data, size_t* len) {
+ rtc::SocketAddress remote_addr(GetRemoteAddress());
+ // STUN packet - First 4 bytes. Total header size is 20 bytes.
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // |0 0| STUN Message Type | Message Length |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ // TURN ChannelData
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | Channel Number | Length |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ while (true) {
+ // We need at least 4 bytes to read the STUN or ChannelData packet length.
+ if (*len < kPacketLenOffset + kPacketLenSize)
+ return;
+
+ int pad_bytes;
+ size_t expected_pkt_len = GetExpectedLength(data, *len, &pad_bytes);
+ size_t actual_length = expected_pkt_len + pad_bytes;
+
+ if (*len < actual_length) {
+ return;
+ }
+
+ SignalReadPacket(this, data, expected_pkt_len, remote_addr,
+ rtc::CreatePacketTime(0));
+
+ *len -= actual_length;
+ if (*len > 0) {
+ memmove(data, data + actual_length, *len);
+ }
+ }
+}
+
+void AsyncStunTCPSocket::HandleIncomingConnection(
+ rtc::AsyncSocket* socket) {
+ SignalNewConnection(this, new AsyncStunTCPSocket(socket, false));
+}
+
+size_t AsyncStunTCPSocket::GetExpectedLength(const void* data, size_t len,
+ int* pad_bytes) {
+ *pad_bytes = 0;
+ PacketLength pkt_len =
+ rtc::GetBE16(static_cast<const char*>(data) + kPacketLenOffset);
+ size_t expected_pkt_len;
+ uint16 msg_type = rtc::GetBE16(data);
+ if (IsStunMessage(msg_type)) {
+ // STUN message.
+ expected_pkt_len = kStunHeaderSize + pkt_len;
+ } else {
+ // TURN ChannelData message.
+ expected_pkt_len = kTurnChannelDataHdrSize + pkt_len;
+ // From RFC 5766 section 11.5
+ // Over TCP and TLS-over-TCP, the ChannelData message MUST be padded to
+ // a multiple of four bytes in order to ensure the alignment of
+ // subsequent messages. The padding is not reflected in the length
+ // field of the ChannelData message, so the actual size of a ChannelData
+ // message (including padding) is (4 + Length) rounded up to the nearest
+ // multiple of 4. Over UDP, the padding is not required but MAY be
+ // included.
+ if (expected_pkt_len % 4)
+ *pad_bytes = 4 - (expected_pkt_len % 4);
+ }
+ return expected_pkt_len;
+}
+
+} // namespace cricket
diff --git a/p2p/base/asyncstuntcpsocket.h b/p2p/base/asyncstuntcpsocket.h
new file mode 100644
index 00000000..4f53b031
--- /dev/null
+++ b/p2p/base/asyncstuntcpsocket.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 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 WEBRTC_P2P_BASE_ASYNCSTUNTCPSOCKET_H_
+#define WEBRTC_P2P_BASE_ASYNCSTUNTCPSOCKET_H_
+
+#include "webrtc/base/asynctcpsocket.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/socketfactory.h"
+
+namespace cricket {
+
+class AsyncStunTCPSocket : public rtc::AsyncTCPSocketBase {
+ public:
+ // Binds and connects |socket| and creates AsyncTCPSocket for
+ // it. Takes ownership of |socket|. Returns NULL if bind() or
+ // connect() fail (|socket| is destroyed in that case).
+ static AsyncStunTCPSocket* Create(
+ rtc::AsyncSocket* socket,
+ const rtc::SocketAddress& bind_address,
+ const rtc::SocketAddress& remote_address);
+
+ AsyncStunTCPSocket(rtc::AsyncSocket* socket, bool listen);
+ virtual ~AsyncStunTCPSocket() {}
+
+ virtual int Send(const void* pv, size_t cb,
+ const rtc::PacketOptions& options);
+ virtual void ProcessInput(char* data, size_t* len);
+ virtual void HandleIncomingConnection(rtc::AsyncSocket* socket);
+
+ private:
+ // This method returns the message hdr + length written in the header.
+ // This method also returns the number of padding bytes needed/added to the
+ // turn message. |pad_bytes| should be used only when |is_turn| is true.
+ size_t GetExpectedLength(const void* data, size_t len,
+ int* pad_bytes);
+
+ DISALLOW_EVIL_CONSTRUCTORS(AsyncStunTCPSocket);
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_ASYNCSTUNTCPSOCKET_H_
diff --git a/p2p/base/asyncstuntcpsocket_unittest.cc b/p2p/base/asyncstuntcpsocket_unittest.cc
new file mode 100644
index 00000000..22c1b269
--- /dev/null
+++ b/p2p/base/asyncstuntcpsocket_unittest.cc
@@ -0,0 +1,263 @@
+/*
+ * Copyright 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.
+ */
+
+#include "webrtc/p2p/base/asyncstuntcpsocket.h"
+#include "webrtc/base/asyncsocket.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/physicalsocketserver.h"
+#include "webrtc/base/virtualsocketserver.h"
+
+namespace cricket {
+
+static unsigned char kStunMessageWithZeroLength[] = {
+ 0x00, 0x01, 0x00, 0x00, // length of 0 (last 2 bytes)
+ 0x21, 0x12, 0xA4, 0x42,
+ '0', '1', '2', '3',
+ '4', '5', '6', '7',
+ '8', '9', 'a', 'b',
+};
+
+
+static unsigned char kTurnChannelDataMessageWithZeroLength[] = {
+ 0x40, 0x00, 0x00, 0x00, // length of 0 (last 2 bytes)
+};
+
+static unsigned char kTurnChannelDataMessage[] = {
+ 0x40, 0x00, 0x00, 0x10,
+ 0x21, 0x12, 0xA4, 0x42,
+ '0', '1', '2', '3',
+ '4', '5', '6', '7',
+ '8', '9', 'a', 'b',
+};
+
+static unsigned char kStunMessageWithInvalidLength[] = {
+ 0x00, 0x01, 0x00, 0x10,
+ 0x21, 0x12, 0xA4, 0x42,
+ '0', '1', '2', '3',
+ '4', '5', '6', '7',
+ '8', '9', 'a', 'b',
+};
+
+static unsigned char kTurnChannelDataMessageWithInvalidLength[] = {
+ 0x80, 0x00, 0x00, 0x20,
+ 0x21, 0x12, 0xA4, 0x42,
+ '0', '1', '2', '3',
+ '4', '5', '6', '7',
+ '8', '9', 'a', 'b',
+};
+
+static unsigned char kTurnChannelDataMessageWithOddLength[] = {
+ 0x40, 0x00, 0x00, 0x05,
+ 0x21, 0x12, 0xA4, 0x42,
+ '0',
+};
+
+
+static const rtc::SocketAddress kClientAddr("11.11.11.11", 0);
+static const rtc::SocketAddress kServerAddr("22.22.22.22", 0);
+
+class AsyncStunTCPSocketTest : public testing::Test,
+ public sigslot::has_slots<> {
+ protected:
+ AsyncStunTCPSocketTest()
+ : vss_(new rtc::VirtualSocketServer(NULL)),
+ ss_scope_(vss_.get()) {
+ }
+
+ virtual void SetUp() {
+ CreateSockets();
+ }
+
+ void CreateSockets() {
+ rtc::AsyncSocket* server = vss_->CreateAsyncSocket(
+ kServerAddr.family(), SOCK_STREAM);
+ server->Bind(kServerAddr);
+ recv_socket_.reset(new AsyncStunTCPSocket(server, true));
+ recv_socket_->SignalNewConnection.connect(
+ this, &AsyncStunTCPSocketTest::OnNewConnection);
+
+ rtc::AsyncSocket* client = vss_->CreateAsyncSocket(
+ kClientAddr.family(), SOCK_STREAM);
+ send_socket_.reset(AsyncStunTCPSocket::Create(
+ client, kClientAddr, recv_socket_->GetLocalAddress()));
+ ASSERT_TRUE(send_socket_.get() != NULL);
+ vss_->ProcessMessagesUntilIdle();
+ }
+
+ void OnReadPacket(rtc::AsyncPacketSocket* socket, const char* data,
+ size_t len, const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time) {
+ recv_packets_.push_back(std::string(data, len));
+ }
+
+ void OnNewConnection(rtc::AsyncPacketSocket* server,
+ rtc::AsyncPacketSocket* new_socket) {
+ listen_socket_.reset(new_socket);
+ new_socket->SignalReadPacket.connect(
+ this, &AsyncStunTCPSocketTest::OnReadPacket);
+ }
+
+ bool Send(const void* data, size_t len) {
+ rtc::PacketOptions options;
+ size_t ret = send_socket_->Send(
+ reinterpret_cast<const char*>(data), len, options);
+ vss_->ProcessMessagesUntilIdle();
+ return (ret == len);
+ }
+
+ bool CheckData(const void* data, int len) {
+ bool ret = false;
+ if (recv_packets_.size()) {
+ std::string packet = recv_packets_.front();
+ recv_packets_.pop_front();
+ ret = (memcmp(data, packet.c_str(), len) == 0);
+ }
+ return ret;
+ }
+
+ rtc::scoped_ptr<rtc::VirtualSocketServer> vss_;
+ rtc::SocketServerScope ss_scope_;
+ rtc::scoped_ptr<AsyncStunTCPSocket> send_socket_;
+ rtc::scoped_ptr<AsyncStunTCPSocket> recv_socket_;
+ rtc::scoped_ptr<rtc::AsyncPacketSocket> listen_socket_;
+ std::list<std::string> recv_packets_;
+};
+
+// Testing a stun packet sent/recv properly.
+TEST_F(AsyncStunTCPSocketTest, TestSingleStunPacket) {
+ EXPECT_TRUE(Send(kStunMessageWithZeroLength,
+ sizeof(kStunMessageWithZeroLength)));
+ EXPECT_EQ(1u, recv_packets_.size());
+ EXPECT_TRUE(CheckData(kStunMessageWithZeroLength,
+ sizeof(kStunMessageWithZeroLength)));
+}
+
+// Verify sending multiple packets.
+TEST_F(AsyncStunTCPSocketTest, TestMultipleStunPackets) {
+ EXPECT_TRUE(Send(kStunMessageWithZeroLength,
+ sizeof(kStunMessageWithZeroLength)));
+ EXPECT_TRUE(Send(kStunMessageWithZeroLength,
+ sizeof(kStunMessageWithZeroLength)));
+ EXPECT_TRUE(Send(kStunMessageWithZeroLength,
+ sizeof(kStunMessageWithZeroLength)));
+ EXPECT_TRUE(Send(kStunMessageWithZeroLength,
+ sizeof(kStunMessageWithZeroLength)));
+ EXPECT_EQ(4u, recv_packets_.size());
+}
+
+// Verifying TURN channel data message with zero length.
+TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithZeroLength) {
+ EXPECT_TRUE(Send(kTurnChannelDataMessageWithZeroLength,
+ sizeof(kTurnChannelDataMessageWithZeroLength)));
+ EXPECT_EQ(1u, recv_packets_.size());
+ EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithZeroLength,
+ sizeof(kTurnChannelDataMessageWithZeroLength)));
+}
+
+// Verifying TURN channel data message.
+TEST_F(AsyncStunTCPSocketTest, TestTurnChannelData) {
+ EXPECT_TRUE(Send(kTurnChannelDataMessage,
+ sizeof(kTurnChannelDataMessage)));
+ EXPECT_EQ(1u, recv_packets_.size());
+ EXPECT_TRUE(CheckData(kTurnChannelDataMessage,
+ sizeof(kTurnChannelDataMessage)));
+}
+
+// Verifying TURN channel messages which needs padding handled properly.
+TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataPadding) {
+ EXPECT_TRUE(Send(kTurnChannelDataMessageWithOddLength,
+ sizeof(kTurnChannelDataMessageWithOddLength)));
+ EXPECT_EQ(1u, recv_packets_.size());
+ EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
+ sizeof(kTurnChannelDataMessageWithOddLength)));
+}
+
+// Verifying stun message with invalid length.
+TEST_F(AsyncStunTCPSocketTest, TestStunInvalidLength) {
+ EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
+ sizeof(kStunMessageWithInvalidLength)));
+ EXPECT_EQ(0u, recv_packets_.size());
+
+ // Modify the message length to larger value.
+ kStunMessageWithInvalidLength[2] = 0xFF;
+ kStunMessageWithInvalidLength[3] = 0xFF;
+ EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
+ sizeof(kStunMessageWithInvalidLength)));
+
+ // Modify the message length to smaller value.
+ kStunMessageWithInvalidLength[2] = 0x00;
+ kStunMessageWithInvalidLength[3] = 0x01;
+ EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
+ sizeof(kStunMessageWithInvalidLength)));
+}
+
+// Verifying TURN channel data message with invalid length.
+TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithInvalidLength) {
+ EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
+ sizeof(kTurnChannelDataMessageWithInvalidLength)));
+ // Modify the length to larger value.
+ kTurnChannelDataMessageWithInvalidLength[2] = 0xFF;
+ kTurnChannelDataMessageWithInvalidLength[3] = 0xF0;
+ EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
+ sizeof(kTurnChannelDataMessageWithInvalidLength)));
+
+ // Modify the length to smaller value.
+ kTurnChannelDataMessageWithInvalidLength[2] = 0x00;
+ kTurnChannelDataMessageWithInvalidLength[3] = 0x00;
+ EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
+ sizeof(kTurnChannelDataMessageWithInvalidLength)));
+}
+
+// Verifying a small buffer handled (dropped) properly. This will be
+// a common one for both stun and turn.
+TEST_F(AsyncStunTCPSocketTest, TestTooSmallMessageBuffer) {
+ char data[1];
+ EXPECT_FALSE(Send(data, sizeof(data)));
+}
+
+// Verifying a legal large turn message.
+TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeTurnPacket) {
+ // We have problem in getting the SignalWriteEvent from the virtual socket
+ // server. So increasing the send buffer to 64k.
+ // TODO(mallinath) - Remove this setting after we fix vss issue.
+ vss_->set_send_buffer_capacity(64 * 1024);
+ unsigned char packet[65539];
+ packet[0] = 0x40;
+ packet[1] = 0x00;
+ packet[2] = 0xFF;
+ packet[3] = 0xFF;
+ EXPECT_TRUE(Send(packet, sizeof(packet)));
+}
+
+// Verifying a legal large stun message.
+TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeStunPacket) {
+ // We have problem in getting the SignalWriteEvent from the virtual socket
+ // server. So increasing the send buffer to 64k.
+ // TODO(mallinath) - Remove this setting after we fix vss issue.
+ vss_->set_send_buffer_capacity(64 * 1024);
+ unsigned char packet[65552];
+ packet[0] = 0x00;
+ packet[1] = 0x01;
+ packet[2] = 0xFF;
+ packet[3] = 0xFC;
+ EXPECT_TRUE(Send(packet, sizeof(packet)));
+}
+
+// Investigate why WriteEvent is not signaled from VSS.
+TEST_F(AsyncStunTCPSocketTest, DISABLED_TestWithSmallSendBuffer) {
+ vss_->set_send_buffer_capacity(1);
+ Send(kTurnChannelDataMessageWithOddLength,
+ sizeof(kTurnChannelDataMessageWithOddLength));
+ EXPECT_EQ(1u, recv_packets_.size());
+ EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
+ sizeof(kTurnChannelDataMessageWithOddLength)));
+}
+
+} // namespace cricket
diff --git a/p2p/base/basicpacketsocketfactory.cc b/p2p/base/basicpacketsocketfactory.cc
new file mode 100644
index 00000000..06dfe76e
--- /dev/null
+++ b/p2p/base/basicpacketsocketfactory.cc
@@ -0,0 +1,204 @@
+/*
+ * 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.
+ */
+
+#include "webrtc/p2p/base/basicpacketsocketfactory.h"
+
+#include "webrtc/p2p/base/asyncstuntcpsocket.h"
+#include "webrtc/p2p/base/stun.h"
+#include "webrtc/base/asynctcpsocket.h"
+#include "webrtc/base/asyncudpsocket.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/nethelpers.h"
+#include "webrtc/base/physicalsocketserver.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/socketadapters.h"
+#include "webrtc/base/ssladapter.h"
+#include "webrtc/base/thread.h"
+
+namespace rtc {
+
+BasicPacketSocketFactory::BasicPacketSocketFactory()
+ : thread_(Thread::Current()),
+ socket_factory_(NULL) {
+}
+
+BasicPacketSocketFactory::BasicPacketSocketFactory(Thread* thread)
+ : thread_(thread),
+ socket_factory_(NULL) {
+}
+
+BasicPacketSocketFactory::BasicPacketSocketFactory(
+ SocketFactory* socket_factory)
+ : thread_(NULL),
+ socket_factory_(socket_factory) {
+}
+
+BasicPacketSocketFactory::~BasicPacketSocketFactory() {
+}
+
+AsyncPacketSocket* BasicPacketSocketFactory::CreateUdpSocket(
+ const SocketAddress& address, int min_port, int max_port) {
+ // UDP sockets are simple.
+ rtc::AsyncSocket* socket =
+ socket_factory()->CreateAsyncSocket(
+ address.family(), SOCK_DGRAM);
+ if (!socket) {
+ return NULL;
+ }
+ if (BindSocket(socket, address, min_port, max_port) < 0) {
+ LOG(LS_ERROR) << "UDP bind failed with error "
+ << socket->GetError();
+ delete socket;
+ return NULL;
+ }
+ return new rtc::AsyncUDPSocket(socket);
+}
+
+AsyncPacketSocket* BasicPacketSocketFactory::CreateServerTcpSocket(
+ const SocketAddress& local_address, int min_port, int max_port, int opts) {
+
+ // Fail if TLS is required.
+ if (opts & PacketSocketFactory::OPT_TLS) {
+ LOG(LS_ERROR) << "TLS support currently is not available.";
+ return NULL;
+ }
+
+ rtc::AsyncSocket* socket =
+ socket_factory()->CreateAsyncSocket(local_address.family(),
+ SOCK_STREAM);
+ if (!socket) {
+ return NULL;
+ }
+
+ if (BindSocket(socket, local_address, min_port, max_port) < 0) {
+ LOG(LS_ERROR) << "TCP bind failed with error "
+ << socket->GetError();
+ delete socket;
+ return NULL;
+ }
+
+ // If using SSLTCP, wrap the TCP socket in a pseudo-SSL socket.
+ if (opts & PacketSocketFactory::OPT_SSLTCP) {
+ ASSERT(!(opts & PacketSocketFactory::OPT_TLS));
+ socket = new rtc::AsyncSSLSocket(socket);
+ }
+
+ // Set TCP_NODELAY (via OPT_NODELAY) for improved performance.
+ // See http://go/gtalktcpnodelayexperiment
+ socket->SetOption(rtc::Socket::OPT_NODELAY, 1);
+
+ if (opts & PacketSocketFactory::OPT_STUN)
+ return new cricket::AsyncStunTCPSocket(socket, true);
+
+ return new rtc::AsyncTCPSocket(socket, true);
+}
+
+AsyncPacketSocket* BasicPacketSocketFactory::CreateClientTcpSocket(
+ const SocketAddress& local_address, const SocketAddress& remote_address,
+ const ProxyInfo& proxy_info, const std::string& user_agent, int opts) {
+
+ rtc::AsyncSocket* socket =
+ socket_factory()->CreateAsyncSocket(local_address.family(), SOCK_STREAM);
+ if (!socket) {
+ return NULL;
+ }
+
+ if (BindSocket(socket, local_address, 0, 0) < 0) {
+ LOG(LS_ERROR) << "TCP bind failed with error "
+ << socket->GetError();
+ delete socket;
+ return NULL;
+ }
+
+ // If using a proxy, wrap the socket in a proxy socket.
+ if (proxy_info.type == rtc::PROXY_SOCKS5) {
+ socket = new rtc::AsyncSocksProxySocket(
+ socket, proxy_info.address, proxy_info.username, proxy_info.password);
+ } else if (proxy_info.type == rtc::PROXY_HTTPS) {
+ socket = new rtc::AsyncHttpsProxySocket(
+ socket, user_agent, proxy_info.address,
+ proxy_info.username, proxy_info.password);
+ }
+
+ // If using TLS, wrap the socket in an SSL adapter.
+ if (opts & PacketSocketFactory::OPT_TLS) {
+ ASSERT(!(opts & PacketSocketFactory::OPT_SSLTCP));
+
+ rtc::SSLAdapter* ssl_adapter = rtc::SSLAdapter::Create(socket);
+ if (!ssl_adapter) {
+ return NULL;
+ }
+
+ socket = ssl_adapter;
+
+ if (ssl_adapter->StartSSL(remote_address.hostname().c_str(), false) != 0) {
+ delete ssl_adapter;
+ return NULL;
+ }
+
+ // If using SSLTCP, wrap the TCP socket in a pseudo-SSL socket.
+ } else if (opts & PacketSocketFactory::OPT_SSLTCP) {
+ ASSERT(!(opts & PacketSocketFactory::OPT_TLS));
+ socket = new rtc::AsyncSSLSocket(socket);
+ }
+
+ if (socket->Connect(remote_address) < 0) {
+ LOG(LS_ERROR) << "TCP connect failed with error "
+ << socket->GetError();
+ delete socket;
+ return NULL;
+ }
+
+ // Finally, wrap that socket in a TCP or STUN TCP packet socket.
+ AsyncPacketSocket* tcp_socket;
+ if (opts & PacketSocketFactory::OPT_STUN) {
+ tcp_socket = new cricket::AsyncStunTCPSocket(socket, false);
+ } else {
+ tcp_socket = new rtc::AsyncTCPSocket(socket, false);
+ }
+
+ // Set TCP_NODELAY (via OPT_NODELAY) for improved performance.
+ // See http://go/gtalktcpnodelayexperiment
+ tcp_socket->SetOption(rtc::Socket::OPT_NODELAY, 1);
+
+ return tcp_socket;
+}
+
+AsyncResolverInterface* BasicPacketSocketFactory::CreateAsyncResolver() {
+ return new rtc::AsyncResolver();
+}
+
+int BasicPacketSocketFactory::BindSocket(
+ AsyncSocket* socket, const SocketAddress& local_address,
+ int min_port, int max_port) {
+ int ret = -1;
+ if (min_port == 0 && max_port == 0) {
+ // If there's no port range, let the OS pick a port for us.
+ ret = socket->Bind(local_address);
+ } else {
+ // Otherwise, try to find a port in the provided range.
+ for (int port = min_port; ret < 0 && port <= max_port; ++port) {
+ ret = socket->Bind(rtc::SocketAddress(local_address.ipaddr(),
+ port));
+ }
+ }
+ return ret;
+}
+
+SocketFactory* BasicPacketSocketFactory::socket_factory() {
+ if (thread_) {
+ ASSERT(thread_ == Thread::Current());
+ return thread_->socketserver();
+ } else {
+ return socket_factory_;
+ }
+}
+
+} // namespace rtc
diff --git a/p2p/base/basicpacketsocketfactory.h b/p2p/base/basicpacketsocketfactory.h
new file mode 100644
index 00000000..fb3a5269
--- /dev/null
+++ b/p2p/base/basicpacketsocketfactory.h
@@ -0,0 +1,51 @@
+/*
+ * 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 WEBRTC_P2P_BASE_BASICPACKETSOCKETFACTORY_H_
+#define WEBRTC_P2P_BASE_BASICPACKETSOCKETFACTORY_H_
+
+#include "webrtc/p2p/base/packetsocketfactory.h"
+
+namespace rtc {
+
+class AsyncSocket;
+class SocketFactory;
+class Thread;
+
+class BasicPacketSocketFactory : public PacketSocketFactory {
+ public:
+ BasicPacketSocketFactory();
+ explicit BasicPacketSocketFactory(Thread* thread);
+ explicit BasicPacketSocketFactory(SocketFactory* socket_factory);
+ virtual ~BasicPacketSocketFactory();
+
+ virtual AsyncPacketSocket* CreateUdpSocket(
+ const SocketAddress& local_address, int min_port, int max_port);
+ virtual AsyncPacketSocket* CreateServerTcpSocket(
+ const SocketAddress& local_address, int min_port, int max_port, int opts);
+ virtual AsyncPacketSocket* CreateClientTcpSocket(
+ const SocketAddress& local_address, const SocketAddress& remote_address,
+ const ProxyInfo& proxy_info, const std::string& user_agent, int opts);
+
+ virtual AsyncResolverInterface* CreateAsyncResolver();
+
+ private:
+ int BindSocket(AsyncSocket* socket, const SocketAddress& local_address,
+ int min_port, int max_port);
+
+ SocketFactory* socket_factory();
+
+ Thread* thread_;
+ SocketFactory* socket_factory_;
+};
+
+} // namespace rtc
+
+#endif // WEBRTC_P2P_BASE_BASICPACKETSOCKETFACTORY_H_
diff --git a/p2p/base/candidate.h b/p2p/base/candidate.h
new file mode 100644
index 00000000..72bc69ef
--- /dev/null
+++ b/p2p/base/candidate.h
@@ -0,0 +1,212 @@
+/*
+ * 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 WEBRTC_P2P_BASE_CANDIDATE_H_
+#define WEBRTC_P2P_BASE_CANDIDATE_H_
+
+#include <limits.h>
+#include <math.h>
+
+#include <iomanip>
+#include <sstream>
+#include <string>
+
+#include "webrtc/p2p/base/constants.h"
+#include "webrtc/base/basictypes.h"
+#include "webrtc/base/socketaddress.h"
+
+namespace cricket {
+
+// Candidate for ICE based connection discovery.
+
+class Candidate {
+ public:
+ // TODO: Match the ordering and param list as per RFC 5245
+ // candidate-attribute syntax. http://tools.ietf.org/html/rfc5245#section-15.1
+ Candidate() : component_(0), priority_(0), generation_(0) {}
+ Candidate(const std::string& id, int component, const std::string& protocol,
+ const rtc::SocketAddress& address, uint32 priority,
+ const std::string& username, const std::string& password,
+ const std::string& type, const std::string& network_name,
+ uint32 generation, const std::string& foundation)
+ : id_(id), component_(component), protocol_(protocol), address_(address),
+ priority_(priority), username_(username), password_(password),
+ type_(type), network_name_(network_name), generation_(generation),
+ foundation_(foundation) {
+ }
+
+ const std::string & id() const { return id_; }
+ void set_id(const std::string & id) { id_ = id; }
+
+ int component() const { return component_; }
+ void set_component(int component) { component_ = component; }
+
+ const std::string & protocol() const { return protocol_; }
+ void set_protocol(const std::string & protocol) { protocol_ = protocol; }
+
+ const rtc::SocketAddress & address() const { return address_; }
+ void set_address(const rtc::SocketAddress & address) {
+ address_ = address;
+ }
+
+ uint32 priority() const { return priority_; }
+ void set_priority(const uint32 priority) { priority_ = priority; }
+
+// void set_type_preference(uint32 type_preference) {
+// priority_ = GetPriority(type_preference);
+// }
+
+ // 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);
+ }
+
+ void set_preference(float preference) {
+ // Limiting priority to UINT_MAX when value exceeds uint32 max.
+ // This can happen for e.g. when preference = 3.
+ uint64 prio_val = static_cast<uint64>(preference * 127) << 24;
+ priority_ = static_cast<uint32>(
+ rtc::_min(prio_val, static_cast<uint64>(UINT_MAX)));
+ }
+
+ const std::string & username() const { return username_; }
+ void set_username(const std::string & username) { username_ = username; }
+
+ const std::string & password() const { return password_; }
+ void set_password(const std::string & password) { password_ = password; }
+
+ const std::string & type() const { return type_; }
+ void set_type(const std::string & type) { type_ = type; }
+
+ const std::string & network_name() const { return network_name_; }
+ void set_network_name(const std::string & network_name) {
+ network_name_ = network_name;
+ }
+
+ // Candidates in a new generation replace those in the old generation.
+ uint32 generation() const { return generation_; }
+ void set_generation(uint32 generation) { generation_ = generation; }
+ const std::string generation_str() const {
+ std::ostringstream ost;
+ ost << generation_;
+ return ost.str();
+ }
+ void set_generation_str(const std::string& str) {
+ std::istringstream ist(str);
+ ist >> generation_;
+ }
+
+ const std::string& foundation() const {
+ return foundation_;
+ }
+
+ void set_foundation(const std::string& foundation) {
+ 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(const std::string& tcptype){
+ tcptype_ = tcptype;
+ }
+
+ // Determines whether this candidate is equivalent to the given one.
+ bool IsEquivalent(const Candidate& c) const {
+ // We ignore the network name, since that is just debug information, and
+ // the priority, since that should be the same if the rest is (and it's
+ // a float so equality checking is always worrisome).
+ return (id_ == c.id_) &&
+ (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_);
+ }
+
+ std::string ToString() const {
+ return ToStringInternal(false);
+ }
+
+ std::string ToSensitiveString() const {
+ return ToStringInternal(true);
+ }
+
+ uint32 GetPriority(uint32 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.
+
+ 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_);
+ }
+
+ private:
+ std::string ToStringInternal(bool sensitive) const {
+ std::ostringstream ost;
+ std::string address = sensitive ? address_.ToSensitiveString() :
+ address_.ToString();
+ ost << "Cand[" << foundation_ << ":" << component_ << ":"
+ << protocol_ << ":" << priority_ << ":"
+ << address << ":" << type_ << ":" << related_address_ << ":"
+ << username_ << ":" << password_ << "]";
+ return ost.str();
+ }
+
+ std::string id_;
+ int component_;
+ std::string protocol_;
+ rtc::SocketAddress address_;
+ uint32 priority_;
+ std::string username_;
+ std::string password_;
+ std::string type_;
+ std::string network_name_;
+ uint32 generation_;
+ std::string foundation_;
+ rtc::SocketAddress related_address_;
+ std::string tcptype_;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_CANDIDATE_H_
diff --git a/p2p/base/common.h b/p2p/base/common.h
new file mode 100644
index 00000000..8a3178c8
--- /dev/null
+++ b/p2p/base/common.h
@@ -0,0 +1,20 @@
+/*
+ * 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 WEBRTC_P2P_BASE_COMMON_H_
+#define WEBRTC_P2P_BASE_COMMON_H_
+
+#include "webrtc/base/logging.h"
+
+// Common log description format for jingle messages
+#define LOG_J(sev, obj) LOG(sev) << "Jingle:" << obj->ToString() << ": "
+#define LOG_JV(sev, obj) LOG_V(sev) << "Jingle:" << obj->ToString() << ": "
+
+#endif // WEBRTC_P2P_BASE_COMMON_H_
diff --git a/p2p/base/constants.cc b/p2p/base/constants.cc
new file mode 100644
index 00000000..84c9ea26
--- /dev/null
+++ b/p2p/base/constants.cc
@@ -0,0 +1,257 @@
+/*
+ * 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 "webrtc/p2p/base/constants.h"
+
+#include <string>
+
+#include "webrtc/libjingle/xmllite/qname.h"
+
+namespace cricket {
+
+const char NS_EMPTY[] = "";
+const char NS_JINGLE[] = "urn:xmpp:jingle:1";
+const char NS_JINGLE_DRAFT[] = "google:jingle";
+const char NS_GINGLE[] = "http://www.google.com/session";
+
+// actions (aka <session> or <jingle>)
+const buzz::StaticQName QN_ACTION = { NS_EMPTY, "action" };
+const char LN_INITIATOR[] = "initiator";
+const buzz::StaticQName QN_INITIATOR = { NS_EMPTY, LN_INITIATOR };
+const buzz::StaticQName QN_CREATOR = { NS_EMPTY, "creator" };
+
+const buzz::StaticQName QN_JINGLE = { NS_JINGLE, "jingle" };
+const buzz::StaticQName QN_JINGLE_CONTENT = { NS_JINGLE, "content" };
+const buzz::StaticQName QN_JINGLE_CONTENT_NAME = { NS_EMPTY, "name" };
+const buzz::StaticQName QN_JINGLE_CONTENT_MEDIA = { NS_EMPTY, "media" };
+const buzz::StaticQName QN_JINGLE_REASON = { NS_JINGLE, "reason" };
+const buzz::StaticQName QN_JINGLE_DRAFT_GROUP = { NS_JINGLE_DRAFT, "group" };
+const buzz::StaticQName QN_JINGLE_DRAFT_GROUP_TYPE = { NS_EMPTY, "type" };
+const char JINGLE_CONTENT_MEDIA_AUDIO[] = "audio";
+const char JINGLE_CONTENT_MEDIA_VIDEO[] = "video";
+const char JINGLE_CONTENT_MEDIA_DATA[] = "data";
+const char JINGLE_ACTION_SESSION_INITIATE[] = "session-initiate";
+const char JINGLE_ACTION_SESSION_INFO[] = "session-info";
+const char JINGLE_ACTION_SESSION_ACCEPT[] = "session-accept";
+const char JINGLE_ACTION_SESSION_TERMINATE[] = "session-terminate";
+const char JINGLE_ACTION_TRANSPORT_INFO[] = "transport-info";
+const char JINGLE_ACTION_TRANSPORT_ACCEPT[] = "transport-accept";
+const char JINGLE_ACTION_DESCRIPTION_INFO[] = "description-info";
+
+const buzz::StaticQName QN_GINGLE_SESSION = { NS_GINGLE, "session" };
+const char GINGLE_ACTION_INITIATE[] = "initiate";
+const char GINGLE_ACTION_INFO[] = "info";
+const char GINGLE_ACTION_ACCEPT[] = "accept";
+const char GINGLE_ACTION_REJECT[] = "reject";
+const char GINGLE_ACTION_TERMINATE[] = "terminate";
+const char GINGLE_ACTION_CANDIDATES[] = "candidates";
+const char GINGLE_ACTION_UPDATE[] = "update";
+
+const char LN_ERROR[] = "error";
+const buzz::StaticQName QN_GINGLE_REDIRECT = { NS_GINGLE, "redirect" };
+const char STR_REDIRECT_PREFIX[] = "xmpp:";
+
+// Session Contents (aka Gingle <session><description>
+// or Jingle <content><description>)
+const char LN_DESCRIPTION[] = "description";
+const char LN_PAYLOADTYPE[] = "payload-type";
+const buzz::StaticQName QN_ID = { NS_EMPTY, "id" };
+const buzz::StaticQName QN_SID = { NS_EMPTY, "sid" };
+const buzz::StaticQName QN_NAME = { NS_EMPTY, "name" };
+const buzz::StaticQName QN_CLOCKRATE = { NS_EMPTY, "clockrate" };
+const buzz::StaticQName QN_BITRATE = { NS_EMPTY, "bitrate" };
+const buzz::StaticQName QN_CHANNELS = { NS_EMPTY, "channels" };
+const buzz::StaticQName QN_WIDTH = { NS_EMPTY, "width" };
+const buzz::StaticQName QN_HEIGHT = { NS_EMPTY, "height" };
+const buzz::StaticQName QN_FRAMERATE = { NS_EMPTY, "framerate" };
+const char LN_NAME[] = "name";
+const char LN_VALUE[] = "value";
+const buzz::StaticQName QN_PAYLOADTYPE_PARAMETER_NAME = { NS_EMPTY, LN_NAME };
+const buzz::StaticQName QN_PAYLOADTYPE_PARAMETER_VALUE = { NS_EMPTY, LN_VALUE };
+const char PAYLOADTYPE_PARAMETER_BITRATE[] = "bitrate";
+const char PAYLOADTYPE_PARAMETER_HEIGHT[] = "height";
+const char PAYLOADTYPE_PARAMETER_WIDTH[] = "width";
+const char PAYLOADTYPE_PARAMETER_FRAMERATE[] = "framerate";
+const char LN_BANDWIDTH[] = "bandwidth";
+
+const char CN_AUDIO[] = "audio";
+const char CN_VIDEO[] = "video";
+const char CN_DATA[] = "data";
+const char CN_OTHER[] = "main";
+// other SDP related strings
+const char GROUP_TYPE_BUNDLE[] = "BUNDLE";
+
+const char NS_JINGLE_RTP[] = "urn:xmpp:jingle:apps:rtp:1";
+const buzz::StaticQName QN_JINGLE_RTP_CONTENT =
+ { NS_JINGLE_RTP, LN_DESCRIPTION };
+const buzz::StaticQName QN_SSRC = { NS_EMPTY, "ssrc" };
+const buzz::StaticQName QN_JINGLE_RTP_PAYLOADTYPE =
+ { NS_JINGLE_RTP, LN_PAYLOADTYPE };
+const buzz::StaticQName QN_JINGLE_RTP_BANDWIDTH =
+ { NS_JINGLE_RTP, LN_BANDWIDTH };
+const buzz::StaticQName QN_JINGLE_RTCP_MUX = { NS_JINGLE_RTP, "rtcp-mux" };
+const buzz::StaticQName QN_JINGLE_RTCP_FB = { NS_JINGLE_RTP, "rtcp-fb" };
+const buzz::StaticQName QN_SUBTYPE = { NS_EMPTY, "subtype" };
+const buzz::StaticQName QN_PARAMETER = { NS_JINGLE_RTP, "parameter" };
+const buzz::StaticQName QN_JINGLE_RTP_HDREXT =
+ { NS_JINGLE_RTP, "rtp-hdrext" };
+const buzz::StaticQName QN_URI = { NS_EMPTY, "uri" };
+
+const char NS_JINGLE_DRAFT_SCTP[] = "google:jingle:sctp";
+const buzz::StaticQName QN_JINGLE_DRAFT_SCTP_CONTENT =
+ { NS_JINGLE_DRAFT_SCTP, LN_DESCRIPTION };
+const buzz::StaticQName QN_JINGLE_DRAFT_SCTP_STREAM =
+ { NS_JINGLE_DRAFT_SCTP, "stream" };
+
+const char NS_GINGLE_AUDIO[] = "http://www.google.com/session/phone";
+const buzz::StaticQName QN_GINGLE_AUDIO_CONTENT =
+ { NS_GINGLE_AUDIO, LN_DESCRIPTION };
+const buzz::StaticQName QN_GINGLE_AUDIO_PAYLOADTYPE =
+ { NS_GINGLE_AUDIO, LN_PAYLOADTYPE };
+const buzz::StaticQName QN_GINGLE_AUDIO_SRCID = { NS_GINGLE_AUDIO, "src-id" };
+const char NS_GINGLE_VIDEO[] = "http://www.google.com/session/video";
+const buzz::StaticQName QN_GINGLE_VIDEO_CONTENT =
+ { NS_GINGLE_VIDEO, LN_DESCRIPTION };
+const buzz::StaticQName QN_GINGLE_VIDEO_PAYLOADTYPE =
+ { NS_GINGLE_VIDEO, LN_PAYLOADTYPE };
+const buzz::StaticQName QN_GINGLE_VIDEO_SRCID = { NS_GINGLE_VIDEO, "src-id" };
+const buzz::StaticQName QN_GINGLE_VIDEO_BANDWIDTH =
+ { NS_GINGLE_VIDEO, LN_BANDWIDTH };
+
+// Crypto support.
+const buzz::StaticQName QN_ENCRYPTION = { NS_JINGLE_RTP, "encryption" };
+const buzz::StaticQName QN_ENCRYPTION_REQUIRED = { NS_EMPTY, "required" };
+const buzz::StaticQName QN_CRYPTO = { NS_JINGLE_RTP, "crypto" };
+const buzz::StaticQName QN_GINGLE_AUDIO_CRYPTO_USAGE =
+ { NS_GINGLE_AUDIO, "usage" };
+const buzz::StaticQName QN_GINGLE_VIDEO_CRYPTO_USAGE =
+ { NS_GINGLE_VIDEO, "usage" };
+const buzz::StaticQName QN_CRYPTO_SUITE = { NS_EMPTY, "crypto-suite" };
+const buzz::StaticQName QN_CRYPTO_KEY_PARAMS = { NS_EMPTY, "key-params" };
+const buzz::StaticQName QN_CRYPTO_TAG = { NS_EMPTY, "tag" };
+const buzz::StaticQName QN_CRYPTO_SESSION_PARAMS =
+ { NS_EMPTY, "session-params" };
+
+// Transports and candidates.
+const char LN_TRANSPORT[] = "transport";
+const char LN_CANDIDATE[] = "candidate";
+const buzz::StaticQName QN_UFRAG = { cricket::NS_EMPTY, "ufrag" };
+const buzz::StaticQName QN_PWD = { cricket::NS_EMPTY, "pwd" };
+const buzz::StaticQName QN_COMPONENT = { cricket::NS_EMPTY, "component" };
+const buzz::StaticQName QN_IP = { cricket::NS_EMPTY, "ip" };
+const buzz::StaticQName QN_PORT = { cricket::NS_EMPTY, "port" };
+const buzz::StaticQName QN_NETWORK = { cricket::NS_EMPTY, "network" };
+const buzz::StaticQName QN_GENERATION = { cricket::NS_EMPTY, "generation" };
+const buzz::StaticQName QN_PRIORITY = { cricket::NS_EMPTY, "priority" };
+const buzz::StaticQName QN_PROTOCOL = { cricket::NS_EMPTY, "protocol" };
+const char ICE_CANDIDATE_TYPE_PEER_STUN[] = "prflx";
+const char ICE_CANDIDATE_TYPE_SERVER_STUN[] = "srflx";
+// Minimum ufrag length is 4 characters as per RFC5245. We chose 16 because
+// some internal systems expect username to be 16 bytes.
+const int ICE_UFRAG_LENGTH = 16;
+// Minimum password length of 22 characters as per RFC5245. We chose 24 because
+// some internal systems expect password to be multiple of 4.
+const int ICE_PWD_LENGTH = 24;
+const size_t ICE_UFRAG_MIN_LENGTH = 4;
+const size_t ICE_PWD_MIN_LENGTH = 22;
+const size_t ICE_UFRAG_MAX_LENGTH = 255;
+const size_t ICE_PWD_MAX_LENGTH = 256;
+// TODO: This is media-specific, so might belong
+// somewhere like media/base/constants.h
+const int ICE_CANDIDATE_COMPONENT_RTP = 1;
+const int ICE_CANDIDATE_COMPONENT_RTCP = 2;
+const int ICE_CANDIDATE_COMPONENT_DEFAULT = 1;
+
+const buzz::StaticQName QN_FINGERPRINT = { cricket::NS_EMPTY, "fingerprint" };
+const buzz::StaticQName QN_FINGERPRINT_ALGORITHM =
+ { cricket::NS_EMPTY, "algorithm" };
+const buzz::StaticQName QN_FINGERPRINT_DIGEST = { cricket::NS_EMPTY, "digest" };
+
+const char NS_JINGLE_ICE_UDP[] = "urn:xmpp:jingle:transports:ice-udp:1";
+
+const char ICE_OPTION_GICE[] = "google-ice";
+const char NS_GINGLE_P2P[] = "http://www.google.com/transport/p2p";
+const buzz::StaticQName QN_GINGLE_P2P_TRANSPORT =
+ { NS_GINGLE_P2P, LN_TRANSPORT };
+const buzz::StaticQName QN_GINGLE_P2P_CANDIDATE =
+ { NS_GINGLE_P2P, LN_CANDIDATE };
+const buzz::StaticQName QN_GINGLE_P2P_UNKNOWN_CHANNEL_NAME =
+ { NS_GINGLE_P2P, "unknown-channel-name" };
+const buzz::StaticQName QN_GINGLE_CANDIDATE = { NS_GINGLE, LN_CANDIDATE };
+const buzz::StaticQName QN_ADDRESS = { cricket::NS_EMPTY, "address" };
+const buzz::StaticQName QN_USERNAME = { cricket::NS_EMPTY, "username" };
+const buzz::StaticQName QN_PASSWORD = { cricket::NS_EMPTY, "password" };
+const buzz::StaticQName QN_PREFERENCE = { cricket::NS_EMPTY, "preference" };
+const char GICE_CHANNEL_NAME_RTP[] = "rtp";
+const char GICE_CHANNEL_NAME_RTCP[] = "rtcp";
+const char GICE_CHANNEL_NAME_VIDEO_RTP[] = "video_rtp";
+const char GICE_CHANNEL_NAME_VIDEO_RTCP[] = "video_rtcp";
+const char GICE_CHANNEL_NAME_DATA_RTP[] = "data_rtp";
+const char GICE_CHANNEL_NAME_DATA_RTCP[] = "data_rtcp";
+
+// terminate reasons and errors
+const char JINGLE_ERROR_BAD_REQUEST[] = "bad-request";
+const char JINGLE_ERROR_OUT_OF_ORDER[] = "out-of-order";
+const char JINGLE_ERROR_UNKNOWN_SESSION[] = "unknown-session";
+
+// Call terminate reasons from XEP-166
+const char STR_TERMINATE_DECLINE[] = "decline";
+const char STR_TERMINATE_SUCCESS[] = "success";
+const char STR_TERMINATE_ERROR[] = "general-error";
+const char STR_TERMINATE_INCOMPATIBLE_PARAMETERS[] = "incompatible-parameters";
+
+// Old terminate reasons used by cricket
+const char STR_TERMINATE_CALL_ENDED[] = "call-ended";
+const char STR_TERMINATE_RECIPIENT_UNAVAILABLE[] = "recipient-unavailable";
+const char STR_TERMINATE_RECIPIENT_BUSY[] = "recipient-busy";
+const char STR_TERMINATE_INSUFFICIENT_FUNDS[] = "insufficient-funds";
+const char STR_TERMINATE_NUMBER_MALFORMED[] = "number-malformed";
+const char STR_TERMINATE_NUMBER_DISALLOWED[] = "number-disallowed";
+const char STR_TERMINATE_PROTOCOL_ERROR[] = "protocol-error";
+const char STR_TERMINATE_INTERNAL_SERVER_ERROR[] = "internal-server-error";
+const char STR_TERMINATE_UNKNOWN_ERROR[] = "unknown-error";
+
+// Draft view and notify messages.
+const char STR_JINGLE_DRAFT_CONTENT_NAME_VIDEO[] = "video";
+const char STR_JINGLE_DRAFT_CONTENT_NAME_AUDIO[] = "audio";
+const buzz::StaticQName QN_NICK = { cricket::NS_EMPTY, "nick" };
+const buzz::StaticQName QN_TYPE = { cricket::NS_EMPTY, "type" };
+const buzz::StaticQName QN_JINGLE_DRAFT_VIEW = { NS_JINGLE_DRAFT, "view" };
+const char STR_JINGLE_DRAFT_VIEW_TYPE_NONE[] = "none";
+const char STR_JINGLE_DRAFT_VIEW_TYPE_STATIC[] = "static";
+const buzz::StaticQName QN_JINGLE_DRAFT_PARAMS = { NS_JINGLE_DRAFT, "params" };
+const buzz::StaticQName QN_JINGLE_DRAFT_STREAMS = { NS_JINGLE_DRAFT, "streams" };
+const buzz::StaticQName QN_JINGLE_DRAFT_STREAM = { NS_JINGLE_DRAFT, "stream" };
+const buzz::StaticQName QN_DISPLAY = { cricket::NS_EMPTY, "display" };
+const buzz::StaticQName QN_CNAME = { cricket::NS_EMPTY, "cname" };
+const buzz::StaticQName QN_JINGLE_DRAFT_SSRC = { NS_JINGLE_DRAFT, "ssrc" };
+const buzz::StaticQName QN_JINGLE_DRAFT_SSRC_GROUP =
+ { NS_JINGLE_DRAFT, "ssrc-group" };
+const buzz::StaticQName QN_SEMANTICS = { cricket::NS_EMPTY, "semantics" };
+const buzz::StaticQName QN_JINGLE_LEGACY_NOTIFY = { NS_JINGLE_DRAFT, "notify" };
+const buzz::StaticQName QN_JINGLE_LEGACY_SOURCE = { NS_JINGLE_DRAFT, "source" };
+
+const char NS_GINGLE_RAW[] = "http://www.google.com/transport/raw-udp";
+const buzz::StaticQName QN_GINGLE_RAW_TRANSPORT = { NS_GINGLE_RAW, "transport" };
+const buzz::StaticQName QN_GINGLE_RAW_CHANNEL = { NS_GINGLE_RAW, "channel" };
+
+// old stuff
+#ifdef FEATURE_ENABLE_VOICEMAIL
+const char NS_VOICEMAIL[] = "http://www.google.com/session/voicemail";
+const buzz::StaticQName QN_VOICEMAIL_REGARDING = { NS_VOICEMAIL, "regarding" };
+#endif
+
+// From RFC 4145, SDP setup attribute values.
+const char CONNECTIONROLE_ACTIVE_STR[] = "active";
+const char CONNECTIONROLE_PASSIVE_STR[] = "passive";
+const char CONNECTIONROLE_ACTPASS_STR[] = "actpass";
+const char CONNECTIONROLE_HOLDCONN_STR[] = "holdconn";
+
+} // namespace cricket
diff --git a/p2p/base/constants.h b/p2p/base/constants.h
new file mode 100644
index 00000000..57423f5b
--- /dev/null
+++ b/p2p/base/constants.h
@@ -0,0 +1,259 @@
+/*
+ * 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 WEBRTC_P2P_BASE_CONSTANTS_H_
+#define WEBRTC_P2P_BASE_CONSTANTS_H_
+
+#include <string>
+#include "webrtc/libjingle/xmllite/qname.h"
+
+// This file contains constants related to signaling that are used in various
+// classes in this directory.
+
+namespace cricket {
+
+// NS_ == namespace
+// QN_ == buzz::QName (namespace + name)
+// LN_ == "local name" == QName::LocalPart()
+// these are useful when you need to find a tag
+// that has different namespaces (like <description> or <transport>)
+
+extern const char NS_EMPTY[];
+extern const char NS_JINGLE[];
+extern const char NS_JINGLE_DRAFT[];
+extern const char NS_GINGLE[];
+
+enum SignalingProtocol {
+ PROTOCOL_JINGLE,
+ PROTOCOL_GINGLE,
+ PROTOCOL_HYBRID,
+};
+
+// actions (aka Gingle <session> or Jingle <jingle>)
+extern const buzz::StaticQName QN_ACTION;
+extern const char LN_INITIATOR[];
+extern const buzz::StaticQName QN_INITIATOR;
+extern const buzz::StaticQName QN_CREATOR;
+
+extern const buzz::StaticQName QN_JINGLE;
+extern const buzz::StaticQName QN_JINGLE_CONTENT;
+extern const buzz::StaticQName QN_JINGLE_CONTENT_NAME;
+extern const buzz::StaticQName QN_JINGLE_CONTENT_MEDIA;
+extern const buzz::StaticQName QN_JINGLE_REASON;
+extern const buzz::StaticQName QN_JINGLE_DRAFT_GROUP;
+extern const buzz::StaticQName QN_JINGLE_DRAFT_GROUP_TYPE;
+extern const char JINGLE_CONTENT_MEDIA_AUDIO[];
+extern const char JINGLE_CONTENT_MEDIA_VIDEO[];
+extern const char JINGLE_CONTENT_MEDIA_DATA[];
+extern const char JINGLE_ACTION_SESSION_INITIATE[];
+extern const char JINGLE_ACTION_SESSION_INFO[];
+extern const char JINGLE_ACTION_SESSION_ACCEPT[];
+extern const char JINGLE_ACTION_SESSION_TERMINATE[];
+extern const char JINGLE_ACTION_TRANSPORT_INFO[];
+extern const char JINGLE_ACTION_TRANSPORT_ACCEPT[];
+extern const char JINGLE_ACTION_DESCRIPTION_INFO[];
+
+extern const buzz::StaticQName QN_GINGLE_SESSION;
+extern const char GINGLE_ACTION_INITIATE[];
+extern const char GINGLE_ACTION_INFO[];
+extern const char GINGLE_ACTION_ACCEPT[];
+extern const char GINGLE_ACTION_REJECT[];
+extern const char GINGLE_ACTION_TERMINATE[];
+extern const char GINGLE_ACTION_CANDIDATES[];
+extern const char GINGLE_ACTION_UPDATE[];
+
+extern const char LN_ERROR[];
+extern const buzz::StaticQName QN_GINGLE_REDIRECT;
+extern const char STR_REDIRECT_PREFIX[];
+
+// Session Contents (aka Gingle <session><description>
+// or Jingle <content><description>)
+extern const char LN_DESCRIPTION[];
+extern const char LN_PAYLOADTYPE[];
+extern const buzz::StaticQName QN_ID;
+extern const buzz::StaticQName QN_SID;
+extern const buzz::StaticQName QN_NAME;
+extern const buzz::StaticQName QN_CLOCKRATE;
+extern const buzz::StaticQName QN_BITRATE;
+extern const buzz::StaticQName QN_CHANNELS;
+extern const buzz::StaticQName QN_PARAMETER;
+extern const char LN_NAME[];
+extern const char LN_VALUE[];
+extern const buzz::StaticQName QN_PAYLOADTYPE_PARAMETER_NAME;
+extern const buzz::StaticQName QN_PAYLOADTYPE_PARAMETER_VALUE;
+extern const char PAYLOADTYPE_PARAMETER_BITRATE[];
+extern const char PAYLOADTYPE_PARAMETER_HEIGHT[];
+extern const char PAYLOADTYPE_PARAMETER_WIDTH[];
+extern const char PAYLOADTYPE_PARAMETER_FRAMERATE[];
+extern const char LN_BANDWIDTH[];
+
+// CN_ == "content name". When we initiate a session, we choose the
+// name, and when we receive a Gingle session, we provide default
+// names (since Gingle has no content names). But when we receive a
+// Jingle call, the content name can be anything, so don't rely on
+// these values being the same as the ones received.
+extern const char CN_AUDIO[];
+extern const char CN_VIDEO[];
+extern const char CN_DATA[];
+extern const char CN_OTHER[];
+// other SDP related strings
+// GN stands for group name
+extern const char GROUP_TYPE_BUNDLE[];
+
+extern const char NS_JINGLE_RTP[];
+extern const buzz::StaticQName QN_JINGLE_RTP_CONTENT;
+extern const buzz::StaticQName QN_SSRC;
+extern const buzz::StaticQName QN_JINGLE_RTP_PAYLOADTYPE;
+extern const buzz::StaticQName QN_JINGLE_RTP_BANDWIDTH;
+extern const buzz::StaticQName QN_JINGLE_RTCP_MUX;
+extern const buzz::StaticQName QN_JINGLE_RTCP_FB;
+extern const buzz::StaticQName QN_SUBTYPE;
+extern const buzz::StaticQName QN_JINGLE_RTP_HDREXT;
+extern const buzz::StaticQName QN_URI;
+
+extern const char NS_JINGLE_DRAFT_SCTP[];
+extern const buzz::StaticQName QN_JINGLE_DRAFT_SCTP_CONTENT;
+extern const buzz::StaticQName QN_JINGLE_DRAFT_SCTP_STREAM;
+
+extern const char NS_GINGLE_AUDIO[];
+extern const buzz::StaticQName QN_GINGLE_AUDIO_CONTENT;
+extern const buzz::StaticQName QN_GINGLE_AUDIO_PAYLOADTYPE;
+extern const buzz::StaticQName QN_GINGLE_AUDIO_SRCID;
+extern const char NS_GINGLE_VIDEO[];
+extern const buzz::StaticQName QN_GINGLE_VIDEO_CONTENT;
+extern const buzz::StaticQName QN_GINGLE_VIDEO_PAYLOADTYPE;
+extern const buzz::StaticQName QN_GINGLE_VIDEO_SRCID;
+extern const buzz::StaticQName QN_GINGLE_VIDEO_BANDWIDTH;
+
+// Crypto support.
+extern const buzz::StaticQName QN_ENCRYPTION;
+extern const buzz::StaticQName QN_ENCRYPTION_REQUIRED;
+extern const buzz::StaticQName QN_CRYPTO;
+extern const buzz::StaticQName QN_GINGLE_AUDIO_CRYPTO_USAGE;
+extern const buzz::StaticQName QN_GINGLE_VIDEO_CRYPTO_USAGE;
+extern const buzz::StaticQName QN_CRYPTO_SUITE;
+extern const buzz::StaticQName QN_CRYPTO_KEY_PARAMS;
+extern const buzz::StaticQName QN_CRYPTO_TAG;
+extern const buzz::StaticQName QN_CRYPTO_SESSION_PARAMS;
+
+// Transports and candidates.
+extern const char LN_TRANSPORT[];
+extern const char LN_CANDIDATE[];
+extern const buzz::StaticQName QN_JINGLE_P2P_TRANSPORT;
+extern const buzz::StaticQName QN_JINGLE_P2P_CANDIDATE;
+extern const buzz::StaticQName QN_UFRAG;
+extern const buzz::StaticQName QN_COMPONENT;
+extern const buzz::StaticQName QN_PWD;
+extern const buzz::StaticQName QN_IP;
+extern const buzz::StaticQName QN_PORT;
+extern const buzz::StaticQName QN_NETWORK;
+extern const buzz::StaticQName QN_GENERATION;
+extern const buzz::StaticQName QN_PRIORITY;
+extern const buzz::StaticQName QN_PROTOCOL;
+extern const char ICE_CANDIDATE_TYPE_PEER_STUN[];
+extern const char ICE_CANDIDATE_TYPE_SERVER_STUN[];
+extern const int ICE_UFRAG_LENGTH;
+extern const int ICE_PWD_LENGTH;
+extern const size_t ICE_UFRAG_MIN_LENGTH;
+extern const size_t ICE_PWD_MIN_LENGTH;
+extern const size_t ICE_UFRAG_MAX_LENGTH;
+extern const size_t ICE_PWD_MAX_LENGTH;
+extern const int ICE_CANDIDATE_COMPONENT_RTP;
+extern const int ICE_CANDIDATE_COMPONENT_RTCP;
+extern const int ICE_CANDIDATE_COMPONENT_DEFAULT;
+
+extern const buzz::StaticQName QN_FINGERPRINT;
+extern const buzz::StaticQName QN_FINGERPRINT_ALGORITHM;
+extern const buzz::StaticQName QN_FINGERPRINT_DIGEST;
+
+extern const char NS_JINGLE_ICE_UDP[];
+
+extern const char ICE_OPTION_GICE[];
+extern const char NS_GINGLE_P2P[];
+extern const buzz::StaticQName QN_GINGLE_P2P_TRANSPORT;
+extern const buzz::StaticQName QN_GINGLE_P2P_CANDIDATE;
+extern const buzz::StaticQName QN_GINGLE_P2P_UNKNOWN_CHANNEL_NAME;
+extern const buzz::StaticQName QN_GINGLE_CANDIDATE;
+extern const buzz::StaticQName QN_ADDRESS;
+extern const buzz::StaticQName QN_USERNAME;
+extern const buzz::StaticQName QN_PASSWORD;
+extern const buzz::StaticQName QN_PREFERENCE;
+extern const char GINGLE_CANDIDATE_TYPE_STUN[];
+extern const char GICE_CHANNEL_NAME_RTP[];
+extern const char GICE_CHANNEL_NAME_RTCP[];
+extern const char GICE_CHANNEL_NAME_VIDEO_RTP[];
+extern const char GICE_CHANNEL_NAME_VIDEO_RTCP[];
+extern const char GICE_CHANNEL_NAME_DATA_RTP[];
+extern const char GICE_CHANNEL_NAME_DATA_RTCP[];
+
+extern const char NS_GINGLE_RAW[];
+extern const buzz::StaticQName QN_GINGLE_RAW_TRANSPORT;
+extern const buzz::StaticQName QN_GINGLE_RAW_CHANNEL;
+
+// terminate reasons and errors: see http://xmpp.org/extensions/xep-0166.html
+extern const char JINGLE_ERROR_BAD_REQUEST[]; // like parse error
+// got transport-info before session-initiate, for example
+extern const char JINGLE_ERROR_OUT_OF_ORDER[];
+extern const char JINGLE_ERROR_UNKNOWN_SESSION[];
+
+// Call terminate reasons from XEP-166
+extern const char STR_TERMINATE_DECLINE[]; // polite reject
+extern const char STR_TERMINATE_SUCCESS[]; // polite hangup
+extern const char STR_TERMINATE_ERROR[]; // something bad happened
+extern const char STR_TERMINATE_INCOMPATIBLE_PARAMETERS[]; // no codecs?
+
+// Old terminate reasons used by cricket
+extern const char STR_TERMINATE_CALL_ENDED[];
+extern const char STR_TERMINATE_RECIPIENT_UNAVAILABLE[];
+extern const char STR_TERMINATE_RECIPIENT_BUSY[];
+extern const char STR_TERMINATE_INSUFFICIENT_FUNDS[];
+extern const char STR_TERMINATE_NUMBER_MALFORMED[];
+extern const char STR_TERMINATE_NUMBER_DISALLOWED[];
+extern const char STR_TERMINATE_PROTOCOL_ERROR[];
+extern const char STR_TERMINATE_INTERNAL_SERVER_ERROR[];
+extern const char STR_TERMINATE_UNKNOWN_ERROR[];
+
+// Draft view and notify messages.
+extern const char STR_JINGLE_DRAFT_CONTENT_NAME_VIDEO[];
+extern const char STR_JINGLE_DRAFT_CONTENT_NAME_AUDIO[];
+extern const buzz::StaticQName QN_NICK;
+extern const buzz::StaticQName QN_TYPE;
+extern const buzz::StaticQName QN_JINGLE_DRAFT_VIEW;
+extern const char STR_JINGLE_DRAFT_VIEW_TYPE_NONE[];
+extern const char STR_JINGLE_DRAFT_VIEW_TYPE_STATIC[];
+extern const buzz::StaticQName QN_JINGLE_DRAFT_PARAMS;
+extern const buzz::StaticQName QN_WIDTH;
+extern const buzz::StaticQName QN_HEIGHT;
+extern const buzz::StaticQName QN_FRAMERATE;
+extern const buzz::StaticQName QN_JINGLE_DRAFT_STREAM;
+extern const buzz::StaticQName QN_JINGLE_DRAFT_STREAMS;
+extern const buzz::StaticQName QN_DISPLAY;
+extern const buzz::StaticQName QN_CNAME;
+extern const buzz::StaticQName QN_JINGLE_DRAFT_SSRC;
+extern const buzz::StaticQName QN_JINGLE_DRAFT_SSRC_GROUP;
+extern const buzz::StaticQName QN_SEMANTICS;
+extern const buzz::StaticQName QN_JINGLE_LEGACY_NOTIFY;
+extern const buzz::StaticQName QN_JINGLE_LEGACY_SOURCE;
+
+// old stuff
+#ifdef FEATURE_ENABLE_VOICEMAIL
+extern const char NS_VOICEMAIL[];
+extern const buzz::StaticQName QN_VOICEMAIL_REGARDING;
+#endif
+
+// RFC 4145, SDP setup attribute values.
+extern const char CONNECTIONROLE_ACTIVE_STR[];
+extern const char CONNECTIONROLE_PASSIVE_STR[];
+extern const char CONNECTIONROLE_ACTPASS_STR[];
+extern const char CONNECTIONROLE_HOLDCONN_STR[];
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_CONSTANTS_H_
diff --git a/p2p/base/dtlstransport.h b/p2p/base/dtlstransport.h
new file mode 100644
index 00000000..bb80dc81
--- /dev/null
+++ b/p2p/base/dtlstransport.h
@@ -0,0 +1,240 @@
+/*
+ * 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 WEBRTC_P2P_BASE_DTLSTRANSPORT_H_
+#define WEBRTC_P2P_BASE_DTLSTRANSPORT_H_
+
+#include "webrtc/p2p/base/dtlstransportchannel.h"
+#include "webrtc/p2p/base/transport.h"
+
+namespace rtc {
+class SSLIdentity;
+}
+
+namespace cricket {
+
+class PortAllocator;
+
+// Base should be a descendant of cricket::Transport
+template<class Base>
+class DtlsTransport : public Base {
+ public:
+ DtlsTransport(rtc::Thread* signaling_thread,
+ rtc::Thread* worker_thread,
+ const std::string& content_name,
+ PortAllocator* allocator,
+ rtc::SSLIdentity* identity)
+ : Base(signaling_thread, worker_thread, content_name, allocator),
+ identity_(identity),
+ secure_role_(rtc::SSL_CLIENT) {
+ }
+
+ ~DtlsTransport() {
+ Base::DestroyAllChannels();
+ }
+ virtual void SetIdentity_w(rtc::SSLIdentity* identity) {
+ identity_ = identity;
+ }
+ virtual bool GetIdentity_w(rtc::SSLIdentity** identity) {
+ if (!identity_)
+ return false;
+
+ *identity = identity_->GetReference();
+ return true;
+ }
+
+ virtual bool ApplyLocalTransportDescription_w(TransportChannelImpl* channel,
+ std::string* error_desc) {
+ rtc::SSLFingerprint* local_fp =
+ Base::local_description()->identity_fingerprint.get();
+
+ if (local_fp) {
+ // Sanity check local fingerprint.
+ if (identity_) {
+ rtc::scoped_ptr<rtc::SSLFingerprint> local_fp_tmp(
+ rtc::SSLFingerprint::Create(local_fp->algorithm,
+ identity_));
+ ASSERT(local_fp_tmp.get() != NULL);
+ if (!(*local_fp_tmp == *local_fp)) {
+ std::ostringstream desc;
+ desc << "Local fingerprint does not match identity. Expected: ";
+ desc << local_fp_tmp->ToString();
+ desc << " Got: " << local_fp->ToString();
+ return BadTransportDescription(desc.str(), error_desc);
+ }
+ } else {
+ return BadTransportDescription(
+ "Local fingerprint provided but no identity available.",
+ error_desc);
+ }
+ } else {
+ identity_ = NULL;
+ }
+
+ if (!channel->SetLocalIdentity(identity_)) {
+ return BadTransportDescription("Failed to set local identity.",
+ error_desc);
+ }
+
+ // Apply the description in the base class.
+ return Base::ApplyLocalTransportDescription_w(channel, error_desc);
+ }
+
+ virtual bool NegotiateTransportDescription_w(ContentAction local_role,
+ std::string* error_desc) {
+ if (!Base::local_description() || !Base::remote_description()) {
+ const std::string msg = "Local and Remote description must be set before "
+ "transport descriptions are negotiated";
+ return BadTransportDescription(msg, error_desc);
+ }
+
+ rtc::SSLFingerprint* local_fp =
+ Base::local_description()->identity_fingerprint.get();
+ rtc::SSLFingerprint* remote_fp =
+ Base::remote_description()->identity_fingerprint.get();
+
+ if (remote_fp && local_fp) {
+ remote_fingerprint_.reset(new rtc::SSLFingerprint(*remote_fp));
+
+ // From RFC 4145, section-4.1, The following are the values that the
+ // 'setup' attribute can take in an offer/answer exchange:
+ // Offer Answer
+ // ________________
+ // active passive / holdconn
+ // passive active / holdconn
+ // actpass active / passive / holdconn
+ // holdconn holdconn
+ //
+ // Set the role that is most conformant with RFC 5763, Section 5, bullet 1
+ // The endpoint MUST use the setup attribute defined in [RFC4145].
+ // The endpoint that is the offerer MUST use the setup attribute
+ // value of setup:actpass and be prepared to receive a client_hello
+ // before it receives the answer. The answerer MUST use either a
+ // setup attribute value of setup:active or setup:passive. Note that
+ // if the answerer uses setup:passive, then the DTLS handshake will
+ // not begin until the answerer is received, which adds additional
+ // latency. setup:active allows the answer and the DTLS handshake to
+ // occur in parallel. Thus, setup:active is RECOMMENDED. Whichever
+ // party is active MUST initiate a DTLS handshake by sending a
+ // ClientHello over each flow (host/port quartet).
+ // IOW - actpass and passive modes should be treated as server and
+ // active as client.
+ ConnectionRole local_connection_role =
+ Base::local_description()->connection_role;
+ ConnectionRole remote_connection_role =
+ Base::remote_description()->connection_role;
+
+ bool is_remote_server = false;
+ if (local_role == CA_OFFER) {
+ if (local_connection_role != CONNECTIONROLE_ACTPASS) {
+ return BadTransportDescription(
+ "Offerer must use actpass value for setup attribute.",
+ error_desc);
+ }
+
+ if (remote_connection_role == CONNECTIONROLE_ACTIVE ||
+ remote_connection_role == CONNECTIONROLE_PASSIVE ||
+ remote_connection_role == CONNECTIONROLE_NONE) {
+ is_remote_server = (remote_connection_role == CONNECTIONROLE_PASSIVE);
+ } else {
+ const std::string msg =
+ "Answerer must use either active or passive value "
+ "for setup attribute.";
+ return BadTransportDescription(msg, error_desc);
+ }
+ // If remote is NONE or ACTIVE it will act as client.
+ } else {
+ if (remote_connection_role != CONNECTIONROLE_ACTPASS &&
+ remote_connection_role != CONNECTIONROLE_NONE) {
+ return BadTransportDescription(
+ "Offerer must use actpass value for setup attribute.",
+ error_desc);
+ }
+
+ if (local_connection_role == CONNECTIONROLE_ACTIVE ||
+ local_connection_role == CONNECTIONROLE_PASSIVE) {
+ is_remote_server = (local_connection_role == CONNECTIONROLE_ACTIVE);
+ } else {
+ const std::string msg =
+ "Answerer must use either active or passive value "
+ "for setup attribute.";
+ return BadTransportDescription(msg, error_desc);
+ }
+
+ // If local is passive, local will act as server.
+ }
+
+ secure_role_ = is_remote_server ? rtc::SSL_CLIENT :
+ rtc::SSL_SERVER;
+
+ } else if (local_fp && (local_role == CA_ANSWER)) {
+ return BadTransportDescription(
+ "Local fingerprint supplied when caller didn't offer DTLS.",
+ error_desc);
+ } else {
+ // We are not doing DTLS
+ remote_fingerprint_.reset(new rtc::SSLFingerprint(
+ "", NULL, 0));
+ }
+
+ // Now run the negotiation for the base class.
+ return Base::NegotiateTransportDescription_w(local_role, error_desc);
+ }
+
+ virtual DtlsTransportChannelWrapper* CreateTransportChannel(int component) {
+ return new DtlsTransportChannelWrapper(
+ this, Base::CreateTransportChannel(component));
+ }
+
+ virtual void DestroyTransportChannel(TransportChannelImpl* channel) {
+ // Kind of ugly, but this lets us do the exact inverse of the create.
+ DtlsTransportChannelWrapper* dtls_channel =
+ static_cast<DtlsTransportChannelWrapper*>(channel);
+ TransportChannelImpl* base_channel = dtls_channel->channel();
+ delete dtls_channel;
+ Base::DestroyTransportChannel(base_channel);
+ }
+
+ virtual bool GetSslRole_w(rtc::SSLRole* ssl_role) const {
+ ASSERT(ssl_role != NULL);
+ *ssl_role = secure_role_;
+ return true;
+ }
+
+ private:
+ virtual bool ApplyNegotiatedTransportDescription_w(
+ TransportChannelImpl* channel,
+ std::string* error_desc) {
+ // Set ssl role. Role must be set before fingerprint is applied, which
+ // initiates DTLS setup.
+ if (!channel->SetSslRole(secure_role_)) {
+ return BadTransportDescription("Failed to set ssl role for the channel.",
+ error_desc);
+ }
+ // Apply remote fingerprint.
+ if (!channel->SetRemoteFingerprint(
+ remote_fingerprint_->algorithm,
+ reinterpret_cast<const uint8 *>(remote_fingerprint_->
+ digest.data()),
+ remote_fingerprint_->digest.length())) {
+ return BadTransportDescription("Failed to apply remote fingerprint.",
+ error_desc);
+ }
+ return Base::ApplyNegotiatedTransportDescription_w(channel, error_desc);
+ }
+
+ rtc::SSLIdentity* identity_;
+ rtc::SSLRole secure_role_;
+ rtc::scoped_ptr<rtc::SSLFingerprint> remote_fingerprint_;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_DTLSTRANSPORT_H_
diff --git a/p2p/base/dtlstransportchannel.cc b/p2p/base/dtlstransportchannel.cc
new file mode 100644
index 00000000..9cceca35
--- /dev/null
+++ b/p2p/base/dtlstransportchannel.cc
@@ -0,0 +1,623 @@
+/*
+ * 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.
+ */
+
+#include "webrtc/p2p/base/dtlstransportchannel.h"
+
+#include "webrtc/p2p/base/common.h"
+#include "webrtc/base/buffer.h"
+#include "webrtc/base/dscp.h"
+#include "webrtc/base/messagequeue.h"
+#include "webrtc/base/sslstreamadapter.h"
+#include "webrtc/base/stream.h"
+#include "webrtc/base/thread.h"
+
+namespace cricket {
+
+// We don't pull the RTP constants from rtputils.h, to avoid a layer violation.
+static const size_t kDtlsRecordHeaderLen = 13;
+static const size_t kMaxDtlsPacketLen = 2048;
+static const size_t kMinRtpPacketLen = 12;
+
+static bool IsDtlsPacket(const char* data, size_t len) {
+ const uint8* u = reinterpret_cast<const uint8*>(data);
+ return (len >= kDtlsRecordHeaderLen && (u[0] > 19 && u[0] < 64));
+}
+static bool IsRtpPacket(const char* data, size_t len) {
+ const uint8* u = reinterpret_cast<const uint8*>(data);
+ return (len >= kMinRtpPacketLen && (u[0] & 0xC0) == 0x80);
+}
+
+rtc::StreamResult StreamInterfaceChannel::Read(void* buffer,
+ size_t buffer_len,
+ size_t* read,
+ int* error) {
+ if (state_ == rtc::SS_CLOSED)
+ return rtc::SR_EOS;
+ if (state_ == rtc::SS_OPENING)
+ return rtc::SR_BLOCK;
+
+ return fifo_.Read(buffer, buffer_len, read, error);
+}
+
+rtc::StreamResult StreamInterfaceChannel::Write(const void* data,
+ size_t data_len,
+ size_t* written,
+ int* error) {
+ // Always succeeds, since this is an unreliable transport anyway.
+ // TODO: Should this block if channel_'s temporarily unwritable?
+ rtc::PacketOptions packet_options;
+ channel_->SendPacket(static_cast<const char*>(data), data_len,
+ packet_options);
+ if (written) {
+ *written = data_len;
+ }
+ return rtc::SR_SUCCESS;
+}
+
+bool StreamInterfaceChannel::OnPacketReceived(const char* data, size_t size) {
+ // We force a read event here to ensure that we don't overflow our FIFO.
+ // Under high packet rate this can occur if we wait for the FIFO to post its
+ // own SE_READ.
+ bool ret = (fifo_.WriteAll(data, size, NULL, NULL) == rtc::SR_SUCCESS);
+ if (ret) {
+ SignalEvent(this, rtc::SE_READ, 0);
+ }
+ return ret;
+}
+
+void StreamInterfaceChannel::OnEvent(rtc::StreamInterface* stream,
+ int sig, int err) {
+ SignalEvent(this, sig, err);
+}
+
+DtlsTransportChannelWrapper::DtlsTransportChannelWrapper(
+ Transport* transport,
+ TransportChannelImpl* channel)
+ : TransportChannelImpl(channel->content_name(), channel->component()),
+ transport_(transport),
+ worker_thread_(rtc::Thread::Current()),
+ channel_(channel),
+ downward_(NULL),
+ dtls_state_(STATE_NONE),
+ local_identity_(NULL),
+ ssl_role_(rtc::SSL_CLIENT) {
+ channel_->SignalReadableState.connect(this,
+ &DtlsTransportChannelWrapper::OnReadableState);
+ channel_->SignalWritableState.connect(this,
+ &DtlsTransportChannelWrapper::OnWritableState);
+ channel_->SignalReadPacket.connect(this,
+ &DtlsTransportChannelWrapper::OnReadPacket);
+ channel_->SignalReadyToSend.connect(this,
+ &DtlsTransportChannelWrapper::OnReadyToSend);
+ channel_->SignalRequestSignaling.connect(this,
+ &DtlsTransportChannelWrapper::OnRequestSignaling);
+ channel_->SignalCandidateReady.connect(this,
+ &DtlsTransportChannelWrapper::OnCandidateReady);
+ channel_->SignalCandidatesAllocationDone.connect(this,
+ &DtlsTransportChannelWrapper::OnCandidatesAllocationDone);
+ channel_->SignalRoleConflict.connect(this,
+ &DtlsTransportChannelWrapper::OnRoleConflict);
+ channel_->SignalRouteChange.connect(this,
+ &DtlsTransportChannelWrapper::OnRouteChange);
+ channel_->SignalConnectionRemoved.connect(this,
+ &DtlsTransportChannelWrapper::OnConnectionRemoved);
+}
+
+DtlsTransportChannelWrapper::~DtlsTransportChannelWrapper() {
+}
+
+void DtlsTransportChannelWrapper::Connect() {
+ // We should only get a single call to Connect.
+ ASSERT(dtls_state_ == STATE_NONE ||
+ dtls_state_ == STATE_OFFERED ||
+ dtls_state_ == STATE_ACCEPTED);
+ channel_->Connect();
+}
+
+void DtlsTransportChannelWrapper::Reset() {
+ channel_->Reset();
+ set_writable(false);
+ set_readable(false);
+
+ // Re-call SetupDtls()
+ if (!SetupDtls()) {
+ LOG_J(LS_ERROR, this) << "Error re-initializing DTLS";
+ dtls_state_ = STATE_CLOSED;
+ return;
+ }
+
+ dtls_state_ = STATE_ACCEPTED;
+}
+
+bool DtlsTransportChannelWrapper::SetLocalIdentity(
+ rtc::SSLIdentity* identity) {
+ if (dtls_state_ != STATE_NONE) {
+ if (identity == local_identity_) {
+ // This may happen during renegotiation.
+ LOG_J(LS_INFO, this) << "Ignoring identical DTLS identity";
+ return true;
+ } else {
+ LOG_J(LS_ERROR, this) << "Can't change DTLS local identity in this state";
+ return false;
+ }
+ }
+
+ if (identity) {
+ local_identity_ = identity;
+ dtls_state_ = STATE_OFFERED;
+ } else {
+ LOG_J(LS_INFO, this) << "NULL DTLS identity supplied. Not doing DTLS";
+ }
+
+ return true;
+}
+
+bool DtlsTransportChannelWrapper::GetLocalIdentity(
+ rtc::SSLIdentity** identity) const {
+ if (!local_identity_)
+ return false;
+
+ *identity = local_identity_->GetReference();
+ return true;
+}
+
+bool DtlsTransportChannelWrapper::SetSslRole(rtc::SSLRole role) {
+ if (dtls_state_ == STATE_OPEN) {
+ if (ssl_role_ != role) {
+ LOG(LS_ERROR) << "SSL Role can't be reversed after the session is setup.";
+ return false;
+ }
+ return true;
+ }
+
+ ssl_role_ = role;
+ return true;
+}
+
+bool DtlsTransportChannelWrapper::GetSslRole(rtc::SSLRole* role) const {
+ *role = ssl_role_;
+ return true;
+}
+
+bool DtlsTransportChannelWrapper::SetRemoteFingerprint(
+ const std::string& digest_alg,
+ const uint8* digest,
+ size_t digest_len) {
+
+ rtc::Buffer remote_fingerprint_value(digest, digest_len);
+
+ if (dtls_state_ != STATE_NONE &&
+ remote_fingerprint_value_ == remote_fingerprint_value &&
+ !digest_alg.empty()) {
+ // This may happen during renegotiation.
+ LOG_J(LS_INFO, this) << "Ignoring identical remote DTLS fingerprint";
+ return true;
+ }
+
+ // Allow SetRemoteFingerprint with a NULL digest even if SetLocalIdentity
+ // hasn't been called.
+ if (dtls_state_ > STATE_OFFERED ||
+ (dtls_state_ == STATE_NONE && !digest_alg.empty())) {
+ LOG_J(LS_ERROR, this) << "Can't set DTLS remote settings in this state.";
+ return false;
+ }
+
+ if (digest_alg.empty()) {
+ LOG_J(LS_INFO, this) << "Other side didn't support DTLS.";
+ dtls_state_ = STATE_NONE;
+ return true;
+ }
+
+ // At this point we know we are doing DTLS
+ remote_fingerprint_value.TransferTo(&remote_fingerprint_value_);
+ remote_fingerprint_algorithm_ = digest_alg;
+
+ if (!SetupDtls()) {
+ dtls_state_ = STATE_CLOSED;
+ return false;
+ }
+
+ dtls_state_ = STATE_ACCEPTED;
+ return true;
+}
+
+bool DtlsTransportChannelWrapper::GetRemoteCertificate(
+ rtc::SSLCertificate** cert) const {
+ if (!dtls_)
+ return false;
+
+ return dtls_->GetPeerCertificate(cert);
+}
+
+bool DtlsTransportChannelWrapper::SetupDtls() {
+ StreamInterfaceChannel* downward =
+ new StreamInterfaceChannel(worker_thread_, channel_);
+
+ dtls_.reset(rtc::SSLStreamAdapter::Create(downward));
+ if (!dtls_) {
+ LOG_J(LS_ERROR, this) << "Failed to create DTLS adapter.";
+ delete downward;
+ return false;
+ }
+
+ downward_ = downward;
+
+ dtls_->SetIdentity(local_identity_->GetReference());
+ dtls_->SetMode(rtc::SSL_MODE_DTLS);
+ dtls_->SetServerRole(ssl_role_);
+ dtls_->SignalEvent.connect(this, &DtlsTransportChannelWrapper::OnDtlsEvent);
+ if (!dtls_->SetPeerCertificateDigest(
+ remote_fingerprint_algorithm_,
+ reinterpret_cast<unsigned char *>(remote_fingerprint_value_.data()),
+ remote_fingerprint_value_.length())) {
+ LOG_J(LS_ERROR, this) << "Couldn't set DTLS certificate digest.";
+ return false;
+ }
+
+ // Set up DTLS-SRTP, if it's been enabled.
+ if (!srtp_ciphers_.empty()) {
+ if (!dtls_->SetDtlsSrtpCiphers(srtp_ciphers_)) {
+ LOG_J(LS_ERROR, this) << "Couldn't set DTLS-SRTP ciphers.";
+ return false;
+ }
+ } else {
+ LOG_J(LS_INFO, this) << "Not using DTLS.";
+ }
+
+ LOG_J(LS_INFO, this) << "DTLS setup complete.";
+ return true;
+}
+
+bool DtlsTransportChannelWrapper::SetSrtpCiphers(
+ const std::vector<std::string>& ciphers) {
+ if (srtp_ciphers_ == ciphers)
+ return true;
+
+ if (dtls_state_ == STATE_STARTED) {
+ LOG(LS_WARNING) << "Ignoring new SRTP ciphers while DTLS is negotiating";
+ return true;
+ }
+
+ if (dtls_state_ == STATE_OPEN) {
+ // We don't support DTLS renegotiation currently. If new set of srtp ciphers
+ // are different than what's being used currently, we will not use it.
+ // So for now, let's be happy (or sad) with a warning message.
+ std::string current_srtp_cipher;
+ if (!dtls_->GetDtlsSrtpCipher(&current_srtp_cipher)) {
+ LOG(LS_ERROR) << "Failed to get the current SRTP cipher for DTLS channel";
+ return false;
+ }
+ const std::vector<std::string>::const_iterator iter =
+ std::find(ciphers.begin(), ciphers.end(), current_srtp_cipher);
+ if (iter == ciphers.end()) {
+ std::string requested_str;
+ for (size_t i = 0; i < ciphers.size(); ++i) {
+ requested_str.append(" ");
+ requested_str.append(ciphers[i]);
+ requested_str.append(" ");
+ }
+ LOG(LS_WARNING) << "Ignoring new set of SRTP ciphers, as DTLS "
+ << "renegotiation is not supported currently "
+ << "current cipher = " << current_srtp_cipher << " and "
+ << "requested = " << "[" << requested_str << "]";
+ }
+ return true;
+ }
+
+ if (dtls_state_ != STATE_NONE &&
+ dtls_state_ != STATE_OFFERED &&
+ dtls_state_ != STATE_ACCEPTED) {
+ ASSERT(false);
+ return false;
+ }
+
+ srtp_ciphers_ = ciphers;
+ return true;
+}
+
+bool DtlsTransportChannelWrapper::GetSrtpCipher(std::string* cipher) {
+ if (dtls_state_ != STATE_OPEN) {
+ return false;
+ }
+
+ return dtls_->GetDtlsSrtpCipher(cipher);
+}
+
+
+// Called from upper layers to send a media packet.
+int DtlsTransportChannelWrapper::SendPacket(
+ const char* data, size_t size,
+ const rtc::PacketOptions& options, int flags) {
+ int result = -1;
+
+ switch (dtls_state_) {
+ case STATE_OFFERED:
+ // We don't know if we are doing DTLS yet, so we can't send a packet.
+ // TODO(ekr@rtfm.com): assert here?
+ result = -1;
+ break;
+
+ case STATE_STARTED:
+ case STATE_ACCEPTED:
+ // Can't send data until the connection is active
+ result = -1;
+ break;
+
+ case STATE_OPEN:
+ if (flags & PF_SRTP_BYPASS) {
+ ASSERT(!srtp_ciphers_.empty());
+ if (!IsRtpPacket(data, size)) {
+ result = -1;
+ break;
+ }
+
+ result = channel_->SendPacket(data, size, options);
+ } else {
+ result = (dtls_->WriteAll(data, size, NULL, NULL) ==
+ rtc::SR_SUCCESS) ? static_cast<int>(size) : -1;
+ }
+ break;
+ // Not doing DTLS.
+ case STATE_NONE:
+ result = channel_->SendPacket(data, size, options);
+ break;
+
+ case STATE_CLOSED: // Can't send anything when we're closed.
+ return -1;
+ }
+
+ return result;
+}
+
+// The state transition logic here is as follows:
+// (1) If we're not doing DTLS-SRTP, then the state is just the
+// state of the underlying impl()
+// (2) If we're doing DTLS-SRTP:
+// - Prior to the DTLS handshake, the state is neither readable or
+// writable
+// - When the impl goes writable for the first time we
+// start the DTLS handshake
+// - Once the DTLS handshake completes, the state is that of the
+// impl again
+void DtlsTransportChannelWrapper::OnReadableState(TransportChannel* channel) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ ASSERT(channel == channel_);
+ LOG_J(LS_VERBOSE, this)
+ << "DTLSTransportChannelWrapper: channel readable state changed.";
+
+ if (dtls_state_ == STATE_NONE || dtls_state_ == STATE_OPEN) {
+ set_readable(channel_->readable());
+ // Note: SignalReadableState fired by set_readable.
+ }
+}
+
+void DtlsTransportChannelWrapper::OnWritableState(TransportChannel* channel) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ ASSERT(channel == channel_);
+ LOG_J(LS_VERBOSE, this)
+ << "DTLSTransportChannelWrapper: channel writable state changed.";
+
+ switch (dtls_state_) {
+ case STATE_NONE:
+ case STATE_OPEN:
+ set_writable(channel_->writable());
+ // Note: SignalWritableState fired by set_writable.
+ break;
+
+ case STATE_OFFERED:
+ // Do nothing
+ break;
+
+ case STATE_ACCEPTED:
+ if (!MaybeStartDtls()) {
+ // This should never happen:
+ // Because we are operating in a nonblocking mode and all
+ // incoming packets come in via OnReadPacket(), which rejects
+ // packets in this state, the incoming queue must be empty. We
+ // ignore write errors, thus any errors must be because of
+ // configuration and therefore are our fault.
+ // Note that in non-debug configurations, failure in
+ // MaybeStartDtls() changes the state to STATE_CLOSED.
+ ASSERT(false);
+ }
+ break;
+
+ case STATE_STARTED:
+ // Do nothing
+ break;
+
+ case STATE_CLOSED:
+ // Should not happen. Do nothing
+ break;
+ }
+}
+
+void DtlsTransportChannelWrapper::OnReadPacket(
+ TransportChannel* channel, const char* data, size_t size,
+ const rtc::PacketTime& packet_time, int flags) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ ASSERT(channel == channel_);
+ ASSERT(flags == 0);
+
+ switch (dtls_state_) {
+ case STATE_NONE:
+ // We are not doing DTLS
+ SignalReadPacket(this, data, size, packet_time, 0);
+ break;
+
+ case STATE_OFFERED:
+ // Currently drop the packet, but we might in future
+ // decide to take this as evidence that the other
+ // side is ready to do DTLS and start the handshake
+ // on our end
+ LOG_J(LS_WARNING, this) << "Received packet before we know if we are "
+ << "doing DTLS or not; dropping.";
+ break;
+
+ case STATE_ACCEPTED:
+ // Drop packets received before DTLS has actually started
+ LOG_J(LS_INFO, this) << "Dropping packet received before DTLS started.";
+ break;
+
+ case STATE_STARTED:
+ case STATE_OPEN:
+ // We should only get DTLS or SRTP packets; STUN's already been demuxed.
+ // Is this potentially a DTLS packet?
+ if (IsDtlsPacket(data, size)) {
+ if (!HandleDtlsPacket(data, size)) {
+ LOG_J(LS_ERROR, this) << "Failed to handle DTLS packet.";
+ return;
+ }
+ } else {
+ // Not a DTLS packet; our handshake should be complete by now.
+ if (dtls_state_ != STATE_OPEN) {
+ LOG_J(LS_ERROR, this) << "Received non-DTLS packet before DTLS "
+ << "complete.";
+ return;
+ }
+
+ // And it had better be a SRTP packet.
+ if (!IsRtpPacket(data, size)) {
+ LOG_J(LS_ERROR, this) << "Received unexpected non-DTLS packet.";
+ return;
+ }
+
+ // Sanity check.
+ ASSERT(!srtp_ciphers_.empty());
+
+ // Signal this upwards as a bypass packet.
+ SignalReadPacket(this, data, size, packet_time, PF_SRTP_BYPASS);
+ }
+ break;
+ case STATE_CLOSED:
+ // This shouldn't be happening. Drop the packet
+ break;
+ }
+}
+
+void DtlsTransportChannelWrapper::OnReadyToSend(TransportChannel* channel) {
+ if (writable()) {
+ SignalReadyToSend(this);
+ }
+}
+
+void DtlsTransportChannelWrapper::OnDtlsEvent(rtc::StreamInterface* dtls,
+ int sig, int err) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ ASSERT(dtls == dtls_.get());
+ if (sig & rtc::SE_OPEN) {
+ // This is the first time.
+ LOG_J(LS_INFO, this) << "DTLS handshake complete.";
+ if (dtls_->GetState() == rtc::SS_OPEN) {
+ // The check for OPEN shouldn't be necessary but let's make
+ // sure we don't accidentally frob the state if it's closed.
+ dtls_state_ = STATE_OPEN;
+
+ set_readable(true);
+ set_writable(true);
+ }
+ }
+ if (sig & rtc::SE_READ) {
+ char buf[kMaxDtlsPacketLen];
+ size_t read;
+ if (dtls_->Read(buf, sizeof(buf), &read, NULL) == rtc::SR_SUCCESS) {
+ SignalReadPacket(this, buf, read, rtc::CreatePacketTime(0), 0);
+ }
+ }
+ if (sig & rtc::SE_CLOSE) {
+ ASSERT(sig == rtc::SE_CLOSE); // SE_CLOSE should be by itself.
+ if (!err) {
+ LOG_J(LS_INFO, this) << "DTLS channel closed";
+ } else {
+ LOG_J(LS_INFO, this) << "DTLS channel error, code=" << err;
+ }
+
+ set_readable(false);
+ set_writable(false);
+ dtls_state_ = STATE_CLOSED;
+ }
+}
+
+bool DtlsTransportChannelWrapper::MaybeStartDtls() {
+ if (channel_->writable()) {
+ if (dtls_->StartSSLWithPeer()) {
+ LOG_J(LS_ERROR, this) << "Couldn't start DTLS handshake";
+ dtls_state_ = STATE_CLOSED;
+ return false;
+ }
+ LOG_J(LS_INFO, this)
+ << "DtlsTransportChannelWrapper: Started DTLS handshake";
+
+ dtls_state_ = STATE_STARTED;
+ }
+ return true;
+}
+
+// Called from OnReadPacket when a DTLS packet is received.
+bool DtlsTransportChannelWrapper::HandleDtlsPacket(const char* data,
+ size_t size) {
+ // Sanity check we're not passing junk that
+ // just looks like DTLS.
+ const uint8* tmp_data = reinterpret_cast<const uint8* >(data);
+ size_t tmp_size = size;
+ while (tmp_size > 0) {
+ if (tmp_size < kDtlsRecordHeaderLen)
+ return false; // Too short for the header
+
+ size_t record_len = (tmp_data[11] << 8) | (tmp_data[12]);
+ if ((record_len + kDtlsRecordHeaderLen) > tmp_size)
+ return false; // Body too short
+
+ tmp_data += record_len + kDtlsRecordHeaderLen;
+ tmp_size -= record_len + kDtlsRecordHeaderLen;
+ }
+
+ // Looks good. Pass to the SIC which ends up being passed to
+ // the DTLS stack.
+ return downward_->OnPacketReceived(data, size);
+}
+
+void DtlsTransportChannelWrapper::OnRequestSignaling(
+ TransportChannelImpl* channel) {
+ ASSERT(channel == channel_);
+ SignalRequestSignaling(this);
+}
+
+void DtlsTransportChannelWrapper::OnCandidateReady(
+ TransportChannelImpl* channel, const Candidate& c) {
+ ASSERT(channel == channel_);
+ SignalCandidateReady(this, c);
+}
+
+void DtlsTransportChannelWrapper::OnCandidatesAllocationDone(
+ TransportChannelImpl* channel) {
+ ASSERT(channel == channel_);
+ SignalCandidatesAllocationDone(this);
+}
+
+void DtlsTransportChannelWrapper::OnRoleConflict(
+ TransportChannelImpl* channel) {
+ ASSERT(channel == channel_);
+ SignalRoleConflict(this);
+}
+
+void DtlsTransportChannelWrapper::OnRouteChange(
+ TransportChannel* channel, const Candidate& candidate) {
+ ASSERT(channel == channel_);
+ SignalRouteChange(this, candidate);
+}
+
+void DtlsTransportChannelWrapper::OnConnectionRemoved(
+ TransportChannelImpl* channel) {
+ ASSERT(channel == channel_);
+ SignalConnectionRemoved(this);
+}
+
+} // namespace cricket
diff --git a/p2p/base/dtlstransportchannel.h b/p2p/base/dtlstransportchannel.h
new file mode 100644
index 00000000..d12f724d
--- /dev/null
+++ b/p2p/base/dtlstransportchannel.h
@@ -0,0 +1,246 @@
+/*
+ * 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 WEBRTC_P2P_BASE_DTLSTRANSPORTCHANNEL_H_
+#define WEBRTC_P2P_BASE_DTLSTRANSPORTCHANNEL_H_
+
+#include <string>
+#include <vector>
+
+#include "webrtc/p2p/base/transportchannelimpl.h"
+#include "webrtc/base/buffer.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/sslstreamadapter.h"
+#include "webrtc/base/stream.h"
+
+namespace cricket {
+
+// A bridge between a packet-oriented/channel-type interface on
+// the bottom and a StreamInterface on the top.
+class StreamInterfaceChannel : public rtc::StreamInterface,
+ public sigslot::has_slots<> {
+ public:
+ StreamInterfaceChannel(rtc::Thread* owner, TransportChannel* channel)
+ : channel_(channel),
+ state_(rtc::SS_OPEN),
+ fifo_(kFifoSize, owner) {
+ fifo_.SignalEvent.connect(this, &StreamInterfaceChannel::OnEvent);
+ }
+
+ // Push in a packet; this gets pulled out from Read().
+ bool OnPacketReceived(const char* data, size_t size);
+
+ // Implementations of StreamInterface
+ virtual rtc::StreamState GetState() const { return state_; }
+ virtual void Close() { state_ = rtc::SS_CLOSED; }
+ virtual rtc::StreamResult Read(void* buffer, size_t buffer_len,
+ size_t* read, int* error);
+ virtual rtc::StreamResult Write(const void* data, size_t data_len,
+ size_t* written, int* error);
+
+ private:
+ static const size_t kFifoSize = 8192;
+
+ // Forward events
+ virtual void OnEvent(rtc::StreamInterface* stream, int sig, int err);
+
+ TransportChannel* channel_; // owned by DtlsTransportChannelWrapper
+ rtc::StreamState state_;
+ rtc::FifoBuffer fifo_;
+
+ DISALLOW_COPY_AND_ASSIGN(StreamInterfaceChannel);
+};
+
+
+// This class provides a DTLS SSLStreamAdapter inside a TransportChannel-style
+// packet-based interface, wrapping an existing TransportChannel instance
+// (e.g a P2PTransportChannel)
+// Here's the way this works:
+//
+// DtlsTransportChannelWrapper {
+// SSLStreamAdapter* dtls_ {
+// StreamInterfaceChannel downward_ {
+// TransportChannelImpl* channel_;
+// }
+// }
+// }
+//
+// - Data which comes into DtlsTransportChannelWrapper from the underlying
+// channel_ via OnReadPacket() is checked for whether it is DTLS
+// or not, and if it is, is passed to DtlsTransportChannelWrapper::
+// HandleDtlsPacket, which pushes it into to downward_.
+// dtls_ is listening for events on downward_, so it immediately calls
+// downward_->Read().
+//
+// - Data written to DtlsTransportChannelWrapper is passed either to
+// downward_ or directly to channel_, depending on whether DTLS is
+// negotiated and whether the flags include PF_SRTP_BYPASS
+//
+// - The SSLStreamAdapter writes to downward_->Write()
+// which translates it into packet writes on channel_.
+class DtlsTransportChannelWrapper : public TransportChannelImpl {
+ public:
+ enum State {
+ STATE_NONE, // No state or rejected.
+ STATE_OFFERED, // Our identity has been set.
+ STATE_ACCEPTED, // The other side sent a fingerprint.
+ STATE_STARTED, // We are negotiating.
+ STATE_OPEN, // Negotiation complete.
+ STATE_CLOSED // Connection closed.
+ };
+
+ // The parameters here are:
+ // transport -- the DtlsTransport that created us
+ // channel -- the TransportChannel we are wrapping
+ DtlsTransportChannelWrapper(Transport* transport,
+ TransportChannelImpl* channel);
+ virtual ~DtlsTransportChannelWrapper();
+
+ virtual void SetIceRole(IceRole role) {
+ channel_->SetIceRole(role);
+ }
+ virtual IceRole GetIceRole() const {
+ return channel_->GetIceRole();
+ }
+ virtual size_t GetConnectionCount() const {
+ return channel_->GetConnectionCount();
+ }
+ virtual bool SetLocalIdentity(rtc::SSLIdentity *identity);
+ virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const;
+
+ virtual bool SetRemoteFingerprint(const std::string& digest_alg,
+ const uint8* digest,
+ size_t digest_len);
+ virtual bool IsDtlsActive() const { return dtls_state_ != STATE_NONE; }
+
+ // Called to send a packet (via DTLS, if turned on).
+ virtual int SendPacket(const char* data, size_t size,
+ const rtc::PacketOptions& options,
+ int flags);
+
+ // TransportChannel calls that we forward to the wrapped transport.
+ virtual int SetOption(rtc::Socket::Option opt, int value) {
+ return channel_->SetOption(opt, value);
+ }
+ virtual int GetError() {
+ return channel_->GetError();
+ }
+ virtual bool GetStats(ConnectionInfos* infos) {
+ return channel_->GetStats(infos);
+ }
+ virtual const std::string SessionId() const {
+ return channel_->SessionId();
+ }
+
+ // Set up the ciphers to use for DTLS-SRTP. If this method is not called
+ // before DTLS starts, or |ciphers| is empty, SRTP keys won't be negotiated.
+ // This method should be called before SetupDtls.
+ virtual bool SetSrtpCiphers(const std::vector<std::string>& ciphers);
+
+ // Find out which DTLS-SRTP cipher was negotiated
+ virtual bool GetSrtpCipher(std::string* cipher);
+
+ virtual bool GetSslRole(rtc::SSLRole* role) const;
+ virtual bool SetSslRole(rtc::SSLRole role);
+
+ // Once DTLS has been established, this method retrieves the certificate in
+ // use by the remote peer, for use in external identity verification.
+ virtual bool GetRemoteCertificate(rtc::SSLCertificate** cert) const;
+
+ // Once DTLS has established (i.e., this channel is writable), this method
+ // extracts the keys negotiated during the DTLS handshake, for use in external
+ // encryption. DTLS-SRTP uses this to extract the needed SRTP keys.
+ // See the SSLStreamAdapter documentation for info on the specific parameters.
+ virtual bool ExportKeyingMaterial(const std::string& label,
+ const uint8* context,
+ size_t context_len,
+ bool use_context,
+ uint8* result,
+ size_t result_len) {
+ return (dtls_.get()) ? dtls_->ExportKeyingMaterial(label, context,
+ context_len,
+ use_context,
+ result, result_len)
+ : false;
+ }
+
+ // TransportChannelImpl calls.
+ virtual Transport* GetTransport() {
+ return transport_;
+ }
+ virtual void SetIceTiebreaker(uint64 tiebreaker) {
+ channel_->SetIceTiebreaker(tiebreaker);
+ }
+ virtual bool GetIceProtocolType(IceProtocolType* type) const {
+ return channel_->GetIceProtocolType(type);
+ }
+ virtual void SetIceProtocolType(IceProtocolType type) {
+ channel_->SetIceProtocolType(type);
+ }
+ virtual void SetIceCredentials(const std::string& ice_ufrag,
+ const std::string& ice_pwd) {
+ channel_->SetIceCredentials(ice_ufrag, ice_pwd);
+ }
+ virtual void SetRemoteIceCredentials(const std::string& ice_ufrag,
+ const std::string& ice_pwd) {
+ channel_->SetRemoteIceCredentials(ice_ufrag, ice_pwd);
+ }
+ virtual void SetRemoteIceMode(IceMode mode) {
+ channel_->SetRemoteIceMode(mode);
+ }
+
+ virtual void Connect();
+ virtual void Reset();
+
+ virtual void OnSignalingReady() {
+ channel_->OnSignalingReady();
+ }
+ virtual void OnCandidate(const Candidate& candidate) {
+ channel_->OnCandidate(candidate);
+ }
+
+ // Needed by DtlsTransport.
+ TransportChannelImpl* channel() { return channel_; }
+
+ private:
+ void OnReadableState(TransportChannel* channel);
+ void OnWritableState(TransportChannel* channel);
+ void OnReadPacket(TransportChannel* channel, const char* data, size_t size,
+ const rtc::PacketTime& packet_time, int flags);
+ void OnReadyToSend(TransportChannel* channel);
+ void OnDtlsEvent(rtc::StreamInterface* stream_, int sig, int err);
+ bool SetupDtls();
+ bool MaybeStartDtls();
+ bool HandleDtlsPacket(const char* data, size_t size);
+ void OnRequestSignaling(TransportChannelImpl* channel);
+ void OnCandidateReady(TransportChannelImpl* channel, const Candidate& c);
+ void OnCandidatesAllocationDone(TransportChannelImpl* channel);
+ void OnRoleConflict(TransportChannelImpl* channel);
+ void OnRouteChange(TransportChannel* channel, const Candidate& candidate);
+ void OnConnectionRemoved(TransportChannelImpl* channel);
+
+ Transport* transport_; // The transport_ that created us.
+ rtc::Thread* worker_thread_; // Everything should occur on this thread.
+ TransportChannelImpl* channel_; // Underlying channel, owned by transport_.
+ rtc::scoped_ptr<rtc::SSLStreamAdapter> dtls_; // The DTLS stream
+ StreamInterfaceChannel* downward_; // Wrapper for channel_, owned by dtls_.
+ std::vector<std::string> srtp_ciphers_; // SRTP ciphers to use with DTLS.
+ State dtls_state_;
+ rtc::SSLIdentity* local_identity_;
+ rtc::SSLRole ssl_role_;
+ rtc::Buffer remote_fingerprint_value_;
+ std::string remote_fingerprint_algorithm_;
+
+ DISALLOW_COPY_AND_ASSIGN(DtlsTransportChannelWrapper);
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_DTLSTRANSPORTCHANNEL_H_
diff --git a/p2p/base/dtlstransportchannel_unittest.cc b/p2p/base/dtlstransportchannel_unittest.cc
new file mode 100644
index 00000000..52f8c1e7
--- /dev/null
+++ b/p2p/base/dtlstransportchannel_unittest.cc
@@ -0,0 +1,823 @@
+/*
+ * 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.
+ */
+
+#include <set>
+
+#include "webrtc/p2p/base/dtlstransport.h"
+#include "webrtc/p2p/base/fakesession.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/dscp.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/ssladapter.h"
+#include "webrtc/base/sslidentity.h"
+#include "webrtc/base/sslstreamadapter.h"
+#include "webrtc/base/stringutils.h"
+#include "webrtc/base/thread.h"
+
+#define MAYBE_SKIP_TEST(feature) \
+ if (!(rtc::SSLStreamAdapter::feature())) { \
+ LOG(LS_INFO) << "Feature disabled... skipping"; \
+ return; \
+ }
+
+static const char AES_CM_128_HMAC_SHA1_80[] = "AES_CM_128_HMAC_SHA1_80";
+static const char kIceUfrag1[] = "TESTICEUFRAG0001";
+static const char kIcePwd1[] = "TESTICEPWD00000000000001";
+static const size_t kPacketNumOffset = 8;
+static const size_t kPacketHeaderLen = 12;
+
+static bool IsRtpLeadByte(uint8 b) {
+ return ((b & 0xC0) == 0x80);
+}
+
+using cricket::ConnectionRole;
+
+enum Flags { NF_REOFFER = 0x1, NF_EXPECT_FAILURE = 0x2 };
+
+class DtlsTestClient : public sigslot::has_slots<> {
+ public:
+ DtlsTestClient(const std::string& name,
+ rtc::Thread* signaling_thread,
+ rtc::Thread* worker_thread) :
+ name_(name),
+ signaling_thread_(signaling_thread),
+ worker_thread_(worker_thread),
+ protocol_(cricket::ICEPROTO_GOOGLE),
+ packet_size_(0),
+ use_dtls_srtp_(false),
+ negotiated_dtls_(false),
+ received_dtls_client_hello_(false),
+ received_dtls_server_hello_(false) {
+ }
+ void SetIceProtocol(cricket::TransportProtocol proto) {
+ protocol_ = proto;
+ }
+ void CreateIdentity() {
+ identity_.reset(rtc::SSLIdentity::Generate(name_));
+ }
+ rtc::SSLIdentity* identity() { return identity_.get(); }
+ void SetupSrtp() {
+ ASSERT(identity_.get() != NULL);
+ use_dtls_srtp_ = true;
+ }
+ void SetupChannels(int count, cricket::IceRole role) {
+ transport_.reset(new cricket::DtlsTransport<cricket::FakeTransport>(
+ signaling_thread_, worker_thread_, "dtls content name", NULL,
+ identity_.get()));
+ transport_->SetAsync(true);
+ transport_->SetIceRole(role);
+ transport_->SetIceTiebreaker(
+ (role == cricket::ICEROLE_CONTROLLING) ? 1 : 2);
+ transport_->SignalWritableState.connect(this,
+ &DtlsTestClient::OnTransportWritableState);
+
+ for (int i = 0; i < count; ++i) {
+ cricket::DtlsTransportChannelWrapper* channel =
+ static_cast<cricket::DtlsTransportChannelWrapper*>(
+ transport_->CreateChannel(i));
+ ASSERT_TRUE(channel != NULL);
+ channel->SignalWritableState.connect(this,
+ &DtlsTestClient::OnTransportChannelWritableState);
+ channel->SignalReadPacket.connect(this,
+ &DtlsTestClient::OnTransportChannelReadPacket);
+ channels_.push_back(channel);
+
+ // Hook the raw packets so that we can verify they are encrypted.
+ channel->channel()->SignalReadPacket.connect(
+ this, &DtlsTestClient::OnFakeTransportChannelReadPacket);
+ }
+ }
+
+ cricket::Transport* transport() { return transport_.get(); }
+
+ cricket::FakeTransportChannel* GetFakeChannel(int component) {
+ cricket::TransportChannelImpl* ch = transport_->GetChannel(component);
+ cricket::DtlsTransportChannelWrapper* wrapper =
+ static_cast<cricket::DtlsTransportChannelWrapper*>(ch);
+ return (wrapper) ?
+ static_cast<cricket::FakeTransportChannel*>(wrapper->channel()) : NULL;
+ }
+
+ // Offer DTLS if we have an identity; pass in a remote fingerprint only if
+ // both sides support DTLS.
+ void Negotiate(DtlsTestClient* peer, cricket::ContentAction action,
+ ConnectionRole local_role, ConnectionRole remote_role,
+ int flags) {
+ Negotiate(identity_.get(), (identity_) ? peer->identity_.get() : NULL,
+ action, local_role, remote_role, flags);
+ }
+
+ // Allow any DTLS configuration to be specified (including invalid ones).
+ void Negotiate(rtc::SSLIdentity* local_identity,
+ rtc::SSLIdentity* remote_identity,
+ cricket::ContentAction action,
+ ConnectionRole local_role,
+ ConnectionRole remote_role,
+ int flags) {
+ rtc::scoped_ptr<rtc::SSLFingerprint> local_fingerprint;
+ rtc::scoped_ptr<rtc::SSLFingerprint> remote_fingerprint;
+ if (local_identity) {
+ local_fingerprint.reset(rtc::SSLFingerprint::Create(
+ rtc::DIGEST_SHA_1, local_identity));
+ ASSERT_TRUE(local_fingerprint.get() != NULL);
+ }
+ if (remote_identity) {
+ remote_fingerprint.reset(rtc::SSLFingerprint::Create(
+ rtc::DIGEST_SHA_1, remote_identity));
+ ASSERT_TRUE(remote_fingerprint.get() != NULL);
+ }
+
+ if (use_dtls_srtp_ && !(flags & NF_REOFFER)) {
+ // SRTP ciphers will be set only in the beginning.
+ for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it =
+ channels_.begin(); it != channels_.end(); ++it) {
+ std::vector<std::string> ciphers;
+ ciphers.push_back(AES_CM_128_HMAC_SHA1_80);
+ ASSERT_TRUE((*it)->SetSrtpCiphers(ciphers));
+ }
+ }
+
+ std::string transport_type = (protocol_ == cricket::ICEPROTO_GOOGLE) ?
+ cricket::NS_GINGLE_P2P : cricket::NS_JINGLE_ICE_UDP;
+ cricket::TransportDescription local_desc(
+ transport_type, std::vector<std::string>(), kIceUfrag1, kIcePwd1,
+ cricket::ICEMODE_FULL, local_role,
+ // If remote if the offerer and has no DTLS support, answer will be
+ // without any fingerprint.
+ (action == cricket::CA_ANSWER && !remote_identity) ?
+ NULL : local_fingerprint.get(),
+ cricket::Candidates());
+
+ cricket::TransportDescription remote_desc(
+ transport_type, std::vector<std::string>(), kIceUfrag1, kIcePwd1,
+ cricket::ICEMODE_FULL, remote_role, remote_fingerprint.get(),
+ cricket::Candidates());
+
+ bool expect_success = (flags & NF_EXPECT_FAILURE) ? false : true;
+ // If |expect_success| is false, expect SRTD or SLTD to fail when
+ // content action is CA_ANSWER.
+ if (action == cricket::CA_OFFER) {
+ ASSERT_TRUE(transport_->SetLocalTransportDescription(
+ local_desc, cricket::CA_OFFER, NULL));
+ ASSERT_EQ(expect_success, transport_->SetRemoteTransportDescription(
+ remote_desc, cricket::CA_ANSWER, NULL));
+ } else {
+ ASSERT_TRUE(transport_->SetRemoteTransportDescription(
+ remote_desc, cricket::CA_OFFER, NULL));
+ ASSERT_EQ(expect_success, transport_->SetLocalTransportDescription(
+ local_desc, cricket::CA_ANSWER, NULL));
+ }
+ negotiated_dtls_ = (local_identity && remote_identity);
+ }
+
+ bool Connect(DtlsTestClient* peer) {
+ transport_->ConnectChannels();
+ transport_->SetDestination(peer->transport_.get());
+ return true;
+ }
+
+ bool writable() const { return transport_->writable(); }
+
+ void CheckRole(rtc::SSLRole role) {
+ if (role == rtc::SSL_CLIENT) {
+ ASSERT_FALSE(received_dtls_client_hello_);
+ ASSERT_TRUE(received_dtls_server_hello_);
+ } else {
+ ASSERT_TRUE(received_dtls_client_hello_);
+ ASSERT_FALSE(received_dtls_server_hello_);
+ }
+ }
+
+ void CheckSrtp(const std::string& expected_cipher) {
+ for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it =
+ channels_.begin(); it != channels_.end(); ++it) {
+ std::string cipher;
+
+ bool rv = (*it)->GetSrtpCipher(&cipher);
+ if (negotiated_dtls_ && !expected_cipher.empty()) {
+ ASSERT_TRUE(rv);
+
+ ASSERT_EQ(cipher, expected_cipher);
+ } else {
+ ASSERT_FALSE(rv);
+ }
+ }
+ }
+
+ void SendPackets(size_t channel, size_t size, size_t count, bool srtp) {
+ ASSERT(channel < channels_.size());
+ rtc::scoped_ptr<char[]> packet(new char[size]);
+ size_t sent = 0;
+ do {
+ // Fill the packet with a known value and a sequence number to check
+ // against, and make sure that it doesn't look like DTLS.
+ memset(packet.get(), sent & 0xff, size);
+ packet[0] = (srtp) ? 0x80 : 0x00;
+ rtc::SetBE32(packet.get() + kPacketNumOffset,
+ static_cast<uint32>(sent));
+
+ // Only set the bypass flag if we've activated DTLS.
+ int flags = (identity_.get() && srtp) ? cricket::PF_SRTP_BYPASS : 0;
+ rtc::PacketOptions packet_options;
+ int rv = channels_[channel]->SendPacket(
+ packet.get(), size, packet_options, flags);
+ ASSERT_GT(rv, 0);
+ ASSERT_EQ(size, static_cast<size_t>(rv));
+ ++sent;
+ } while (sent < count);
+ }
+
+ int SendInvalidSrtpPacket(size_t channel, size_t size) {
+ ASSERT(channel < channels_.size());
+ rtc::scoped_ptr<char[]> packet(new char[size]);
+ // Fill the packet with 0 to form an invalid SRTP packet.
+ memset(packet.get(), 0, size);
+
+ rtc::PacketOptions packet_options;
+ return channels_[channel]->SendPacket(
+ packet.get(), size, packet_options, cricket::PF_SRTP_BYPASS);
+ }
+
+ void ExpectPackets(size_t channel, size_t size) {
+ packet_size_ = size;
+ received_.clear();
+ }
+
+ size_t NumPacketsReceived() {
+ return received_.size();
+ }
+
+ bool VerifyPacket(const char* data, size_t size, uint32* out_num) {
+ if (size != packet_size_ ||
+ (data[0] != 0 && static_cast<uint8>(data[0]) != 0x80)) {
+ return false;
+ }
+ uint32 packet_num = rtc::GetBE32(data + kPacketNumOffset);
+ for (size_t i = kPacketHeaderLen; i < size; ++i) {
+ if (static_cast<uint8>(data[i]) != (packet_num & 0xff)) {
+ return false;
+ }
+ }
+ if (out_num) {
+ *out_num = packet_num;
+ }
+ return true;
+ }
+ bool VerifyEncryptedPacket(const char* data, size_t size) {
+ // This is an encrypted data packet; let's make sure it's mostly random;
+ // less than 10% of the bytes should be equal to the cleartext packet.
+ if (size <= packet_size_) {
+ return false;
+ }
+ uint32 packet_num = rtc::GetBE32(data + kPacketNumOffset);
+ int num_matches = 0;
+ for (size_t i = kPacketNumOffset; i < size; ++i) {
+ if (static_cast<uint8>(data[i]) == (packet_num & 0xff)) {
+ ++num_matches;
+ }
+ }
+ return (num_matches < ((static_cast<int>(size) - 5) / 10));
+ }
+
+ // Transport callbacks
+ void OnTransportWritableState(cricket::Transport* transport) {
+ LOG(LS_INFO) << name_ << ": is writable";
+ }
+
+ // Transport channel callbacks
+ void OnTransportChannelWritableState(cricket::TransportChannel* channel) {
+ LOG(LS_INFO) << name_ << ": Channel '" << channel->component()
+ << "' is writable";
+ }
+
+ void OnTransportChannelReadPacket(cricket::TransportChannel* channel,
+ const char* data, size_t size,
+ const rtc::PacketTime& packet_time,
+ int flags) {
+ uint32 packet_num = 0;
+ ASSERT_TRUE(VerifyPacket(data, size, &packet_num));
+ received_.insert(packet_num);
+ // Only DTLS-SRTP packets should have the bypass flag set.
+ int expected_flags = (identity_.get() && IsRtpLeadByte(data[0])) ?
+ cricket::PF_SRTP_BYPASS : 0;
+ ASSERT_EQ(expected_flags, flags);
+ }
+
+ // Hook into the raw packet stream to make sure DTLS packets are encrypted.
+ void OnFakeTransportChannelReadPacket(cricket::TransportChannel* channel,
+ const char* data, size_t size,
+ const rtc::PacketTime& time,
+ int flags) {
+ // Flags shouldn't be set on the underlying TransportChannel packets.
+ ASSERT_EQ(0, flags);
+
+ // Look at the handshake packets to see what role we played.
+ // Check that non-handshake packets are DTLS data or SRTP bypass.
+ if (negotiated_dtls_) {
+ if (data[0] == 22 && size > 17) {
+ if (data[13] == 1) {
+ received_dtls_client_hello_ = true;
+ } else if (data[13] == 2) {
+ received_dtls_server_hello_ = true;
+ }
+ } else if (!(data[0] >= 20 && data[0] <= 22)) {
+ ASSERT_TRUE(data[0] == 23 || IsRtpLeadByte(data[0]));
+ if (data[0] == 23) {
+ ASSERT_TRUE(VerifyEncryptedPacket(data, size));
+ } else if (IsRtpLeadByte(data[0])) {
+ ASSERT_TRUE(VerifyPacket(data, size, NULL));
+ }
+ }
+ }
+ }
+
+ private:
+ std::string name_;
+ rtc::Thread* signaling_thread_;
+ rtc::Thread* worker_thread_;
+ cricket::TransportProtocol protocol_;
+ rtc::scoped_ptr<rtc::SSLIdentity> identity_;
+ rtc::scoped_ptr<cricket::FakeTransport> transport_;
+ std::vector<cricket::DtlsTransportChannelWrapper*> channels_;
+ size_t packet_size_;
+ std::set<int> received_;
+ bool use_dtls_srtp_;
+ bool negotiated_dtls_;
+ bool received_dtls_client_hello_;
+ bool received_dtls_server_hello_;
+};
+
+
+class DtlsTransportChannelTest : public testing::Test {
+ public:
+ DtlsTransportChannelTest() :
+ client1_("P1", rtc::Thread::Current(),
+ rtc::Thread::Current()),
+ client2_("P2", rtc::Thread::Current(),
+ rtc::Thread::Current()),
+ channel_ct_(1),
+ use_dtls_(false),
+ use_dtls_srtp_(false) {
+ }
+
+ void SetChannelCount(size_t channel_ct) {
+ channel_ct_ = static_cast<int>(channel_ct);
+ }
+ void PrepareDtls(bool c1, bool c2) {
+ if (c1) {
+ client1_.CreateIdentity();
+ }
+ if (c2) {
+ client2_.CreateIdentity();
+ }
+ if (c1 && c2)
+ use_dtls_ = true;
+ }
+ void PrepareDtlsSrtp(bool c1, bool c2) {
+ if (!use_dtls_)
+ return;
+
+ if (c1)
+ client1_.SetupSrtp();
+ if (c2)
+ client2_.SetupSrtp();
+
+ if (c1 && c2)
+ use_dtls_srtp_ = true;
+ }
+
+ bool Connect(ConnectionRole client1_role, ConnectionRole client2_role) {
+ Negotiate(client1_role, client2_role);
+
+ bool rv = client1_.Connect(&client2_);
+ EXPECT_TRUE(rv);
+ if (!rv)
+ return false;
+
+ EXPECT_TRUE_WAIT(client1_.writable() && client2_.writable(), 10000);
+ if (!client1_.writable() || !client2_.writable())
+ return false;
+
+ // Check that we used the right roles.
+ if (use_dtls_) {
+ rtc::SSLRole client1_ssl_role =
+ (client1_role == cricket::CONNECTIONROLE_ACTIVE ||
+ (client2_role == cricket::CONNECTIONROLE_PASSIVE &&
+ client1_role == cricket::CONNECTIONROLE_ACTPASS)) ?
+ rtc::SSL_CLIENT : rtc::SSL_SERVER;
+
+ rtc::SSLRole client2_ssl_role =
+ (client2_role == cricket::CONNECTIONROLE_ACTIVE ||
+ (client1_role == cricket::CONNECTIONROLE_PASSIVE &&
+ client2_role == cricket::CONNECTIONROLE_ACTPASS)) ?
+ rtc::SSL_CLIENT : rtc::SSL_SERVER;
+
+ client1_.CheckRole(client1_ssl_role);
+ client2_.CheckRole(client2_ssl_role);
+ }
+
+ // Check that we negotiated the right ciphers.
+ if (use_dtls_srtp_) {
+ client1_.CheckSrtp(AES_CM_128_HMAC_SHA1_80);
+ client2_.CheckSrtp(AES_CM_128_HMAC_SHA1_80);
+ } else {
+ client1_.CheckSrtp("");
+ client2_.CheckSrtp("");
+ }
+
+ return true;
+ }
+
+ bool Connect() {
+ // By default, Client1 will be Server and Client2 will be Client.
+ return Connect(cricket::CONNECTIONROLE_ACTPASS,
+ cricket::CONNECTIONROLE_ACTIVE);
+ }
+
+ void Negotiate() {
+ Negotiate(cricket::CONNECTIONROLE_ACTPASS, cricket::CONNECTIONROLE_ACTIVE);
+ }
+
+ void Negotiate(ConnectionRole client1_role, ConnectionRole client2_role) {
+ client1_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLING);
+ client2_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLED);
+ // Expect success from SLTD and SRTD.
+ client1_.Negotiate(&client2_, cricket::CA_OFFER,
+ client1_role, client2_role, 0);
+ client2_.Negotiate(&client1_, cricket::CA_ANSWER,
+ client2_role, client1_role, 0);
+ }
+
+ // Negotiate with legacy client |client2|. Legacy client doesn't use setup
+ // attributes, except NONE.
+ void NegotiateWithLegacy() {
+ client1_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLING);
+ client2_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLED);
+ // Expect success from SLTD and SRTD.
+ client1_.Negotiate(&client2_, cricket::CA_OFFER,
+ cricket::CONNECTIONROLE_ACTPASS,
+ cricket::CONNECTIONROLE_NONE, 0);
+ client2_.Negotiate(&client1_, cricket::CA_ANSWER,
+ cricket::CONNECTIONROLE_ACTIVE,
+ cricket::CONNECTIONROLE_NONE, 0);
+ }
+
+ void Renegotiate(DtlsTestClient* reoffer_initiator,
+ ConnectionRole client1_role, ConnectionRole client2_role,
+ int flags) {
+ if (reoffer_initiator == &client1_) {
+ client1_.Negotiate(&client2_, cricket::CA_OFFER,
+ client1_role, client2_role, flags);
+ client2_.Negotiate(&client1_, cricket::CA_ANSWER,
+ client2_role, client1_role, flags);
+ } else {
+ client2_.Negotiate(&client1_, cricket::CA_OFFER,
+ client2_role, client1_role, flags);
+ client1_.Negotiate(&client2_, cricket::CA_ANSWER,
+ client1_role, client2_role, flags);
+ }
+ }
+
+ void TestTransfer(size_t channel, size_t size, size_t count, bool srtp) {
+ LOG(LS_INFO) << "Expect packets, size=" << size;
+ client2_.ExpectPackets(channel, size);
+ client1_.SendPackets(channel, size, count, srtp);
+ EXPECT_EQ_WAIT(count, client2_.NumPacketsReceived(), 10000);
+ }
+
+ protected:
+ DtlsTestClient client1_;
+ DtlsTestClient client2_;
+ int channel_ct_;
+ bool use_dtls_;
+ bool use_dtls_srtp_;
+};
+
+// Test that transport negotiation of ICE, no DTLS works properly.
+TEST_F(DtlsTransportChannelTest, TestChannelSetupIce) {
+ client1_.SetIceProtocol(cricket::ICEPROTO_RFC5245);
+ client2_.SetIceProtocol(cricket::ICEPROTO_RFC5245);
+ Negotiate();
+ cricket::FakeTransportChannel* channel1 = client1_.GetFakeChannel(0);
+ cricket::FakeTransportChannel* channel2 = client2_.GetFakeChannel(0);
+ ASSERT_TRUE(channel1 != NULL);
+ ASSERT_TRUE(channel2 != NULL);
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole());
+ EXPECT_EQ(1U, channel1->IceTiebreaker());
+ EXPECT_EQ(cricket::ICEPROTO_RFC5245, channel1->protocol());
+ EXPECT_EQ(kIceUfrag1, channel1->ice_ufrag());
+ EXPECT_EQ(kIcePwd1, channel1->ice_pwd());
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel2->GetIceRole());
+ EXPECT_EQ(2U, channel2->IceTiebreaker());
+ EXPECT_EQ(cricket::ICEPROTO_RFC5245, channel2->protocol());
+}
+
+// Test that transport negotiation of GICE, no DTLS works properly.
+TEST_F(DtlsTransportChannelTest, TestChannelSetupGice) {
+ client1_.SetIceProtocol(cricket::ICEPROTO_GOOGLE);
+ client2_.SetIceProtocol(cricket::ICEPROTO_GOOGLE);
+ Negotiate();
+ cricket::FakeTransportChannel* channel1 = client1_.GetFakeChannel(0);
+ cricket::FakeTransportChannel* channel2 = client2_.GetFakeChannel(0);
+ ASSERT_TRUE(channel1 != NULL);
+ ASSERT_TRUE(channel2 != NULL);
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole());
+ EXPECT_EQ(1U, channel1->IceTiebreaker());
+ EXPECT_EQ(cricket::ICEPROTO_GOOGLE, channel1->protocol());
+ EXPECT_EQ(kIceUfrag1, channel1->ice_ufrag());
+ EXPECT_EQ(kIcePwd1, channel1->ice_pwd());
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel2->GetIceRole());
+ EXPECT_EQ(2U, channel2->IceTiebreaker());
+ EXPECT_EQ(cricket::ICEPROTO_GOOGLE, channel2->protocol());
+}
+
+// Connect without DTLS, and transfer some data.
+TEST_F(DtlsTransportChannelTest, TestTransfer) {
+ ASSERT_TRUE(Connect());
+ TestTransfer(0, 1000, 100, false);
+}
+
+// Create two channels without DTLS, and transfer some data.
+TEST_F(DtlsTransportChannelTest, TestTransferTwoChannels) {
+ SetChannelCount(2);
+ ASSERT_TRUE(Connect());
+ TestTransfer(0, 1000, 100, false);
+ TestTransfer(1, 1000, 100, false);
+}
+
+// Connect without DTLS, and transfer SRTP data.
+TEST_F(DtlsTransportChannelTest, TestTransferSrtp) {
+ ASSERT_TRUE(Connect());
+ TestTransfer(0, 1000, 100, true);
+}
+
+// Create two channels without DTLS, and transfer SRTP data.
+TEST_F(DtlsTransportChannelTest, TestTransferSrtpTwoChannels) {
+ SetChannelCount(2);
+ ASSERT_TRUE(Connect());
+ TestTransfer(0, 1000, 100, true);
+ TestTransfer(1, 1000, 100, true);
+}
+
+// Connect with DTLS, and transfer some data.
+TEST_F(DtlsTransportChannelTest, TestTransferDtls) {
+ MAYBE_SKIP_TEST(HaveDtls);
+ PrepareDtls(true, true);
+ ASSERT_TRUE(Connect());
+ TestTransfer(0, 1000, 100, false);
+}
+
+// Create two channels with DTLS, and transfer some data.
+TEST_F(DtlsTransportChannelTest, TestTransferDtlsTwoChannels) {
+ MAYBE_SKIP_TEST(HaveDtls);
+ SetChannelCount(2);
+ PrepareDtls(true, true);
+ ASSERT_TRUE(Connect());
+ TestTransfer(0, 1000, 100, false);
+ TestTransfer(1, 1000, 100, false);
+}
+
+// Connect with A doing DTLS and B not, and transfer some data.
+TEST_F(DtlsTransportChannelTest, TestTransferDtlsRejected) {
+ PrepareDtls(true, false);
+ ASSERT_TRUE(Connect());
+ TestTransfer(0, 1000, 100, false);
+}
+
+// Connect with B doing DTLS and A not, and transfer some data.
+TEST_F(DtlsTransportChannelTest, TestTransferDtlsNotOffered) {
+ PrepareDtls(false, true);
+ ASSERT_TRUE(Connect());
+ TestTransfer(0, 1000, 100, false);
+}
+
+// Connect with DTLS, negotiate DTLS-SRTP, and transfer SRTP using bypass.
+TEST_F(DtlsTransportChannelTest, TestTransferDtlsSrtp) {
+ MAYBE_SKIP_TEST(HaveDtlsSrtp);
+ PrepareDtls(true, true);
+ PrepareDtlsSrtp(true, true);
+ ASSERT_TRUE(Connect());
+ TestTransfer(0, 1000, 100, true);
+}
+
+// Connect with DTLS-SRTP, transfer an invalid SRTP packet, and expects -1
+// returned.
+TEST_F(DtlsTransportChannelTest, TestTransferDtlsInvalidSrtpPacket) {
+ MAYBE_SKIP_TEST(HaveDtls);
+ PrepareDtls(true, true);
+ PrepareDtlsSrtp(true, true);
+ ASSERT_TRUE(Connect());
+ int result = client1_.SendInvalidSrtpPacket(0, 100);
+ ASSERT_EQ(-1, result);
+}
+
+// Connect with DTLS. A does DTLS-SRTP but B does not.
+TEST_F(DtlsTransportChannelTest, TestTransferDtlsSrtpRejected) {
+ MAYBE_SKIP_TEST(HaveDtlsSrtp);
+ PrepareDtls(true, true);
+ PrepareDtlsSrtp(true, false);
+ ASSERT_TRUE(Connect());
+}
+
+// Connect with DTLS. B does DTLS-SRTP but A does not.
+TEST_F(DtlsTransportChannelTest, TestTransferDtlsSrtpNotOffered) {
+ MAYBE_SKIP_TEST(HaveDtlsSrtp);
+ PrepareDtls(true, true);
+ PrepareDtlsSrtp(false, true);
+ ASSERT_TRUE(Connect());
+}
+
+// Create two channels with DTLS, negotiate DTLS-SRTP, and transfer bypass SRTP.
+TEST_F(DtlsTransportChannelTest, TestTransferDtlsSrtpTwoChannels) {
+ MAYBE_SKIP_TEST(HaveDtlsSrtp);
+ SetChannelCount(2);
+ PrepareDtls(true, true);
+ PrepareDtlsSrtp(true, true);
+ ASSERT_TRUE(Connect());
+ TestTransfer(0, 1000, 100, true);
+ TestTransfer(1, 1000, 100, true);
+}
+
+// Create a single channel with DTLS, and send normal data and SRTP data on it.
+TEST_F(DtlsTransportChannelTest, TestTransferDtlsSrtpDemux) {
+ MAYBE_SKIP_TEST(HaveDtlsSrtp);
+ PrepareDtls(true, true);
+ PrepareDtlsSrtp(true, true);
+ ASSERT_TRUE(Connect());
+ TestTransfer(0, 1000, 100, false);
+ TestTransfer(0, 1000, 100, true);
+}
+
+// Testing when the remote is passive.
+TEST_F(DtlsTransportChannelTest, TestTransferDtlsAnswererIsPassive) {
+ MAYBE_SKIP_TEST(HaveDtlsSrtp);
+ SetChannelCount(2);
+ PrepareDtls(true, true);
+ PrepareDtlsSrtp(true, true);
+ ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS,
+ cricket::CONNECTIONROLE_PASSIVE));
+ TestTransfer(0, 1000, 100, true);
+ TestTransfer(1, 1000, 100, true);
+}
+
+// Testing with the legacy DTLS client which doesn't use setup attribute.
+// In this case legacy is the answerer.
+TEST_F(DtlsTransportChannelTest, TestDtlsSetupWithLegacyAsAnswerer) {
+ MAYBE_SKIP_TEST(HaveDtlsSrtp);
+ PrepareDtls(true, true);
+ NegotiateWithLegacy();
+ rtc::SSLRole channel1_role;
+ rtc::SSLRole channel2_role;
+ EXPECT_TRUE(client1_.transport()->GetSslRole(&channel1_role));
+ EXPECT_TRUE(client2_.transport()->GetSslRole(&channel2_role));
+ EXPECT_EQ(rtc::SSL_SERVER, channel1_role);
+ EXPECT_EQ(rtc::SSL_CLIENT, channel2_role);
+}
+
+// Testing re offer/answer after the session is estbalished. Roles will be
+// kept same as of the previous negotiation.
+TEST_F(DtlsTransportChannelTest, TestDtlsReOfferFromOfferer) {
+ MAYBE_SKIP_TEST(HaveDtlsSrtp);
+ SetChannelCount(2);
+ PrepareDtls(true, true);
+ PrepareDtlsSrtp(true, true);
+ // Initial role for client1 is ACTPASS and client2 is ACTIVE.
+ ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS,
+ cricket::CONNECTIONROLE_ACTIVE));
+ TestTransfer(0, 1000, 100, true);
+ TestTransfer(1, 1000, 100, true);
+ // Using input roles for the re-offer.
+ Renegotiate(&client1_, cricket::CONNECTIONROLE_ACTPASS,
+ cricket::CONNECTIONROLE_ACTIVE, NF_REOFFER);
+ TestTransfer(0, 1000, 100, true);
+ TestTransfer(1, 1000, 100, true);
+}
+
+TEST_F(DtlsTransportChannelTest, TestDtlsReOfferFromAnswerer) {
+ MAYBE_SKIP_TEST(HaveDtlsSrtp);
+ SetChannelCount(2);
+ PrepareDtls(true, true);
+ PrepareDtlsSrtp(true, true);
+ // Initial role for client1 is ACTPASS and client2 is ACTIVE.
+ ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS,
+ cricket::CONNECTIONROLE_ACTIVE));
+ TestTransfer(0, 1000, 100, true);
+ TestTransfer(1, 1000, 100, true);
+ // Using input roles for the re-offer.
+ Renegotiate(&client2_, cricket::CONNECTIONROLE_PASSIVE,
+ cricket::CONNECTIONROLE_ACTPASS, NF_REOFFER);
+ TestTransfer(0, 1000, 100, true);
+ TestTransfer(1, 1000, 100, true);
+}
+
+// Test that any change in role after the intial setup will result in failure.
+TEST_F(DtlsTransportChannelTest, TestDtlsRoleReversal) {
+ MAYBE_SKIP_TEST(HaveDtlsSrtp);
+ SetChannelCount(2);
+ PrepareDtls(true, true);
+ PrepareDtlsSrtp(true, true);
+ ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS,
+ cricket::CONNECTIONROLE_PASSIVE));
+
+ // Renegotiate from client2 with actpass and client1 as active.
+ Renegotiate(&client2_, cricket::CONNECTIONROLE_ACTPASS,
+ cricket::CONNECTIONROLE_ACTIVE,
+ NF_REOFFER | NF_EXPECT_FAILURE);
+}
+
+// Test that using different setup attributes which results in similar ssl
+// role as the initial negotiation will result in success.
+TEST_F(DtlsTransportChannelTest, TestDtlsReOfferWithDifferentSetupAttr) {
+ MAYBE_SKIP_TEST(HaveDtlsSrtp);
+ SetChannelCount(2);
+ PrepareDtls(true, true);
+ PrepareDtlsSrtp(true, true);
+ ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS,
+ cricket::CONNECTIONROLE_PASSIVE));
+ // Renegotiate from client2 with actpass and client1 as active.
+ Renegotiate(&client2_, cricket::CONNECTIONROLE_ACTIVE,
+ cricket::CONNECTIONROLE_ACTPASS, NF_REOFFER);
+ TestTransfer(0, 1000, 100, true);
+ TestTransfer(1, 1000, 100, true);
+}
+
+// Test that re-negotiation can be started before the clients become connected
+// in the first negotiation.
+TEST_F(DtlsTransportChannelTest, TestRenegotiateBeforeConnect) {
+ MAYBE_SKIP_TEST(HaveDtlsSrtp);
+ SetChannelCount(2);
+ PrepareDtls(true, true);
+ PrepareDtlsSrtp(true, true);
+ Negotiate();
+
+ Renegotiate(&client1_, cricket::CONNECTIONROLE_ACTPASS,
+ cricket::CONNECTIONROLE_ACTIVE, NF_REOFFER);
+ bool rv = client1_.Connect(&client2_);
+ EXPECT_TRUE(rv);
+ EXPECT_TRUE_WAIT(client1_.writable() && client2_.writable(), 10000);
+
+ TestTransfer(0, 1000, 100, true);
+ TestTransfer(1, 1000, 100, true);
+}
+
+// Test Certificates state after negotiation but before connection.
+TEST_F(DtlsTransportChannelTest, TestCertificatesBeforeConnect) {
+ MAYBE_SKIP_TEST(HaveDtls);
+ PrepareDtls(true, true);
+ Negotiate();
+
+ rtc::scoped_ptr<rtc::SSLIdentity> identity1;
+ rtc::scoped_ptr<rtc::SSLIdentity> identity2;
+ rtc::scoped_ptr<rtc::SSLCertificate> remote_cert1;
+ rtc::scoped_ptr<rtc::SSLCertificate> remote_cert2;
+
+ // After negotiation, each side has a distinct local certificate, but still no
+ // remote certificate, because connection has not yet occurred.
+ ASSERT_TRUE(client1_.transport()->GetIdentity(identity1.accept()));
+ ASSERT_TRUE(client2_.transport()->GetIdentity(identity2.accept()));
+ ASSERT_NE(identity1->certificate().ToPEMString(),
+ identity2->certificate().ToPEMString());
+ ASSERT_FALSE(
+ client1_.transport()->GetRemoteCertificate(remote_cert1.accept()));
+ ASSERT_FALSE(remote_cert1 != NULL);
+ ASSERT_FALSE(
+ client2_.transport()->GetRemoteCertificate(remote_cert2.accept()));
+ ASSERT_FALSE(remote_cert2 != NULL);
+}
+
+// Test Certificates state after connection.
+TEST_F(DtlsTransportChannelTest, TestCertificatesAfterConnect) {
+ MAYBE_SKIP_TEST(HaveDtls);
+ PrepareDtls(true, true);
+ ASSERT_TRUE(Connect());
+
+ rtc::scoped_ptr<rtc::SSLIdentity> identity1;
+ rtc::scoped_ptr<rtc::SSLIdentity> identity2;
+ rtc::scoped_ptr<rtc::SSLCertificate> remote_cert1;
+ rtc::scoped_ptr<rtc::SSLCertificate> remote_cert2;
+
+ // After connection, each side has a distinct local certificate.
+ ASSERT_TRUE(client1_.transport()->GetIdentity(identity1.accept()));
+ ASSERT_TRUE(client2_.transport()->GetIdentity(identity2.accept()));
+ ASSERT_NE(identity1->certificate().ToPEMString(),
+ identity2->certificate().ToPEMString());
+
+ // Each side's remote certificate is the other side's local certificate.
+ ASSERT_TRUE(
+ client1_.transport()->GetRemoteCertificate(remote_cert1.accept()));
+ ASSERT_EQ(remote_cert1->ToPEMString(),
+ identity2->certificate().ToPEMString());
+ ASSERT_TRUE(
+ client2_.transport()->GetRemoteCertificate(remote_cert2.accept()));
+ ASSERT_EQ(remote_cert2->ToPEMString(),
+ identity1->certificate().ToPEMString());
+}
diff --git a/p2p/base/fakesession.h b/p2p/base/fakesession.h
new file mode 100644
index 00000000..30bc9816
--- /dev/null
+++ b/p2p/base/fakesession.h
@@ -0,0 +1,492 @@
+/*
+ * Copyright 2009 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_P2P_BASE_FAKESESSION_H_
+#define WEBRTC_P2P_BASE_FAKESESSION_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "webrtc/p2p/base/session.h"
+#include "webrtc/p2p/base/transport.h"
+#include "webrtc/p2p/base/transportchannel.h"
+#include "webrtc/p2p/base/transportchannelimpl.h"
+#include "webrtc/base/buffer.h"
+#include "webrtc/base/fakesslidentity.h"
+#include "webrtc/base/messagequeue.h"
+#include "webrtc/base/sigslot.h"
+#include "webrtc/base/sslfingerprint.h"
+
+namespace cricket {
+
+class FakeTransport;
+
+struct PacketMessageData : public rtc::MessageData {
+ PacketMessageData(const char* data, size_t len) : packet(data, len) {
+ }
+ rtc::Buffer packet;
+};
+
+// Fake transport channel class, which can be passed to anything that needs a
+// transport channel. Can be informed of another FakeTransportChannel via
+// SetDestination.
+class FakeTransportChannel : public TransportChannelImpl,
+ public rtc::MessageHandler {
+ public:
+ explicit FakeTransportChannel(Transport* transport,
+ const std::string& content_name,
+ int component)
+ : TransportChannelImpl(content_name, component),
+ transport_(transport),
+ dest_(NULL),
+ state_(STATE_INIT),
+ async_(false),
+ identity_(NULL),
+ do_dtls_(false),
+ role_(ICEROLE_UNKNOWN),
+ tiebreaker_(0),
+ ice_proto_(ICEPROTO_HYBRID),
+ remote_ice_mode_(ICEMODE_FULL),
+ dtls_fingerprint_("", NULL, 0),
+ ssl_role_(rtc::SSL_CLIENT),
+ connection_count_(0) {
+ }
+ ~FakeTransportChannel() {
+ Reset();
+ }
+
+ uint64 IceTiebreaker() const { return tiebreaker_; }
+ TransportProtocol protocol() const { return ice_proto_; }
+ IceMode remote_ice_mode() const { return remote_ice_mode_; }
+ const std::string& ice_ufrag() const { return ice_ufrag_; }
+ const std::string& ice_pwd() const { return ice_pwd_; }
+ const std::string& remote_ice_ufrag() const { return remote_ice_ufrag_; }
+ const std::string& remote_ice_pwd() const { return remote_ice_pwd_; }
+ const rtc::SSLFingerprint& dtls_fingerprint() const {
+ return dtls_fingerprint_;
+ }
+
+ void SetAsync(bool async) {
+ async_ = async;
+ }
+
+ virtual Transport* GetTransport() {
+ return transport_;
+ }
+
+ virtual void SetIceRole(IceRole role) { role_ = role; }
+ virtual IceRole GetIceRole() const { return role_; }
+ virtual size_t GetConnectionCount() const { return connection_count_; }
+ virtual void SetIceTiebreaker(uint64 tiebreaker) { tiebreaker_ = tiebreaker; }
+ virtual bool GetIceProtocolType(IceProtocolType* type) const {
+ *type = ice_proto_;
+ return true;
+ }
+ virtual void SetIceProtocolType(IceProtocolType type) { ice_proto_ = type; }
+ virtual void SetIceCredentials(const std::string& ice_ufrag,
+ const std::string& ice_pwd) {
+ ice_ufrag_ = ice_ufrag;
+ ice_pwd_ = ice_pwd;
+ }
+ virtual void SetRemoteIceCredentials(const std::string& ice_ufrag,
+ const std::string& ice_pwd) {
+ remote_ice_ufrag_ = ice_ufrag;
+ remote_ice_pwd_ = ice_pwd;
+ }
+
+ virtual void SetRemoteIceMode(IceMode mode) { remote_ice_mode_ = mode; }
+ virtual bool SetRemoteFingerprint(const std::string& alg, const uint8* digest,
+ size_t digest_len) {
+ dtls_fingerprint_ = rtc::SSLFingerprint(alg, digest, digest_len);
+ return true;
+ }
+ virtual bool SetSslRole(rtc::SSLRole role) {
+ ssl_role_ = role;
+ return true;
+ }
+ virtual bool GetSslRole(rtc::SSLRole* role) const {
+ *role = ssl_role_;
+ return true;
+ }
+
+ virtual void Connect() {
+ if (state_ == STATE_INIT) {
+ state_ = STATE_CONNECTING;
+ }
+ }
+ virtual void Reset() {
+ if (state_ != STATE_INIT) {
+ state_ = STATE_INIT;
+ if (dest_) {
+ dest_->state_ = STATE_INIT;
+ dest_->dest_ = NULL;
+ dest_ = NULL;
+ }
+ }
+ }
+
+ void SetWritable(bool writable) {
+ set_writable(writable);
+ }
+
+ void SetDestination(FakeTransportChannel* dest) {
+ if (state_ == STATE_CONNECTING && dest) {
+ // This simulates the delivery of candidates.
+ dest_ = dest;
+ dest_->dest_ = this;
+ if (identity_ && dest_->identity_) {
+ do_dtls_ = true;
+ dest_->do_dtls_ = true;
+ NegotiateSrtpCiphers();
+ }
+ state_ = STATE_CONNECTED;
+ dest_->state_ = STATE_CONNECTED;
+ set_writable(true);
+ dest_->set_writable(true);
+ } else if (state_ == STATE_CONNECTED && !dest) {
+ // Simulates loss of connectivity, by asymmetrically forgetting dest_.
+ dest_ = NULL;
+ state_ = STATE_CONNECTING;
+ set_writable(false);
+ }
+ }
+
+ void SetConnectionCount(size_t connection_count) {
+ size_t old_connection_count = connection_count_;
+ connection_count_ = connection_count;
+ if (connection_count_ < old_connection_count)
+ SignalConnectionRemoved(this);
+ }
+
+ virtual int SendPacket(const char* data, size_t len,
+ const rtc::PacketOptions& options, int flags) {
+ if (state_ != STATE_CONNECTED) {
+ return -1;
+ }
+
+ if (flags != PF_SRTP_BYPASS && flags != 0) {
+ return -1;
+ }
+
+ PacketMessageData* packet = new PacketMessageData(data, len);
+ if (async_) {
+ rtc::Thread::Current()->Post(this, 0, packet);
+ } else {
+ rtc::Thread::Current()->Send(this, 0, packet);
+ }
+ return static_cast<int>(len);
+ }
+ virtual int SetOption(rtc::Socket::Option opt, int value) {
+ return true;
+ }
+ virtual int GetError() {
+ return 0;
+ }
+
+ virtual void OnSignalingReady() {
+ }
+ virtual void OnCandidate(const Candidate& candidate) {
+ }
+
+ virtual void OnMessage(rtc::Message* msg) {
+ PacketMessageData* data = static_cast<PacketMessageData*>(
+ msg->pdata);
+ dest_->SignalReadPacket(dest_, data->packet.data(),
+ data->packet.length(),
+ rtc::CreatePacketTime(0), 0);
+ delete data;
+ }
+
+ bool SetLocalIdentity(rtc::SSLIdentity* identity) {
+ identity_ = identity;
+ return true;
+ }
+
+
+ void SetRemoteCertificate(rtc::FakeSSLCertificate* cert) {
+ remote_cert_ = cert;
+ }
+
+ virtual bool IsDtlsActive() const {
+ return do_dtls_;
+ }
+
+ virtual bool SetSrtpCiphers(const std::vector<std::string>& ciphers) {
+ srtp_ciphers_ = ciphers;
+ return true;
+ }
+
+ virtual bool GetSrtpCipher(std::string* cipher) {
+ if (!chosen_srtp_cipher_.empty()) {
+ *cipher = chosen_srtp_cipher_;
+ return true;
+ }
+ return false;
+ }
+
+ virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const {
+ if (!identity_)
+ return false;
+
+ *identity = identity_->GetReference();
+ return true;
+ }
+
+ virtual bool GetRemoteCertificate(rtc::SSLCertificate** cert) const {
+ if (!remote_cert_)
+ return false;
+
+ *cert = remote_cert_->GetReference();
+ return true;
+ }
+
+ virtual bool ExportKeyingMaterial(const std::string& label,
+ const uint8* context,
+ size_t context_len,
+ bool use_context,
+ uint8* result,
+ size_t result_len) {
+ if (!chosen_srtp_cipher_.empty()) {
+ memset(result, 0xff, result_len);
+ return true;
+ }
+
+ return false;
+ }
+
+ virtual void NegotiateSrtpCiphers() {
+ for (std::vector<std::string>::const_iterator it1 = srtp_ciphers_.begin();
+ it1 != srtp_ciphers_.end(); ++it1) {
+ for (std::vector<std::string>::const_iterator it2 =
+ dest_->srtp_ciphers_.begin();
+ it2 != dest_->srtp_ciphers_.end(); ++it2) {
+ if (*it1 == *it2) {
+ chosen_srtp_cipher_ = *it1;
+ dest_->chosen_srtp_cipher_ = *it2;
+ return;
+ }
+ }
+ }
+ }
+
+ virtual bool GetStats(ConnectionInfos* infos) OVERRIDE {
+ ConnectionInfo info;
+ infos->clear();
+ infos->push_back(info);
+ return true;
+ }
+
+ private:
+ enum State { STATE_INIT, STATE_CONNECTING, STATE_CONNECTED };
+ Transport* transport_;
+ FakeTransportChannel* dest_;
+ State state_;
+ bool async_;
+ rtc::SSLIdentity* identity_;
+ rtc::FakeSSLCertificate* remote_cert_;
+ bool do_dtls_;
+ std::vector<std::string> srtp_ciphers_;
+ std::string chosen_srtp_cipher_;
+ IceRole role_;
+ uint64 tiebreaker_;
+ IceProtocolType ice_proto_;
+ std::string ice_ufrag_;
+ std::string ice_pwd_;
+ std::string remote_ice_ufrag_;
+ std::string remote_ice_pwd_;
+ IceMode remote_ice_mode_;
+ rtc::SSLFingerprint dtls_fingerprint_;
+ rtc::SSLRole ssl_role_;
+ size_t connection_count_;
+};
+
+// Fake transport class, which can be passed to anything that needs a Transport.
+// Can be informed of another FakeTransport via SetDestination (low-tech way
+// of doing candidates)
+class FakeTransport : public Transport {
+ public:
+ typedef std::map<int, FakeTransportChannel*> ChannelMap;
+ FakeTransport(rtc::Thread* signaling_thread,
+ rtc::Thread* worker_thread,
+ const std::string& content_name,
+ PortAllocator* alllocator = NULL)
+ : Transport(signaling_thread, worker_thread,
+ content_name, "test_type", NULL),
+ dest_(NULL),
+ async_(false),
+ identity_(NULL) {
+ }
+ ~FakeTransport() {
+ DestroyAllChannels();
+ }
+
+ const ChannelMap& channels() const { return channels_; }
+
+ void SetAsync(bool async) { async_ = async; }
+ void SetDestination(FakeTransport* dest) {
+ dest_ = dest;
+ for (ChannelMap::iterator it = channels_.begin(); it != channels_.end();
+ ++it) {
+ it->second->SetLocalIdentity(identity_);
+ SetChannelDestination(it->first, it->second);
+ }
+ }
+
+ void SetWritable(bool writable) {
+ for (ChannelMap::iterator it = channels_.begin(); it != channels_.end();
+ ++it) {
+ it->second->SetWritable(writable);
+ }
+ }
+
+ void set_identity(rtc::SSLIdentity* identity) {
+ identity_ = identity;
+ }
+
+ using Transport::local_description;
+ using Transport::remote_description;
+
+ protected:
+ virtual TransportChannelImpl* CreateTransportChannel(int component) {
+ if (channels_.find(component) != channels_.end()) {
+ return NULL;
+ }
+ FakeTransportChannel* channel =
+ new FakeTransportChannel(this, content_name(), component);
+ channel->SetAsync(async_);
+ SetChannelDestination(component, channel);
+ channels_[component] = channel;
+ return channel;
+ }
+ virtual void DestroyTransportChannel(TransportChannelImpl* channel) {
+ channels_.erase(channel->component());
+ delete channel;
+ }
+ virtual void SetIdentity_w(rtc::SSLIdentity* identity) {
+ identity_ = identity;
+ }
+ virtual bool GetIdentity_w(rtc::SSLIdentity** identity) {
+ if (!identity_)
+ return false;
+
+ *identity = identity_->GetReference();
+ return true;
+ }
+
+ private:
+ FakeTransportChannel* GetFakeChannel(int component) {
+ ChannelMap::iterator it = channels_.find(component);
+ return (it != channels_.end()) ? it->second : NULL;
+ }
+ void SetChannelDestination(int component,
+ FakeTransportChannel* channel) {
+ FakeTransportChannel* dest_channel = NULL;
+ if (dest_) {
+ dest_channel = dest_->GetFakeChannel(component);
+ if (dest_channel) {
+ dest_channel->SetLocalIdentity(dest_->identity_);
+ }
+ }
+ channel->SetDestination(dest_channel);
+ }
+
+ // Note, this is distinct from the Channel map owned by Transport.
+ // This map just tracks the FakeTransportChannels created by this class.
+ ChannelMap channels_;
+ FakeTransport* dest_;
+ bool async_;
+ rtc::SSLIdentity* identity_;
+};
+
+// Fake session class, which can be passed into a BaseChannel object for
+// test purposes. Can be connected to other FakeSessions via Connect().
+class FakeSession : public BaseSession {
+ public:
+ explicit FakeSession()
+ : BaseSession(rtc::Thread::Current(),
+ rtc::Thread::Current(),
+ NULL, "", "", true),
+ fail_create_channel_(false) {
+ }
+ explicit FakeSession(bool initiator)
+ : BaseSession(rtc::Thread::Current(),
+ rtc::Thread::Current(),
+ NULL, "", "", initiator),
+ fail_create_channel_(false) {
+ }
+ FakeSession(rtc::Thread* worker_thread, bool initiator)
+ : BaseSession(rtc::Thread::Current(),
+ worker_thread,
+ NULL, "", "", initiator),
+ fail_create_channel_(false) {
+ }
+
+ FakeTransport* GetTransport(const std::string& content_name) {
+ return static_cast<FakeTransport*>(
+ BaseSession::GetTransport(content_name));
+ }
+
+ void Connect(FakeSession* dest) {
+ // Simulate the exchange of candidates.
+ CompleteNegotiation();
+ dest->CompleteNegotiation();
+ for (TransportMap::const_iterator it = transport_proxies().begin();
+ it != transport_proxies().end(); ++it) {
+ static_cast<FakeTransport*>(it->second->impl())->SetDestination(
+ dest->GetTransport(it->first));
+ }
+ }
+
+ virtual TransportChannel* CreateChannel(
+ const std::string& content_name,
+ const std::string& channel_name,
+ int component) {
+ if (fail_create_channel_) {
+ return NULL;
+ }
+ return BaseSession::CreateChannel(content_name, channel_name, component);
+ }
+
+ void set_fail_channel_creation(bool fail_channel_creation) {
+ fail_create_channel_ = fail_channel_creation;
+ }
+
+ // TODO: Hoist this into Session when we re-work the Session code.
+ void set_ssl_identity(rtc::SSLIdentity* identity) {
+ for (TransportMap::const_iterator it = transport_proxies().begin();
+ it != transport_proxies().end(); ++it) {
+ // We know that we have a FakeTransport*
+
+ static_cast<FakeTransport*>(it->second->impl())->set_identity
+ (identity);
+ }
+ }
+
+ protected:
+ virtual Transport* CreateTransport(const std::string& content_name) {
+ return new FakeTransport(signaling_thread(), worker_thread(), content_name);
+ }
+
+ void CompleteNegotiation() {
+ for (TransportMap::const_iterator it = transport_proxies().begin();
+ it != transport_proxies().end(); ++it) {
+ it->second->CompleteNegotiation();
+ it->second->ConnectChannels();
+ }
+ }
+
+ private:
+ bool fail_create_channel_;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_FAKESESSION_H_
diff --git a/p2p/base/p2ptransport.cc b/p2p/base/p2ptransport.cc
new file mode 100644
index 00000000..e873756f
--- /dev/null
+++ b/p2p/base/p2ptransport.cc
@@ -0,0 +1,246 @@
+/*
+ * 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 "webrtc/p2p/base/p2ptransport.h"
+
+#include <string>
+#include <vector>
+
+#include "webrtc/p2p/base/constants.h"
+#include "webrtc/p2p/base/p2ptransportchannel.h"
+#include "webrtc/p2p/base/parsing.h"
+#include "webrtc/p2p/base/sessionmanager.h"
+#include "webrtc/p2p/base/sessionmessages.h"
+#include "webrtc/libjingle/xmllite/qname.h"
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/base/base64.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/stringencode.h"
+#include "webrtc/base/stringutils.h"
+
+namespace {
+
+// Limits for GICE and ICE username sizes.
+const size_t kMaxGiceUsernameSize = 16;
+const size_t kMaxIceUsernameSize = 512;
+
+} // namespace
+
+namespace cricket {
+
+static buzz::XmlElement* NewTransportElement(const std::string& name) {
+ return new buzz::XmlElement(buzz::QName(name, LN_TRANSPORT), true);
+}
+
+P2PTransport::P2PTransport(rtc::Thread* signaling_thread,
+ rtc::Thread* worker_thread,
+ const std::string& content_name,
+ PortAllocator* allocator)
+ : Transport(signaling_thread, worker_thread,
+ content_name, NS_GINGLE_P2P, allocator) {
+}
+
+P2PTransport::~P2PTransport() {
+ DestroyAllChannels();
+}
+
+TransportChannelImpl* P2PTransport::CreateTransportChannel(int component) {
+ return new P2PTransportChannel(content_name(), component, this,
+ port_allocator());
+}
+
+void P2PTransport::DestroyTransportChannel(TransportChannelImpl* channel) {
+ delete channel;
+}
+
+bool P2PTransportParser::ParseTransportDescription(
+ const buzz::XmlElement* elem,
+ const CandidateTranslator* translator,
+ TransportDescription* desc,
+ ParseError* error) {
+ ASSERT(elem->Name().LocalPart() == LN_TRANSPORT);
+ desc->transport_type = elem->Name().Namespace();
+ if (desc->transport_type != NS_GINGLE_P2P)
+ return BadParse("Unsupported transport type", error);
+
+ for (const buzz::XmlElement* candidate_elem = elem->FirstElement();
+ candidate_elem != NULL;
+ candidate_elem = candidate_elem->NextElement()) {
+ // Only look at local part because the namespace might (eventually)
+ // be NS_GINGLE_P2P or NS_JINGLE_ICE_UDP.
+ if (candidate_elem->Name().LocalPart() == LN_CANDIDATE) {
+ Candidate candidate;
+ if (!ParseCandidate(ICEPROTO_GOOGLE, candidate_elem, translator,
+ &candidate, error)) {
+ return false;
+ }
+
+ desc->candidates.push_back(candidate);
+ }
+ }
+ return true;
+}
+
+bool P2PTransportParser::WriteTransportDescription(
+ const TransportDescription& desc,
+ const CandidateTranslator* translator,
+ buzz::XmlElement** out_elem,
+ WriteError* error) {
+ TransportProtocol proto = TransportProtocolFromDescription(&desc);
+ rtc::scoped_ptr<buzz::XmlElement> trans_elem(
+ NewTransportElement(desc.transport_type));
+
+ // Fail if we get HYBRID or ICE right now.
+ // TODO(juberti): Add ICE and HYBRID serialization.
+ if (proto != ICEPROTO_GOOGLE) {
+ LOG(LS_ERROR) << "Failed to serialize non-GICE TransportDescription";
+ return false;
+ }
+
+ for (std::vector<Candidate>::const_iterator iter = desc.candidates.begin();
+ iter != desc.candidates.end(); ++iter) {
+ rtc::scoped_ptr<buzz::XmlElement> cand_elem(
+ new buzz::XmlElement(QN_GINGLE_P2P_CANDIDATE));
+ if (!WriteCandidate(proto, *iter, translator, cand_elem.get(), error)) {
+ return false;
+ }
+ trans_elem->AddElement(cand_elem.release());
+ }
+
+ *out_elem = trans_elem.release();
+ return true;
+}
+
+bool P2PTransportParser::ParseGingleCandidate(
+ const buzz::XmlElement* elem,
+ const CandidateTranslator* translator,
+ Candidate* candidate,
+ ParseError* error) {
+ return ParseCandidate(ICEPROTO_GOOGLE, elem, translator, candidate, error);
+}
+
+bool P2PTransportParser::WriteGingleCandidate(
+ const Candidate& candidate,
+ const CandidateTranslator* translator,
+ buzz::XmlElement** out_elem,
+ WriteError* error) {
+ rtc::scoped_ptr<buzz::XmlElement> elem(
+ new buzz::XmlElement(QN_GINGLE_CANDIDATE));
+ bool ret = WriteCandidate(ICEPROTO_GOOGLE, candidate, translator, elem.get(),
+ error);
+ if (ret) {
+ *out_elem = elem.release();
+ }
+ return ret;
+}
+
+bool P2PTransportParser::VerifyUsernameFormat(TransportProtocol proto,
+ const std::string& username,
+ ParseError* error) {
+ if (proto == ICEPROTO_GOOGLE || proto == ICEPROTO_HYBRID) {
+ if (username.size() > kMaxGiceUsernameSize)
+ return BadParse("candidate username is too long", error);
+ if (!rtc::Base64::IsBase64Encoded(username))
+ return BadParse("candidate username has non-base64 encoded characters",
+ error);
+ } else if (proto == ICEPROTO_RFC5245) {
+ if (username.size() > kMaxIceUsernameSize)
+ return BadParse("candidate username is too long", error);
+ }
+ return true;
+}
+
+bool P2PTransportParser::ParseCandidate(TransportProtocol proto,
+ const buzz::XmlElement* elem,
+ const CandidateTranslator* translator,
+ Candidate* candidate,
+ ParseError* error) {
+ ASSERT(proto == ICEPROTO_GOOGLE);
+ ASSERT(translator != NULL);
+
+ if (!elem->HasAttr(buzz::QN_NAME) ||
+ !elem->HasAttr(QN_ADDRESS) ||
+ !elem->HasAttr(QN_PORT) ||
+ !elem->HasAttr(QN_USERNAME) ||
+ !elem->HasAttr(QN_PROTOCOL) ||
+ !elem->HasAttr(QN_GENERATION)) {
+ return BadParse("candidate missing required attribute", error);
+ }
+
+ rtc::SocketAddress address;
+ if (!ParseAddress(elem, QN_ADDRESS, QN_PORT, &address, error))
+ return false;
+
+ std::string channel_name = elem->Attr(buzz::QN_NAME);
+ int component = 0;
+ if (!translator ||
+ !translator->GetComponentFromChannelName(channel_name, &component)) {
+ return BadParse("candidate has unknown channel name " + channel_name,
+ error);
+ }
+
+ float preference = 0.0;
+ if (!GetXmlAttr(elem, QN_PREFERENCE, 0.0f, &preference)) {
+ return BadParse("candidate has unknown preference", error);
+ }
+
+ candidate->set_component(component);
+ candidate->set_address(address);
+ candidate->set_username(elem->Attr(QN_USERNAME));
+ candidate->set_preference(preference);
+ candidate->set_protocol(elem->Attr(QN_PROTOCOL));
+ candidate->set_generation_str(elem->Attr(QN_GENERATION));
+ if (elem->HasAttr(QN_PASSWORD))
+ candidate->set_password(elem->Attr(QN_PASSWORD));
+ if (elem->HasAttr(buzz::QN_TYPE))
+ candidate->set_type(elem->Attr(buzz::QN_TYPE));
+ if (elem->HasAttr(QN_NETWORK))
+ candidate->set_network_name(elem->Attr(QN_NETWORK));
+
+ if (!VerifyUsernameFormat(proto, candidate->username(), error))
+ return false;
+
+ return true;
+}
+
+bool P2PTransportParser::WriteCandidate(TransportProtocol proto,
+ const Candidate& candidate,
+ const CandidateTranslator* translator,
+ buzz::XmlElement* elem,
+ WriteError* error) {
+ ASSERT(proto == ICEPROTO_GOOGLE);
+ ASSERT(translator != NULL);
+
+ std::string channel_name;
+ if (!translator ||
+ !translator->GetChannelNameFromComponent(
+ candidate.component(), &channel_name)) {
+ return BadWrite("Cannot write candidate because of unknown component.",
+ error);
+ }
+
+ elem->SetAttr(buzz::QN_NAME, channel_name);
+ elem->SetAttr(QN_ADDRESS, candidate.address().ipaddr().ToString());
+ elem->SetAttr(QN_PORT, candidate.address().PortAsString());
+ AddXmlAttr(elem, QN_PREFERENCE, candidate.preference());
+ elem->SetAttr(QN_USERNAME, candidate.username());
+ elem->SetAttr(QN_PROTOCOL, candidate.protocol());
+ elem->SetAttr(QN_GENERATION, candidate.generation_str());
+ if (!candidate.password().empty())
+ elem->SetAttr(QN_PASSWORD, candidate.password());
+ elem->SetAttr(buzz::QN_TYPE, candidate.type());
+ if (!candidate.network_name().empty())
+ elem->SetAttr(QN_NETWORK, candidate.network_name());
+
+ return true;
+}
+
+} // namespace cricket
diff --git a/p2p/base/p2ptransport.h b/p2p/base/p2ptransport.h
new file mode 100644
index 00000000..efc65991
--- /dev/null
+++ b/p2p/base/p2ptransport.h
@@ -0,0 +1,86 @@
+/*
+ * 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 WEBRTC_P2P_BASE_P2PTRANSPORT_H_
+#define WEBRTC_P2P_BASE_P2PTRANSPORT_H_
+
+#include <string>
+#include <vector>
+#include "webrtc/p2p/base/transport.h"
+
+namespace cricket {
+
+class P2PTransport : public Transport {
+ public:
+ P2PTransport(rtc::Thread* signaling_thread,
+ rtc::Thread* worker_thread,
+ const std::string& content_name,
+ PortAllocator* allocator);
+ virtual ~P2PTransport();
+
+ protected:
+ // Creates and destroys P2PTransportChannel.
+ virtual TransportChannelImpl* CreateTransportChannel(int component);
+ virtual void DestroyTransportChannel(TransportChannelImpl* channel);
+
+ friend class P2PTransportChannel;
+
+ DISALLOW_EVIL_CONSTRUCTORS(P2PTransport);
+};
+
+class P2PTransportParser : public TransportParser {
+ public:
+ P2PTransportParser() {}
+ // Translator may be null, in which case ParseCandidates should
+ // return false if there are candidates to parse. We can't not call
+ // ParseCandidates because there's no way to know ahead of time if
+ // there are candidates or not.
+
+ // Jingle-specific functions; can be used with either ICE, GICE, or HYBRID.
+ virtual bool ParseTransportDescription(const buzz::XmlElement* elem,
+ const CandidateTranslator* translator,
+ TransportDescription* desc,
+ ParseError* error);
+ virtual bool WriteTransportDescription(const TransportDescription& desc,
+ const CandidateTranslator* translator,
+ buzz::XmlElement** elem,
+ WriteError* error);
+
+ // Legacy Gingle functions; only can be used with GICE.
+ virtual bool ParseGingleCandidate(const buzz::XmlElement* elem,
+ const CandidateTranslator* translator,
+ Candidate* candidate,
+ ParseError* error);
+ virtual bool WriteGingleCandidate(const Candidate& candidate,
+ const CandidateTranslator* translator,
+ buzz::XmlElement** elem,
+ WriteError* error);
+
+ private:
+ bool ParseCandidate(TransportProtocol proto,
+ const buzz::XmlElement* elem,
+ const CandidateTranslator* translator,
+ Candidate* candidate,
+ ParseError* error);
+ bool WriteCandidate(TransportProtocol proto,
+ const Candidate& candidate,
+ const CandidateTranslator* translator,
+ buzz::XmlElement* elem,
+ WriteError* error);
+ bool VerifyUsernameFormat(TransportProtocol proto,
+ const std::string& username,
+ ParseError* error);
+
+ DISALLOW_EVIL_CONSTRUCTORS(P2PTransportParser);
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_P2PTRANSPORT_H_
diff --git a/p2p/base/p2ptransportchannel.cc b/p2p/base/p2ptransportchannel.cc
new file mode 100644
index 00000000..84a2420b
--- /dev/null
+++ b/p2p/base/p2ptransportchannel.cc
@@ -0,0 +1,1274 @@
+/*
+ * 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 "webrtc/p2p/base/p2ptransportchannel.h"
+
+#include <set>
+#include "webrtc/p2p/base/common.h"
+#include "webrtc/p2p/base/relayport.h" // For RELAY_PORT_TYPE.
+#include "webrtc/p2p/base/stunport.h" // For STUN_PORT_TYPE.
+#include "webrtc/base/common.h"
+#include "webrtc/base/crc32.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/stringencode.h"
+
+namespace {
+
+// messages for queuing up work for ourselves
+enum {
+ MSG_SORT = 1,
+ MSG_PING,
+};
+
+// When the socket is unwritable, we will use 10 Kbps (ignoring IP+UDP headers)
+// for pinging. When the socket is writable, we will use only 1 Kbps because
+// we don't want to degrade the quality on a modem. These numbers should work
+// well on a 28.8K modem, which is the slowest connection on which the voice
+// quality is reasonable at all.
+static const uint32 PING_PACKET_SIZE = 60 * 8;
+static const uint32 WRITABLE_DELAY = 1000 * PING_PACKET_SIZE / 1000; // 480ms
+static const uint32 UNWRITABLE_DELAY = 1000 * PING_PACKET_SIZE / 10000; // 50ms
+
+// If there is a current writable connection, then we will also try hard to
+// make sure it is pinged at this rate.
+static const uint32 MAX_CURRENT_WRITABLE_DELAY = 900; // 2*WRITABLE_DELAY - bit
+
+// The minimum improvement in RTT that justifies a switch.
+static const double kMinImprovement = 10;
+
+cricket::PortInterface::CandidateOrigin GetOrigin(cricket::PortInterface* port,
+ cricket::PortInterface* origin_port) {
+ if (!origin_port)
+ return cricket::PortInterface::ORIGIN_MESSAGE;
+ else if (port == origin_port)
+ return cricket::PortInterface::ORIGIN_THIS_PORT;
+ else
+ return cricket::PortInterface::ORIGIN_OTHER_PORT;
+}
+
+// Compares two connections based only on static information about them.
+int CompareConnectionCandidates(cricket::Connection* a,
+ cricket::Connection* b) {
+ // Compare connection priority. Lower values get sorted last.
+ if (a->priority() > b->priority())
+ return 1;
+ if (a->priority() < b->priority())
+ return -1;
+
+ // If we're still tied at this point, prefer a younger generation.
+ return (a->remote_candidate().generation() + a->port()->generation()) -
+ (b->remote_candidate().generation() + b->port()->generation());
+}
+
+// Compare two connections based on their writability and static preferences.
+int CompareConnections(cricket::Connection *a, cricket::Connection *b) {
+ // Sort based on write-state. Better states have lower values.
+ if (a->write_state() < b->write_state())
+ return 1;
+ if (a->write_state() > b->write_state())
+ return -1;
+
+ // Compare the candidate information.
+ return CompareConnectionCandidates(a, b);
+}
+
+// Wraps the comparison connection into a less than operator that puts higher
+// priority writable connections first.
+class ConnectionCompare {
+ public:
+ bool operator()(const cricket::Connection *ca,
+ const cricket::Connection *cb) {
+ cricket::Connection* a = const_cast<cricket::Connection*>(ca);
+ cricket::Connection* b = const_cast<cricket::Connection*>(cb);
+
+ ASSERT(a->port()->IceProtocol() == b->port()->IceProtocol());
+
+ // Compare first on writability and static preferences.
+ int cmp = CompareConnections(a, b);
+ if (cmp > 0)
+ return true;
+ if (cmp < 0)
+ return false;
+
+ // Otherwise, sort based on latency estimate.
+ return a->rtt() < b->rtt();
+
+ // Should we bother checking for the last connection that last received
+ // data? It would help rendezvous on the connection that is also receiving
+ // packets.
+ //
+ // TODO: Yes we should definitely do this. The TCP protocol gains
+ // efficiency by being used bidirectionally, as opposed to two separate
+ // unidirectional streams. This test should probably occur before
+ // comparison of local prefs (assuming combined prefs are the same). We
+ // need to be careful though, not to bounce back and forth with both sides
+ // trying to rendevous with the other.
+ }
+};
+
+// Determines whether we should switch between two connections, based first on
+// static preferences and then (if those are equal) on latency estimates.
+bool ShouldSwitch(cricket::Connection* a_conn, cricket::Connection* b_conn) {
+ if (a_conn == b_conn)
+ return false;
+
+ if (!a_conn || !b_conn) // don't think the latter should happen
+ return true;
+
+ int prefs_cmp = CompareConnections(a_conn, b_conn);
+ if (prefs_cmp < 0)
+ return true;
+ if (prefs_cmp > 0)
+ return false;
+
+ return b_conn->rtt() <= a_conn->rtt() + kMinImprovement;
+}
+
+} // unnamed namespace
+
+namespace cricket {
+
+P2PTransportChannel::P2PTransportChannel(const std::string& content_name,
+ int component,
+ P2PTransport* transport,
+ PortAllocator *allocator) :
+ TransportChannelImpl(content_name, component),
+ transport_(transport),
+ allocator_(allocator),
+ worker_thread_(rtc::Thread::Current()),
+ incoming_only_(false),
+ waiting_for_signaling_(false),
+ error_(0),
+ best_connection_(NULL),
+ pending_best_connection_(NULL),
+ sort_dirty_(false),
+ was_writable_(false),
+ protocol_type_(ICEPROTO_HYBRID),
+ remote_ice_mode_(ICEMODE_FULL),
+ ice_role_(ICEROLE_UNKNOWN),
+ tiebreaker_(0),
+ remote_candidate_generation_(0) {
+}
+
+P2PTransportChannel::~P2PTransportChannel() {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+
+ for (uint32 i = 0; i < allocator_sessions_.size(); ++i)
+ delete allocator_sessions_[i];
+}
+
+// Add the allocator session to our list so that we know which sessions
+// are still active.
+void P2PTransportChannel::AddAllocatorSession(PortAllocatorSession* session) {
+ session->set_generation(static_cast<uint32>(allocator_sessions_.size()));
+ allocator_sessions_.push_back(session);
+
+ // We now only want to apply new candidates that we receive to the ports
+ // created by this new session because these are replacing those of the
+ // previous sessions.
+ ports_.clear();
+
+ session->SignalPortReady.connect(this, &P2PTransportChannel::OnPortReady);
+ session->SignalCandidatesReady.connect(
+ this, &P2PTransportChannel::OnCandidatesReady);
+ session->SignalCandidatesAllocationDone.connect(
+ this, &P2PTransportChannel::OnCandidatesAllocationDone);
+ session->StartGettingPorts();
+}
+
+void P2PTransportChannel::AddConnection(Connection* connection) {
+ connections_.push_back(connection);
+ connection->set_remote_ice_mode(remote_ice_mode_);
+ connection->SignalReadPacket.connect(
+ this, &P2PTransportChannel::OnReadPacket);
+ connection->SignalReadyToSend.connect(
+ this, &P2PTransportChannel::OnReadyToSend);
+ connection->SignalStateChange.connect(
+ this, &P2PTransportChannel::OnConnectionStateChange);
+ connection->SignalDestroyed.connect(
+ this, &P2PTransportChannel::OnConnectionDestroyed);
+ connection->SignalUseCandidate.connect(
+ this, &P2PTransportChannel::OnUseCandidate);
+}
+
+void P2PTransportChannel::SetIceRole(IceRole ice_role) {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+ if (ice_role_ != ice_role) {
+ ice_role_ = ice_role;
+ for (std::vector<PortInterface *>::iterator it = ports_.begin();
+ it != ports_.end(); ++it) {
+ (*it)->SetIceRole(ice_role);
+ }
+ }
+}
+
+void P2PTransportChannel::SetIceTiebreaker(uint64 tiebreaker) {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+ if (!ports_.empty()) {
+ LOG(LS_ERROR)
+ << "Attempt to change tiebreaker after Port has been allocated.";
+ return;
+ }
+
+ tiebreaker_ = tiebreaker;
+}
+
+bool P2PTransportChannel::GetIceProtocolType(IceProtocolType* type) const {
+ *type = protocol_type_;
+ return true;
+}
+
+void P2PTransportChannel::SetIceProtocolType(IceProtocolType type) {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+
+ protocol_type_ = type;
+ for (std::vector<PortInterface *>::iterator it = ports_.begin();
+ it != ports_.end(); ++it) {
+ (*it)->SetIceProtocolType(protocol_type_);
+ }
+}
+
+void P2PTransportChannel::SetIceCredentials(const std::string& ice_ufrag,
+ const std::string& ice_pwd) {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+ bool ice_restart = false;
+ if (!ice_ufrag_.empty() && !ice_pwd_.empty()) {
+ // Restart candidate allocation if there is any change in either
+ // ice ufrag or password.
+ ice_restart =
+ IceCredentialsChanged(ice_ufrag_, ice_pwd_, ice_ufrag, ice_pwd);
+ }
+
+ ice_ufrag_ = ice_ufrag;
+ ice_pwd_ = ice_pwd;
+
+ if (ice_restart) {
+ // Restart candidate gathering.
+ Allocate();
+ }
+}
+
+void P2PTransportChannel::SetRemoteIceCredentials(const std::string& ice_ufrag,
+ const std::string& ice_pwd) {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+ bool ice_restart = false;
+ if (!remote_ice_ufrag_.empty() && !remote_ice_pwd_.empty()) {
+ ice_restart = (remote_ice_ufrag_ != ice_ufrag) ||
+ (remote_ice_pwd_!= ice_pwd);
+ }
+
+ remote_ice_ufrag_ = ice_ufrag;
+ remote_ice_pwd_ = ice_pwd;
+
+ if (ice_restart) {
+ // |candidate.generation()| is not signaled in ICEPROTO_RFC5245.
+ // Therefore we need to keep track of the remote ice restart so
+ // newer connections are prioritized over the older.
+ ++remote_candidate_generation_;
+ }
+}
+
+void P2PTransportChannel::SetRemoteIceMode(IceMode mode) {
+ remote_ice_mode_ = mode;
+}
+
+// Go into the state of processing candidates, and running in general
+void P2PTransportChannel::Connect() {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+ if (ice_ufrag_.empty() || ice_pwd_.empty()) {
+ ASSERT(false);
+ LOG(LS_ERROR) << "P2PTransportChannel::Connect: The ice_ufrag_ and the "
+ << "ice_pwd_ are not set.";
+ return;
+ }
+
+ // Kick off an allocator session
+ Allocate();
+
+ // Start pinging as the ports come in.
+ thread()->Post(this, MSG_PING);
+}
+
+// Reset the socket, clear up any previous allocations and start over
+void P2PTransportChannel::Reset() {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+
+ // Get rid of all the old allocators. This should clean up everything.
+ for (uint32 i = 0; i < allocator_sessions_.size(); ++i)
+ delete allocator_sessions_[i];
+
+ allocator_sessions_.clear();
+ ports_.clear();
+ connections_.clear();
+ best_connection_ = NULL;
+
+ // Forget about all of the candidates we got before.
+ remote_candidates_.clear();
+
+ // Revert to the initial state.
+ set_readable(false);
+ set_writable(false);
+
+ // Reinitialize the rest of our state.
+ waiting_for_signaling_ = false;
+ sort_dirty_ = false;
+
+ // If we allocated before, start a new one now.
+ if (transport_->connect_requested())
+ Allocate();
+
+ // Start pinging as the ports come in.
+ thread()->Clear(this);
+ thread()->Post(this, MSG_PING);
+}
+
+// A new port is available, attempt to make connections for it
+void P2PTransportChannel::OnPortReady(PortAllocatorSession *session,
+ PortInterface* port) {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+
+ // Set in-effect options on the new port
+ for (OptionMap::const_iterator it = options_.begin();
+ it != options_.end();
+ ++it) {
+ int val = port->SetOption(it->first, it->second);
+ if (val < 0) {
+ LOG_J(LS_WARNING, port) << "SetOption(" << it->first
+ << ", " << it->second
+ << ") failed: " << port->GetError();
+ }
+ }
+
+ // Remember the ports and candidates, and signal that candidates are ready.
+ // The session will handle this, and send an initiate/accept/modify message
+ // if one is pending.
+
+ port->SetIceProtocolType(protocol_type_);
+ port->SetIceRole(ice_role_);
+ port->SetIceTiebreaker(tiebreaker_);
+ ports_.push_back(port);
+ port->SignalUnknownAddress.connect(
+ this, &P2PTransportChannel::OnUnknownAddress);
+ port->SignalDestroyed.connect(this, &P2PTransportChannel::OnPortDestroyed);
+ port->SignalRoleConflict.connect(
+ this, &P2PTransportChannel::OnRoleConflict);
+
+ // Attempt to create a connection from this new port to all of the remote
+ // candidates that we were given so far.
+
+ std::vector<RemoteCandidate>::iterator iter;
+ for (iter = remote_candidates_.begin(); iter != remote_candidates_.end();
+ ++iter) {
+ CreateConnection(port, *iter, iter->origin_port(), false);
+ }
+
+ SortConnections();
+}
+
+// A new candidate is available, let listeners know
+void P2PTransportChannel::OnCandidatesReady(
+ PortAllocatorSession *session, const std::vector<Candidate>& candidates) {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+ for (size_t i = 0; i < candidates.size(); ++i) {
+ SignalCandidateReady(this, candidates[i]);
+ }
+}
+
+void P2PTransportChannel::OnCandidatesAllocationDone(
+ PortAllocatorSession* session) {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+ SignalCandidatesAllocationDone(this);
+}
+
+// Handle stun packets
+void P2PTransportChannel::OnUnknownAddress(
+ PortInterface* port,
+ const rtc::SocketAddress& address, ProtocolType proto,
+ IceMessage* stun_msg, const std::string &remote_username,
+ bool port_muxed) {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+
+ // Port has received a valid stun packet from an address that no Connection
+ // is currently available for. See if we already have a candidate with the
+ // address. If it isn't we need to create new candidate for it.
+
+ // Determine if the remote candidates use shared ufrag.
+ bool ufrag_per_port = false;
+ std::vector<RemoteCandidate>::iterator it;
+ if (remote_candidates_.size() > 0) {
+ it = remote_candidates_.begin();
+ std::string username = it->username();
+ for (; it != remote_candidates_.end(); ++it) {
+ if (it->username() != username) {
+ ufrag_per_port = true;
+ break;
+ }
+ }
+ }
+
+ const Candidate* candidate = NULL;
+ bool known_username = false;
+ std::string remote_password;
+ for (it = remote_candidates_.begin(); it != remote_candidates_.end(); ++it) {
+ if (it->username() == remote_username) {
+ remote_password = it->password();
+ known_username = true;
+ if (ufrag_per_port ||
+ (it->address() == address &&
+ it->protocol() == ProtoToString(proto))) {
+ candidate = &(*it);
+ break;
+ }
+ // We don't want to break here because we may find a match of the address
+ // later.
+ }
+ }
+
+ if (!known_username) {
+ if (port_muxed) {
+ // When Ports are muxed, SignalUnknownAddress is delivered to all
+ // P2PTransportChannel belong to a session. Return from here will
+ // save us from sending stun binding error message from incorrect channel.
+ return;
+ }
+ // Don't know about this username, the request is bogus
+ // This sometimes happens if a binding response comes in before the ACCEPT
+ // message. It is totally valid; the retry state machine will try again.
+ port->SendBindingErrorResponse(stun_msg, address,
+ STUN_ERROR_STALE_CREDENTIALS, STUN_ERROR_REASON_STALE_CREDENTIALS);
+ return;
+ }
+
+ Candidate new_remote_candidate;
+ if (candidate != NULL) {
+ new_remote_candidate = *candidate;
+ if (ufrag_per_port) {
+ new_remote_candidate.set_address(address);
+ }
+ } else {
+ // Create a new candidate with this address.
+ std::string type;
+ if (port->IceProtocol() == ICEPROTO_RFC5245) {
+ type = PRFLX_PORT_TYPE;
+ } else {
+ // G-ICE doesn't support prflx candidate.
+ // We set candidate type to STUN_PORT_TYPE if the binding request comes
+ // from a relay port or the shared socket is used. Otherwise we use the
+ // port's type as the candidate type.
+ if (port->Type() == RELAY_PORT_TYPE || port->SharedSocket()) {
+ type = STUN_PORT_TYPE;
+ } else {
+ type = port->Type();
+ }
+ }
+
+ std::string id = rtc::CreateRandomString(8);
+ new_remote_candidate = Candidate(
+ id, component(), ProtoToString(proto), address,
+ 0, remote_username, remote_password, type,
+ port->Network()->name(), 0U,
+ rtc::ToString<uint32>(rtc::ComputeCrc32(id)));
+ new_remote_candidate.set_priority(
+ new_remote_candidate.GetPriority(ICE_TYPE_PREFERENCE_SRFLX,
+ port->Network()->preference(), 0));
+ }
+
+ if (port->IceProtocol() == ICEPROTO_RFC5245) {
+ // RFC 5245
+ // If the source transport address of the request does not match any
+ // existing remote candidates, it represents a new peer reflexive remote
+ // candidate.
+
+ // The priority of the candidate is set to the PRIORITY attribute
+ // from the request.
+ const StunUInt32Attribute* priority_attr =
+ stun_msg->GetUInt32(STUN_ATTR_PRIORITY);
+ if (!priority_attr) {
+ LOG(LS_WARNING) << "P2PTransportChannel::OnUnknownAddress - "
+ << "No STUN_ATTR_PRIORITY found in the "
+ << "stun request message";
+ port->SendBindingErrorResponse(stun_msg, address,
+ STUN_ERROR_BAD_REQUEST,
+ STUN_ERROR_REASON_BAD_REQUEST);
+ return;
+ }
+ new_remote_candidate.set_priority(priority_attr->value());
+
+ // RFC5245, the agent constructs a pair whose local candidate is equal to
+ // the transport address on which the STUN request was received, and a
+ // remote candidate equal to the source transport address where the
+ // request came from.
+
+ // There shouldn't be an existing connection with this remote address.
+ // When ports are muxed, this channel might get multiple unknown address
+ // signals. In that case if the connection is already exists, we should
+ // simply ignore the signal othewise send server error.
+ if (port->GetConnection(new_remote_candidate.address())) {
+ if (port_muxed) {
+ LOG(LS_INFO) << "Connection already exists for peer reflexive "
+ << "candidate: " << new_remote_candidate.ToString();
+ return;
+ } else {
+ ASSERT(false);
+ port->SendBindingErrorResponse(stun_msg, address,
+ STUN_ERROR_SERVER_ERROR,
+ STUN_ERROR_REASON_SERVER_ERROR);
+ return;
+ }
+ }
+
+ Connection* connection = port->CreateConnection(
+ new_remote_candidate, cricket::PortInterface::ORIGIN_THIS_PORT);
+ if (!connection) {
+ ASSERT(false);
+ port->SendBindingErrorResponse(stun_msg, address,
+ STUN_ERROR_SERVER_ERROR,
+ STUN_ERROR_REASON_SERVER_ERROR);
+ return;
+ }
+
+ AddConnection(connection);
+ connection->ReceivedPing();
+
+ // Send the pinger a successful stun response.
+ port->SendBindingResponse(stun_msg, address);
+
+ // Update the list of connections since we just added another. We do this
+ // after sending the response since it could (in principle) delete the
+ // connection in question.
+ SortConnections();
+ } else {
+ // Check for connectivity to this address. Create connections
+ // to this address across all local ports. First, add this as a new remote
+ // address
+ if (!CreateConnections(new_remote_candidate, port, true)) {
+ // Hopefully this won't occur, because changing a destination address
+ // shouldn't cause a new connection to fail
+ ASSERT(false);
+ port->SendBindingErrorResponse(stun_msg, address, STUN_ERROR_SERVER_ERROR,
+ STUN_ERROR_REASON_SERVER_ERROR);
+ return;
+ }
+
+ // Send the pinger a successful stun response.
+ port->SendBindingResponse(stun_msg, address);
+
+ // Update the list of connections since we just added another. We do this
+ // after sending the response since it could (in principle) delete the
+ // connection in question.
+ SortConnections();
+ }
+}
+
+void P2PTransportChannel::OnRoleConflict(PortInterface* port) {
+ SignalRoleConflict(this); // STUN ping will be sent when SetRole is called
+ // from Transport.
+}
+
+// When the signalling channel is ready, we can really kick off the allocator
+void P2PTransportChannel::OnSignalingReady() {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+ if (waiting_for_signaling_) {
+ waiting_for_signaling_ = false;
+ AddAllocatorSession(allocator_->CreateSession(
+ SessionId(), content_name(), component(), ice_ufrag_, ice_pwd_));
+ }
+}
+
+void P2PTransportChannel::OnUseCandidate(Connection* conn) {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+ ASSERT(ice_role_ == ICEROLE_CONTROLLED);
+ ASSERT(protocol_type_ == ICEPROTO_RFC5245);
+ if (conn->write_state() == Connection::STATE_WRITABLE) {
+ if (best_connection_ != conn) {
+ pending_best_connection_ = NULL;
+ SwitchBestConnectionTo(conn);
+ // Now we have selected the best connection, time to prune other existing
+ // connections and update the read/write state of the channel.
+ RequestSort();
+ }
+ } else {
+ pending_best_connection_ = conn;
+ }
+}
+
+void P2PTransportChannel::OnCandidate(const Candidate& candidate) {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+
+ // Create connections to this remote candidate.
+ CreateConnections(candidate, NULL, false);
+
+ // Resort the connections list, which may have new elements.
+ SortConnections();
+}
+
+// Creates connections from all of the ports that we care about to the given
+// remote candidate. The return value is true if we created a connection from
+// the origin port.
+bool P2PTransportChannel::CreateConnections(const Candidate& remote_candidate,
+ PortInterface* origin_port,
+ bool readable) {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+
+ Candidate new_remote_candidate(remote_candidate);
+ new_remote_candidate.set_generation(
+ GetRemoteCandidateGeneration(remote_candidate));
+ // ICE candidates don't need to have username and password set, but
+ // the code below this (specifically, ConnectionRequest::Prepare in
+ // port.cc) uses the remote candidates's username. So, we set it
+ // here.
+ if (remote_candidate.username().empty()) {
+ new_remote_candidate.set_username(remote_ice_ufrag_);
+ }
+ if (remote_candidate.password().empty()) {
+ new_remote_candidate.set_password(remote_ice_pwd_);
+ }
+
+ // If we've already seen the new remote candidate (in the current candidate
+ // generation), then we shouldn't try creating connections for it.
+ // We either already have a connection for it, or we previously created one
+ // and then later pruned it. If we don't return, the channel will again
+ // re-create any connections that were previously pruned, which will then
+ // immediately be re-pruned, churning the network for no purpose.
+ // This only applies to candidates received over signaling (i.e. origin_port
+ // is NULL).
+ if (!origin_port && IsDuplicateRemoteCandidate(new_remote_candidate)) {
+ // return true to indicate success, without creating any new connections.
+ return true;
+ }
+
+ // Add a new connection for this candidate to every port that allows such a
+ // connection (i.e., if they have compatible protocols) and that does not
+ // already have a connection to an equivalent candidate. We must be careful
+ // to make sure that the origin port is included, even if it was pruned,
+ // since that may be the only port that can create this connection.
+ bool created = false;
+ std::vector<PortInterface *>::reverse_iterator it;
+ for (it = ports_.rbegin(); it != ports_.rend(); ++it) {
+ if (CreateConnection(*it, new_remote_candidate, origin_port, readable)) {
+ if (*it == origin_port)
+ created = true;
+ }
+ }
+
+ if ((origin_port != NULL) &&
+ std::find(ports_.begin(), ports_.end(), origin_port) == ports_.end()) {
+ if (CreateConnection(
+ origin_port, new_remote_candidate, origin_port, readable))
+ created = true;
+ }
+
+ // Remember this remote candidate so that we can add it to future ports.
+ RememberRemoteCandidate(new_remote_candidate, origin_port);
+
+ return created;
+}
+
+// Setup a connection object for the local and remote candidate combination.
+// And then listen to connection object for changes.
+bool P2PTransportChannel::CreateConnection(PortInterface* port,
+ const Candidate& remote_candidate,
+ PortInterface* origin_port,
+ bool readable) {
+ // Look for an existing connection with this remote address. If one is not
+ // found, then we can create a new connection for this address.
+ Connection* connection = port->GetConnection(remote_candidate.address());
+ if (connection != NULL) {
+ // It is not legal to try to change any of the parameters of an existing
+ // connection; however, the other side can send a duplicate candidate.
+ if (!remote_candidate.IsEquivalent(connection->remote_candidate())) {
+ LOG(INFO) << "Attempt to change a remote candidate."
+ << " Existing remote candidate: "
+ << connection->remote_candidate().ToString()
+ << "New remote candidate: "
+ << remote_candidate.ToString();
+ return false;
+ }
+ } else {
+ PortInterface::CandidateOrigin origin = GetOrigin(port, origin_port);
+
+ // Don't create connection if this is a candidate we received in a
+ // message and we are not allowed to make outgoing connections.
+ if (origin == cricket::PortInterface::ORIGIN_MESSAGE && incoming_only_)
+ return false;
+
+ connection = port->CreateConnection(remote_candidate, origin);
+ if (!connection)
+ return false;
+
+ AddConnection(connection);
+
+ LOG_J(LS_INFO, this) << "Created connection with origin=" << origin << ", ("
+ << connections_.size() << " total)";
+ }
+
+ // If we are readable, it is because we are creating this in response to a
+ // ping from the other side. This will cause the state to become readable.
+ if (readable)
+ connection->ReceivedPing();
+
+ return true;
+}
+
+bool P2PTransportChannel::FindConnection(
+ cricket::Connection* connection) const {
+ std::vector<Connection*>::const_iterator citer =
+ std::find(connections_.begin(), connections_.end(), connection);
+ return citer != connections_.end();
+}
+
+uint32 P2PTransportChannel::GetRemoteCandidateGeneration(
+ const Candidate& candidate) {
+ if (protocol_type_ == ICEPROTO_GOOGLE) {
+ // The Candidate.generation() can be trusted. Nothing needs to be done.
+ return candidate.generation();
+ }
+ // |candidate.generation()| is not signaled in ICEPROTO_RFC5245.
+ // Therefore we need to keep track of the remote ice restart so
+ // newer connections are prioritized over the older.
+ ASSERT(candidate.generation() == 0 ||
+ candidate.generation() == remote_candidate_generation_);
+ return remote_candidate_generation_;
+}
+
+// Check if remote candidate is already cached.
+bool P2PTransportChannel::IsDuplicateRemoteCandidate(
+ const Candidate& candidate) {
+ for (uint32 i = 0; i < remote_candidates_.size(); ++i) {
+ if (remote_candidates_[i].IsEquivalent(candidate)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Maintain our remote candidate list, adding this new remote one.
+void P2PTransportChannel::RememberRemoteCandidate(
+ const Candidate& remote_candidate, PortInterface* origin_port) {
+ // Remove any candidates whose generation is older than this one. The
+ // presence of a new generation indicates that the old ones are not useful.
+ uint32 i = 0;
+ while (i < remote_candidates_.size()) {
+ if (remote_candidates_[i].generation() < remote_candidate.generation()) {
+ LOG(INFO) << "Pruning candidate from old generation: "
+ << remote_candidates_[i].address().ToSensitiveString();
+ remote_candidates_.erase(remote_candidates_.begin() + i);
+ } else {
+ i += 1;
+ }
+ }
+
+ // Make sure this candidate is not a duplicate.
+ if (IsDuplicateRemoteCandidate(remote_candidate)) {
+ LOG(INFO) << "Duplicate candidate: " << remote_candidate.ToString();
+ return;
+ }
+
+ // Try this candidate for all future ports.
+ remote_candidates_.push_back(RemoteCandidate(remote_candidate, origin_port));
+}
+
+// Set options on ourselves is simply setting options on all of our available
+// port objects.
+int P2PTransportChannel::SetOption(rtc::Socket::Option opt, int value) {
+ OptionMap::iterator it = options_.find(opt);
+ if (it == options_.end()) {
+ options_.insert(std::make_pair(opt, value));
+ } else if (it->second == value) {
+ return 0;
+ } else {
+ it->second = value;
+ }
+
+ for (uint32 i = 0; i < ports_.size(); ++i) {
+ int val = ports_[i]->SetOption(opt, value);
+ if (val < 0) {
+ // Because this also occurs deferred, probably no point in reporting an
+ // error
+ LOG(WARNING) << "SetOption(" << opt << ", " << value << ") failed: "
+ << ports_[i]->GetError();
+ }
+ }
+ return 0;
+}
+
+// Send data to the other side, using our best connection.
+int P2PTransportChannel::SendPacket(const char *data, size_t len,
+ const rtc::PacketOptions& options,
+ int flags) {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+ if (flags != 0) {
+ error_ = EINVAL;
+ return -1;
+ }
+ if (best_connection_ == NULL) {
+ error_ = EWOULDBLOCK;
+ return -1;
+ }
+
+ int sent = best_connection_->Send(data, len, options);
+ if (sent <= 0) {
+ ASSERT(sent < 0);
+ error_ = best_connection_->GetError();
+ }
+ return sent;
+}
+
+bool P2PTransportChannel::GetStats(ConnectionInfos *infos) {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+ // Gather connection infos.
+ infos->clear();
+
+ std::vector<Connection *>::const_iterator it;
+ for (it = connections_.begin(); it != connections_.end(); ++it) {
+ Connection *connection = *it;
+ ConnectionInfo info;
+ info.best_connection = (best_connection_ == connection);
+ info.readable =
+ (connection->read_state() == Connection::STATE_READABLE);
+ info.writable =
+ (connection->write_state() == Connection::STATE_WRITABLE);
+ info.timeout =
+ (connection->write_state() == Connection::STATE_WRITE_TIMEOUT);
+ info.new_connection = !connection->reported();
+ connection->set_reported(true);
+ info.rtt = connection->rtt();
+ info.sent_total_bytes = connection->sent_total_bytes();
+ info.sent_bytes_second = connection->sent_bytes_second();
+ info.recv_total_bytes = connection->recv_total_bytes();
+ info.recv_bytes_second = connection->recv_bytes_second();
+ info.local_candidate = connection->local_candidate();
+ info.remote_candidate = connection->remote_candidate();
+ info.key = connection;
+ infos->push_back(info);
+ }
+
+ return true;
+}
+
+rtc::DiffServCodePoint P2PTransportChannel::DefaultDscpValue() const {
+ OptionMap::const_iterator it = options_.find(rtc::Socket::OPT_DSCP);
+ if (it == options_.end()) {
+ return rtc::DSCP_NO_CHANGE;
+ }
+ return static_cast<rtc::DiffServCodePoint> (it->second);
+}
+
+// Begin allocate (or immediately re-allocate, if MSG_ALLOCATE pending)
+void P2PTransportChannel::Allocate() {
+ // Time for a new allocator, lets make sure we have a signalling channel
+ // to communicate candidates through first.
+ waiting_for_signaling_ = true;
+ SignalRequestSignaling(this);
+}
+
+// Monitor connection states.
+void P2PTransportChannel::UpdateConnectionStates() {
+ uint32 now = rtc::Time();
+
+ // We need to copy the list of connections since some may delete themselves
+ // when we call UpdateState.
+ for (uint32 i = 0; i < connections_.size(); ++i)
+ connections_[i]->UpdateState(now);
+}
+
+// Prepare for best candidate sorting.
+void P2PTransportChannel::RequestSort() {
+ if (!sort_dirty_) {
+ worker_thread_->Post(this, MSG_SORT);
+ sort_dirty_ = true;
+ }
+}
+
+// Sort the available connections to find the best one. We also monitor
+// the number of available connections and the current state.
+void P2PTransportChannel::SortConnections() {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+
+ // Make sure the connection states are up-to-date since this affects how they
+ // will be sorted.
+ UpdateConnectionStates();
+
+ if (protocol_type_ == ICEPROTO_HYBRID) {
+ // If we are in hybrid mode, we are not sending any ping requests, so there
+ // is no point in sorting the connections. In hybrid state, ports can have
+ // different protocol than hybrid and protocol may differ from one another.
+ // Instead just update the state of this channel
+ UpdateChannelState();
+ return;
+ }
+
+ // Any changes after this point will require a re-sort.
+ sort_dirty_ = false;
+
+ // Get a list of the networks that we are using.
+ std::set<rtc::Network*> networks;
+ for (uint32 i = 0; i < connections_.size(); ++i)
+ networks.insert(connections_[i]->port()->Network());
+
+ // Find the best alternative connection by sorting. It is important to note
+ // that amongst equal preference, writable connections, this will choose the
+ // one whose estimated latency is lowest. So it is the only one that we
+ // need to consider switching to.
+
+ ConnectionCompare cmp;
+ std::stable_sort(connections_.begin(), connections_.end(), cmp);
+ LOG(LS_VERBOSE) << "Sorting available connections:";
+ for (uint32 i = 0; i < connections_.size(); ++i) {
+ LOG(LS_VERBOSE) << connections_[i]->ToString();
+ }
+
+ Connection* top_connection = NULL;
+ if (connections_.size() > 0)
+ top_connection = connections_[0];
+
+ // We don't want to pick the best connections if channel is using RFC5245
+ // and it's mode is CONTROLLED, as connections will be selected by the
+ // CONTROLLING agent.
+
+ // If necessary, switch to the new choice.
+ if (protocol_type_ != ICEPROTO_RFC5245 || ice_role_ == ICEROLE_CONTROLLING) {
+ if (ShouldSwitch(best_connection_, top_connection))
+ SwitchBestConnectionTo(top_connection);
+ }
+
+ // We can prune any connection for which there is a writable connection on
+ // the same network with better or equal priority. We leave those with
+ // better priority just in case they become writable later (at which point,
+ // we would prune out the current best connection). We leave connections on
+ // other networks because they may not be using the same resources and they
+ // may represent very distinct paths over which we can switch.
+ std::set<rtc::Network*>::iterator network;
+ for (network = networks.begin(); network != networks.end(); ++network) {
+ Connection* primier = GetBestConnectionOnNetwork(*network);
+ if (!primier || (primier->write_state() != Connection::STATE_WRITABLE))
+ continue;
+
+ for (uint32 i = 0; i < connections_.size(); ++i) {
+ if ((connections_[i] != primier) &&
+ (connections_[i]->port()->Network() == *network) &&
+ (CompareConnectionCandidates(primier, connections_[i]) >= 0)) {
+ connections_[i]->Prune();
+ }
+ }
+ }
+
+ // Check if all connections are timedout.
+ bool all_connections_timedout = true;
+ for (uint32 i = 0; i < connections_.size(); ++i) {
+ if (connections_[i]->write_state() != Connection::STATE_WRITE_TIMEOUT) {
+ all_connections_timedout = false;
+ break;
+ }
+ }
+
+ // Now update the writable state of the channel with the information we have
+ // so far.
+ if (best_connection_ && best_connection_->writable()) {
+ HandleWritable();
+ } else if (all_connections_timedout) {
+ HandleAllTimedOut();
+ } else {
+ HandleNotWritable();
+ }
+
+ // Update the state of this channel. This method is called whenever the
+ // state of any connection changes, so this is a good place to do this.
+ UpdateChannelState();
+}
+
+
+// Track the best connection, and let listeners know
+void P2PTransportChannel::SwitchBestConnectionTo(Connection* conn) {
+ // Note: if conn is NULL, the previous best_connection_ has been destroyed,
+ // so don't use it.
+ Connection* old_best_connection = best_connection_;
+ best_connection_ = conn;
+ if (best_connection_) {
+ if (old_best_connection) {
+ LOG_J(LS_INFO, this) << "Previous best connection: "
+ << old_best_connection->ToString();
+ }
+ LOG_J(LS_INFO, this) << "New best connection: "
+ << best_connection_->ToString();
+ SignalRouteChange(this, best_connection_->remote_candidate());
+ } else {
+ LOG_J(LS_INFO, this) << "No best connection";
+ }
+}
+
+void P2PTransportChannel::UpdateChannelState() {
+ // The Handle* functions already set the writable state. We'll just double-
+ // check it here.
+ bool writable = ((best_connection_ != NULL) &&
+ (best_connection_->write_state() ==
+ Connection::STATE_WRITABLE));
+ ASSERT(writable == this->writable());
+ if (writable != this->writable())
+ LOG(LS_ERROR) << "UpdateChannelState: writable state mismatch";
+
+ bool readable = false;
+ for (uint32 i = 0; i < connections_.size(); ++i) {
+ if (connections_[i]->read_state() == Connection::STATE_READABLE) {
+ readable = true;
+ break;
+ }
+ }
+ set_readable(readable);
+}
+
+// We checked the status of our connections and we had at least one that
+// was writable, go into the writable state.
+void P2PTransportChannel::HandleWritable() {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+ if (!writable()) {
+ for (uint32 i = 0; i < allocator_sessions_.size(); ++i) {
+ if (allocator_sessions_[i]->IsGettingPorts()) {
+ allocator_sessions_[i]->StopGettingPorts();
+ }
+ }
+ }
+
+ was_writable_ = true;
+ set_writable(true);
+}
+
+// Notify upper layer about channel not writable state, if it was before.
+void P2PTransportChannel::HandleNotWritable() {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+ if (was_writable_) {
+ was_writable_ = false;
+ set_writable(false);
+ }
+}
+
+void P2PTransportChannel::HandleAllTimedOut() {
+ // Currently we are treating this as channel not writable.
+ HandleNotWritable();
+}
+
+// If we have a best connection, return it, otherwise return top one in the
+// list (later we will mark it best).
+Connection* P2PTransportChannel::GetBestConnectionOnNetwork(
+ rtc::Network* network) {
+ // If the best connection is on this network, then it wins.
+ if (best_connection_ && (best_connection_->port()->Network() == network))
+ return best_connection_;
+
+ // Otherwise, we return the top-most in sorted order.
+ for (uint32 i = 0; i < connections_.size(); ++i) {
+ if (connections_[i]->port()->Network() == network)
+ return connections_[i];
+ }
+
+ return NULL;
+}
+
+// Handle any queued up requests
+void P2PTransportChannel::OnMessage(rtc::Message *pmsg) {
+ switch (pmsg->message_id) {
+ case MSG_SORT:
+ OnSort();
+ break;
+ case MSG_PING:
+ OnPing();
+ break;
+ default:
+ ASSERT(false);
+ break;
+ }
+}
+
+// Handle queued up sort request
+void P2PTransportChannel::OnSort() {
+ // Resort the connections based on the new statistics.
+ SortConnections();
+}
+
+// Handle queued up ping request
+void P2PTransportChannel::OnPing() {
+ // Make sure the states of the connections are up-to-date (since this affects
+ // which ones are pingable).
+ UpdateConnectionStates();
+
+ // Find the oldest pingable connection and have it do a ping.
+ Connection* conn = FindNextPingableConnection();
+ if (conn)
+ PingConnection(conn);
+
+ // Post ourselves a message to perform the next ping.
+ uint32 delay = writable() ? WRITABLE_DELAY : UNWRITABLE_DELAY;
+ thread()->PostDelayed(delay, this, MSG_PING);
+}
+
+// Is the connection in a state for us to even consider pinging the other side?
+bool P2PTransportChannel::IsPingable(Connection* conn) {
+ // An unconnected connection cannot be written to at all, so pinging is out
+ // of the question.
+ if (!conn->connected())
+ return false;
+
+ if (writable()) {
+ // If we are writable, then we only want to ping connections that could be
+ // better than this one, i.e., the ones that were not pruned.
+ return (conn->write_state() != Connection::STATE_WRITE_TIMEOUT);
+ } else {
+ // If we are not writable, then we need to try everything that might work.
+ // This includes both connections that do not have write timeout as well as
+ // ones that do not have read timeout. A connection could be readable but
+ // be in write-timeout if we pruned it before. Since the other side is
+ // still pinging it, it very well might still work.
+ return (conn->write_state() != Connection::STATE_WRITE_TIMEOUT) ||
+ (conn->read_state() != Connection::STATE_READ_TIMEOUT);
+ }
+}
+
+// Returns the next pingable connection to ping. This will be the oldest
+// pingable connection unless we have a writable connection that is past the
+// maximum acceptable ping delay.
+Connection* P2PTransportChannel::FindNextPingableConnection() {
+ uint32 now = rtc::Time();
+ if (best_connection_ &&
+ (best_connection_->write_state() == Connection::STATE_WRITABLE) &&
+ (best_connection_->last_ping_sent()
+ + MAX_CURRENT_WRITABLE_DELAY <= now)) {
+ return best_connection_;
+ }
+
+ Connection* oldest_conn = NULL;
+ uint32 oldest_time = 0xFFFFFFFF;
+ for (uint32 i = 0; i < connections_.size(); ++i) {
+ if (IsPingable(connections_[i])) {
+ if (connections_[i]->last_ping_sent() < oldest_time) {
+ oldest_time = connections_[i]->last_ping_sent();
+ oldest_conn = connections_[i];
+ }
+ }
+ }
+ return oldest_conn;
+}
+
+// Apart from sending ping from |conn| this method also updates
+// |use_candidate_attr| flag. The criteria to update this flag is
+// explained below.
+// Set USE-CANDIDATE if doing ICE AND this channel is in CONTROLLING AND
+// a) Channel is in FULL ICE AND
+// a.1) |conn| is the best connection OR
+// a.2) there is no best connection OR
+// a.3) the best connection is unwritable OR
+// a.4) |conn| has higher priority than best_connection.
+// b) we're doing LITE ICE AND
+// b.1) |conn| is the best_connection AND
+// b.2) |conn| is writable.
+void P2PTransportChannel::PingConnection(Connection* conn) {
+ bool use_candidate = false;
+ if (protocol_type_ == ICEPROTO_RFC5245) {
+ if (remote_ice_mode_ == ICEMODE_FULL && ice_role_ == ICEROLE_CONTROLLING) {
+ use_candidate = (conn == best_connection_) ||
+ (best_connection_ == NULL) ||
+ (!best_connection_->writable()) ||
+ (conn->priority() > best_connection_->priority());
+ } else if (remote_ice_mode_ == ICEMODE_LITE && conn == best_connection_) {
+ use_candidate = best_connection_->writable();
+ }
+ }
+ conn->set_use_candidate_attr(use_candidate);
+ conn->Ping(rtc::Time());
+}
+
+// When a connection's state changes, we need to figure out who to use as
+// the best connection again. It could have become usable, or become unusable.
+void P2PTransportChannel::OnConnectionStateChange(Connection* connection) {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+
+ // Update the best connection if the state change is from pending best
+ // connection and role is controlled.
+ if (protocol_type_ == ICEPROTO_RFC5245 && ice_role_ == ICEROLE_CONTROLLED) {
+ if (connection == pending_best_connection_ && connection->writable()) {
+ pending_best_connection_ = NULL;
+ SwitchBestConnectionTo(connection);
+ }
+ }
+
+ // We have to unroll the stack before doing this because we may be changing
+ // the state of connections while sorting.
+ RequestSort();
+}
+
+// When a connection is removed, edit it out, and then update our best
+// connection.
+void P2PTransportChannel::OnConnectionDestroyed(Connection* connection) {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+
+ // Note: the previous best_connection_ may be destroyed by now, so don't
+ // use it.
+
+ // Remove this connection from the list.
+ std::vector<Connection*>::iterator iter =
+ std::find(connections_.begin(), connections_.end(), connection);
+ ASSERT(iter != connections_.end());
+ connections_.erase(iter);
+
+ LOG_J(LS_INFO, this) << "Removed connection ("
+ << static_cast<int>(connections_.size()) << " remaining)";
+
+ if (pending_best_connection_ == connection) {
+ pending_best_connection_ = NULL;
+ }
+
+ // If this is currently the best connection, then we need to pick a new one.
+ // The call to SortConnections will pick a new one. It looks at the current
+ // best connection in order to avoid switching between fairly similar ones.
+ // Since this connection is no longer an option, we can just set best to NULL
+ // and re-choose a best assuming that there was no best connection.
+ if (best_connection_ == connection) {
+ SwitchBestConnectionTo(NULL);
+ RequestSort();
+ }
+
+ SignalConnectionRemoved(this);
+}
+
+// When a port is destroyed remove it from our list of ports to use for
+// connection attempts.
+void P2PTransportChannel::OnPortDestroyed(PortInterface* port) {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+
+ // Remove this port from the list (if we didn't drop it already).
+ std::vector<PortInterface*>::iterator iter =
+ std::find(ports_.begin(), ports_.end(), port);
+ if (iter != ports_.end())
+ ports_.erase(iter);
+
+ LOG(INFO) << "Removed port from p2p socket: "
+ << static_cast<int>(ports_.size()) << " remaining";
+}
+
+// We data is available, let listeners know
+void P2PTransportChannel::OnReadPacket(
+ Connection *connection, const char *data, size_t len,
+ const rtc::PacketTime& packet_time) {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+
+ // Do not deliver, if packet doesn't belong to the correct transport channel.
+ if (!FindConnection(connection))
+ return;
+
+ // Let the client know of an incoming packet
+ SignalReadPacket(this, data, len, packet_time, 0);
+}
+
+void P2PTransportChannel::OnReadyToSend(Connection* connection) {
+ if (connection == best_connection_ && writable()) {
+ SignalReadyToSend(this);
+ }
+}
+
+} // namespace cricket
diff --git a/p2p/base/p2ptransportchannel.h b/p2p/base/p2ptransportchannel.h
new file mode 100644
index 00000000..8e3d50de
--- /dev/null
+++ b/p2p/base/p2ptransportchannel.h
@@ -0,0 +1,242 @@
+/*
+ * 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.
+ */
+
+// P2PTransportChannel wraps up the state management of the connection between
+// two P2P clients. Clients have candidate ports for connecting, and
+// connections which are combinations of candidates from each end (Alice and
+// Bob each have candidates, one candidate from Alice and one candidate from
+// Bob are used to make a connection, repeat to make many connections).
+//
+// When all of the available connections become invalid (non-writable), we
+// kick off a process of determining more candidates and more connections.
+//
+#ifndef WEBRTC_P2P_BASE_P2PTRANSPORTCHANNEL_H_
+#define WEBRTC_P2P_BASE_P2PTRANSPORTCHANNEL_H_
+
+#include <map>
+#include <string>
+#include <vector>
+#include "webrtc/p2p/base/candidate.h"
+#include "webrtc/p2p/base/p2ptransport.h"
+#include "webrtc/p2p/base/portallocator.h"
+#include "webrtc/p2p/base/portinterface.h"
+#include "webrtc/p2p/base/transport.h"
+#include "webrtc/p2p/base/transportchannelimpl.h"
+#include "webrtc/base/asyncpacketsocket.h"
+#include "webrtc/base/sigslot.h"
+
+namespace cricket {
+
+// Adds the port on which the candidate originated.
+class RemoteCandidate : public Candidate {
+ public:
+ RemoteCandidate(const Candidate& c, PortInterface* origin_port)
+ : Candidate(c), origin_port_(origin_port) {}
+
+ PortInterface* origin_port() { return origin_port_; }
+
+ private:
+ PortInterface* origin_port_;
+};
+
+// P2PTransportChannel manages the candidates and connection process to keep
+// two P2P clients connected to each other.
+class P2PTransportChannel : public TransportChannelImpl,
+ public rtc::MessageHandler {
+ public:
+ P2PTransportChannel(const std::string& content_name,
+ int component,
+ P2PTransport* transport,
+ PortAllocator *allocator);
+ virtual ~P2PTransportChannel();
+
+ // From TransportChannelImpl:
+ virtual Transport* GetTransport() { return transport_; }
+ virtual void SetIceRole(IceRole role);
+ virtual IceRole GetIceRole() const { return ice_role_; }
+ virtual void SetIceTiebreaker(uint64 tiebreaker);
+ virtual size_t GetConnectionCount() const { return connections_.size(); }
+ virtual bool GetIceProtocolType(IceProtocolType* type) const;
+ virtual void SetIceProtocolType(IceProtocolType type);
+ virtual void SetIceCredentials(const std::string& ice_ufrag,
+ const std::string& ice_pwd);
+ virtual void SetRemoteIceCredentials(const std::string& ice_ufrag,
+ const std::string& ice_pwd);
+ virtual void SetRemoteIceMode(IceMode mode);
+ virtual void Connect();
+ virtual void Reset();
+ virtual void OnSignalingReady();
+ virtual void OnCandidate(const Candidate& candidate);
+
+ // From TransportChannel:
+ virtual int SendPacket(const char *data, size_t len,
+ const rtc::PacketOptions& options, int flags);
+ virtual int SetOption(rtc::Socket::Option opt, int value);
+ virtual int GetError() { return error_; }
+ virtual bool GetStats(std::vector<ConnectionInfo>* stats);
+
+ const Connection* best_connection() const { return best_connection_; }
+ void set_incoming_only(bool value) { incoming_only_ = value; }
+
+ // Note: This is only for testing purpose.
+ // |ports_| should not be changed from outside.
+ const std::vector<PortInterface *>& ports() { return ports_; }
+
+ IceMode remote_ice_mode() const { return remote_ice_mode_; }
+
+ // DTLS methods.
+ virtual bool IsDtlsActive() const { return false; }
+
+ // Default implementation.
+ virtual bool GetSslRole(rtc::SSLRole* role) const {
+ return false;
+ }
+
+ virtual bool SetSslRole(rtc::SSLRole role) {
+ return false;
+ }
+
+ // Set up the ciphers to use for DTLS-SRTP.
+ virtual bool SetSrtpCiphers(const std::vector<std::string>& ciphers) {
+ return false;
+ }
+
+ // Find out which DTLS-SRTP cipher was negotiated
+ virtual bool GetSrtpCipher(std::string* cipher) {
+ return false;
+ }
+
+ // Returns false because the channel is not encrypted by default.
+ virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const {
+ return false;
+ }
+
+ virtual bool GetRemoteCertificate(rtc::SSLCertificate** cert) const {
+ return false;
+ }
+
+ // Allows key material to be extracted for external encryption.
+ virtual bool ExportKeyingMaterial(
+ const std::string& label,
+ const uint8* context,
+ size_t context_len,
+ bool use_context,
+ uint8* result,
+ size_t result_len) {
+ return false;
+ }
+
+ virtual bool SetLocalIdentity(rtc::SSLIdentity* identity) {
+ return false;
+ }
+
+ // Set DTLS Remote fingerprint. Must be after local identity set.
+ virtual bool SetRemoteFingerprint(
+ const std::string& digest_alg,
+ const uint8* digest,
+ size_t digest_len) {
+ return false;
+ }
+
+ // Helper method used only in unittest.
+ rtc::DiffServCodePoint DefaultDscpValue() const;
+
+ private:
+ rtc::Thread* thread() { return worker_thread_; }
+ PortAllocatorSession* allocator_session() {
+ return allocator_sessions_.back();
+ }
+
+ void Allocate();
+ void UpdateConnectionStates();
+ void RequestSort();
+ void SortConnections();
+ void SwitchBestConnectionTo(Connection* conn);
+ void UpdateChannelState();
+ void HandleWritable();
+ void HandleNotWritable();
+ void HandleAllTimedOut();
+
+ Connection* GetBestConnectionOnNetwork(rtc::Network* network);
+ bool CreateConnections(const Candidate &remote_candidate,
+ PortInterface* origin_port, bool readable);
+ bool CreateConnection(PortInterface* port, const Candidate& remote_candidate,
+ PortInterface* origin_port, bool readable);
+ bool FindConnection(cricket::Connection* connection) const;
+
+ uint32 GetRemoteCandidateGeneration(const Candidate& candidate);
+ bool IsDuplicateRemoteCandidate(const Candidate& candidate);
+ void RememberRemoteCandidate(const Candidate& remote_candidate,
+ PortInterface* origin_port);
+ bool IsPingable(Connection* conn);
+ Connection* FindNextPingableConnection();
+ void PingConnection(Connection* conn);
+ void AddAllocatorSession(PortAllocatorSession* session);
+ void AddConnection(Connection* connection);
+
+ void OnPortReady(PortAllocatorSession *session, PortInterface* port);
+ void OnCandidatesReady(PortAllocatorSession *session,
+ const std::vector<Candidate>& candidates);
+ void OnCandidatesAllocationDone(PortAllocatorSession* session);
+ void OnUnknownAddress(PortInterface* port,
+ const rtc::SocketAddress& addr,
+ ProtocolType proto,
+ IceMessage* stun_msg,
+ const std::string& remote_username,
+ bool port_muxed);
+ void OnPortDestroyed(PortInterface* port);
+ void OnRoleConflict(PortInterface* port);
+
+ void OnConnectionStateChange(Connection* connection);
+ void OnReadPacket(Connection *connection, const char *data, size_t len,
+ const rtc::PacketTime& packet_time);
+ void OnReadyToSend(Connection* connection);
+ void OnConnectionDestroyed(Connection *connection);
+
+ void OnUseCandidate(Connection* conn);
+
+ virtual void OnMessage(rtc::Message *pmsg);
+ void OnSort();
+ void OnPing();
+
+ P2PTransport* transport_;
+ PortAllocator *allocator_;
+ rtc::Thread *worker_thread_;
+ bool incoming_only_;
+ bool waiting_for_signaling_;
+ int error_;
+ std::vector<PortAllocatorSession*> allocator_sessions_;
+ std::vector<PortInterface *> ports_;
+ std::vector<Connection *> connections_;
+ Connection* best_connection_;
+ // Connection selected by the controlling agent. This should be used only
+ // at controlled side when protocol type is RFC5245.
+ Connection* pending_best_connection_;
+ std::vector<RemoteCandidate> remote_candidates_;
+ bool sort_dirty_; // indicates whether another sort is needed right now
+ bool was_writable_;
+ typedef std::map<rtc::Socket::Option, int> OptionMap;
+ OptionMap options_;
+ std::string ice_ufrag_;
+ std::string ice_pwd_;
+ std::string remote_ice_ufrag_;
+ std::string remote_ice_pwd_;
+ IceProtocolType protocol_type_;
+ IceMode remote_ice_mode_;
+ IceRole ice_role_;
+ uint64 tiebreaker_;
+ uint32 remote_candidate_generation_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(P2PTransportChannel);
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_P2PTRANSPORTCHANNEL_H_
diff --git a/p2p/base/p2ptransportchannel_unittest.cc b/p2p/base/p2ptransportchannel_unittest.cc
new file mode 100644
index 00000000..4f32719e
--- /dev/null
+++ b/p2p/base/p2ptransportchannel_unittest.cc
@@ -0,0 +1,1702 @@
+/*
+ * Copyright 2009 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can 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 "webrtc/p2p/base/p2ptransportchannel.h"
+#include "webrtc/p2p/base/testrelayserver.h"
+#include "webrtc/p2p/base/teststunserver.h"
+#include "webrtc/p2p/base/testturnserver.h"
+#include "webrtc/p2p/client/basicportallocator.h"
+#include "webrtc/base/dscp.h"
+#include "webrtc/base/fakenetwork.h"
+#include "webrtc/base/firewallsocketserver.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/natserver.h"
+#include "webrtc/base/natsocketfactory.h"
+#include "webrtc/base/physicalsocketserver.h"
+#include "webrtc/base/proxyserver.h"
+#include "webrtc/base/socketaddress.h"
+#include "webrtc/base/ssladapter.h"
+#include "webrtc/base/thread.h"
+#include "webrtc/base/virtualsocketserver.h"
+
+using cricket::kDefaultPortAllocatorFlags;
+using cricket::kMinimumStepDelay;
+using cricket::kDefaultStepDelay;
+using cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG;
+using cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET;
+using cricket::ServerAddresses;
+using rtc::SocketAddress;
+
+static const int kDefaultTimeout = 1000;
+static const int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
+ cricket::PORTALLOCATOR_DISABLE_RELAY |
+ cricket::PORTALLOCATOR_DISABLE_TCP;
+// Addresses on the public internet.
+static const SocketAddress kPublicAddrs[2] =
+ { SocketAddress("11.11.11.11", 0), SocketAddress("22.22.22.22", 0) };
+// IPv6 Addresses on the public internet.
+static const SocketAddress kIPv6PublicAddrs[2] = {
+ SocketAddress("2400:4030:1:2c00:be30:abcd:efab:cdef", 0),
+ SocketAddress("2620:0:1000:1b03:2e41:38ff:fea6:f2a4", 0)
+};
+// For configuring multihomed clients.
+static const SocketAddress kAlternateAddrs[2] =
+ { SocketAddress("11.11.11.101", 0), SocketAddress("22.22.22.202", 0) };
+// Addresses for HTTP proxy servers.
+static const SocketAddress kHttpsProxyAddrs[2] =
+ { SocketAddress("11.11.11.1", 443), SocketAddress("22.22.22.1", 443) };
+// Addresses for SOCKS proxy servers.
+static const SocketAddress kSocksProxyAddrs[2] =
+ { SocketAddress("11.11.11.1", 1080), SocketAddress("22.22.22.1", 1080) };
+// Internal addresses for NAT boxes.
+static const SocketAddress kNatAddrs[2] =
+ { SocketAddress("192.168.1.1", 0), SocketAddress("192.168.2.1", 0) };
+// Private addresses inside the NAT private networks.
+static const SocketAddress kPrivateAddrs[2] =
+ { SocketAddress("192.168.1.11", 0), SocketAddress("192.168.2.22", 0) };
+// For cascaded NATs, the internal addresses of the inner NAT boxes.
+static const SocketAddress kCascadedNatAddrs[2] =
+ { SocketAddress("192.168.10.1", 0), SocketAddress("192.168.20.1", 0) };
+// For cascaded NATs, private addresses inside the inner private networks.
+static const SocketAddress kCascadedPrivateAddrs[2] =
+ { SocketAddress("192.168.10.11", 0), SocketAddress("192.168.20.22", 0) };
+// The address of the public STUN server.
+static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
+// The addresses for the public relay server.
+static const SocketAddress kRelayUdpIntAddr("99.99.99.2", 5000);
+static const SocketAddress kRelayUdpExtAddr("99.99.99.3", 5001);
+static const SocketAddress kRelayTcpIntAddr("99.99.99.2", 5002);
+static const SocketAddress kRelayTcpExtAddr("99.99.99.3", 5003);
+static const SocketAddress kRelaySslTcpIntAddr("99.99.99.2", 5004);
+static const SocketAddress kRelaySslTcpExtAddr("99.99.99.3", 5005);
+// The addresses for the public turn server.
+static const SocketAddress kTurnUdpIntAddr("99.99.99.4",
+ cricket::STUN_SERVER_PORT);
+static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
+static const cricket::RelayCredentials kRelayCredentials("test", "test");
+
+// Based on ICE_UFRAG_LENGTH
+static const char* kIceUfrag[4] = {"TESTICEUFRAG0000", "TESTICEUFRAG0001",
+ "TESTICEUFRAG0002", "TESTICEUFRAG0003"};
+// Based on ICE_PWD_LENGTH
+static const char* kIcePwd[4] = {"TESTICEPWD00000000000000",
+ "TESTICEPWD00000000000001",
+ "TESTICEPWD00000000000002",
+ "TESTICEPWD00000000000003"};
+
+static const uint64 kTiebreaker1 = 11111;
+static const uint64 kTiebreaker2 = 22222;
+
+// This test simulates 2 P2P endpoints that want to establish connectivity
+// with each other over various network topologies and conditions, which can be
+// specified in each individial test.
+// A virtual network (via VirtualSocketServer) along with virtual firewalls and
+// NATs (via Firewall/NATSocketServer) are used to simulate the various network
+// conditions. We can configure the IP addresses of the endpoints,
+// block various types of connectivity, or add arbitrary levels of NAT.
+// We also run a STUN server and a relay server on the virtual network to allow
+// our typical P2P mechanisms to do their thing.
+// For each case, we expect the P2P stack to eventually settle on a specific
+// form of connectivity to the other side. The test checks that the P2P
+// negotiation successfully establishes connectivity within a certain time,
+// and that the result is what we expect.
+// Note that this class is a base class for use by other tests, who will provide
+// specialized test behavior.
+class P2PTransportChannelTestBase : public testing::Test,
+ public rtc::MessageHandler,
+ public sigslot::has_slots<> {
+ public:
+ P2PTransportChannelTestBase()
+ : main_(rtc::Thread::Current()),
+ pss_(new rtc::PhysicalSocketServer),
+ vss_(new rtc::VirtualSocketServer(pss_.get())),
+ nss_(new rtc::NATSocketServer(vss_.get())),
+ ss_(new rtc::FirewallSocketServer(nss_.get())),
+ ss_scope_(ss_.get()),
+ stun_server_(cricket::TestStunServer::Create(main_, kStunAddr)),
+ turn_server_(main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
+ relay_server_(main_, kRelayUdpIntAddr, kRelayUdpExtAddr,
+ kRelayTcpIntAddr, kRelayTcpExtAddr,
+ kRelaySslTcpIntAddr, kRelaySslTcpExtAddr),
+ socks_server1_(ss_.get(), kSocksProxyAddrs[0],
+ ss_.get(), kSocksProxyAddrs[0]),
+ socks_server2_(ss_.get(), kSocksProxyAddrs[1],
+ ss_.get(), kSocksProxyAddrs[1]),
+ clear_remote_candidates_ufrag_pwd_(false),
+ force_relay_(false) {
+ ep1_.role_ = cricket::ICEROLE_CONTROLLING;
+ ep2_.role_ = cricket::ICEROLE_CONTROLLED;
+
+ ServerAddresses stun_servers;
+ stun_servers.insert(kStunAddr);
+ ep1_.allocator_.reset(new cricket::BasicPortAllocator(
+ &ep1_.network_manager_,
+ stun_servers, kRelayUdpIntAddr, kRelayTcpIntAddr, kRelaySslTcpIntAddr));
+ ep2_.allocator_.reset(new cricket::BasicPortAllocator(
+ &ep2_.network_manager_,
+ stun_servers, kRelayUdpIntAddr, kRelayTcpIntAddr, kRelaySslTcpIntAddr));
+ }
+
+ protected:
+ enum Config {
+ OPEN, // Open to the Internet
+ NAT_FULL_CONE, // NAT, no filtering
+ NAT_ADDR_RESTRICTED, // NAT, must send to an addr to recv
+ NAT_PORT_RESTRICTED, // NAT, must send to an addr+port to recv
+ NAT_SYMMETRIC, // NAT, endpoint-dependent bindings
+ NAT_DOUBLE_CONE, // Double NAT, both cone
+ NAT_SYMMETRIC_THEN_CONE, // Double NAT, symmetric outer, cone inner
+ BLOCK_UDP, // Firewall, UDP in/out blocked
+ BLOCK_UDP_AND_INCOMING_TCP, // Firewall, UDP in/out and TCP in blocked
+ BLOCK_ALL_BUT_OUTGOING_HTTP, // Firewall, only TCP out on 80/443
+ PROXY_HTTPS, // All traffic through HTTPS proxy
+ PROXY_SOCKS, // All traffic through SOCKS proxy
+ NUM_CONFIGS
+ };
+
+ struct Result {
+ Result(const std::string& lt, const std::string& lp,
+ const std::string& rt, const std::string& rp,
+ const std::string& lt2, const std::string& lp2,
+ const std::string& rt2, const std::string& rp2, int wait)
+ : local_type(lt), local_proto(lp), remote_type(rt), remote_proto(rp),
+ local_type2(lt2), local_proto2(lp2), remote_type2(rt2),
+ remote_proto2(rp2), connect_wait(wait) {
+ }
+ std::string local_type;
+ std::string local_proto;
+ std::string remote_type;
+ std::string remote_proto;
+ std::string local_type2;
+ std::string local_proto2;
+ std::string remote_type2;
+ std::string remote_proto2;
+ int connect_wait;
+ };
+
+ struct ChannelData {
+ bool CheckData(const char* data, int len) {
+ bool ret = false;
+ if (!ch_packets_.empty()) {
+ std::string packet = ch_packets_.front();
+ ret = (packet == std::string(data, len));
+ ch_packets_.pop_front();
+ }
+ return ret;
+ }
+
+ std::string name_; // TODO - Currently not used.
+ std::list<std::string> ch_packets_;
+ rtc::scoped_ptr<cricket::P2PTransportChannel> ch_;
+ };
+
+ struct Endpoint {
+ Endpoint() : signaling_delay_(0), role_(cricket::ICEROLE_UNKNOWN),
+ tiebreaker_(0), role_conflict_(false),
+ protocol_type_(cricket::ICEPROTO_GOOGLE) {}
+ bool HasChannel(cricket::TransportChannel* ch) {
+ return (ch == cd1_.ch_.get() || ch == cd2_.ch_.get());
+ }
+ ChannelData* GetChannelData(cricket::TransportChannel* ch) {
+ if (!HasChannel(ch)) return NULL;
+ if (cd1_.ch_.get() == ch)
+ return &cd1_;
+ else
+ return &cd2_;
+ }
+ void SetSignalingDelay(int delay) { signaling_delay_ = delay; }
+
+ void SetIceRole(cricket::IceRole role) { role_ = role; }
+ cricket::IceRole ice_role() { return role_; }
+ void SetIceProtocolType(cricket::IceProtocolType type) {
+ protocol_type_ = type;
+ }
+ cricket::IceProtocolType protocol_type() { return protocol_type_; }
+ void SetIceTiebreaker(uint64 tiebreaker) { tiebreaker_ = tiebreaker; }
+ uint64 GetIceTiebreaker() { return tiebreaker_; }
+ void OnRoleConflict(bool role_conflict) { role_conflict_ = role_conflict; }
+ bool role_conflict() { return role_conflict_; }
+ void SetAllocationStepDelay(uint32 delay) {
+ allocator_->set_step_delay(delay);
+ }
+ void SetAllowTcpListen(bool allow_tcp_listen) {
+ allocator_->set_allow_tcp_listen(allow_tcp_listen);
+ }
+
+ rtc::FakeNetworkManager network_manager_;
+ rtc::scoped_ptr<cricket::BasicPortAllocator> allocator_;
+ ChannelData cd1_;
+ ChannelData cd2_;
+ int signaling_delay_;
+ cricket::IceRole role_;
+ uint64 tiebreaker_;
+ bool role_conflict_;
+ cricket::IceProtocolType protocol_type_;
+ };
+
+ struct CandidateData : public rtc::MessageData {
+ CandidateData(cricket::TransportChannel* ch, const cricket::Candidate& c)
+ : channel(ch), candidate(c) {
+ }
+ cricket::TransportChannel* channel;
+ cricket::Candidate candidate;
+ };
+
+ ChannelData* GetChannelData(cricket::TransportChannel* channel) {
+ if (ep1_.HasChannel(channel))
+ return ep1_.GetChannelData(channel);
+ else
+ return ep2_.GetChannelData(channel);
+ }
+
+ void CreateChannels(int num) {
+ std::string ice_ufrag_ep1_cd1_ch = kIceUfrag[0];
+ std::string ice_pwd_ep1_cd1_ch = kIcePwd[0];
+ std::string ice_ufrag_ep2_cd1_ch = kIceUfrag[1];
+ std::string ice_pwd_ep2_cd1_ch = kIcePwd[1];
+ ep1_.cd1_.ch_.reset(CreateChannel(
+ 0, cricket::ICE_CANDIDATE_COMPONENT_DEFAULT,
+ ice_ufrag_ep1_cd1_ch, ice_pwd_ep1_cd1_ch,
+ ice_ufrag_ep2_cd1_ch, ice_pwd_ep2_cd1_ch));
+ ep2_.cd1_.ch_.reset(CreateChannel(
+ 1, cricket::ICE_CANDIDATE_COMPONENT_DEFAULT,
+ ice_ufrag_ep2_cd1_ch, ice_pwd_ep2_cd1_ch,
+ ice_ufrag_ep1_cd1_ch, ice_pwd_ep1_cd1_ch));
+ if (num == 2) {
+ std::string ice_ufrag_ep1_cd2_ch = kIceUfrag[2];
+ std::string ice_pwd_ep1_cd2_ch = kIcePwd[2];
+ std::string ice_ufrag_ep2_cd2_ch = kIceUfrag[3];
+ std::string ice_pwd_ep2_cd2_ch = kIcePwd[3];
+ // In BUNDLE each endpoint must share common ICE credentials.
+ if (ep1_.allocator_->flags() & cricket::PORTALLOCATOR_ENABLE_BUNDLE) {
+ ice_ufrag_ep1_cd2_ch = ice_ufrag_ep1_cd1_ch;
+ ice_pwd_ep1_cd2_ch = ice_pwd_ep1_cd1_ch;
+ }
+ if (ep2_.allocator_->flags() & cricket::PORTALLOCATOR_ENABLE_BUNDLE) {
+ ice_ufrag_ep2_cd2_ch = ice_ufrag_ep2_cd1_ch;
+ ice_pwd_ep2_cd2_ch = ice_pwd_ep2_cd1_ch;
+ }
+ ep1_.cd2_.ch_.reset(CreateChannel(
+ 0, cricket::ICE_CANDIDATE_COMPONENT_DEFAULT,
+ ice_ufrag_ep1_cd2_ch, ice_pwd_ep1_cd2_ch,
+ ice_ufrag_ep2_cd2_ch, ice_pwd_ep2_cd2_ch));
+ ep2_.cd2_.ch_.reset(CreateChannel(
+ 1, cricket::ICE_CANDIDATE_COMPONENT_DEFAULT,
+ ice_ufrag_ep2_cd2_ch, ice_pwd_ep2_cd2_ch,
+ ice_ufrag_ep1_cd2_ch, ice_pwd_ep1_cd2_ch));
+ }
+ }
+ cricket::P2PTransportChannel* CreateChannel(
+ int endpoint,
+ int component,
+ const std::string& local_ice_ufrag,
+ const std::string& local_ice_pwd,
+ const std::string& remote_ice_ufrag,
+ const std::string& remote_ice_pwd) {
+ cricket::P2PTransportChannel* channel = new cricket::P2PTransportChannel(
+ "test content name", component, NULL, GetAllocator(endpoint));
+ channel->SignalRequestSignaling.connect(
+ this, &P2PTransportChannelTestBase::OnChannelRequestSignaling);
+ channel->SignalCandidateReady.connect(this,
+ &P2PTransportChannelTestBase::OnCandidate);
+ channel->SignalReadPacket.connect(
+ this, &P2PTransportChannelTestBase::OnReadPacket);
+ channel->SignalRoleConflict.connect(
+ this, &P2PTransportChannelTestBase::OnRoleConflict);
+ channel->SetIceProtocolType(GetEndpoint(endpoint)->protocol_type());
+ channel->SetIceCredentials(local_ice_ufrag, local_ice_pwd);
+ if (clear_remote_candidates_ufrag_pwd_) {
+ // This only needs to be set if we're clearing them from the
+ // candidates. Some unit tests rely on this not being set.
+ channel->SetRemoteIceCredentials(remote_ice_ufrag, remote_ice_pwd);
+ }
+ channel->SetIceRole(GetEndpoint(endpoint)->ice_role());
+ channel->SetIceTiebreaker(GetEndpoint(endpoint)->GetIceTiebreaker());
+ channel->Connect();
+ return channel;
+ }
+ void DestroyChannels() {
+ ep1_.cd1_.ch_.reset();
+ ep2_.cd1_.ch_.reset();
+ ep1_.cd2_.ch_.reset();
+ ep2_.cd2_.ch_.reset();
+ }
+ cricket::P2PTransportChannel* ep1_ch1() { return ep1_.cd1_.ch_.get(); }
+ cricket::P2PTransportChannel* ep1_ch2() { return ep1_.cd2_.ch_.get(); }
+ cricket::P2PTransportChannel* ep2_ch1() { return ep2_.cd1_.ch_.get(); }
+ cricket::P2PTransportChannel* ep2_ch2() { return ep2_.cd2_.ch_.get(); }
+
+ // Common results.
+ static const Result kLocalUdpToLocalUdp;
+ static const Result kLocalUdpToStunUdp;
+ static const Result kLocalUdpToPrflxUdp;
+ static const Result kPrflxUdpToLocalUdp;
+ static const Result kStunUdpToLocalUdp;
+ static const Result kStunUdpToStunUdp;
+ static const Result kPrflxUdpToStunUdp;
+ static const Result kLocalUdpToRelayUdp;
+ static const Result kPrflxUdpToRelayUdp;
+ static const Result kLocalTcpToLocalTcp;
+ static const Result kLocalTcpToPrflxTcp;
+ static const Result kPrflxTcpToLocalTcp;
+
+ rtc::NATSocketServer* nat() { return nss_.get(); }
+ rtc::FirewallSocketServer* fw() { return ss_.get(); }
+
+ Endpoint* GetEndpoint(int endpoint) {
+ if (endpoint == 0) {
+ return &ep1_;
+ } else if (endpoint == 1) {
+ return &ep2_;
+ } else {
+ return NULL;
+ }
+ }
+ cricket::PortAllocator* GetAllocator(int endpoint) {
+ return GetEndpoint(endpoint)->allocator_.get();
+ }
+ void AddAddress(int endpoint, const SocketAddress& addr) {
+ GetEndpoint(endpoint)->network_manager_.AddInterface(addr);
+ }
+ void RemoveAddress(int endpoint, const SocketAddress& addr) {
+ GetEndpoint(endpoint)->network_manager_.RemoveInterface(addr);
+ }
+ void SetProxy(int endpoint, rtc::ProxyType type) {
+ rtc::ProxyInfo info;
+ info.type = type;
+ info.address = (type == rtc::PROXY_HTTPS) ?
+ kHttpsProxyAddrs[endpoint] : kSocksProxyAddrs[endpoint];
+ GetAllocator(endpoint)->set_proxy("unittest/1.0", info);
+ }
+ void SetAllocatorFlags(int endpoint, int flags) {
+ GetAllocator(endpoint)->set_flags(flags);
+ }
+ void SetSignalingDelay(int endpoint, int delay) {
+ GetEndpoint(endpoint)->SetSignalingDelay(delay);
+ }
+ void SetIceProtocol(int endpoint, cricket::IceProtocolType type) {
+ GetEndpoint(endpoint)->SetIceProtocolType(type);
+ }
+ void SetIceRole(int endpoint, cricket::IceRole role) {
+ GetEndpoint(endpoint)->SetIceRole(role);
+ }
+ void SetIceTiebreaker(int endpoint, uint64 tiebreaker) {
+ GetEndpoint(endpoint)->SetIceTiebreaker(tiebreaker);
+ }
+ bool GetRoleConflict(int endpoint) {
+ return GetEndpoint(endpoint)->role_conflict();
+ }
+ void SetAllocationStepDelay(int endpoint, uint32 delay) {
+ return GetEndpoint(endpoint)->SetAllocationStepDelay(delay);
+ }
+ void SetAllowTcpListen(int endpoint, bool allow_tcp_listen) {
+ return GetEndpoint(endpoint)->SetAllowTcpListen(allow_tcp_listen);
+ }
+
+ void Test(const Result& expected) {
+ int32 connect_start = rtc::Time(), connect_time;
+
+ // Create the channels and wait for them to connect.
+ CreateChannels(1);
+ EXPECT_TRUE_WAIT_MARGIN(ep1_ch1() != NULL &&
+ ep2_ch1() != NULL &&
+ ep1_ch1()->readable() &&
+ ep1_ch1()->writable() &&
+ ep2_ch1()->readable() &&
+ ep2_ch1()->writable(),
+ expected.connect_wait,
+ 1000);
+ connect_time = rtc::TimeSince(connect_start);
+ if (connect_time < expected.connect_wait) {
+ LOG(LS_INFO) << "Connect time: " << connect_time << " ms";
+ } else {
+ LOG(LS_INFO) << "Connect time: " << "TIMEOUT ("
+ << expected.connect_wait << " ms)";
+ }
+
+ // Allow a few turns of the crank for the best connections to emerge.
+ // This may take up to 2 seconds.
+ if (ep1_ch1()->best_connection() &&
+ ep2_ch1()->best_connection()) {
+ int32 converge_start = rtc::Time(), converge_time;
+ int converge_wait = 2000;
+ EXPECT_TRUE_WAIT_MARGIN(
+ LocalCandidate(ep1_ch1())->type() == expected.local_type &&
+ LocalCandidate(ep1_ch1())->protocol() == expected.local_proto &&
+ RemoteCandidate(ep1_ch1())->type() == expected.remote_type &&
+ RemoteCandidate(ep1_ch1())->protocol() == expected.remote_proto,
+ converge_wait,
+ converge_wait);
+
+ // Also do EXPECT_EQ on each part so that failures are more verbose.
+ EXPECT_EQ(expected.local_type, LocalCandidate(ep1_ch1())->type());
+ EXPECT_EQ(expected.local_proto, LocalCandidate(ep1_ch1())->protocol());
+ EXPECT_EQ(expected.remote_type, RemoteCandidate(ep1_ch1())->type());
+ EXPECT_EQ(expected.remote_proto, RemoteCandidate(ep1_ch1())->protocol());
+
+ // Verifying remote channel best connection information. This is done
+ // only for the RFC 5245 as controlled agent will use USE-CANDIDATE
+ // from controlling (ep1) agent. We can easily predict from EP1 result
+ // matrix.
+ if (ep2_.protocol_type_ == cricket::ICEPROTO_RFC5245) {
+ // Checking for best connection candidates information at remote.
+ EXPECT_TRUE_WAIT(
+ LocalCandidate(ep2_ch1())->type() == expected.local_type2 &&
+ LocalCandidate(ep2_ch1())->protocol() == expected.local_proto2 &&
+ RemoteCandidate(ep2_ch1())->protocol() == expected.remote_proto2,
+ kDefaultTimeout);
+
+ // For verbose
+ EXPECT_EQ(expected.local_type2, LocalCandidate(ep2_ch1())->type());
+ EXPECT_EQ(expected.local_proto2, LocalCandidate(ep2_ch1())->protocol());
+ EXPECT_EQ(expected.remote_proto2,
+ RemoteCandidate(ep2_ch1())->protocol());
+ // Removed remote_type comparision aginst best connection remote
+ // candidate. This is done to handle remote type discrepancy from
+ // local to stun based on the test type.
+ // For example in case of Open -> NAT, ep2 channels will have LULU
+ // and in other cases like NAT -> NAT it will be LUSU. To avoid these
+ // mismatches and we are doing comparision in different way.
+ // i.e. when don't match its remote type is either local or stun.
+ // TODO(ronghuawu): Refine the test criteria.
+ // https://code.google.com/p/webrtc/issues/detail?id=1953
+ if (expected.remote_type2 != RemoteCandidate(ep2_ch1())->type()) {
+ EXPECT_TRUE(expected.remote_type2 == cricket::LOCAL_PORT_TYPE ||
+ expected.remote_type2 == cricket::STUN_PORT_TYPE);
+ EXPECT_TRUE(
+ RemoteCandidate(ep2_ch1())->type() == cricket::LOCAL_PORT_TYPE ||
+ RemoteCandidate(ep2_ch1())->type() == cricket::STUN_PORT_TYPE ||
+ RemoteCandidate(ep2_ch1())->type() == cricket::PRFLX_PORT_TYPE);
+ }
+ }
+
+ converge_time = rtc::TimeSince(converge_start);
+ if (converge_time < converge_wait) {
+ LOG(LS_INFO) << "Converge time: " << converge_time << " ms";
+ } else {
+ LOG(LS_INFO) << "Converge time: " << "TIMEOUT ("
+ << converge_wait << " ms)";
+ }
+ }
+ // Try sending some data to other end.
+ TestSendRecv(1);
+
+ // Destroy the channels, and wait for them to be fully cleaned up.
+ DestroyChannels();
+ }
+
+ void TestSendRecv(int channels) {
+ for (int i = 0; i < 10; ++i) {
+ const char* data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
+ int len = static_cast<int>(strlen(data));
+ // local_channel1 <==> remote_channel1
+ EXPECT_EQ_WAIT(len, SendData(ep1_ch1(), data, len), 1000);
+ EXPECT_TRUE_WAIT(CheckDataOnChannel(ep2_ch1(), data, len), 1000);
+ EXPECT_EQ_WAIT(len, SendData(ep2_ch1(), data, len), 1000);
+ EXPECT_TRUE_WAIT(CheckDataOnChannel(ep1_ch1(), data, len), 1000);
+ if (channels == 2 && ep1_ch2() && ep2_ch2()) {
+ // local_channel2 <==> remote_channel2
+ EXPECT_EQ_WAIT(len, SendData(ep1_ch2(), data, len), 1000);
+ EXPECT_TRUE_WAIT(CheckDataOnChannel(ep2_ch2(), data, len), 1000);
+ EXPECT_EQ_WAIT(len, SendData(ep2_ch2(), data, len), 1000);
+ EXPECT_TRUE_WAIT(CheckDataOnChannel(ep1_ch2(), data, len), 1000);
+ }
+ }
+ }
+
+ // This test waits for the transport to become readable and writable on both
+ // end points. Once they are, the end points set new local ice credentials to
+ // restart the ice gathering. Finally it waits for the transport to select a
+ // new connection using the newly generated ice candidates.
+ // Before calling this function the end points must be configured.
+ void TestHandleIceUfragPasswordChanged() {
+ ep1_ch1()->SetRemoteIceCredentials(kIceUfrag[1], kIcePwd[1]);
+ ep2_ch1()->SetRemoteIceCredentials(kIceUfrag[0], kIcePwd[0]);
+ EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->readable() && ep1_ch1()->writable() &&
+ ep2_ch1()->readable() && ep2_ch1()->writable(),
+ 1000, 1000);
+
+ const cricket::Candidate* old_local_candidate1 = LocalCandidate(ep1_ch1());
+ const cricket::Candidate* old_local_candidate2 = LocalCandidate(ep2_ch1());
+ const cricket::Candidate* old_remote_candidate1 =
+ RemoteCandidate(ep1_ch1());
+ const cricket::Candidate* old_remote_candidate2 =
+ RemoteCandidate(ep2_ch1());
+
+ ep1_ch1()->SetIceCredentials(kIceUfrag[2], kIcePwd[2]);
+ ep1_ch1()->SetRemoteIceCredentials(kIceUfrag[3], kIcePwd[3]);
+ ep2_ch1()->SetIceCredentials(kIceUfrag[3], kIcePwd[3]);
+ ep2_ch1()->SetRemoteIceCredentials(kIceUfrag[2], kIcePwd[2]);
+
+ EXPECT_TRUE_WAIT_MARGIN(LocalCandidate(ep1_ch1())->generation() !=
+ old_local_candidate1->generation(),
+ 1000, 1000);
+ EXPECT_TRUE_WAIT_MARGIN(LocalCandidate(ep2_ch1())->generation() !=
+ old_local_candidate2->generation(),
+ 1000, 1000);
+ EXPECT_TRUE_WAIT_MARGIN(RemoteCandidate(ep1_ch1())->generation() !=
+ old_remote_candidate1->generation(),
+ 1000, 1000);
+ EXPECT_TRUE_WAIT_MARGIN(RemoteCandidate(ep2_ch1())->generation() !=
+ old_remote_candidate2->generation(),
+ 1000, 1000);
+ EXPECT_EQ(1u, RemoteCandidate(ep2_ch1())->generation());
+ EXPECT_EQ(1u, RemoteCandidate(ep1_ch1())->generation());
+ }
+
+ void TestSignalRoleConflict() {
+ SetIceProtocol(0, cricket::ICEPROTO_RFC5245);
+ SetIceTiebreaker(0, kTiebreaker1); // Default EP1 is in controlling state.
+
+ SetIceProtocol(1, cricket::ICEPROTO_RFC5245);
+ SetIceRole(1, cricket::ICEROLE_CONTROLLING);
+ SetIceTiebreaker(1, kTiebreaker2);
+
+ // Creating channels with both channels role set to CONTROLLING.
+ CreateChannels(1);
+ // Since both the channels initiated with controlling state and channel2
+ // has higher tiebreaker value, channel1 should receive SignalRoleConflict.
+ EXPECT_TRUE_WAIT(GetRoleConflict(0), 1000);
+ EXPECT_FALSE(GetRoleConflict(1));
+
+ EXPECT_TRUE_WAIT(ep1_ch1()->readable() &&
+ ep1_ch1()->writable() &&
+ ep2_ch1()->readable() &&
+ ep2_ch1()->writable(),
+ 1000);
+
+ EXPECT_TRUE(ep1_ch1()->best_connection() &&
+ ep2_ch1()->best_connection());
+
+ TestSendRecv(1);
+ }
+
+ void TestHybridConnectivity(cricket::IceProtocolType proto) {
+ AddAddress(0, kPublicAddrs[0]);
+ AddAddress(1, kPublicAddrs[1]);
+
+ SetAllocationStepDelay(0, kMinimumStepDelay);
+ SetAllocationStepDelay(1, kMinimumStepDelay);
+
+ SetIceRole(0, cricket::ICEROLE_CONTROLLING);
+ SetIceProtocol(0, cricket::ICEPROTO_HYBRID);
+ SetIceTiebreaker(0, kTiebreaker1);
+ SetIceRole(1, cricket::ICEROLE_CONTROLLED);
+ SetIceProtocol(1, proto);
+ SetIceTiebreaker(1, kTiebreaker2);
+
+ CreateChannels(1);
+ // When channel is in hybrid and it's controlling agent, channel will
+ // receive ping request from the remote. Hence connection is readable.
+ // Since channel is in hybrid, it will not send any pings, so no writable
+ // connection. Since channel2 is in controlled state, it will not have
+ // any connections which are readable or writable, as it didn't received
+ // pings (or none) with USE-CANDIDATE attribute.
+ EXPECT_TRUE_WAIT(ep1_ch1()->readable(), 1000);
+
+ // Set real protocol type.
+ ep1_ch1()->SetIceProtocolType(proto);
+
+ // Channel should able to send ping requests and connections become writable
+ // in both directions.
+ EXPECT_TRUE_WAIT(ep1_ch1()->readable() && ep1_ch1()->writable() &&
+ ep2_ch1()->readable() && ep2_ch1()->writable(),
+ 1000);
+ EXPECT_TRUE(
+ ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
+ LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
+ RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
+
+ TestSendRecv(1);
+ DestroyChannels();
+ }
+
+ void OnChannelRequestSignaling(cricket::TransportChannelImpl* channel) {
+ channel->OnSignalingReady();
+ }
+ // We pass the candidates directly to the other side.
+ void OnCandidate(cricket::TransportChannelImpl* ch,
+ const cricket::Candidate& c) {
+ if (force_relay_ && c.type() != cricket::RELAY_PORT_TYPE)
+ return;
+
+ main_->PostDelayed(GetEndpoint(ch)->signaling_delay_, this, 0,
+ new CandidateData(ch, c));
+ }
+ void OnMessage(rtc::Message* msg) {
+ rtc::scoped_ptr<CandidateData> data(
+ static_cast<CandidateData*>(msg->pdata));
+ cricket::P2PTransportChannel* rch = GetRemoteChannel(data->channel);
+ cricket::Candidate c = data->candidate;
+ if (clear_remote_candidates_ufrag_pwd_) {
+ c.set_username("");
+ c.set_password("");
+ }
+ LOG(LS_INFO) << "Candidate(" << data->channel->component() << "->"
+ << rch->component() << "): " << c.type() << ", " << c.protocol()
+ << ", " << c.address().ToString() << ", " << c.username()
+ << ", " << c.generation();
+ rch->OnCandidate(c);
+ }
+ void OnReadPacket(cricket::TransportChannel* channel, const char* data,
+ size_t len, const rtc::PacketTime& packet_time,
+ int flags) {
+ std::list<std::string>& packets = GetPacketList(channel);
+ packets.push_front(std::string(data, len));
+ }
+ void OnRoleConflict(cricket::TransportChannelImpl* channel) {
+ GetEndpoint(channel)->OnRoleConflict(true);
+ cricket::IceRole new_role =
+ GetEndpoint(channel)->ice_role() == cricket::ICEROLE_CONTROLLING ?
+ cricket::ICEROLE_CONTROLLED : cricket::ICEROLE_CONTROLLING;
+ channel->SetIceRole(new_role);
+ }
+ int SendData(cricket::TransportChannel* channel,
+ const char* data, size_t len) {
+ rtc::PacketOptions options;
+ return channel->SendPacket(data, len, options, 0);
+ }
+ bool CheckDataOnChannel(cricket::TransportChannel* channel,
+ const char* data, int len) {
+ return GetChannelData(channel)->CheckData(data, len);
+ }
+ static const cricket::Candidate* LocalCandidate(
+ cricket::P2PTransportChannel* ch) {
+ return (ch && ch->best_connection()) ?
+ &ch->best_connection()->local_candidate() : NULL;
+ }
+ static const cricket::Candidate* RemoteCandidate(
+ cricket::P2PTransportChannel* ch) {
+ return (ch && ch->best_connection()) ?
+ &ch->best_connection()->remote_candidate() : NULL;
+ }
+ Endpoint* GetEndpoint(cricket::TransportChannel* ch) {
+ if (ep1_.HasChannel(ch)) {
+ return &ep1_;
+ } else if (ep2_.HasChannel(ch)) {
+ return &ep2_;
+ } else {
+ return NULL;
+ }
+ }
+ cricket::P2PTransportChannel* GetRemoteChannel(
+ cricket::TransportChannel* ch) {
+ if (ch == ep1_ch1())
+ return ep2_ch1();
+ else if (ch == ep1_ch2())
+ return ep2_ch2();
+ else if (ch == ep2_ch1())
+ return ep1_ch1();
+ else if (ch == ep2_ch2())
+ return ep1_ch2();
+ else
+ return NULL;
+ }
+ std::list<std::string>& GetPacketList(cricket::TransportChannel* ch) {
+ return GetChannelData(ch)->ch_packets_;
+ }
+
+ void set_clear_remote_candidates_ufrag_pwd(bool clear) {
+ clear_remote_candidates_ufrag_pwd_ = clear;
+ }
+
+ void set_force_relay(bool relay) {
+ force_relay_ = relay;
+ }
+
+ private:
+ rtc::Thread* main_;
+ rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
+ rtc::scoped_ptr<rtc::VirtualSocketServer> vss_;
+ rtc::scoped_ptr<rtc::NATSocketServer> nss_;
+ rtc::scoped_ptr<rtc::FirewallSocketServer> ss_;
+ rtc::SocketServerScope ss_scope_;
+ rtc::scoped_ptr<cricket::TestStunServer> stun_server_;
+ cricket::TestTurnServer turn_server_;
+ cricket::TestRelayServer relay_server_;
+ rtc::SocksProxyServer socks_server1_;
+ rtc::SocksProxyServer socks_server2_;
+ Endpoint ep1_;
+ Endpoint ep2_;
+ bool clear_remote_candidates_ufrag_pwd_;
+ bool force_relay_;
+};
+
+// The tests have only a few outcomes, which we predefine.
+const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
+ kLocalUdpToLocalUdp("local", "udp", "local", "udp",
+ "local", "udp", "local", "udp", 1000);
+const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
+ kLocalUdpToStunUdp("local", "udp", "stun", "udp",
+ "local", "udp", "stun", "udp", 1000);
+const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
+ kLocalUdpToPrflxUdp("local", "udp", "prflx", "udp",
+ "prflx", "udp", "local", "udp", 1000);
+const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
+ kPrflxUdpToLocalUdp("prflx", "udp", "local", "udp",
+ "local", "udp", "prflx", "udp", 1000);
+const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
+ kStunUdpToLocalUdp("stun", "udp", "local", "udp",
+ "local", "udp", "stun", "udp", 1000);
+const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
+ kStunUdpToStunUdp("stun", "udp", "stun", "udp",
+ "stun", "udp", "stun", "udp", 1000);
+const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
+ kPrflxUdpToStunUdp("prflx", "udp", "stun", "udp",
+ "local", "udp", "prflx", "udp", 1000);
+const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
+ kLocalUdpToRelayUdp("local", "udp", "relay", "udp",
+ "relay", "udp", "local", "udp", 2000);
+const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
+ kPrflxUdpToRelayUdp("prflx", "udp", "relay", "udp",
+ "relay", "udp", "prflx", "udp", 2000);
+const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
+ kLocalTcpToLocalTcp("local", "tcp", "local", "tcp",
+ "local", "tcp", "local", "tcp", 3000);
+const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
+ kLocalTcpToPrflxTcp("local", "tcp", "prflx", "tcp",
+ "prflx", "tcp", "local", "tcp", 3000);
+const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
+ kPrflxTcpToLocalTcp("prflx", "tcp", "local", "tcp",
+ "local", "tcp", "prflx", "tcp", 3000);
+
+// Test the matrix of all the connectivity types we expect to see in the wild.
+// Just test every combination of the configs in the Config enum.
+class P2PTransportChannelTest : public P2PTransportChannelTestBase {
+ protected:
+ static const Result* kMatrix[NUM_CONFIGS][NUM_CONFIGS];
+ static const Result* kMatrixSharedUfrag[NUM_CONFIGS][NUM_CONFIGS];
+ static const Result* kMatrixSharedSocketAsGice[NUM_CONFIGS][NUM_CONFIGS];
+ static const Result* kMatrixSharedSocketAsIce[NUM_CONFIGS][NUM_CONFIGS];
+ void ConfigureEndpoints(Config config1, Config config2,
+ int allocator_flags1, int allocator_flags2,
+ int delay1, int delay2,
+ cricket::IceProtocolType type) {
+ // Ideally we want to use TURN server for both GICE and ICE, but in case
+ // of GICE, TURN server usage is not producing results reliabally.
+ // TODO(mallinath): Remove Relay and use TURN server for all tests.
+ ServerAddresses stun_servers;
+ stun_servers.insert(kStunAddr);
+ GetEndpoint(0)->allocator_.reset(
+ new cricket::BasicPortAllocator(&(GetEndpoint(0)->network_manager_),
+ stun_servers,
+ rtc::SocketAddress(), rtc::SocketAddress(),
+ rtc::SocketAddress()));
+ GetEndpoint(1)->allocator_.reset(
+ new cricket::BasicPortAllocator(&(GetEndpoint(1)->network_manager_),
+ stun_servers,
+ rtc::SocketAddress(), rtc::SocketAddress(),
+ rtc::SocketAddress()));
+
+ cricket::RelayServerConfig relay_server(cricket::RELAY_GTURN);
+ if (type == cricket::ICEPROTO_RFC5245) {
+ relay_server.type = cricket::RELAY_TURN;
+ relay_server.credentials = kRelayCredentials;
+ relay_server.ports.push_back(cricket::ProtocolAddress(
+ kTurnUdpIntAddr, cricket::PROTO_UDP, false));
+ } else {
+ relay_server.ports.push_back(cricket::ProtocolAddress(
+ kRelayUdpIntAddr, cricket::PROTO_UDP, false));
+ relay_server.ports.push_back(cricket::ProtocolAddress(
+ kRelayTcpIntAddr, cricket::PROTO_TCP, false));
+ relay_server.ports.push_back(cricket::ProtocolAddress(
+ kRelaySslTcpIntAddr, cricket::PROTO_SSLTCP, false));
+ }
+ GetEndpoint(0)->allocator_->AddRelay(relay_server);
+ GetEndpoint(1)->allocator_->AddRelay(relay_server);
+
+ ConfigureEndpoint(0, config1);
+ SetIceProtocol(0, type);
+ SetAllocatorFlags(0, allocator_flags1);
+ SetAllocationStepDelay(0, delay1);
+ ConfigureEndpoint(1, config2);
+ SetIceProtocol(1, type);
+ SetAllocatorFlags(1, allocator_flags2);
+ SetAllocationStepDelay(1, delay2);
+ }
+ void ConfigureEndpoint(int endpoint, Config config) {
+ switch (config) {
+ case OPEN:
+ AddAddress(endpoint, kPublicAddrs[endpoint]);
+ break;
+ case NAT_FULL_CONE:
+ case NAT_ADDR_RESTRICTED:
+ case NAT_PORT_RESTRICTED:
+ case NAT_SYMMETRIC:
+ AddAddress(endpoint, kPrivateAddrs[endpoint]);
+ // Add a single NAT of the desired type
+ nat()->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
+ static_cast<rtc::NATType>(config - NAT_FULL_CONE))->
+ AddClient(kPrivateAddrs[endpoint]);
+ break;
+ case NAT_DOUBLE_CONE:
+ case NAT_SYMMETRIC_THEN_CONE:
+ AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
+ // Add a two cascaded NATs of the desired types
+ nat()->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
+ (config == NAT_DOUBLE_CONE) ?
+ rtc::NAT_OPEN_CONE : rtc::NAT_SYMMETRIC)->
+ AddTranslator(kPrivateAddrs[endpoint], kCascadedNatAddrs[endpoint],
+ rtc::NAT_OPEN_CONE)->
+ AddClient(kCascadedPrivateAddrs[endpoint]);
+ break;
+ case BLOCK_UDP:
+ case BLOCK_UDP_AND_INCOMING_TCP:
+ case BLOCK_ALL_BUT_OUTGOING_HTTP:
+ case PROXY_HTTPS:
+ case PROXY_SOCKS:
+ AddAddress(endpoint, kPublicAddrs[endpoint]);
+ // Block all UDP
+ fw()->AddRule(false, rtc::FP_UDP, rtc::FD_ANY,
+ kPublicAddrs[endpoint]);
+ if (config == BLOCK_UDP_AND_INCOMING_TCP) {
+ // Block TCP inbound to the endpoint
+ fw()->AddRule(false, rtc::FP_TCP, SocketAddress(),
+ kPublicAddrs[endpoint]);
+ } else if (config == BLOCK_ALL_BUT_OUTGOING_HTTP) {
+ // Block all TCP to/from the endpoint except 80/443 out
+ fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
+ SocketAddress(rtc::IPAddress(INADDR_ANY), 80));
+ fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
+ SocketAddress(rtc::IPAddress(INADDR_ANY), 443));
+ fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
+ kPublicAddrs[endpoint]);
+ } else if (config == PROXY_HTTPS) {
+ // Block all TCP to/from the endpoint except to the proxy server
+ fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
+ kHttpsProxyAddrs[endpoint]);
+ fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
+ kPublicAddrs[endpoint]);
+ SetProxy(endpoint, rtc::PROXY_HTTPS);
+ } else if (config == PROXY_SOCKS) {
+ // Block all TCP to/from the endpoint except to the proxy server
+ fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
+ kSocksProxyAddrs[endpoint]);
+ fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
+ kPublicAddrs[endpoint]);
+ SetProxy(endpoint, rtc::PROXY_SOCKS5);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+};
+
+// Shorthands for use in the test matrix.
+#define LULU &kLocalUdpToLocalUdp
+#define LUSU &kLocalUdpToStunUdp
+#define LUPU &kLocalUdpToPrflxUdp
+#define PULU &kPrflxUdpToLocalUdp
+#define SULU &kStunUdpToLocalUdp
+#define SUSU &kStunUdpToStunUdp
+#define PUSU &kPrflxUdpToStunUdp
+#define LURU &kLocalUdpToRelayUdp
+#define PURU &kPrflxUdpToRelayUdp
+#define LTLT &kLocalTcpToLocalTcp
+#define LTPT &kLocalTcpToPrflxTcp
+#define PTLT &kPrflxTcpToLocalTcp
+// TODO: Enable these once TestRelayServer can accept external TCP.
+#define LTRT NULL
+#define LSRS NULL
+
+// Test matrix. Originator behavior defined by rows, receiever by columns.
+
+// Currently the p2ptransportchannel.cc (specifically the
+// P2PTransportChannel::OnUnknownAddress) operates in 2 modes depend on the
+// remote candidates - ufrag per port or shared ufrag.
+// For example, if the remote candidates have the shared ufrag, for the unknown
+// address reaches the OnUnknownAddress, we will try to find the matched
+// remote candidate based on the address and protocol, if not found, a new
+// remote candidate will be created for this address. But if the remote
+// candidates have different ufrags, we will try to find the matched remote
+// candidate by comparing the ufrag. If not found, an error will be returned.
+// Because currently the shared ufrag feature is under the experiment and will
+// be rolled out gradually. We want to test the different combinations of peers
+// with/without the shared ufrag enabled. And those different combinations have
+// different expectation of the best connection. For example in the OpenToCONE
+// case, an unknown address will be updated to a "host" remote candidate if the
+// remote peer uses different ufrag per port. But in the shared ufrag case,
+// a "stun" (should be peer-reflexive eventually) candidate will be created for
+// that. So the expected best candidate will be LUSU instead of LULU.
+// With all these, we have to keep 2 test matrixes for the tests:
+// kMatrix - for the tests that the remote peer uses different ufrag per port.
+// kMatrixSharedUfrag - for the tests that remote peer uses shared ufrag.
+// The different between the two matrixes are on:
+// OPToCONE, OPTo2CON,
+// COToCONE, COToADDR, COToPORT, COToSYMM, COTo2CON, COToSCON,
+// ADToCONE, ADToADDR, ADTo2CON,
+// POToADDR,
+// SYToADDR,
+// 2CToCONE, 2CToADDR, 2CToPORT, 2CToSYMM, 2CTo2CON, 2CToSCON,
+// SCToADDR,
+
+// TODO: Fix NULLs caused by lack of TCP support in NATSocket.
+// TODO: Fix NULLs caused by no HTTP proxy support.
+// TODO: Rearrange rows/columns from best to worst.
+// TODO(ronghuawu): Keep only one test matrix once the shared ufrag is enabled.
+const P2PTransportChannelTest::Result*
+ P2PTransportChannelTest::kMatrix[NUM_CONFIGS][NUM_CONFIGS] = {
+// OPEN CONE ADDR PORT SYMM 2CON SCON !UDP !TCP HTTP PRXH PRXS
+/*OP*/ {LULU, LULU, LULU, LULU, LULU, LULU, LULU, LTLT, LTLT, LSRS, NULL, LTLT},
+/*CO*/ {LULU, LULU, LULU, SULU, SULU, LULU, SULU, NULL, NULL, LSRS, NULL, LTRT},
+/*AD*/ {LULU, LULU, LULU, SUSU, SUSU, LULU, SUSU, NULL, NULL, LSRS, NULL, LTRT},
+/*PO*/ {LULU, LUSU, LUSU, SUSU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
+/*SY*/ {LULU, LUSU, LUSU, LURU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
+/*2C*/ {LULU, LULU, LULU, SULU, SULU, LULU, SULU, NULL, NULL, LSRS, NULL, LTRT},
+/*SC*/ {LULU, LUSU, LUSU, LURU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
+/*!U*/ {LTLT, NULL, NULL, NULL, NULL, NULL, NULL, LTLT, LTLT, LSRS, NULL, LTRT},
+/*!T*/ {LTRT, NULL, NULL, NULL, NULL, NULL, NULL, LTLT, LTRT, LSRS, NULL, LTRT},
+/*HT*/ {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL, LSRS},
+/*PR*/ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+/*PR*/ {LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LSRS, NULL, LTRT},
+};
+const P2PTransportChannelTest::Result*
+ P2PTransportChannelTest::kMatrixSharedUfrag[NUM_CONFIGS][NUM_CONFIGS] = {
+// OPEN CONE ADDR PORT SYMM 2CON SCON !UDP !TCP HTTP PRXH PRXS
+/*OP*/ {LULU, LUSU, LULU, LULU, LULU, LUSU, LULU, LTLT, LTLT, LSRS, NULL, LTLT},
+/*CO*/ {LULU, LUSU, LUSU, SUSU, SUSU, LUSU, SUSU, NULL, NULL, LSRS, NULL, LTRT},
+/*AD*/ {LULU, LUSU, LUSU, SUSU, SUSU, LUSU, SUSU, NULL, NULL, LSRS, NULL, LTRT},
+/*PO*/ {LULU, LUSU, LUSU, SUSU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
+/*SY*/ {LULU, LUSU, LUSU, LURU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
+/*2C*/ {LULU, LUSU, LUSU, SUSU, SUSU, LUSU, SUSU, NULL, NULL, LSRS, NULL, LTRT},
+/*SC*/ {LULU, LUSU, LUSU, LURU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
+/*!U*/ {LTLT, NULL, NULL, NULL, NULL, NULL, NULL, LTLT, LTLT, LSRS, NULL, LTRT},
+/*!T*/ {LTRT, NULL, NULL, NULL, NULL, NULL, NULL, LTLT, LTRT, LSRS, NULL, LTRT},
+/*HT*/ {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL, LSRS},
+/*PR*/ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+/*PR*/ {LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LSRS, NULL, LTRT},
+};
+const P2PTransportChannelTest::Result*
+ P2PTransportChannelTest::kMatrixSharedSocketAsGice
+ [NUM_CONFIGS][NUM_CONFIGS] = {
+// OPEN CONE ADDR PORT SYMM 2CON SCON !UDP !TCP HTTP PRXH PRXS
+/*OP*/ {LULU, LUSU, LUSU, LUSU, LUSU, LUSU, LUSU, LTLT, LTLT, LSRS, NULL, LTLT},
+/*CO*/ {LULU, LUSU, LUSU, LUSU, LUSU, LUSU, LUSU, NULL, NULL, LSRS, NULL, LTRT},
+/*AD*/ {LULU, LUSU, LUSU, LUSU, LUSU, LUSU, LUSU, NULL, NULL, LSRS, NULL, LTRT},
+/*PO*/ {LULU, LUSU, LUSU, LUSU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
+/*SY*/ {LULU, LUSU, LUSU, LURU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
+/*2C*/ {LULU, LUSU, LUSU, LUSU, LUSU, LUSU, LUSU, NULL, NULL, LSRS, NULL, LTRT},
+/*SC*/ {LULU, LUSU, LUSU, LURU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
+/*!U*/ {LTLT, NULL, NULL, NULL, NULL, NULL, NULL, LTLT, LTLT, LSRS, NULL, LTRT},
+/*!T*/ {LTRT, NULL, NULL, NULL, NULL, NULL, NULL, LTLT, LTRT, LSRS, NULL, LTRT},
+/*HT*/ {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL, LSRS},
+/*PR*/ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+/*PR*/ {LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LSRS, NULL, LTRT},
+};
+const P2PTransportChannelTest::Result*
+ P2PTransportChannelTest::kMatrixSharedSocketAsIce
+ [NUM_CONFIGS][NUM_CONFIGS] = {
+// OPEN CONE ADDR PORT SYMM 2CON SCON !UDP !TCP HTTP PRXH PRXS
+/*OP*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, PTLT, LTPT, LSRS, NULL, PTLT},
+/*CO*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, NULL, NULL, LSRS, NULL, LTRT},
+/*AD*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, NULL, NULL, LSRS, NULL, LTRT},
+/*PO*/ {LULU, LUSU, LUSU, LUSU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
+/*SY*/ {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL, LTRT},
+/*2C*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, NULL, NULL, LSRS, NULL, LTRT},
+/*SC*/ {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL, LTRT},
+/*!U*/ {PTLT, NULL, NULL, NULL, NULL, NULL, NULL, PTLT, LTPT, LSRS, NULL, LTRT},
+/*!T*/ {LTRT, NULL, NULL, NULL, NULL, NULL, NULL, PTLT, LTRT, LSRS, NULL, LTRT},
+/*HT*/ {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL, LSRS},
+/*PR*/ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+/*PR*/ {LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LSRS, NULL, LTRT},
+};
+
+// The actual tests that exercise all the various configurations.
+// Test names are of the form P2PTransportChannelTest_TestOPENToNAT_FULL_CONE
+// Same test case is run in both GICE and ICE mode.
+// kDefaultStepDelay - is used for all Gice cases.
+// kMinimumStepDelay - is used when both end points have
+// PORTALLOCATOR_ENABLE_SHARED_UFRAG flag enabled.
+// Technically we should be able to use kMinimumStepDelay irrespective of
+// protocol type. But which might need modifications to current result matrices
+// for tests in this file.
+#define P2P_TEST_DECLARATION(x, y, z) \
+ TEST_F(P2PTransportChannelTest, z##Test##x##To##y##AsGiceNoneSharedUfrag) { \
+ ConfigureEndpoints(x, y, kDefaultPortAllocatorFlags, \
+ kDefaultPortAllocatorFlags, \
+ kDefaultStepDelay, kDefaultStepDelay, \
+ cricket::ICEPROTO_GOOGLE); \
+ if (kMatrix[x][y] != NULL) \
+ Test(*kMatrix[x][y]); \
+ else \
+ LOG(LS_WARNING) << "Not yet implemented"; \
+ } \
+ TEST_F(P2PTransportChannelTest, z##Test##x##To##y##AsGiceP0SharedUfrag) { \
+ ConfigureEndpoints(x, y, PORTALLOCATOR_ENABLE_SHARED_UFRAG, \
+ kDefaultPortAllocatorFlags, \
+ kDefaultStepDelay, kDefaultStepDelay, \
+ cricket::ICEPROTO_GOOGLE); \
+ if (kMatrix[x][y] != NULL) \
+ Test(*kMatrix[x][y]); \
+ else \
+ LOG(LS_WARNING) << "Not yet implemented"; \
+ } \
+ TEST_F(P2PTransportChannelTest, z##Test##x##To##y##AsGiceP1SharedUfrag) { \
+ ConfigureEndpoints(x, y, kDefaultPortAllocatorFlags, \
+ PORTALLOCATOR_ENABLE_SHARED_UFRAG, \
+ kDefaultStepDelay, kDefaultStepDelay, \
+ cricket::ICEPROTO_GOOGLE); \
+ if (kMatrixSharedUfrag[x][y] != NULL) \
+ Test(*kMatrixSharedUfrag[x][y]); \
+ else \
+ LOG(LS_WARNING) << "Not yet implemented"; \
+ } \
+ TEST_F(P2PTransportChannelTest, z##Test##x##To##y##AsGiceBothSharedUfrag) { \
+ ConfigureEndpoints(x, y, PORTALLOCATOR_ENABLE_SHARED_UFRAG, \
+ PORTALLOCATOR_ENABLE_SHARED_UFRAG, \
+ kDefaultStepDelay, kDefaultStepDelay, \
+ cricket::ICEPROTO_GOOGLE); \
+ if (kMatrixSharedUfrag[x][y] != NULL) \
+ Test(*kMatrixSharedUfrag[x][y]); \
+ else \
+ LOG(LS_WARNING) << "Not yet implemented"; \
+ } \
+ TEST_F(P2PTransportChannelTest, \
+ z##Test##x##To##y##AsGiceBothSharedUfragWithMinimumStepDelay) { \
+ ConfigureEndpoints(x, y, PORTALLOCATOR_ENABLE_SHARED_UFRAG, \
+ PORTALLOCATOR_ENABLE_SHARED_UFRAG, \
+ kMinimumStepDelay, kMinimumStepDelay, \
+ cricket::ICEPROTO_GOOGLE); \
+ if (kMatrixSharedUfrag[x][y] != NULL) \
+ Test(*kMatrixSharedUfrag[x][y]); \
+ else \
+ LOG(LS_WARNING) << "Not yet implemented"; \
+ } \
+ TEST_F(P2PTransportChannelTest, \
+ z##Test##x##To##y##AsGiceBothSharedUfragSocket) { \
+ ConfigureEndpoints(x, y, PORTALLOCATOR_ENABLE_SHARED_UFRAG | \
+ PORTALLOCATOR_ENABLE_SHARED_SOCKET, \
+ PORTALLOCATOR_ENABLE_SHARED_UFRAG | \
+ PORTALLOCATOR_ENABLE_SHARED_SOCKET, \
+ kMinimumStepDelay, kMinimumStepDelay, \
+ cricket::ICEPROTO_GOOGLE); \
+ if (kMatrixSharedSocketAsGice[x][y] != NULL) \
+ Test(*kMatrixSharedSocketAsGice[x][y]); \
+ else \
+ LOG(LS_WARNING) << "Not yet implemented"; \
+ } \
+ TEST_F(P2PTransportChannelTest, z##Test##x##To##y##AsIce) { \
+ ConfigureEndpoints(x, y, PORTALLOCATOR_ENABLE_SHARED_UFRAG | \
+ PORTALLOCATOR_ENABLE_SHARED_SOCKET, \
+ PORTALLOCATOR_ENABLE_SHARED_UFRAG | \
+ PORTALLOCATOR_ENABLE_SHARED_SOCKET, \
+ kMinimumStepDelay, kMinimumStepDelay, \
+ cricket::ICEPROTO_RFC5245); \
+ if (kMatrixSharedSocketAsIce[x][y] != NULL) \
+ Test(*kMatrixSharedSocketAsIce[x][y]); \
+ else \
+ LOG(LS_WARNING) << "Not yet implemented"; \
+ }
+
+#define P2P_TEST(x, y) \
+ P2P_TEST_DECLARATION(x, y,)
+
+#define FLAKY_P2P_TEST(x, y) \
+ P2P_TEST_DECLARATION(x, y, DISABLED_)
+
+// TODO(holmer): Disabled due to randomly failing on webrtc buildbots.
+// Issue: webrtc/2383
+#define P2P_TEST_SET(x) \
+ P2P_TEST(x, OPEN) \
+ FLAKY_P2P_TEST(x, NAT_FULL_CONE) \
+ FLAKY_P2P_TEST(x, NAT_ADDR_RESTRICTED) \
+ FLAKY_P2P_TEST(x, NAT_PORT_RESTRICTED) \
+ P2P_TEST(x, NAT_SYMMETRIC) \
+ FLAKY_P2P_TEST(x, NAT_DOUBLE_CONE) \
+ P2P_TEST(x, NAT_SYMMETRIC_THEN_CONE) \
+ P2P_TEST(x, BLOCK_UDP) \
+ P2P_TEST(x, BLOCK_UDP_AND_INCOMING_TCP) \
+ P2P_TEST(x, BLOCK_ALL_BUT_OUTGOING_HTTP) \
+ P2P_TEST(x, PROXY_HTTPS) \
+ P2P_TEST(x, PROXY_SOCKS)
+
+#define FLAKY_P2P_TEST_SET(x) \
+ P2P_TEST(x, OPEN) \
+ P2P_TEST(x, NAT_FULL_CONE) \
+ P2P_TEST(x, NAT_ADDR_RESTRICTED) \
+ P2P_TEST(x, NAT_PORT_RESTRICTED) \
+ P2P_TEST(x, NAT_SYMMETRIC) \
+ P2P_TEST(x, NAT_DOUBLE_CONE) \
+ P2P_TEST(x, NAT_SYMMETRIC_THEN_CONE) \
+ P2P_TEST(x, BLOCK_UDP) \
+ P2P_TEST(x, BLOCK_UDP_AND_INCOMING_TCP) \
+ P2P_TEST(x, BLOCK_ALL_BUT_OUTGOING_HTTP) \
+ P2P_TEST(x, PROXY_HTTPS) \
+ P2P_TEST(x, PROXY_SOCKS)
+
+P2P_TEST_SET(OPEN)
+P2P_TEST_SET(NAT_FULL_CONE)
+P2P_TEST_SET(NAT_ADDR_RESTRICTED)
+P2P_TEST_SET(NAT_PORT_RESTRICTED)
+P2P_TEST_SET(NAT_SYMMETRIC)
+P2P_TEST_SET(NAT_DOUBLE_CONE)
+P2P_TEST_SET(NAT_SYMMETRIC_THEN_CONE)
+P2P_TEST_SET(BLOCK_UDP)
+P2P_TEST_SET(BLOCK_UDP_AND_INCOMING_TCP)
+P2P_TEST_SET(BLOCK_ALL_BUT_OUTGOING_HTTP)
+P2P_TEST_SET(PROXY_HTTPS)
+P2P_TEST_SET(PROXY_SOCKS)
+
+// Test that we restart candidate allocation when local ufrag&pwd changed.
+// Standard Ice protocol is used.
+TEST_F(P2PTransportChannelTest, HandleUfragPwdChangeAsIce) {
+ ConfigureEndpoints(OPEN, OPEN,
+ PORTALLOCATOR_ENABLE_SHARED_UFRAG,
+ PORTALLOCATOR_ENABLE_SHARED_UFRAG,
+ kMinimumStepDelay, kMinimumStepDelay,
+ cricket::ICEPROTO_RFC5245);
+ CreateChannels(1);
+ TestHandleIceUfragPasswordChanged();
+ DestroyChannels();
+}
+
+// Test that we restart candidate allocation when local ufrag&pwd changed.
+// Standard Ice protocol is used.
+TEST_F(P2PTransportChannelTest, HandleUfragPwdChangeBundleAsIce) {
+ ConfigureEndpoints(OPEN, OPEN,
+ PORTALLOCATOR_ENABLE_SHARED_UFRAG,
+ PORTALLOCATOR_ENABLE_SHARED_UFRAG,
+ kMinimumStepDelay, kMinimumStepDelay,
+ cricket::ICEPROTO_RFC5245);
+ SetAllocatorFlags(0, cricket::PORTALLOCATOR_ENABLE_BUNDLE);
+ SetAllocatorFlags(1, cricket::PORTALLOCATOR_ENABLE_BUNDLE);
+
+ CreateChannels(2);
+ TestHandleIceUfragPasswordChanged();
+ DestroyChannels();
+}
+
+// Test that we restart candidate allocation when local ufrag&pwd changed.
+// Google Ice protocol is used.
+TEST_F(P2PTransportChannelTest, HandleUfragPwdChangeAsGice) {
+ ConfigureEndpoints(OPEN, OPEN,
+ PORTALLOCATOR_ENABLE_SHARED_UFRAG,
+ PORTALLOCATOR_ENABLE_SHARED_UFRAG,
+ kDefaultStepDelay, kDefaultStepDelay,
+ cricket::ICEPROTO_GOOGLE);
+ CreateChannels(1);
+ TestHandleIceUfragPasswordChanged();
+ DestroyChannels();
+}
+
+// Test that ICE restart works when bundle is enabled.
+// Google Ice protocol is used.
+TEST_F(P2PTransportChannelTest, HandleUfragPwdChangeBundleAsGice) {
+ ConfigureEndpoints(OPEN, OPEN,
+ PORTALLOCATOR_ENABLE_SHARED_UFRAG,
+ PORTALLOCATOR_ENABLE_SHARED_UFRAG,
+ kDefaultStepDelay, kDefaultStepDelay,
+ cricket::ICEPROTO_GOOGLE);
+ SetAllocatorFlags(0, cricket::PORTALLOCATOR_ENABLE_BUNDLE);
+ SetAllocatorFlags(1, cricket::PORTALLOCATOR_ENABLE_BUNDLE);
+
+ CreateChannels(2);
+ TestHandleIceUfragPasswordChanged();
+ DestroyChannels();
+}
+
+// Test the operation of GetStats.
+TEST_F(P2PTransportChannelTest, GetStats) {
+ ConfigureEndpoints(OPEN, OPEN,
+ kDefaultPortAllocatorFlags,
+ kDefaultPortAllocatorFlags,
+ kDefaultStepDelay, kDefaultStepDelay,
+ cricket::ICEPROTO_GOOGLE);
+ CreateChannels(1);
+ EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->readable() && ep1_ch1()->writable() &&
+ ep2_ch1()->readable() && ep2_ch1()->writable(),
+ 1000, 1000);
+ TestSendRecv(1);
+ cricket::ConnectionInfos infos;
+ ASSERT_TRUE(ep1_ch1()->GetStats(&infos));
+ ASSERT_EQ(1U, infos.size());
+ EXPECT_TRUE(infos[0].new_connection);
+ EXPECT_TRUE(infos[0].best_connection);
+ EXPECT_TRUE(infos[0].readable);
+ EXPECT_TRUE(infos[0].writable);
+ EXPECT_FALSE(infos[0].timeout);
+ EXPECT_EQ(10 * 36U, infos[0].sent_total_bytes);
+ EXPECT_EQ(10 * 36U, infos[0].recv_total_bytes);
+ EXPECT_GT(infos[0].rtt, 0U);
+ DestroyChannels();
+}
+
+// Test that we properly handle getting a STUN error due to slow signaling.
+TEST_F(P2PTransportChannelTest, DISABLED_SlowSignaling) {
+ ConfigureEndpoints(OPEN, NAT_SYMMETRIC,
+ kDefaultPortAllocatorFlags,
+ kDefaultPortAllocatorFlags,
+ kDefaultStepDelay, kDefaultStepDelay,
+ cricket::ICEPROTO_GOOGLE);
+ // Make signaling from the callee take 500ms, so that the initial STUN pings
+ // from the callee beat the signaling, and so the caller responds with a
+ // unknown username error. We should just eat that and carry on; mishandling
+ // this will instead cause all the callee's connections to be discarded.
+ SetSignalingDelay(1, 1000);
+ CreateChannels(1);
+ const cricket::Connection* best_connection = NULL;
+ // Wait until the callee's connections are created.
+ WAIT((best_connection = ep2_ch1()->best_connection()) != NULL, 1000);
+ // Wait to see if they get culled; they shouldn't.
+ WAIT(ep2_ch1()->best_connection() != best_connection, 1000);
+ EXPECT_TRUE(ep2_ch1()->best_connection() == best_connection);
+ DestroyChannels();
+}
+
+// Test that if remote candidates don't have ufrag and pwd, we still work.
+TEST_F(P2PTransportChannelTest, RemoteCandidatesWithoutUfragPwd) {
+ set_clear_remote_candidates_ufrag_pwd(true);
+ ConfigureEndpoints(OPEN, OPEN,
+ PORTALLOCATOR_ENABLE_SHARED_UFRAG,
+ PORTALLOCATOR_ENABLE_SHARED_UFRAG,
+ kMinimumStepDelay, kMinimumStepDelay,
+ cricket::ICEPROTO_GOOGLE);
+ CreateChannels(1);
+ const cricket::Connection* best_connection = NULL;
+ // Wait until the callee's connections are created.
+ WAIT((best_connection = ep2_ch1()->best_connection()) != NULL, 1000);
+ // Wait to see if they get culled; they shouldn't.
+ WAIT(ep2_ch1()->best_connection() != best_connection, 1000);
+ EXPECT_TRUE(ep2_ch1()->best_connection() == best_connection);
+ DestroyChannels();
+}
+
+// Test that a host behind NAT cannot be reached when incoming_only
+// is set to true.
+TEST_F(P2PTransportChannelTest, IncomingOnlyBlocked) {
+ ConfigureEndpoints(NAT_FULL_CONE, OPEN,
+ kDefaultPortAllocatorFlags,
+ kDefaultPortAllocatorFlags,
+ kDefaultStepDelay, kDefaultStepDelay,
+ cricket::ICEPROTO_GOOGLE);
+
+ SetAllocatorFlags(0, kOnlyLocalPorts);
+ CreateChannels(1);
+ ep1_ch1()->set_incoming_only(true);
+
+ // Pump for 1 second and verify that the channels are not connected.
+ rtc::Thread::Current()->ProcessMessages(1000);
+
+ EXPECT_FALSE(ep1_ch1()->readable());
+ EXPECT_FALSE(ep1_ch1()->writable());
+ EXPECT_FALSE(ep2_ch1()->readable());
+ EXPECT_FALSE(ep2_ch1()->writable());
+
+ DestroyChannels();
+}
+
+// Test that a peer behind NAT can connect to a peer that has
+// incoming_only flag set.
+TEST_F(P2PTransportChannelTest, IncomingOnlyOpen) {
+ ConfigureEndpoints(OPEN, NAT_FULL_CONE,
+ kDefaultPortAllocatorFlags,
+ kDefaultPortAllocatorFlags,
+ kDefaultStepDelay, kDefaultStepDelay,
+ cricket::ICEPROTO_GOOGLE);
+
+ SetAllocatorFlags(0, kOnlyLocalPorts);
+ CreateChannels(1);
+ ep1_ch1()->set_incoming_only(true);
+
+ EXPECT_TRUE_WAIT_MARGIN(ep1_ch1() != NULL && ep2_ch1() != NULL &&
+ ep1_ch1()->readable() && ep1_ch1()->writable() &&
+ ep2_ch1()->readable() && ep2_ch1()->writable(),
+ 1000, 1000);
+
+ DestroyChannels();
+}
+
+TEST_F(P2PTransportChannelTest, TestTcpConnectionsFromActiveToPassive) {
+ AddAddress(0, kPublicAddrs[0]);
+ AddAddress(1, kPublicAddrs[1]);
+
+ SetAllocationStepDelay(0, kMinimumStepDelay);
+ SetAllocationStepDelay(1, kMinimumStepDelay);
+
+ int kOnlyLocalTcpPorts = cricket::PORTALLOCATOR_DISABLE_UDP |
+ cricket::PORTALLOCATOR_DISABLE_STUN |
+ cricket::PORTALLOCATOR_DISABLE_RELAY |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG;
+ // Disable all protocols except TCP.
+ SetAllocatorFlags(0, kOnlyLocalTcpPorts);
+ SetAllocatorFlags(1, kOnlyLocalTcpPorts);
+
+ SetAllowTcpListen(0, true); // actpass.
+ SetAllowTcpListen(1, false); // active.
+
+ CreateChannels(1);
+
+ EXPECT_TRUE_WAIT(ep1_ch1()->readable() && ep1_ch1()->writable() &&
+ ep2_ch1()->readable() && ep2_ch1()->writable(),
+ 1000);
+ EXPECT_TRUE(
+ ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
+ LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
+ RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
+
+ std::string kTcpProtocol = "tcp";
+ EXPECT_EQ(kTcpProtocol, RemoteCandidate(ep1_ch1())->protocol());
+ EXPECT_EQ(kTcpProtocol, LocalCandidate(ep1_ch1())->protocol());
+ EXPECT_EQ(kTcpProtocol, RemoteCandidate(ep2_ch1())->protocol());
+ EXPECT_EQ(kTcpProtocol, LocalCandidate(ep2_ch1())->protocol());
+
+ TestSendRecv(1);
+ DestroyChannels();
+}
+
+TEST_F(P2PTransportChannelTest, TestBundleAllocatorToBundleAllocator) {
+ AddAddress(0, kPublicAddrs[0]);
+ AddAddress(1, kPublicAddrs[1]);
+ SetAllocatorFlags(0, cricket::PORTALLOCATOR_ENABLE_BUNDLE);
+ SetAllocatorFlags(1, cricket::PORTALLOCATOR_ENABLE_BUNDLE);
+
+ CreateChannels(2);
+
+ EXPECT_TRUE_WAIT(ep1_ch1()->readable() &&
+ ep1_ch1()->writable() &&
+ ep2_ch1()->readable() &&
+ ep2_ch1()->writable(),
+ 1000);
+ EXPECT_TRUE(ep1_ch1()->best_connection() &&
+ ep2_ch1()->best_connection());
+
+ EXPECT_FALSE(ep1_ch2()->readable());
+ EXPECT_FALSE(ep1_ch2()->writable());
+ EXPECT_FALSE(ep2_ch2()->readable());
+ EXPECT_FALSE(ep2_ch2()->writable());
+
+ TestSendRecv(1); // Only 1 channel is writable per Endpoint.
+ DestroyChannels();
+}
+
+TEST_F(P2PTransportChannelTest, TestBundleAllocatorToNonBundleAllocator) {
+ AddAddress(0, kPublicAddrs[0]);
+ AddAddress(1, kPublicAddrs[1]);
+ // Enable BUNDLE flag at one side.
+ SetAllocatorFlags(0, cricket::PORTALLOCATOR_ENABLE_BUNDLE);
+
+ CreateChannels(2);
+
+ EXPECT_TRUE_WAIT(ep1_ch1()->readable() &&
+ ep1_ch1()->writable() &&
+ ep2_ch1()->readable() &&
+ ep2_ch1()->writable(),
+ 1000);
+ EXPECT_TRUE_WAIT(ep1_ch2()->readable() &&
+ ep1_ch2()->writable() &&
+ ep2_ch2()->readable() &&
+ ep2_ch2()->writable(),
+ 1000);
+
+ EXPECT_TRUE(ep1_ch1()->best_connection() &&
+ ep2_ch1()->best_connection());
+ EXPECT_TRUE(ep1_ch2()->best_connection() &&
+ ep2_ch2()->best_connection());
+
+ TestSendRecv(2);
+ DestroyChannels();
+}
+
+TEST_F(P2PTransportChannelTest, TestIceRoleConflictWithoutBundle) {
+ AddAddress(0, kPublicAddrs[0]);
+ AddAddress(1, kPublicAddrs[1]);
+ TestSignalRoleConflict();
+}
+
+TEST_F(P2PTransportChannelTest, TestIceRoleConflictWithBundle) {
+ AddAddress(0, kPublicAddrs[0]);
+ AddAddress(1, kPublicAddrs[1]);
+ SetAllocatorFlags(0, cricket::PORTALLOCATOR_ENABLE_BUNDLE);
+ SetAllocatorFlags(1, cricket::PORTALLOCATOR_ENABLE_BUNDLE);
+ TestSignalRoleConflict();
+}
+
+// Tests that the ice configs (protocol, tiebreaker and role) can be passed
+// down to ports.
+TEST_F(P2PTransportChannelTest, TestIceConfigWillPassDownToPort) {
+ AddAddress(0, kPublicAddrs[0]);
+ AddAddress(1, kPublicAddrs[1]);
+
+ SetIceRole(0, cricket::ICEROLE_CONTROLLING);
+ SetIceProtocol(0, cricket::ICEPROTO_GOOGLE);
+ SetIceTiebreaker(0, kTiebreaker1);
+ SetIceRole(1, cricket::ICEROLE_CONTROLLING);
+ SetIceProtocol(1, cricket::ICEPROTO_RFC5245);
+ SetIceTiebreaker(1, kTiebreaker2);
+
+ CreateChannels(1);
+
+ EXPECT_EQ_WAIT(2u, ep1_ch1()->ports().size(), 1000);
+
+ const std::vector<cricket::PortInterface *> ports_before = ep1_ch1()->ports();
+ for (size_t i = 0; i < ports_before.size(); ++i) {
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLING, ports_before[i]->GetIceRole());
+ EXPECT_EQ(cricket::ICEPROTO_GOOGLE, ports_before[i]->IceProtocol());
+ EXPECT_EQ(kTiebreaker1, ports_before[i]->IceTiebreaker());
+ }
+
+ ep1_ch1()->SetIceRole(cricket::ICEROLE_CONTROLLED);
+ ep1_ch1()->SetIceProtocolType(cricket::ICEPROTO_RFC5245);
+ ep1_ch1()->SetIceTiebreaker(kTiebreaker2);
+
+ const std::vector<cricket::PortInterface *> ports_after = ep1_ch1()->ports();
+ for (size_t i = 0; i < ports_after.size(); ++i) {
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLED, ports_before[i]->GetIceRole());
+ EXPECT_EQ(cricket::ICEPROTO_RFC5245, ports_before[i]->IceProtocol());
+ // SetIceTiebreaker after Connect() has been called will fail. So expect the
+ // original value.
+ EXPECT_EQ(kTiebreaker1, ports_before[i]->IceTiebreaker());
+ }
+
+ EXPECT_TRUE_WAIT(ep1_ch1()->readable() &&
+ ep1_ch1()->writable() &&
+ ep2_ch1()->readable() &&
+ ep2_ch1()->writable(),
+ 1000);
+
+ EXPECT_TRUE(ep1_ch1()->best_connection() &&
+ ep2_ch1()->best_connection());
+
+ TestSendRecv(1);
+ DestroyChannels();
+}
+
+// This test verifies channel can handle ice messages when channel is in
+// hybrid mode.
+TEST_F(P2PTransportChannelTest, TestConnectivityBetweenHybridandIce) {
+ TestHybridConnectivity(cricket::ICEPROTO_RFC5245);
+}
+
+// This test verifies channel can handle Gice messages when channel is in
+// hybrid mode.
+TEST_F(P2PTransportChannelTest, TestConnectivityBetweenHybridandGice) {
+ TestHybridConnectivity(cricket::ICEPROTO_GOOGLE);
+}
+
+// Verify that we can set DSCP value and retrieve properly from P2PTC.
+TEST_F(P2PTransportChannelTest, TestDefaultDscpValue) {
+ AddAddress(0, kPublicAddrs[0]);
+ AddAddress(1, kPublicAddrs[1]);
+
+ CreateChannels(1);
+ EXPECT_EQ(rtc::DSCP_NO_CHANGE,
+ GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
+ EXPECT_EQ(rtc::DSCP_NO_CHANGE,
+ GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
+ GetEndpoint(0)->cd1_.ch_->SetOption(
+ rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
+ GetEndpoint(1)->cd1_.ch_->SetOption(
+ rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
+ EXPECT_EQ(rtc::DSCP_CS6,
+ GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
+ EXPECT_EQ(rtc::DSCP_CS6,
+ GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
+ GetEndpoint(0)->cd1_.ch_->SetOption(
+ rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
+ GetEndpoint(1)->cd1_.ch_->SetOption(
+ rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
+ EXPECT_EQ(rtc::DSCP_AF41,
+ GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
+ EXPECT_EQ(rtc::DSCP_AF41,
+ GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
+}
+
+// Verify IPv6 connection is preferred over IPv4.
+// Flaky: https://code.google.com/p/webrtc/issues/detail?id=3317
+TEST_F(P2PTransportChannelTest, DISABLED_TestIPv6Connections) {
+ AddAddress(0, kIPv6PublicAddrs[0]);
+ AddAddress(0, kPublicAddrs[0]);
+ AddAddress(1, kIPv6PublicAddrs[1]);
+ AddAddress(1, kPublicAddrs[1]);
+
+ SetAllocationStepDelay(0, kMinimumStepDelay);
+ SetAllocationStepDelay(1, kMinimumStepDelay);
+
+ // Enable IPv6
+ SetAllocatorFlags(0, cricket::PORTALLOCATOR_ENABLE_IPV6);
+ SetAllocatorFlags(1, cricket::PORTALLOCATOR_ENABLE_IPV6);
+
+ CreateChannels(1);
+
+ EXPECT_TRUE_WAIT(ep1_ch1()->readable() && ep1_ch1()->writable() &&
+ ep2_ch1()->readable() && ep2_ch1()->writable(),
+ 1000);
+ EXPECT_TRUE(
+ ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
+ LocalCandidate(ep1_ch1())->address().EqualIPs(kIPv6PublicAddrs[0]) &&
+ RemoteCandidate(ep1_ch1())->address().EqualIPs(kIPv6PublicAddrs[1]));
+
+ TestSendRecv(1);
+ DestroyChannels();
+}
+
+// Testing forceful TURN connections.
+TEST_F(P2PTransportChannelTest, TestForceTurn) {
+ ConfigureEndpoints(NAT_PORT_RESTRICTED, NAT_SYMMETRIC,
+ kDefaultPortAllocatorFlags |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG,
+ kDefaultPortAllocatorFlags |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG,
+ kDefaultStepDelay, kDefaultStepDelay,
+ cricket::ICEPROTO_RFC5245);
+ set_force_relay(true);
+
+ SetAllocationStepDelay(0, kMinimumStepDelay);
+ SetAllocationStepDelay(1, kMinimumStepDelay);
+
+ CreateChannels(1);
+
+ EXPECT_TRUE_WAIT(ep1_ch1()->readable() &&
+ ep1_ch1()->writable() &&
+ ep2_ch1()->readable() &&
+ ep2_ch1()->writable(),
+ 1000);
+
+ EXPECT_TRUE(ep1_ch1()->best_connection() &&
+ ep2_ch1()->best_connection());
+
+ EXPECT_EQ("relay", RemoteCandidate(ep1_ch1())->type());
+ EXPECT_EQ("relay", LocalCandidate(ep1_ch1())->type());
+ EXPECT_EQ("relay", RemoteCandidate(ep2_ch1())->type());
+ EXPECT_EQ("relay", LocalCandidate(ep2_ch1())->type());
+
+ TestSendRecv(1);
+ DestroyChannels();
+}
+
+// Test what happens when we have 2 users behind the same NAT. This can lead
+// to interesting behavior because the STUN server will only give out the
+// address of the outermost NAT.
+class P2PTransportChannelSameNatTest : public P2PTransportChannelTestBase {
+ protected:
+ void ConfigureEndpoints(Config nat_type, Config config1, Config config2) {
+ ASSERT(nat_type >= NAT_FULL_CONE && nat_type <= NAT_SYMMETRIC);
+ rtc::NATSocketServer::Translator* outer_nat =
+ nat()->AddTranslator(kPublicAddrs[0], kNatAddrs[0],
+ static_cast<rtc::NATType>(nat_type - NAT_FULL_CONE));
+ ConfigureEndpoint(outer_nat, 0, config1);
+ ConfigureEndpoint(outer_nat, 1, config2);
+ }
+ void ConfigureEndpoint(rtc::NATSocketServer::Translator* nat,
+ int endpoint, Config config) {
+ ASSERT(config <= NAT_SYMMETRIC);
+ if (config == OPEN) {
+ AddAddress(endpoint, kPrivateAddrs[endpoint]);
+ nat->AddClient(kPrivateAddrs[endpoint]);
+ } else {
+ AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
+ nat->AddTranslator(kPrivateAddrs[endpoint], kCascadedNatAddrs[endpoint],
+ static_cast<rtc::NATType>(config - NAT_FULL_CONE))->AddClient(
+ kCascadedPrivateAddrs[endpoint]);
+ }
+ }
+};
+
+TEST_F(P2PTransportChannelSameNatTest, TestConesBehindSameCone) {
+ ConfigureEndpoints(NAT_FULL_CONE, NAT_FULL_CONE, NAT_FULL_CONE);
+ Test(kLocalUdpToStunUdp);
+}
+
+// Test what happens when we have multiple available pathways.
+// In the future we will try different RTTs and configs for the different
+// interfaces, so that we can simulate a user with Ethernet and VPN networks.
+class P2PTransportChannelMultihomedTest : public P2PTransportChannelTestBase {
+};
+
+// Test that we can establish connectivity when both peers are multihomed.
+TEST_F(P2PTransportChannelMultihomedTest, DISABLED_TestBasic) {
+ AddAddress(0, kPublicAddrs[0]);
+ AddAddress(0, kAlternateAddrs[0]);
+ AddAddress(1, kPublicAddrs[1]);
+ AddAddress(1, kAlternateAddrs[1]);
+ Test(kLocalUdpToLocalUdp);
+}
+
+// Test that we can quickly switch links if an interface goes down.
+TEST_F(P2PTransportChannelMultihomedTest, TestFailover) {
+ AddAddress(0, kPublicAddrs[0]);
+ // Adding alternate address will make sure |kPublicAddrs| has the higher
+ // priority than others. This is due to FakeNetwork::AddInterface method.
+ AddAddress(1, kAlternateAddrs[1]);
+ AddAddress(1, kPublicAddrs[1]);
+
+ // Use only local ports for simplicity.
+ SetAllocatorFlags(0, kOnlyLocalPorts);
+ SetAllocatorFlags(1, kOnlyLocalPorts);
+
+ // Create channels and let them go writable, as usual.
+ CreateChannels(1);
+ EXPECT_TRUE_WAIT(ep1_ch1()->readable() && ep1_ch1()->writable() &&
+ ep2_ch1()->readable() && ep2_ch1()->writable(),
+ 1000);
+ EXPECT_TRUE(
+ ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
+ LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
+ RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
+
+ // Blackhole any traffic to or from the public addrs.
+ LOG(LS_INFO) << "Failing over...";
+ fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY,
+ kPublicAddrs[1]);
+
+ // We should detect loss of connectivity within 5 seconds or so.
+ EXPECT_TRUE_WAIT(!ep1_ch1()->writable(), 7000);
+
+ // We should switch over to use the alternate addr immediately
+ // when we lose writability.
+ EXPECT_TRUE_WAIT(
+ ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
+ LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
+ RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]),
+ 3000);
+
+ DestroyChannels();
+}
+
+// Test that we can switch links in a coordinated fashion.
+TEST_F(P2PTransportChannelMultihomedTest, TestDrain) {
+ AddAddress(0, kPublicAddrs[0]);
+ AddAddress(1, kPublicAddrs[1]);
+ // Use only local ports for simplicity.
+ SetAllocatorFlags(0, kOnlyLocalPorts);
+ SetAllocatorFlags(1, kOnlyLocalPorts);
+
+ // Create channels and let them go writable, as usual.
+ CreateChannels(1);
+ EXPECT_TRUE_WAIT(ep1_ch1()->readable() && ep1_ch1()->writable() &&
+ ep2_ch1()->readable() && ep2_ch1()->writable(),
+ 1000);
+ EXPECT_TRUE(
+ ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
+ LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
+ RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
+
+ // Remove the public interface, add the alternate interface, and allocate
+ // a new generation of candidates for the new interface (via Connect()).
+ LOG(LS_INFO) << "Draining...";
+ AddAddress(1, kAlternateAddrs[1]);
+ RemoveAddress(1, kPublicAddrs[1]);
+ ep2_ch1()->Connect();
+
+ // We should switch over to use the alternate address after
+ // an exchange of pings.
+ EXPECT_TRUE_WAIT(
+ ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
+ LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
+ RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]),
+ 3000);
+
+ DestroyChannels();
+}
diff --git a/p2p/base/packetsocketfactory.h b/p2p/base/packetsocketfactory.h
new file mode 100644
index 00000000..1f45feca
--- /dev/null
+++ b/p2p/base/packetsocketfactory.h
@@ -0,0 +1,52 @@
+/*
+ * 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 WEBRTC_P2P_BASE_PACKETSOCKETFACTORY_H_
+#define WEBRTC_P2P_BASE_PACKETSOCKETFACTORY_H_
+
+#include "webrtc/base/proxyinfo.h"
+
+namespace rtc {
+
+class AsyncPacketSocket;
+class AsyncResolverInterface;
+
+class PacketSocketFactory {
+ public:
+ enum Options {
+ OPT_SSLTCP = 0x01, // Pseudo-TLS.
+ OPT_TLS = 0x02,
+ OPT_STUN = 0x04,
+ };
+
+ PacketSocketFactory() { }
+ virtual ~PacketSocketFactory() { }
+
+ virtual AsyncPacketSocket* CreateUdpSocket(
+ const SocketAddress& address, int min_port, int max_port) = 0;
+ virtual AsyncPacketSocket* CreateServerTcpSocket(
+ const SocketAddress& local_address, int min_port, int max_port,
+ int opts) = 0;
+
+ // TODO: |proxy_info| and |user_agent| should be set
+ // per-factory and not when socket is created.
+ virtual AsyncPacketSocket* CreateClientTcpSocket(
+ const SocketAddress& local_address, const SocketAddress& remote_address,
+ const ProxyInfo& proxy_info, const std::string& user_agent, int opts) = 0;
+
+ virtual AsyncResolverInterface* CreateAsyncResolver() = 0;
+
+ private:
+ DISALLOW_EVIL_CONSTRUCTORS(PacketSocketFactory);
+};
+
+} // namespace rtc
+
+#endif // WEBRTC_P2P_BASE_PACKETSOCKETFACTORY_H_
diff --git a/p2p/base/parsing.cc b/p2p/base/parsing.cc
new file mode 100644
index 00000000..04d7e79e
--- /dev/null
+++ b/p2p/base/parsing.cc
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2010 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can 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 "webrtc/p2p/base/parsing.h"
+
+#include <stdlib.h>
+#include <algorithm>
+#include "webrtc/base/stringutils.h"
+
+namespace {
+static const char kTrue[] = "true";
+static const char kOne[] = "1";
+}
+
+namespace cricket {
+
+bool BadParse(const std::string& text, ParseError* err) {
+ if (err != NULL) {
+ err->text = text;
+ }
+ return false;
+}
+
+bool BadWrite(const std::string& text, WriteError* err) {
+ if (err != NULL) {
+ err->text = text;
+ }
+ return false;
+}
+
+std::string GetXmlAttr(const buzz::XmlElement* elem,
+ const buzz::QName& name,
+ const std::string& def) {
+ std::string val = elem->Attr(name);
+ return val.empty() ? def : val;
+}
+
+std::string GetXmlAttr(const buzz::XmlElement* elem,
+ const buzz::QName& name,
+ const char* def) {
+ return GetXmlAttr(elem, name, std::string(def));
+}
+
+bool GetXmlAttr(const buzz::XmlElement* elem,
+ const buzz::QName& name, bool def) {
+ std::string val = elem->Attr(name);
+ std::transform(val.begin(), val.end(), val.begin(), tolower);
+
+ return val.empty() ? def : (val == kTrue || val == kOne);
+}
+
+int GetXmlAttr(const buzz::XmlElement* elem,
+ const buzz::QName& name, int def) {
+ std::string val = elem->Attr(name);
+ return val.empty() ? def : atoi(val.c_str());
+}
+
+const buzz::XmlElement* GetXmlChild(const buzz::XmlElement* parent,
+ const std::string& name) {
+ for (const buzz::XmlElement* child = parent->FirstElement();
+ child != NULL;
+ child = child->NextElement()) {
+ if (child->Name().LocalPart() == name) {
+ return child;
+ }
+ }
+ return NULL;
+}
+
+bool RequireXmlChild(const buzz::XmlElement* parent,
+ const std::string& name,
+ const buzz::XmlElement** child,
+ ParseError* error) {
+ *child = GetXmlChild(parent, name);
+ if (*child == NULL) {
+ return BadParse("element '" + parent->Name().Merged() +
+ "' missing required child '" + name,
+ error);
+ } else {
+ return true;
+ }
+}
+
+bool RequireXmlAttr(const buzz::XmlElement* elem,
+ const buzz::QName& name,
+ std::string* value,
+ ParseError* error) {
+ if (!elem->HasAttr(name)) {
+ return BadParse("element '" + elem->Name().Merged() +
+ "' missing required attribute '"
+ + name.Merged() + "'",
+ error);
+ } else {
+ *value = elem->Attr(name);
+ return true;
+ }
+}
+
+void AddXmlAttrIfNonEmpty(buzz::XmlElement* elem,
+ const buzz::QName name,
+ const std::string& value) {
+ if (!value.empty()) {
+ elem->AddAttr(name, value);
+ }
+}
+
+void AddXmlChildren(buzz::XmlElement* parent,
+ const std::vector<buzz::XmlElement*>& children) {
+ for (std::vector<buzz::XmlElement*>::const_iterator iter = children.begin();
+ iter != children.end();
+ iter++) {
+ parent->AddElement(*iter);
+ }
+}
+
+void CopyXmlChildren(const buzz::XmlElement* source, buzz::XmlElement* dest) {
+ for (const buzz::XmlElement* child = source->FirstElement();
+ child != NULL;
+ child = child->NextElement()) {
+ dest->AddElement(new buzz::XmlElement(*child));
+ }
+}
+
+std::vector<buzz::XmlElement*> CopyOfXmlChildren(const buzz::XmlElement* elem) {
+ std::vector<buzz::XmlElement*> children;
+ for (const buzz::XmlElement* child = elem->FirstElement();
+ child != NULL;
+ child = child->NextElement()) {
+ children.push_back(new buzz::XmlElement(*child));
+ }
+ return children;
+}
+
+} // namespace cricket
diff --git a/p2p/base/parsing.h b/p2p/base/parsing.h
new file mode 100644
index 00000000..6b32b5db
--- /dev/null
+++ b/p2p/base/parsing.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2010 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_P2P_BASE_PARSING_H_
+#define WEBRTC_P2P_BASE_PARSING_H_
+
+#include <string>
+#include <vector>
+#include "webrtc/libjingle/xmllite/xmlelement.h" // Needed to delete ParseError.extra.
+#include "webrtc/base/basictypes.h"
+#include "webrtc/base/stringencode.h"
+
+namespace cricket {
+
+typedef std::vector<buzz::XmlElement*> XmlElements;
+
+// We decided "bool Parse(in, out*, error*)" is generally the best
+// parse signature. "out Parse(in)" doesn't allow for errors.
+// "error* Parse(in, out*)" doesn't allow flexible memory management.
+
+// The error type for parsing.
+struct ParseError {
+ public:
+ // explains the error
+ std::string text;
+ // provide details about what wasn't parsable
+ const buzz::XmlElement* extra;
+
+ ParseError() : extra(NULL) {}
+
+ ~ParseError() {
+ delete extra;
+ }
+
+ void SetText(const std::string& text) {
+ this->text = text;
+ }
+};
+
+// The error type for writing.
+struct WriteError {
+ std::string text;
+
+ void SetText(const std::string& text) {
+ this->text = text;
+ }
+};
+
+// Convenience method for returning a message when parsing fails.
+bool BadParse(const std::string& text, ParseError* err);
+
+// Convenience method for returning a message when writing fails.
+bool BadWrite(const std::string& text, WriteError* error);
+
+// helper XML functions
+std::string GetXmlAttr(const buzz::XmlElement* elem,
+ const buzz::QName& name,
+ const std::string& def);
+std::string GetXmlAttr(const buzz::XmlElement* elem,
+ const buzz::QName& name,
+ const char* def);
+// Return true if the value is "true" or "1".
+bool GetXmlAttr(const buzz::XmlElement* elem,
+ const buzz::QName& name, bool def);
+int GetXmlAttr(const buzz::XmlElement* elem,
+ const buzz::QName& name, int def);
+
+template <class T>
+bool GetXmlAttr(const buzz::XmlElement* elem,
+ const buzz::QName& name,
+ T* val_out) {
+ if (!elem->HasAttr(name)) {
+ return false;
+ }
+ std::string unparsed = elem->Attr(name);
+ return rtc::FromString(unparsed, val_out);
+}
+
+template <class T>
+bool GetXmlAttr(const buzz::XmlElement* elem,
+ const buzz::QName& name,
+ const T& def,
+ T* val_out) {
+ if (!elem->HasAttr(name)) {
+ *val_out = def;
+ return true;
+ }
+ return GetXmlAttr(elem, name, val_out);
+}
+
+template <class T>
+bool AddXmlAttr(buzz::XmlElement* elem,
+ const buzz::QName& name, const T& val) {
+ std::string buf;
+ if (!rtc::ToString(val, &buf)) {
+ return false;
+ }
+ elem->AddAttr(name, buf);
+ return true;
+}
+
+template <class T>
+bool SetXmlBody(buzz::XmlElement* elem, const T& val) {
+ std::string buf;
+ if (!rtc::ToString(val, &buf)) {
+ return false;
+ }
+ elem->SetBodyText(buf);
+ return true;
+}
+
+const buzz::XmlElement* GetXmlChild(const buzz::XmlElement* parent,
+ const std::string& name);
+
+bool RequireXmlChild(const buzz::XmlElement* parent,
+ const std::string& name,
+ const buzz::XmlElement** child,
+ ParseError* error);
+bool RequireXmlAttr(const buzz::XmlElement* elem,
+ const buzz::QName& name,
+ std::string* value,
+ ParseError* error);
+void AddXmlAttrIfNonEmpty(buzz::XmlElement* elem,
+ const buzz::QName name,
+ const std::string& value);
+void AddXmlChildren(buzz::XmlElement* parent,
+ const std::vector<buzz::XmlElement*>& children);
+void CopyXmlChildren(const buzz::XmlElement* source, buzz::XmlElement* dest);
+std::vector<buzz::XmlElement*> CopyOfXmlChildren(const buzz::XmlElement* elem);
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_PARSING_H_
diff --git a/p2p/base/port.cc b/p2p/base/port.cc
new file mode 100644
index 00000000..f569d9f5
--- /dev/null
+++ b/p2p/base/port.cc
@@ -0,0 +1,1430 @@
+/*
+ * 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 "webrtc/p2p/base/port.h"
+
+#include <algorithm>
+#include <vector>
+
+#include "webrtc/p2p/base/common.h"
+#include "webrtc/p2p/base/portallocator.h"
+#include "webrtc/base/base64.h"
+#include "webrtc/base/crc32.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/messagedigest.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/stringencode.h"
+#include "webrtc/base/stringutils.h"
+
+namespace {
+
+// Determines whether we have seen at least the given maximum number of
+// pings fail to have a response.
+inline bool TooManyFailures(
+ const std::vector<uint32>& pings_since_last_response,
+ uint32 maximum_failures,
+ uint32 rtt_estimate,
+ uint32 now) {
+
+ // If we haven't sent that many pings, then we can't have failed that many.
+ if (pings_since_last_response.size() < maximum_failures)
+ return false;
+
+ // Check if the window in which we would expect a response to the ping has
+ // already elapsed.
+ return pings_since_last_response[maximum_failures - 1] + rtt_estimate < now;
+}
+
+// Determines whether we have gone too long without seeing any response.
+inline bool TooLongWithoutResponse(
+ const std::vector<uint32>& pings_since_last_response,
+ uint32 maximum_time,
+ uint32 now) {
+
+ if (pings_since_last_response.size() == 0)
+ return false;
+
+ return pings_since_last_response[0] + maximum_time < now;
+}
+
+// GICE(ICEPROTO_GOOGLE) requires different username for RTP and RTCP.
+// This function generates a different username by +1 on the last character of
+// the given username (|rtp_ufrag|).
+std::string GetRtcpUfragFromRtpUfrag(const std::string& rtp_ufrag) {
+ ASSERT(!rtp_ufrag.empty());
+ if (rtp_ufrag.empty()) {
+ return rtp_ufrag;
+ }
+ // Change the last character to the one next to it in the base64 table.
+ char new_last_char;
+ if (!rtc::Base64::GetNextBase64Char(rtp_ufrag[rtp_ufrag.size() - 1],
+ &new_last_char)) {
+ // Should not be here.
+ ASSERT(false);
+ }
+ std::string rtcp_ufrag = rtp_ufrag;
+ rtcp_ufrag[rtcp_ufrag.size() - 1] = new_last_char;
+ ASSERT(rtcp_ufrag != rtp_ufrag);
+ return rtcp_ufrag;
+}
+
+// We will restrict RTT estimates (when used for determining state) to be
+// within a reasonable range.
+const uint32 MINIMUM_RTT = 100; // 0.1 seconds
+const uint32 MAXIMUM_RTT = 3000; // 3 seconds
+
+// When we don't have any RTT data, we have to pick something reasonable. We
+// use a large value just in case the connection is really slow.
+const uint32 DEFAULT_RTT = MAXIMUM_RTT;
+
+// Computes our estimate of the RTT given the current estimate.
+inline uint32 ConservativeRTTEstimate(uint32 rtt) {
+ return rtc::_max(MINIMUM_RTT, rtc::_min(MAXIMUM_RTT, 2 * rtt));
+}
+
+// Weighting of the old rtt value to new data.
+const int RTT_RATIO = 3; // 3 : 1
+
+// The delay before we begin checking if this port is useless.
+const int kPortTimeoutDelay = 30 * 1000; // 30 seconds
+
+// Used by the Connection.
+const uint32 MSG_DELETE = 1;
+}
+
+namespace cricket {
+
+// TODO(ronghuawu): Use "host", "srflx", "prflx" and "relay". But this requires
+// the signaling part be updated correspondingly as well.
+const char LOCAL_PORT_TYPE[] = "local";
+const char STUN_PORT_TYPE[] = "stun";
+const char PRFLX_PORT_TYPE[] = "prflx";
+const char RELAY_PORT_TYPE[] = "relay";
+
+const char UDP_PROTOCOL_NAME[] = "udp";
+const char TCP_PROTOCOL_NAME[] = "tcp";
+const char SSLTCP_PROTOCOL_NAME[] = "ssltcp";
+
+static const char* const PROTO_NAMES[] = { UDP_PROTOCOL_NAME,
+ TCP_PROTOCOL_NAME,
+ SSLTCP_PROTOCOL_NAME };
+
+const char* ProtoToString(ProtocolType proto) {
+ return PROTO_NAMES[proto];
+}
+
+bool StringToProto(const char* value, ProtocolType* proto) {
+ for (size_t i = 0; i <= PROTO_LAST; ++i) {
+ if (_stricmp(PROTO_NAMES[i], value) == 0) {
+ *proto = static_cast<ProtocolType>(i);
+ return true;
+ }
+ }
+ return false;
+}
+
+// RFC 6544, TCP candidate encoding rules.
+const int DISCARD_PORT = 9;
+const char TCPTYPE_ACTIVE_STR[] = "active";
+const char TCPTYPE_PASSIVE_STR[] = "passive";
+const char TCPTYPE_SIMOPEN_STR[] = "so";
+
+// Foundation: An arbitrary string that is the same for two candidates
+// that have the same type, base IP address, protocol (UDP, TCP,
+// etc.), and STUN or TURN server. If any of these are different,
+// then the foundation will be different. Two candidate pairs with
+// the same foundation pairs are likely to have similar network
+// characteristics. Foundations are used in the frozen algorithm.
+static std::string ComputeFoundation(
+ const std::string& type,
+ const std::string& protocol,
+ const rtc::SocketAddress& base_address) {
+ std::ostringstream ost;
+ ost << type << base_address.ipaddr().ToString() << protocol;
+ return rtc::ToString<uint32>(rtc::ComputeCrc32(ost.str()));
+}
+
+Port::Port(rtc::Thread* thread, rtc::PacketSocketFactory* factory,
+ rtc::Network* network, const rtc::IPAddress& ip,
+ const std::string& username_fragment, const std::string& password)
+ : thread_(thread),
+ factory_(factory),
+ send_retransmit_count_attribute_(false),
+ network_(network),
+ ip_(ip),
+ min_port_(0),
+ max_port_(0),
+ component_(ICE_CANDIDATE_COMPONENT_DEFAULT),
+ generation_(0),
+ ice_username_fragment_(username_fragment),
+ password_(password),
+ timeout_delay_(kPortTimeoutDelay),
+ enable_port_packets_(false),
+ ice_protocol_(ICEPROTO_HYBRID),
+ ice_role_(ICEROLE_UNKNOWN),
+ tiebreaker_(0),
+ shared_socket_(true),
+ candidate_filter_(CF_ALL) {
+ Construct();
+}
+
+Port::Port(rtc::Thread* thread, const std::string& type,
+ rtc::PacketSocketFactory* factory,
+ rtc::Network* network, const rtc::IPAddress& ip,
+ int min_port, int max_port, const std::string& username_fragment,
+ const std::string& password)
+ : thread_(thread),
+ factory_(factory),
+ type_(type),
+ send_retransmit_count_attribute_(false),
+ network_(network),
+ ip_(ip),
+ min_port_(min_port),
+ max_port_(max_port),
+ component_(ICE_CANDIDATE_COMPONENT_DEFAULT),
+ generation_(0),
+ ice_username_fragment_(username_fragment),
+ password_(password),
+ timeout_delay_(kPortTimeoutDelay),
+ enable_port_packets_(false),
+ ice_protocol_(ICEPROTO_HYBRID),
+ ice_role_(ICEROLE_UNKNOWN),
+ tiebreaker_(0),
+ shared_socket_(false),
+ candidate_filter_(CF_ALL) {
+ ASSERT(factory_ != NULL);
+ Construct();
+}
+
+void Port::Construct() {
+ // If the username_fragment and password are empty, we should just create one.
+ if (ice_username_fragment_.empty()) {
+ ASSERT(password_.empty());
+ ice_username_fragment_ = rtc::CreateRandomString(ICE_UFRAG_LENGTH);
+ password_ = rtc::CreateRandomString(ICE_PWD_LENGTH);
+ }
+ LOG_J(LS_INFO, this) << "Port created";
+}
+
+Port::~Port() {
+ // Delete all of the remaining connections. We copy the list up front
+ // because each deletion will cause it to be modified.
+
+ std::vector<Connection*> list;
+
+ AddressMap::iterator iter = connections_.begin();
+ while (iter != connections_.end()) {
+ list.push_back(iter->second);
+ ++iter;
+ }
+
+ for (uint32 i = 0; i < list.size(); i++)
+ delete list[i];
+}
+
+Connection* Port::GetConnection(const rtc::SocketAddress& remote_addr) {
+ AddressMap::const_iterator iter = connections_.find(remote_addr);
+ if (iter != connections_.end())
+ return iter->second;
+ else
+ return NULL;
+}
+
+void Port::AddAddress(const rtc::SocketAddress& address,
+ const rtc::SocketAddress& base_address,
+ const rtc::SocketAddress& related_address,
+ const std::string& protocol,
+ const std::string& tcptype,
+ const std::string& type,
+ uint32 type_preference,
+ uint32 relay_preference,
+ bool final) {
+ if (protocol == TCP_PROTOCOL_NAME && type == LOCAL_PORT_TYPE) {
+ ASSERT(!tcptype.empty());
+ }
+
+ Candidate c;
+ c.set_id(rtc::CreateRandomString(8));
+ c.set_component(component_);
+ c.set_type(type);
+ c.set_protocol(protocol);
+ c.set_tcptype(tcptype);
+ c.set_address(address);
+ c.set_priority(c.GetPriority(type_preference, network_->preference(),
+ relay_preference));
+ c.set_username(username_fragment());
+ c.set_password(password_);
+ c.set_network_name(network_->name());
+ c.set_generation(generation_);
+ c.set_related_address(related_address);
+ c.set_foundation(ComputeFoundation(type, protocol, base_address));
+ candidates_.push_back(c);
+ SignalCandidateReady(this, c);
+
+ if (final) {
+ SignalPortComplete(this);
+ }
+}
+
+void Port::AddConnection(Connection* conn) {
+ connections_[conn->remote_candidate().address()] = conn;
+ conn->SignalDestroyed.connect(this, &Port::OnConnectionDestroyed);
+ SignalConnectionCreated(this, conn);
+}
+
+void Port::OnReadPacket(
+ const char* data, size_t size, const rtc::SocketAddress& addr,
+ ProtocolType proto) {
+ // If the user has enabled port packets, just hand this over.
+ if (enable_port_packets_) {
+ SignalReadPacket(this, data, size, addr);
+ return;
+ }
+
+ // If this is an authenticated STUN request, then signal unknown address and
+ // send back a proper binding response.
+ rtc::scoped_ptr<IceMessage> msg;
+ std::string remote_username;
+ if (!GetStunMessage(data, size, addr, msg.accept(), &remote_username)) {
+ LOG_J(LS_ERROR, this) << "Received non-STUN packet from unknown address ("
+ << addr.ToSensitiveString() << ")";
+ } else if (!msg) {
+ // STUN message handled already
+ } else if (msg->type() == STUN_BINDING_REQUEST) {
+ // Check for role conflicts.
+ if (IsStandardIce() &&
+ !MaybeIceRoleConflict(addr, msg.get(), remote_username)) {
+ LOG(LS_INFO) << "Received conflicting role from the peer.";
+ return;
+ }
+
+ SignalUnknownAddress(this, addr, proto, msg.get(), remote_username, false);
+ } else {
+ // NOTE(tschmelcher): STUN_BINDING_RESPONSE is benign. It occurs if we
+ // pruned a connection for this port while it had STUN requests in flight,
+ // because we then get back responses for them, which this code correctly
+ // does not handle.
+ if (msg->type() != STUN_BINDING_RESPONSE) {
+ LOG_J(LS_ERROR, this) << "Received unexpected STUN message type ("
+ << msg->type() << ") from unknown address ("
+ << addr.ToSensitiveString() << ")";
+ }
+ }
+}
+
+void Port::OnReadyToSend() {
+ AddressMap::iterator iter = connections_.begin();
+ for (; iter != connections_.end(); ++iter) {
+ iter->second->OnReadyToSend();
+ }
+}
+
+size_t Port::AddPrflxCandidate(const Candidate& local) {
+ candidates_.push_back(local);
+ return (candidates_.size() - 1);
+}
+
+bool Port::IsStandardIce() const {
+ return (ice_protocol_ == ICEPROTO_RFC5245);
+}
+
+bool Port::IsGoogleIce() const {
+ return (ice_protocol_ == ICEPROTO_GOOGLE);
+}
+
+bool Port::IsHybridIce() const {
+ return (ice_protocol_ == ICEPROTO_HYBRID);
+}
+
+bool Port::GetStunMessage(const char* data, size_t size,
+ const rtc::SocketAddress& addr,
+ IceMessage** out_msg, std::string* out_username) {
+ // NOTE: This could clearly be optimized to avoid allocating any memory.
+ // However, at the data rates we'll be looking at on the client side,
+ // this probably isn't worth worrying about.
+ ASSERT(out_msg != NULL);
+ ASSERT(out_username != NULL);
+ *out_msg = NULL;
+ out_username->clear();
+
+ // Don't bother parsing the packet if we can tell it's not STUN.
+ // In ICE mode, all STUN packets will have a valid fingerprint.
+ if (IsStandardIce() && !StunMessage::ValidateFingerprint(data, size)) {
+ return false;
+ }
+
+ // Parse the request message. If the packet is not a complete and correct
+ // STUN message, then ignore it.
+ rtc::scoped_ptr<IceMessage> stun_msg(new IceMessage());
+ rtc::ByteBuffer buf(data, size);
+ if (!stun_msg->Read(&buf) || (buf.Length() > 0)) {
+ return false;
+ }
+
+ if (stun_msg->type() == STUN_BINDING_REQUEST) {
+ // Check for the presence of USERNAME and MESSAGE-INTEGRITY (if ICE) first.
+ // If not present, fail with a 400 Bad Request.
+ if (!stun_msg->GetByteString(STUN_ATTR_USERNAME) ||
+ (IsStandardIce() &&
+ !stun_msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY))) {
+ LOG_J(LS_ERROR, this) << "Received STUN request without username/M-I "
+ << "from " << addr.ToSensitiveString();
+ SendBindingErrorResponse(stun_msg.get(), addr, STUN_ERROR_BAD_REQUEST,
+ STUN_ERROR_REASON_BAD_REQUEST);
+ return true;
+ }
+
+ // If the username is bad or unknown, fail with a 401 Unauthorized.
+ std::string local_ufrag;
+ std::string remote_ufrag;
+ IceProtocolType remote_protocol_type;
+ if (!ParseStunUsername(stun_msg.get(), &local_ufrag, &remote_ufrag,
+ &remote_protocol_type) ||
+ local_ufrag != username_fragment()) {
+ LOG_J(LS_ERROR, this) << "Received STUN request with bad local username "
+ << local_ufrag << " from "
+ << addr.ToSensitiveString();
+ SendBindingErrorResponse(stun_msg.get(), addr, STUN_ERROR_UNAUTHORIZED,
+ STUN_ERROR_REASON_UNAUTHORIZED);
+ return true;
+ }
+
+ // Port is initialized to GOOGLE-ICE protocol type. If pings from remote
+ // are received before the signal message, protocol type may be different.
+ // Based on the STUN username, we can determine what's the remote protocol.
+ // This also enables us to send the response back using the same protocol
+ // as the request.
+ if (IsHybridIce()) {
+ SetIceProtocolType(remote_protocol_type);
+ }
+
+ // If ICE, and the MESSAGE-INTEGRITY is bad, fail with a 401 Unauthorized
+ if (IsStandardIce() &&
+ !stun_msg->ValidateMessageIntegrity(data, size, password_)) {
+ LOG_J(LS_ERROR, this) << "Received STUN request with bad M-I "
+ << "from " << addr.ToSensitiveString();
+ SendBindingErrorResponse(stun_msg.get(), addr, STUN_ERROR_UNAUTHORIZED,
+ STUN_ERROR_REASON_UNAUTHORIZED);
+ return true;
+ }
+ out_username->assign(remote_ufrag);
+ } else if ((stun_msg->type() == STUN_BINDING_RESPONSE) ||
+ (stun_msg->type() == STUN_BINDING_ERROR_RESPONSE)) {
+ if (stun_msg->type() == STUN_BINDING_ERROR_RESPONSE) {
+ if (const StunErrorCodeAttribute* error_code = stun_msg->GetErrorCode()) {
+ LOG_J(LS_ERROR, this) << "Received STUN binding error:"
+ << " class=" << error_code->eclass()
+ << " number=" << error_code->number()
+ << " reason='" << error_code->reason() << "'"
+ << " from " << addr.ToSensitiveString();
+ // Return message to allow error-specific processing
+ } else {
+ LOG_J(LS_ERROR, this) << "Received STUN binding error without a error "
+ << "code from " << addr.ToSensitiveString();
+ return true;
+ }
+ }
+ // NOTE: Username should not be used in verifying response messages.
+ out_username->clear();
+ } else if (stun_msg->type() == STUN_BINDING_INDICATION) {
+ LOG_J(LS_VERBOSE, this) << "Received STUN binding indication:"
+ << " from " << addr.ToSensitiveString();
+ out_username->clear();
+ // No stun attributes will be verified, if it's stun indication message.
+ // Returning from end of the this method.
+ } else {
+ LOG_J(LS_ERROR, this) << "Received STUN packet with invalid type ("
+ << stun_msg->type() << ") from "
+ << addr.ToSensitiveString();
+ return true;
+ }
+
+ // Return the STUN message found.
+ *out_msg = stun_msg.release();
+ return true;
+}
+
+bool Port::IsCompatibleAddress(const rtc::SocketAddress& addr) {
+ int family = ip().family();
+ // We use single-stack sockets, so families must match.
+ if (addr.family() != family) {
+ return false;
+ }
+ // Link-local IPv6 ports can only connect to other link-local IPv6 ports.
+ if (family == AF_INET6 && (IPIsPrivate(ip()) != IPIsPrivate(addr.ipaddr()))) {
+ return false;
+ }
+ return true;
+}
+
+bool Port::ParseStunUsername(const StunMessage* stun_msg,
+ std::string* local_ufrag,
+ std::string* remote_ufrag,
+ IceProtocolType* remote_protocol_type) const {
+ // The packet must include a username that either begins or ends with our
+ // fragment. It should begin with our fragment if it is a request and it
+ // should end with our fragment if it is a response.
+ local_ufrag->clear();
+ remote_ufrag->clear();
+ const StunByteStringAttribute* username_attr =
+ stun_msg->GetByteString(STUN_ATTR_USERNAME);
+ if (username_attr == NULL)
+ return false;
+
+ const std::string username_attr_str = username_attr->GetString();
+ size_t colon_pos = username_attr_str.find(":");
+ // If we are in hybrid mode set the appropriate ice protocol type based on
+ // the username argument style.
+ if (IsHybridIce()) {
+ *remote_protocol_type = (colon_pos != std::string::npos) ?
+ ICEPROTO_RFC5245 : ICEPROTO_GOOGLE;
+ } else {
+ *remote_protocol_type = ice_protocol_;
+ }
+ if (*remote_protocol_type == ICEPROTO_RFC5245) {
+ if (colon_pos != std::string::npos) { // RFRAG:LFRAG
+ *local_ufrag = username_attr_str.substr(0, colon_pos);
+ *remote_ufrag = username_attr_str.substr(
+ colon_pos + 1, username_attr_str.size());
+ } else {
+ return false;
+ }
+ } else if (*remote_protocol_type == ICEPROTO_GOOGLE) {
+ int remote_frag_len = static_cast<int>(username_attr_str.size());
+ remote_frag_len -= static_cast<int>(username_fragment().size());
+ if (remote_frag_len < 0)
+ return false;
+
+ *local_ufrag = username_attr_str.substr(0, username_fragment().size());
+ *remote_ufrag = username_attr_str.substr(
+ username_fragment().size(), username_attr_str.size());
+ }
+ return true;
+}
+
+bool Port::MaybeIceRoleConflict(
+ const rtc::SocketAddress& addr, IceMessage* stun_msg,
+ const std::string& remote_ufrag) {
+ // Validate ICE_CONTROLLING or ICE_CONTROLLED attributes.
+ bool ret = true;
+ IceRole remote_ice_role = ICEROLE_UNKNOWN;
+ uint64 remote_tiebreaker = 0;
+ const StunUInt64Attribute* stun_attr =
+ stun_msg->GetUInt64(STUN_ATTR_ICE_CONTROLLING);
+ if (stun_attr) {
+ remote_ice_role = ICEROLE_CONTROLLING;
+ remote_tiebreaker = stun_attr->value();
+ }
+
+ // If |remote_ufrag| is same as port local username fragment and
+ // tie breaker value received in the ping message matches port
+ // tiebreaker value this must be a loopback call.
+ // We will treat this as valid scenario.
+ if (remote_ice_role == ICEROLE_CONTROLLING &&
+ username_fragment() == remote_ufrag &&
+ remote_tiebreaker == IceTiebreaker()) {
+ return true;
+ }
+
+ stun_attr = stun_msg->GetUInt64(STUN_ATTR_ICE_CONTROLLED);
+ if (stun_attr) {
+ remote_ice_role = ICEROLE_CONTROLLED;
+ remote_tiebreaker = stun_attr->value();
+ }
+
+ switch (ice_role_) {
+ case ICEROLE_CONTROLLING:
+ if (ICEROLE_CONTROLLING == remote_ice_role) {
+ if (remote_tiebreaker >= tiebreaker_) {
+ SignalRoleConflict(this);
+ } else {
+ // Send Role Conflict (487) error response.
+ SendBindingErrorResponse(stun_msg, addr,
+ STUN_ERROR_ROLE_CONFLICT, STUN_ERROR_REASON_ROLE_CONFLICT);
+ ret = false;
+ }
+ }
+ break;
+ case ICEROLE_CONTROLLED:
+ if (ICEROLE_CONTROLLED == remote_ice_role) {
+ if (remote_tiebreaker < tiebreaker_) {
+ SignalRoleConflict(this);
+ } else {
+ // Send Role Conflict (487) error response.
+ SendBindingErrorResponse(stun_msg, addr,
+ STUN_ERROR_ROLE_CONFLICT, STUN_ERROR_REASON_ROLE_CONFLICT);
+ ret = false;
+ }
+ }
+ break;
+ default:
+ ASSERT(false);
+ }
+ return ret;
+}
+
+void Port::CreateStunUsername(const std::string& remote_username,
+ std::string* stun_username_attr_str) const {
+ stun_username_attr_str->clear();
+ *stun_username_attr_str = remote_username;
+ if (IsStandardIce()) {
+ // Connectivity checks from L->R will have username RFRAG:LFRAG.
+ stun_username_attr_str->append(":");
+ }
+ stun_username_attr_str->append(username_fragment());
+}
+
+void Port::SendBindingResponse(StunMessage* request,
+ const rtc::SocketAddress& addr) {
+ ASSERT(request->type() == STUN_BINDING_REQUEST);
+
+ // Retrieve the username from the request.
+ const StunByteStringAttribute* username_attr =
+ request->GetByteString(STUN_ATTR_USERNAME);
+ ASSERT(username_attr != NULL);
+ if (username_attr == NULL) {
+ // No valid username, skip the response.
+ return;
+ }
+
+ // Fill in the response message.
+ StunMessage response;
+ response.SetType(STUN_BINDING_RESPONSE);
+ response.SetTransactionID(request->transaction_id());
+ const StunUInt32Attribute* retransmit_attr =
+ request->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT);
+ if (retransmit_attr) {
+ // Inherit the incoming retransmit value in the response so the other side
+ // can see our view of lost pings.
+ response.AddAttribute(new StunUInt32Attribute(
+ STUN_ATTR_RETRANSMIT_COUNT, retransmit_attr->value()));
+
+ if (retransmit_attr->value() > CONNECTION_WRITE_CONNECT_FAILURES) {
+ LOG_J(LS_INFO, this)
+ << "Received a remote ping with high retransmit count: "
+ << retransmit_attr->value();
+ }
+ }
+
+ // Only GICE messages have USERNAME and MAPPED-ADDRESS in the response.
+ // ICE messages use XOR-MAPPED-ADDRESS, and add MESSAGE-INTEGRITY.
+ if (IsStandardIce()) {
+ response.AddAttribute(
+ new StunXorAddressAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, addr));
+ response.AddMessageIntegrity(password_);
+ response.AddFingerprint();
+ } else if (IsGoogleIce()) {
+ response.AddAttribute(
+ new StunAddressAttribute(STUN_ATTR_MAPPED_ADDRESS, addr));
+ response.AddAttribute(new StunByteStringAttribute(
+ STUN_ATTR_USERNAME, username_attr->GetString()));
+ }
+
+ // Send the response message.
+ rtc::ByteBuffer buf;
+ response.Write(&buf);
+ rtc::PacketOptions options(DefaultDscpValue());
+ if (SendTo(buf.Data(), buf.Length(), addr, options, false) < 0) {
+ LOG_J(LS_ERROR, this) << "Failed to send STUN ping response to "
+ << addr.ToSensitiveString();
+ }
+
+ // The fact that we received a successful request means that this connection
+ // (if one exists) should now be readable.
+ Connection* conn = GetConnection(addr);
+ ASSERT(conn != NULL);
+ if (conn)
+ conn->ReceivedPing();
+}
+
+void Port::SendBindingErrorResponse(StunMessage* request,
+ const rtc::SocketAddress& addr,
+ int error_code, const std::string& reason) {
+ ASSERT(request->type() == STUN_BINDING_REQUEST);
+
+ // Fill in the response message.
+ StunMessage response;
+ response.SetType(STUN_BINDING_ERROR_RESPONSE);
+ response.SetTransactionID(request->transaction_id());
+
+ // When doing GICE, we need to write out the error code incorrectly to
+ // maintain backwards compatiblility.
+ StunErrorCodeAttribute* error_attr = StunAttribute::CreateErrorCode();
+ if (IsStandardIce()) {
+ error_attr->SetCode(error_code);
+ } else if (IsGoogleIce()) {
+ error_attr->SetClass(error_code / 256);
+ error_attr->SetNumber(error_code % 256);
+ }
+ error_attr->SetReason(reason);
+ response.AddAttribute(error_attr);
+
+ if (IsStandardIce()) {
+ // Per Section 10.1.2, certain error cases don't get a MESSAGE-INTEGRITY,
+ // because we don't have enough information to determine the shared secret.
+ if (error_code != STUN_ERROR_BAD_REQUEST &&
+ error_code != STUN_ERROR_UNAUTHORIZED)
+ response.AddMessageIntegrity(password_);
+ response.AddFingerprint();
+ } else if (IsGoogleIce()) {
+ // GICE responses include a username, if one exists.
+ const StunByteStringAttribute* username_attr =
+ request->GetByteString(STUN_ATTR_USERNAME);
+ if (username_attr)
+ response.AddAttribute(new StunByteStringAttribute(
+ STUN_ATTR_USERNAME, username_attr->GetString()));
+ }
+
+ // Send the response message.
+ rtc::ByteBuffer buf;
+ response.Write(&buf);
+ rtc::PacketOptions options(DefaultDscpValue());
+ SendTo(buf.Data(), buf.Length(), addr, options, false);
+ LOG_J(LS_INFO, this) << "Sending STUN binding error: reason=" << reason
+ << " to " << addr.ToSensitiveString();
+}
+
+void Port::OnMessage(rtc::Message *pmsg) {
+ ASSERT(pmsg->message_id == MSG_CHECKTIMEOUT);
+ CheckTimeout();
+}
+
+std::string Port::ToString() const {
+ std::stringstream ss;
+ ss << "Port[" << content_name_ << ":" << component_
+ << ":" << generation_ << ":" << type_
+ << ":" << network_->ToString() << "]";
+ return ss.str();
+}
+
+void Port::EnablePortPackets() {
+ enable_port_packets_ = true;
+}
+
+void Port::OnConnectionDestroyed(Connection* conn) {
+ AddressMap::iterator iter =
+ connections_.find(conn->remote_candidate().address());
+ ASSERT(iter != connections_.end());
+ connections_.erase(iter);
+
+ // On the controlled side, ports time out, but only after all connections
+ // fail. Note: If a new connection is added after this message is posted,
+ // but it fails and is removed before kPortTimeoutDelay, then this message
+ // will still cause the Port to be destroyed.
+ if (ice_role_ == ICEROLE_CONTROLLED)
+ thread_->PostDelayed(timeout_delay_, this, MSG_CHECKTIMEOUT);
+}
+
+void Port::Destroy() {
+ ASSERT(connections_.empty());
+ LOG_J(LS_INFO, this) << "Port deleted";
+ SignalDestroyed(this);
+ delete this;
+}
+
+void Port::CheckTimeout() {
+ ASSERT(ice_role_ == ICEROLE_CONTROLLED);
+ // If this port has no connections, then there's no reason to keep it around.
+ // When the connections time out (both read and write), they will delete
+ // themselves, so if we have any connections, they are either readable or
+ // writable (or still connecting).
+ if (connections_.empty())
+ Destroy();
+}
+
+const std::string Port::username_fragment() const {
+ if (!IsStandardIce() &&
+ component_ == ICE_CANDIDATE_COMPONENT_RTCP) {
+ // In GICE mode, we should adjust username fragment for rtcp component.
+ return GetRtcpUfragFromRtpUfrag(ice_username_fragment_);
+ } else {
+ return ice_username_fragment_;
+ }
+}
+
+// A ConnectionRequest is a simple STUN ping used to determine writability.
+class ConnectionRequest : public StunRequest {
+ public:
+ explicit ConnectionRequest(Connection* connection)
+ : StunRequest(new IceMessage()),
+ connection_(connection) {
+ }
+
+ virtual ~ConnectionRequest() {
+ }
+
+ virtual void Prepare(StunMessage* request) {
+ request->SetType(STUN_BINDING_REQUEST);
+ std::string username;
+ connection_->port()->CreateStunUsername(
+ connection_->remote_candidate().username(), &username);
+ request->AddAttribute(
+ new StunByteStringAttribute(STUN_ATTR_USERNAME, username));
+
+ // connection_ already holds this ping, so subtract one from count.
+ if (connection_->port()->send_retransmit_count_attribute()) {
+ request->AddAttribute(new StunUInt32Attribute(
+ STUN_ATTR_RETRANSMIT_COUNT,
+ static_cast<uint32>(
+ connection_->pings_since_last_response_.size() - 1)));
+ }
+
+ // Adding ICE-specific attributes to the STUN request message.
+ if (connection_->port()->IsStandardIce()) {
+ // Adding ICE_CONTROLLED or ICE_CONTROLLING attribute based on the role.
+ if (connection_->port()->GetIceRole() == ICEROLE_CONTROLLING) {
+ request->AddAttribute(new StunUInt64Attribute(
+ STUN_ATTR_ICE_CONTROLLING, connection_->port()->IceTiebreaker()));
+ // Since we are trying aggressive nomination, sending USE-CANDIDATE
+ // attribute in every ping.
+ // If we are dealing with a ice-lite end point, nomination flag
+ // in Connection will be set to false by default. Once the connection
+ // becomes "best connection", nomination flag will be turned on.
+ if (connection_->use_candidate_attr()) {
+ request->AddAttribute(new StunByteStringAttribute(
+ STUN_ATTR_USE_CANDIDATE));
+ }
+ } else if (connection_->port()->GetIceRole() == ICEROLE_CONTROLLED) {
+ request->AddAttribute(new StunUInt64Attribute(
+ STUN_ATTR_ICE_CONTROLLED, connection_->port()->IceTiebreaker()));
+ } else {
+ ASSERT(false);
+ }
+
+ // Adding PRIORITY Attribute.
+ // Changing the type preference to Peer Reflexive and local preference
+ // and component id information is unchanged from the original priority.
+ // priority = (2^24)*(type preference) +
+ // (2^8)*(local preference) +
+ // (2^0)*(256 - component ID)
+ uint32 prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24 |
+ (connection_->local_candidate().priority() & 0x00FFFFFF);
+ request->AddAttribute(
+ new StunUInt32Attribute(STUN_ATTR_PRIORITY, prflx_priority));
+
+ // Adding Message Integrity attribute.
+ request->AddMessageIntegrity(connection_->remote_candidate().password());
+ // Adding Fingerprint.
+ request->AddFingerprint();
+ }
+ }
+
+ virtual void OnResponse(StunMessage* response) {
+ connection_->OnConnectionRequestResponse(this, response);
+ }
+
+ virtual void OnErrorResponse(StunMessage* response) {
+ connection_->OnConnectionRequestErrorResponse(this, response);
+ }
+
+ virtual void OnTimeout() {
+ connection_->OnConnectionRequestTimeout(this);
+ }
+
+ virtual int GetNextDelay() {
+ // Each request is sent only once. After a single delay , the request will
+ // time out.
+ timeout_ = true;
+ return CONNECTION_RESPONSE_TIMEOUT;
+ }
+
+ private:
+ Connection* connection_;
+};
+
+//
+// Connection
+//
+
+Connection::Connection(Port* port, size_t index,
+ const Candidate& remote_candidate)
+ : port_(port), local_candidate_index_(index),
+ remote_candidate_(remote_candidate), read_state_(STATE_READ_INIT),
+ write_state_(STATE_WRITE_INIT), connected_(true), pruned_(false),
+ use_candidate_attr_(false), remote_ice_mode_(ICEMODE_FULL),
+ requests_(port->thread()), rtt_(DEFAULT_RTT), last_ping_sent_(0),
+ last_ping_received_(0), last_data_received_(0),
+ last_ping_response_received_(0), reported_(false), state_(STATE_WAITING) {
+ // All of our connections start in WAITING state.
+ // TODO(mallinath) - Start connections from STATE_FROZEN.
+ // Wire up to send stun packets
+ requests_.SignalSendPacket.connect(this, &Connection::OnSendStunPacket);
+ LOG_J(LS_INFO, this) << "Connection created";
+}
+
+Connection::~Connection() {
+}
+
+const Candidate& Connection::local_candidate() const {
+ ASSERT(local_candidate_index_ < port_->Candidates().size());
+ return port_->Candidates()[local_candidate_index_];
+}
+
+uint64 Connection::priority() const {
+ uint64 priority = 0;
+ // RFC 5245 - 5.7.2. Computing Pair Priority and Ordering Pairs
+ // Let G be the priority for the candidate provided by the controlling
+ // agent. Let D be the priority for the candidate provided by the
+ // controlled agent.
+ // pair priority = 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0)
+ IceRole role = port_->GetIceRole();
+ if (role != ICEROLE_UNKNOWN) {
+ uint32 g = 0;
+ uint32 d = 0;
+ if (role == ICEROLE_CONTROLLING) {
+ g = local_candidate().priority();
+ d = remote_candidate_.priority();
+ } else {
+ g = remote_candidate_.priority();
+ d = local_candidate().priority();
+ }
+ priority = rtc::_min(g, d);
+ priority = priority << 32;
+ priority += 2 * rtc::_max(g, d) + (g > d ? 1 : 0);
+ }
+ return priority;
+}
+
+void Connection::set_read_state(ReadState value) {
+ ReadState old_value = read_state_;
+ read_state_ = value;
+ if (value != old_value) {
+ LOG_J(LS_VERBOSE, this) << "set_read_state";
+ SignalStateChange(this);
+ CheckTimeout();
+ }
+}
+
+void Connection::set_write_state(WriteState value) {
+ WriteState old_value = write_state_;
+ write_state_ = value;
+ if (value != old_value) {
+ LOG_J(LS_VERBOSE, this) << "set_write_state";
+ SignalStateChange(this);
+ CheckTimeout();
+ }
+}
+
+void Connection::set_state(State state) {
+ State old_state = state_;
+ state_ = state;
+ if (state != old_state) {
+ LOG_J(LS_VERBOSE, this) << "set_state";
+ }
+}
+
+void Connection::set_connected(bool value) {
+ bool old_value = connected_;
+ connected_ = value;
+ if (value != old_value) {
+ LOG_J(LS_VERBOSE, this) << "set_connected";
+ }
+}
+
+void Connection::set_use_candidate_attr(bool enable) {
+ use_candidate_attr_ = enable;
+}
+
+void Connection::OnSendStunPacket(const void* data, size_t size,
+ StunRequest* req) {
+ rtc::PacketOptions options(port_->DefaultDscpValue());
+ if (port_->SendTo(data, size, remote_candidate_.address(),
+ options, false) < 0) {
+ LOG_J(LS_WARNING, this) << "Failed to send STUN ping " << req->id();
+ }
+}
+
+void Connection::OnReadPacket(
+ const char* data, size_t size, const rtc::PacketTime& packet_time) {
+ rtc::scoped_ptr<IceMessage> msg;
+ std::string remote_ufrag;
+ const rtc::SocketAddress& addr(remote_candidate_.address());
+ if (!port_->GetStunMessage(data, size, addr, msg.accept(), &remote_ufrag)) {
+ // The packet did not parse as a valid STUN message
+
+ // If this connection is readable, then pass along the packet.
+ if (read_state_ == STATE_READABLE) {
+ // readable means data from this address is acceptable
+ // Send it on!
+
+ last_data_received_ = rtc::Time();
+ recv_rate_tracker_.Update(size);
+ SignalReadPacket(this, data, size, packet_time);
+
+ // If timed out sending writability checks, start up again
+ if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT)) {
+ LOG(LS_WARNING) << "Received a data packet on a timed-out Connection. "
+ << "Resetting state to STATE_WRITE_INIT.";
+ set_write_state(STATE_WRITE_INIT);
+ }
+ } else {
+ // Not readable means the remote address hasn't sent a valid
+ // binding request yet.
+
+ LOG_J(LS_WARNING, this)
+ << "Received non-STUN packet from an unreadable connection.";
+ }
+ } else if (!msg) {
+ // The packet was STUN, but failed a check and was handled internally.
+ } else {
+ // The packet is STUN and passed the Port checks.
+ // Perform our own checks to ensure this packet is valid.
+ // If this is a STUN request, then update the readable bit and respond.
+ // If this is a STUN response, then update the writable bit.
+ switch (msg->type()) {
+ case STUN_BINDING_REQUEST:
+ if (remote_ufrag == remote_candidate_.username()) {
+ // Check for role conflicts.
+ if (port_->IsStandardIce() &&
+ !port_->MaybeIceRoleConflict(addr, msg.get(), remote_ufrag)) {
+ // Received conflicting role from the peer.
+ LOG(LS_INFO) << "Received conflicting role from the peer.";
+ return;
+ }
+
+ // Incoming, validated stun request from remote peer.
+ // This call will also set the connection readable.
+ port_->SendBindingResponse(msg.get(), addr);
+
+ // If timed out sending writability checks, start up again
+ if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT))
+ set_write_state(STATE_WRITE_INIT);
+
+ if ((port_->IsStandardIce()) &&
+ (port_->GetIceRole() == ICEROLE_CONTROLLED)) {
+ const StunByteStringAttribute* use_candidate_attr =
+ msg->GetByteString(STUN_ATTR_USE_CANDIDATE);
+ if (use_candidate_attr)
+ SignalUseCandidate(this);
+ }
+ } else {
+ // The packet had the right local username, but the remote username
+ // was not the right one for the remote address.
+ LOG_J(LS_ERROR, this)
+ << "Received STUN request with bad remote username "
+ << remote_ufrag;
+ port_->SendBindingErrorResponse(msg.get(), addr,
+ STUN_ERROR_UNAUTHORIZED,
+ STUN_ERROR_REASON_UNAUTHORIZED);
+
+ }
+ break;
+
+ // Response from remote peer. Does it match request sent?
+ // This doesn't just check, it makes callbacks if transaction
+ // id's match.
+ case STUN_BINDING_RESPONSE:
+ case STUN_BINDING_ERROR_RESPONSE:
+ if (port_->IsGoogleIce() ||
+ msg->ValidateMessageIntegrity(
+ data, size, remote_candidate().password())) {
+ requests_.CheckResponse(msg.get());
+ }
+ // Otherwise silently discard the response message.
+ break;
+
+ // Remote end point sent an STUN indication instead of regular
+ // binding request. In this case |last_ping_received_| will be updated.
+ // Otherwise we can mark connection to read timeout. No response will be
+ // sent in this scenario.
+ case STUN_BINDING_INDICATION:
+ if (port_->IsStandardIce() && read_state_ == STATE_READABLE) {
+ ReceivedPing();
+ } else {
+ LOG_J(LS_WARNING, this) << "Received STUN binding indication "
+ << "from an unreadable connection.";
+ }
+ break;
+
+ default:
+ ASSERT(false);
+ break;
+ }
+ }
+}
+
+void Connection::OnReadyToSend() {
+ if (write_state_ == STATE_WRITABLE) {
+ SignalReadyToSend(this);
+ }
+}
+
+void Connection::Prune() {
+ if (!pruned_) {
+ LOG_J(LS_VERBOSE, this) << "Connection pruned";
+ pruned_ = true;
+ requests_.Clear();
+ set_write_state(STATE_WRITE_TIMEOUT);
+ }
+}
+
+void Connection::Destroy() {
+ LOG_J(LS_VERBOSE, this) << "Connection destroyed";
+ set_read_state(STATE_READ_TIMEOUT);
+ set_write_state(STATE_WRITE_TIMEOUT);
+}
+
+void Connection::UpdateState(uint32 now) {
+ uint32 rtt = ConservativeRTTEstimate(rtt_);
+
+ std::string pings;
+ for (size_t i = 0; i < pings_since_last_response_.size(); ++i) {
+ char buf[32];
+ rtc::sprintfn(buf, sizeof(buf), "%u",
+ pings_since_last_response_[i]);
+ pings.append(buf).append(" ");
+ }
+ LOG_J(LS_VERBOSE, this) << "UpdateState(): pings_since_last_response_=" <<
+ pings << ", rtt=" << rtt << ", now=" << now;
+
+ // Check the readable state.
+ //
+ // Since we don't know how many pings the other side has attempted, the best
+ // test we can do is a simple window.
+ // If other side has not sent ping after connection has become readable, use
+ // |last_data_received_| as the indication.
+ // If remote endpoint is doing RFC 5245, it's not required to send ping
+ // after connection is established. If this connection is serving a data
+ // channel, it may not be in a position to send media continuously. Do not
+ // mark connection timeout if it's in RFC5245 mode.
+ // Below check will be performed with end point if it's doing google-ice.
+ if (port_->IsGoogleIce() && (read_state_ == STATE_READABLE) &&
+ (last_ping_received_ + CONNECTION_READ_TIMEOUT <= now) &&
+ (last_data_received_ + CONNECTION_READ_TIMEOUT <= now)) {
+ LOG_J(LS_INFO, this) << "Unreadable after "
+ << now - last_ping_received_
+ << " ms without a ping,"
+ << " ms since last received response="
+ << now - last_ping_response_received_
+ << " ms since last received data="
+ << now - last_data_received_
+ << " rtt=" << rtt;
+ set_read_state(STATE_READ_TIMEOUT);
+ }
+
+ // Check the writable state. (The order of these checks is important.)
+ //
+ // Before becoming unwritable, we allow for a fixed number of pings to fail
+ // (i.e., receive no response). We also have to give the response time to
+ // get back, so we include a conservative estimate of this.
+ //
+ // Before timing out writability, we give a fixed amount of time. This is to
+ // allow for changes in network conditions.
+
+ if ((write_state_ == STATE_WRITABLE) &&
+ TooManyFailures(pings_since_last_response_,
+ CONNECTION_WRITE_CONNECT_FAILURES,
+ rtt,
+ now) &&
+ TooLongWithoutResponse(pings_since_last_response_,
+ CONNECTION_WRITE_CONNECT_TIMEOUT,
+ now)) {
+ uint32 max_pings = CONNECTION_WRITE_CONNECT_FAILURES;
+ LOG_J(LS_INFO, this) << "Unwritable after " << max_pings
+ << " ping failures and "
+ << now - pings_since_last_response_[0]
+ << " ms without a response,"
+ << " ms since last received ping="
+ << now - last_ping_received_
+ << " ms since last received data="
+ << now - last_data_received_
+ << " rtt=" << rtt;
+ set_write_state(STATE_WRITE_UNRELIABLE);
+ }
+
+ if ((write_state_ == STATE_WRITE_UNRELIABLE ||
+ write_state_ == STATE_WRITE_INIT) &&
+ TooLongWithoutResponse(pings_since_last_response_,
+ CONNECTION_WRITE_TIMEOUT,
+ now)) {
+ LOG_J(LS_INFO, this) << "Timed out after "
+ << now - pings_since_last_response_[0]
+ << " ms without a response, rtt=" << rtt;
+ set_write_state(STATE_WRITE_TIMEOUT);
+ }
+}
+
+void Connection::Ping(uint32 now) {
+ ASSERT(connected_);
+ last_ping_sent_ = now;
+ pings_since_last_response_.push_back(now);
+ ConnectionRequest *req = new ConnectionRequest(this);
+ LOG_J(LS_VERBOSE, this) << "Sending STUN ping " << req->id() << " at " << now;
+ requests_.Send(req);
+ state_ = STATE_INPROGRESS;
+}
+
+void Connection::ReceivedPing() {
+ last_ping_received_ = rtc::Time();
+ set_read_state(STATE_READABLE);
+}
+
+std::string Connection::ToString() const {
+ const char CONNECT_STATE_ABBREV[2] = {
+ '-', // not connected (false)
+ 'C', // connected (true)
+ };
+ const char READ_STATE_ABBREV[3] = {
+ '-', // STATE_READ_INIT
+ 'R', // STATE_READABLE
+ 'x', // STATE_READ_TIMEOUT
+ };
+ const char WRITE_STATE_ABBREV[4] = {
+ 'W', // STATE_WRITABLE
+ 'w', // STATE_WRITE_UNRELIABLE
+ '-', // STATE_WRITE_INIT
+ 'x', // STATE_WRITE_TIMEOUT
+ };
+ const std::string ICESTATE[4] = {
+ "W", // STATE_WAITING
+ "I", // STATE_INPROGRESS
+ "S", // STATE_SUCCEEDED
+ "F" // STATE_FAILED
+ };
+ const Candidate& local = local_candidate();
+ const Candidate& remote = remote_candidate();
+ std::stringstream ss;
+ ss << "Conn[" << port_->content_name()
+ << ":" << local.id() << ":" << local.component()
+ << ":" << local.generation()
+ << ":" << local.type() << ":" << local.protocol()
+ << ":" << local.address().ToSensitiveString()
+ << "->" << remote.id() << ":" << remote.component()
+ << ":" << remote.priority()
+ << ":" << remote.type() << ":"
+ << remote.protocol() << ":" << remote.address().ToSensitiveString() << "|"
+ << CONNECT_STATE_ABBREV[connected()]
+ << READ_STATE_ABBREV[read_state()]
+ << WRITE_STATE_ABBREV[write_state()]
+ << ICESTATE[state()] << "|"
+ << priority() << "|";
+ if (rtt_ < DEFAULT_RTT) {
+ ss << rtt_ << "]";
+ } else {
+ ss << "-]";
+ }
+ return ss.str();
+}
+
+std::string Connection::ToSensitiveString() const {
+ return ToString();
+}
+
+void Connection::OnConnectionRequestResponse(ConnectionRequest* request,
+ StunMessage* response) {
+ // We've already validated that this is a STUN binding response with
+ // the correct local and remote username for this connection.
+ // So if we're not already, become writable. We may be bringing a pruned
+ // connection back to life, but if we don't really want it, we can always
+ // prune it again.
+ uint32 rtt = request->Elapsed();
+ set_write_state(STATE_WRITABLE);
+ set_state(STATE_SUCCEEDED);
+
+ if (remote_ice_mode_ == ICEMODE_LITE) {
+ // A ice-lite end point never initiates ping requests. This will allow
+ // us to move to STATE_READABLE.
+ ReceivedPing();
+ }
+
+ std::string pings;
+ for (size_t i = 0; i < pings_since_last_response_.size(); ++i) {
+ char buf[32];
+ rtc::sprintfn(buf, sizeof(buf), "%u",
+ pings_since_last_response_[i]);
+ pings.append(buf).append(" ");
+ }
+
+ rtc::LoggingSeverity level =
+ (pings_since_last_response_.size() > CONNECTION_WRITE_CONNECT_FAILURES) ?
+ rtc::LS_INFO : rtc::LS_VERBOSE;
+
+ LOG_JV(level, this) << "Received STUN ping response " << request->id()
+ << ", pings_since_last_response_=" << pings
+ << ", rtt=" << rtt;
+
+ pings_since_last_response_.clear();
+ last_ping_response_received_ = rtc::Time();
+ rtt_ = (RTT_RATIO * rtt_ + rtt) / (RTT_RATIO + 1);
+
+ // Peer reflexive candidate is only for RFC 5245 ICE.
+ if (port_->IsStandardIce()) {
+ MaybeAddPrflxCandidate(request, response);
+ }
+}
+
+void Connection::OnConnectionRequestErrorResponse(ConnectionRequest* request,
+ StunMessage* response) {
+ const StunErrorCodeAttribute* error_attr = response->GetErrorCode();
+ int error_code = STUN_ERROR_GLOBAL_FAILURE;
+ if (error_attr) {
+ if (port_->IsGoogleIce()) {
+ // When doing GICE, the error code is written out incorrectly, so we need
+ // to unmunge it here.
+ error_code = error_attr->eclass() * 256 + error_attr->number();
+ } else {
+ error_code = error_attr->code();
+ }
+ }
+
+ if (error_code == STUN_ERROR_UNKNOWN_ATTRIBUTE ||
+ error_code == STUN_ERROR_SERVER_ERROR ||
+ error_code == STUN_ERROR_UNAUTHORIZED) {
+ // Recoverable error, retry
+ } else if (error_code == STUN_ERROR_STALE_CREDENTIALS) {
+ // Race failure, retry
+ } else if (error_code == STUN_ERROR_ROLE_CONFLICT) {
+ HandleRoleConflictFromPeer();
+ } else {
+ // This is not a valid connection.
+ LOG_J(LS_ERROR, this) << "Received STUN error response, code="
+ << error_code << "; killing connection";
+ set_state(STATE_FAILED);
+ set_write_state(STATE_WRITE_TIMEOUT);
+ }
+}
+
+void Connection::OnConnectionRequestTimeout(ConnectionRequest* request) {
+ // Log at LS_INFO if we miss a ping on a writable connection.
+ rtc::LoggingSeverity sev = (write_state_ == STATE_WRITABLE) ?
+ rtc::LS_INFO : rtc::LS_VERBOSE;
+ LOG_JV(sev, this) << "Timing-out STUN ping " << request->id()
+ << " after " << request->Elapsed() << " ms";
+}
+
+void Connection::CheckTimeout() {
+ // If both read and write have timed out or read has never initialized, then
+ // this connection can contribute no more to p2p socket unless at some later
+ // date readability were to come back. However, we gave readability a long
+ // time to timeout, so at this point, it seems fair to get rid of this
+ // connection.
+ if ((read_state_ == STATE_READ_TIMEOUT ||
+ read_state_ == STATE_READ_INIT) &&
+ write_state_ == STATE_WRITE_TIMEOUT) {
+ port_->thread()->Post(this, MSG_DELETE);
+ }
+}
+
+void Connection::HandleRoleConflictFromPeer() {
+ port_->SignalRoleConflict(port_);
+}
+
+void Connection::OnMessage(rtc::Message *pmsg) {
+ ASSERT(pmsg->message_id == MSG_DELETE);
+
+ LOG_J(LS_INFO, this) << "Connection deleted";
+ SignalDestroyed(this);
+ delete this;
+}
+
+size_t Connection::recv_bytes_second() {
+ return recv_rate_tracker_.units_second();
+}
+
+size_t Connection::recv_total_bytes() {
+ return recv_rate_tracker_.total_units();
+}
+
+size_t Connection::sent_bytes_second() {
+ return send_rate_tracker_.units_second();
+}
+
+size_t Connection::sent_total_bytes() {
+ return send_rate_tracker_.total_units();
+}
+
+void Connection::MaybeAddPrflxCandidate(ConnectionRequest* request,
+ StunMessage* response) {
+ // RFC 5245
+ // The agent checks the mapped address from the STUN response. If the
+ // transport address does not match any of the local candidates that the
+ // agent knows about, the mapped address represents a new candidate -- a
+ // peer reflexive candidate.
+ const StunAddressAttribute* addr =
+ response->GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
+ if (!addr) {
+ LOG(LS_WARNING) << "Connection::OnConnectionRequestResponse - "
+ << "No MAPPED-ADDRESS or XOR-MAPPED-ADDRESS found in the "
+ << "stun response message";
+ return;
+ }
+
+ bool known_addr = false;
+ for (size_t i = 0; i < port_->Candidates().size(); ++i) {
+ if (port_->Candidates()[i].address() == addr->GetAddress()) {
+ known_addr = true;
+ break;
+ }
+ }
+ if (known_addr) {
+ return;
+ }
+
+ // RFC 5245
+ // Its priority is set equal to the value of the PRIORITY attribute
+ // in the Binding request.
+ const StunUInt32Attribute* priority_attr =
+ request->msg()->GetUInt32(STUN_ATTR_PRIORITY);
+ if (!priority_attr) {
+ LOG(LS_WARNING) << "Connection::OnConnectionRequestResponse - "
+ << "No STUN_ATTR_PRIORITY found in the "
+ << "stun response message";
+ return;
+ }
+ const uint32 priority = priority_attr->value();
+ std::string id = rtc::CreateRandomString(8);
+
+ Candidate new_local_candidate;
+ new_local_candidate.set_id(id);
+ new_local_candidate.set_component(local_candidate().component());
+ new_local_candidate.set_type(PRFLX_PORT_TYPE);
+ new_local_candidate.set_protocol(local_candidate().protocol());
+ new_local_candidate.set_address(addr->GetAddress());
+ new_local_candidate.set_priority(priority);
+ new_local_candidate.set_username(local_candidate().username());
+ new_local_candidate.set_password(local_candidate().password());
+ new_local_candidate.set_network_name(local_candidate().network_name());
+ new_local_candidate.set_related_address(local_candidate().address());
+ new_local_candidate.set_foundation(
+ ComputeFoundation(PRFLX_PORT_TYPE, local_candidate().protocol(),
+ local_candidate().address()));
+
+ // Change the local candidate of this Connection to the new prflx candidate.
+ local_candidate_index_ = port_->AddPrflxCandidate(new_local_candidate);
+
+ // SignalStateChange to force a re-sort in P2PTransportChannel as this
+ // Connection's local candidate has changed.
+ SignalStateChange(this);
+}
+
+ProxyConnection::ProxyConnection(Port* port, size_t index,
+ const Candidate& candidate)
+ : Connection(port, index, candidate), error_(0) {
+}
+
+int ProxyConnection::Send(const void* data, size_t size,
+ const rtc::PacketOptions& options) {
+ if (write_state_ == STATE_WRITE_INIT || write_state_ == STATE_WRITE_TIMEOUT) {
+ error_ = EWOULDBLOCK;
+ return SOCKET_ERROR;
+ }
+ int sent = port_->SendTo(data, size, remote_candidate_.address(),
+ options, true);
+ if (sent <= 0) {
+ ASSERT(sent < 0);
+ error_ = port_->GetError();
+ } else {
+ send_rate_tracker_.Update(sent);
+ }
+ return sent;
+}
+
+} // namespace cricket
diff --git a/p2p/base/port.h b/p2p/base/port.h
new file mode 100644
index 00000000..48b85302
--- /dev/null
+++ b/p2p/base/port.h
@@ -0,0 +1,602 @@
+/*
+ * 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 WEBRTC_P2P_BASE_PORT_H_
+#define WEBRTC_P2P_BASE_PORT_H_
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "webrtc/p2p/base/candidate.h"
+#include "webrtc/p2p/base/packetsocketfactory.h"
+#include "webrtc/p2p/base/portinterface.h"
+#include "webrtc/p2p/base/stun.h"
+#include "webrtc/p2p/base/stunrequest.h"
+#include "webrtc/p2p/base/transport.h"
+#include "webrtc/base/asyncpacketsocket.h"
+#include "webrtc/base/network.h"
+#include "webrtc/base/proxyinfo.h"
+#include "webrtc/base/ratetracker.h"
+#include "webrtc/base/sigslot.h"
+#include "webrtc/base/socketaddress.h"
+#include "webrtc/base/thread.h"
+
+namespace cricket {
+
+class Connection;
+class ConnectionRequest;
+
+extern const char LOCAL_PORT_TYPE[];
+extern const char STUN_PORT_TYPE[];
+extern const char PRFLX_PORT_TYPE[];
+extern const char RELAY_PORT_TYPE[];
+
+extern const char UDP_PROTOCOL_NAME[];
+extern const char TCP_PROTOCOL_NAME[];
+extern const char SSLTCP_PROTOCOL_NAME[];
+
+// RFC 6544, TCP candidate encoding rules.
+extern const int DISCARD_PORT;
+extern const char TCPTYPE_ACTIVE_STR[];
+extern const char TCPTYPE_PASSIVE_STR[];
+extern const char TCPTYPE_SIMOPEN_STR[];
+
+// The length of time we wait before timing out readability on a connection.
+const uint32 CONNECTION_READ_TIMEOUT = 30 * 1000; // 30 seconds
+
+// The length of time we wait before timing out writability on a connection.
+const uint32 CONNECTION_WRITE_TIMEOUT = 15 * 1000; // 15 seconds
+
+// The length of time we wait before we become unwritable.
+const uint32 CONNECTION_WRITE_CONNECT_TIMEOUT = 5 * 1000; // 5 seconds
+
+// The number of pings that must fail to respond before we become unwritable.
+const uint32 CONNECTION_WRITE_CONNECT_FAILURES = 5;
+
+// This is the length of time that we wait for a ping response to come back.
+const int CONNECTION_RESPONSE_TIMEOUT = 5 * 1000; // 5 seconds
+
+enum RelayType {
+ RELAY_GTURN, // Legacy google relay service.
+ RELAY_TURN // Standard (TURN) relay service.
+};
+
+enum IcePriorityValue {
+ // The reason we are choosing Relay preference 2 is because, we can run
+ // Relay from client to server on UDP/TCP/TLS. To distinguish the transport
+ // protocol, we prefer UDP over TCP over TLS.
+ // For UDP ICE_TYPE_PREFERENCE_RELAY will be 2.
+ // For TCP ICE_TYPE_PREFERENCE_RELAY will be 1.
+ // For TLS ICE_TYPE_PREFERENCE_RELAY will be 0.
+ // Check turnport.cc for setting these values.
+ ICE_TYPE_PREFERENCE_RELAY = 2,
+ ICE_TYPE_PREFERENCE_HOST_TCP = 90,
+ ICE_TYPE_PREFERENCE_SRFLX = 100,
+ ICE_TYPE_PREFERENCE_PRFLX = 110,
+ ICE_TYPE_PREFERENCE_HOST = 126
+};
+
+const char* ProtoToString(ProtocolType proto);
+bool StringToProto(const char* value, ProtocolType* proto);
+
+struct ProtocolAddress {
+ rtc::SocketAddress address;
+ ProtocolType proto;
+ bool secure;
+
+ ProtocolAddress(const rtc::SocketAddress& a, ProtocolType p)
+ : address(a), proto(p), secure(false) { }
+ ProtocolAddress(const rtc::SocketAddress& a, ProtocolType p, bool sec)
+ : address(a), proto(p), secure(sec) { }
+};
+
+typedef std::set<rtc::SocketAddress> ServerAddresses;
+
+// Represents a local communication mechanism that can be used to create
+// connections to similar mechanisms of the other client. Subclasses of this
+// one add support for specific mechanisms like local UDP ports.
+class Port : public PortInterface, public rtc::MessageHandler,
+ public sigslot::has_slots<> {
+ public:
+ Port(rtc::Thread* thread, rtc::PacketSocketFactory* factory,
+ rtc::Network* network, const rtc::IPAddress& ip,
+ const std::string& username_fragment, const std::string& password);
+ Port(rtc::Thread* thread, const std::string& type,
+ rtc::PacketSocketFactory* factory,
+ rtc::Network* network, const rtc::IPAddress& ip,
+ int min_port, int max_port, const std::string& username_fragment,
+ const std::string& password);
+ virtual ~Port();
+
+ virtual const std::string& Type() const { return type_; }
+ virtual rtc::Network* Network() const { return network_; }
+
+ // This method will set the flag which enables standard ICE/STUN procedures
+ // in STUN connectivity checks. Currently this method does
+ // 1. Add / Verify MI attribute in STUN binding requests.
+ // 2. Username attribute in STUN binding request will be RFRAF:LFRAG,
+ // as opposed to RFRAGLFRAG.
+ virtual void SetIceProtocolType(IceProtocolType protocol) {
+ ice_protocol_ = protocol;
+ }
+ virtual IceProtocolType IceProtocol() const { return ice_protocol_; }
+
+ // Methods to set/get ICE role and tiebreaker values.
+ IceRole GetIceRole() const { return ice_role_; }
+ void SetIceRole(IceRole role) { ice_role_ = role; }
+
+ void SetIceTiebreaker(uint64 tiebreaker) { tiebreaker_ = tiebreaker; }
+ uint64 IceTiebreaker() const { return tiebreaker_; }
+
+ virtual bool SharedSocket() const { return shared_socket_; }
+ void ResetSharedSocket() { shared_socket_ = false; }
+
+ // The thread on which this port performs its I/O.
+ rtc::Thread* thread() { return thread_; }
+
+ // The factory used to create the sockets of this port.
+ rtc::PacketSocketFactory* socket_factory() const { return factory_; }
+ void set_socket_factory(rtc::PacketSocketFactory* factory) {
+ factory_ = factory;
+ }
+
+ // For debugging purposes.
+ const std::string& content_name() const { return content_name_; }
+ void set_content_name(const std::string& content_name) {
+ content_name_ = content_name;
+ }
+
+ int component() const { return component_; }
+ void set_component(int component) { component_ = component; }
+
+ bool send_retransmit_count_attribute() const {
+ return send_retransmit_count_attribute_;
+ }
+ void set_send_retransmit_count_attribute(bool enable) {
+ send_retransmit_count_attribute_ = enable;
+ }
+
+ // Identifies the generation that this port was created in.
+ uint32 generation() { return generation_; }
+ void set_generation(uint32 generation) { generation_ = generation; }
+
+ // ICE requires a single username/password per content/media line. So the
+ // |ice_username_fragment_| of the ports that belongs to the same content will
+ // be the same. However this causes a small complication with our relay
+ // server, which expects different username for RTP and RTCP.
+ //
+ // To resolve this problem, we implemented the username_fragment(),
+ // which returns a different username (calculated from
+ // |ice_username_fragment_|) for RTCP in the case of ICEPROTO_GOOGLE. And the
+ // username_fragment() simply returns |ice_username_fragment_| when running
+ // in ICEPROTO_RFC5245.
+ //
+ // As a result the ICEPROTO_GOOGLE will use different usernames for RTP and
+ // RTCP. And the ICEPROTO_RFC5245 will use same username for both RTP and
+ // RTCP.
+ const std::string username_fragment() const;
+ const std::string& password() const { return password_; }
+
+ // Fired when candidates are discovered by the port. When all candidates
+ // are discovered that belong to port SignalAddressReady is fired.
+ sigslot::signal2<Port*, const Candidate&> SignalCandidateReady;
+
+ // Provides all of the above information in one handy object.
+ virtual const std::vector<Candidate>& Candidates() const {
+ return candidates_;
+ }
+
+ // SignalPortComplete is sent when port completes the task of candidates
+ // allocation.
+ sigslot::signal1<Port*> SignalPortComplete;
+ // This signal sent when port fails to allocate candidates and this port
+ // can't be used in establishing the connections. When port is in shared mode
+ // and port fails to allocate one of the candidates, port shouldn't send
+ // this signal as other candidates might be usefull in establishing the
+ // connection.
+ sigslot::signal1<Port*> SignalPortError;
+
+ // Returns a map containing all of the connections of this port, keyed by the
+ // remote address.
+ typedef std::map<rtc::SocketAddress, Connection*> AddressMap;
+ const AddressMap& connections() { return connections_; }
+
+ // Returns the connection to the given address or NULL if none exists.
+ virtual Connection* GetConnection(
+ const rtc::SocketAddress& remote_addr);
+
+ // Called each time a connection is created.
+ sigslot::signal2<Port*, Connection*> SignalConnectionCreated;
+
+ // In a shared socket mode each port which shares the socket will decide
+ // to accept the packet based on the |remote_addr|. Currently only UDP
+ // port implemented this method.
+ // TODO(mallinath) - Make it pure virtual.
+ virtual bool HandleIncomingPacket(
+ rtc::AsyncPacketSocket* socket, const char* data, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time) {
+ ASSERT(false);
+ return false;
+ }
+
+ // Sends a response message (normal or error) to the given request. One of
+ // these methods should be called as a response to SignalUnknownAddress.
+ // NOTE: You MUST call CreateConnection BEFORE SendBindingResponse.
+ virtual void SendBindingResponse(StunMessage* request,
+ const rtc::SocketAddress& addr);
+ virtual void SendBindingErrorResponse(
+ StunMessage* request, const rtc::SocketAddress& addr,
+ int error_code, const std::string& reason);
+
+ void set_proxy(const std::string& user_agent,
+ const rtc::ProxyInfo& proxy) {
+ user_agent_ = user_agent;
+ proxy_ = proxy;
+ }
+ const std::string& user_agent() { return user_agent_; }
+ const rtc::ProxyInfo& proxy() { return proxy_; }
+
+ virtual void EnablePortPackets();
+
+ // Called if the port has no connections and is no longer useful.
+ void Destroy();
+
+ virtual void OnMessage(rtc::Message *pmsg);
+
+ // Debugging description of this port
+ virtual std::string ToString() const;
+ rtc::IPAddress& ip() { return ip_; }
+ int min_port() { return min_port_; }
+ int max_port() { return max_port_; }
+
+ // Timeout shortening function to speed up unit tests.
+ void set_timeout_delay(int delay) { timeout_delay_ = delay; }
+
+ // This method will return local and remote username fragements from the
+ // stun username attribute if present.
+ bool ParseStunUsername(const StunMessage* stun_msg,
+ std::string* local_username,
+ std::string* remote_username,
+ IceProtocolType* remote_protocol_type) const;
+ void CreateStunUsername(const std::string& remote_username,
+ std::string* stun_username_attr_str) const;
+
+ bool MaybeIceRoleConflict(const rtc::SocketAddress& addr,
+ IceMessage* stun_msg,
+ const std::string& remote_ufrag);
+
+ // Called when the socket is currently able to send.
+ void OnReadyToSend();
+
+ // Called when the Connection discovers a local peer reflexive candidate.
+ // Returns the index of the new local candidate.
+ size_t AddPrflxCandidate(const Candidate& local);
+
+ // Returns if RFC 5245 ICE protocol is used.
+ bool IsStandardIce() const;
+
+ // Returns if Google ICE protocol is used.
+ bool IsGoogleIce() const;
+
+ // Returns if Hybrid ICE protocol is used.
+ bool IsHybridIce() const;
+
+ void set_candidate_filter(uint32 candidate_filter) {
+ candidate_filter_ = candidate_filter;
+ }
+
+ protected:
+ enum {
+ MSG_CHECKTIMEOUT = 0,
+ MSG_FIRST_AVAILABLE
+ };
+
+ void set_type(const std::string& type) { type_ = type; }
+
+ void AddAddress(const rtc::SocketAddress& address,
+ const rtc::SocketAddress& base_address,
+ const rtc::SocketAddress& related_address,
+ const std::string& protocol, const std::string& tcptype,
+ const std::string& type, uint32 type_preference,
+ uint32 relay_preference, bool final);
+
+ // Adds the given connection to the list. (Deleting removes them.)
+ void AddConnection(Connection* conn);
+
+ // Called when a packet is received from an unknown address that is not
+ // currently a connection. If this is an authenticated STUN binding request,
+ // then we will signal the client.
+ void OnReadPacket(const char* data, size_t size,
+ const rtc::SocketAddress& addr,
+ ProtocolType proto);
+
+ // If the given data comprises a complete and correct STUN message then the
+ // return value is true, otherwise false. If the message username corresponds
+ // with this port's username fragment, msg will contain the parsed STUN
+ // message. Otherwise, the function may send a STUN response internally.
+ // remote_username contains the remote fragment of the STUN username.
+ bool GetStunMessage(const char* data, size_t size,
+ const rtc::SocketAddress& addr,
+ IceMessage** out_msg, std::string* out_username);
+
+ // Checks if the address in addr is compatible with the port's ip.
+ bool IsCompatibleAddress(const rtc::SocketAddress& addr);
+
+ // Returns default DSCP value.
+ rtc::DiffServCodePoint DefaultDscpValue() const {
+ // No change from what MediaChannel set.
+ return rtc::DSCP_NO_CHANGE;
+ }
+
+ uint32 candidate_filter() { return candidate_filter_; }
+
+ private:
+ void Construct();
+ // Called when one of our connections deletes itself.
+ void OnConnectionDestroyed(Connection* conn);
+
+ // Checks if this port is useless, and hence, should be destroyed.
+ void CheckTimeout();
+
+ rtc::Thread* thread_;
+ rtc::PacketSocketFactory* factory_;
+ std::string type_;
+ bool send_retransmit_count_attribute_;
+ rtc::Network* network_;
+ rtc::IPAddress ip_;
+ int min_port_;
+ int max_port_;
+ std::string content_name_;
+ int component_;
+ uint32 generation_;
+ // In order to establish a connection to this Port (so that real data can be
+ // sent through), the other side must send us a STUN binding request that is
+ // authenticated with this username_fragment and password.
+ // PortAllocatorSession will provide these username_fragment and password.
+ //
+ // Note: we should always use username_fragment() instead of using
+ // |ice_username_fragment_| directly. For the details see the comment on
+ // username_fragment().
+ std::string ice_username_fragment_;
+ std::string password_;
+ std::vector<Candidate> candidates_;
+ AddressMap connections_;
+ int timeout_delay_;
+ bool enable_port_packets_;
+ IceProtocolType ice_protocol_;
+ IceRole ice_role_;
+ uint64 tiebreaker_;
+ bool shared_socket_;
+ // Information to use when going through a proxy.
+ std::string user_agent_;
+ rtc::ProxyInfo proxy_;
+
+ // Candidate filter is pushed down to Port such that each Port could
+ // make its own decision on how to create candidates. For example,
+ // when IceTransportsType is set to relay, both RelayPort and
+ // TurnPort will hide raddr to avoid local address leakage.
+ uint32 candidate_filter_;
+
+ friend class Connection;
+};
+
+// Represents a communication link between a port on the local client and a
+// port on the remote client.
+class Connection : public rtc::MessageHandler,
+ public sigslot::has_slots<> {
+ public:
+ // States are from RFC 5245. http://tools.ietf.org/html/rfc5245#section-5.7.4
+ enum State {
+ STATE_WAITING = 0, // Check has not been performed, Waiting pair on CL.
+ STATE_INPROGRESS, // Check has been sent, transaction is in progress.
+ STATE_SUCCEEDED, // Check already done, produced a successful result.
+ STATE_FAILED // Check for this connection failed.
+ };
+
+ virtual ~Connection();
+
+ // The local port where this connection sends and receives packets.
+ Port* port() { return port_; }
+ const Port* port() const { return port_; }
+
+ // Returns the description of the local port
+ virtual const Candidate& local_candidate() const;
+
+ // Returns the description of the remote port to which we communicate.
+ const Candidate& remote_candidate() const { return remote_candidate_; }
+
+ // Returns the pair priority.
+ uint64 priority() const;
+
+ enum ReadState {
+ STATE_READ_INIT = 0, // we have yet to receive a ping
+ STATE_READABLE = 1, // we have received pings recently
+ STATE_READ_TIMEOUT = 2, // we haven't received pings in a while
+ };
+
+ ReadState read_state() const { return read_state_; }
+ bool readable() const { return read_state_ == STATE_READABLE; }
+
+ enum WriteState {
+ STATE_WRITABLE = 0, // we have received ping responses recently
+ STATE_WRITE_UNRELIABLE = 1, // we have had a few ping failures
+ STATE_WRITE_INIT = 2, // we have yet to receive a ping response
+ STATE_WRITE_TIMEOUT = 3, // we have had a large number of ping failures
+ };
+
+ WriteState write_state() const { return write_state_; }
+ bool writable() const { return write_state_ == STATE_WRITABLE; }
+
+ // Determines whether the connection has finished connecting. This can only
+ // be false for TCP connections.
+ bool connected() const { return connected_; }
+
+ // Estimate of the round-trip time over this connection.
+ uint32 rtt() const { return rtt_; }
+
+ size_t sent_total_bytes();
+ size_t sent_bytes_second();
+ size_t recv_total_bytes();
+ size_t recv_bytes_second();
+ sigslot::signal1<Connection*> SignalStateChange;
+
+ // Sent when the connection has decided that it is no longer of value. It
+ // will delete itself immediately after this call.
+ sigslot::signal1<Connection*> SignalDestroyed;
+
+ // The connection can send and receive packets asynchronously. This matches
+ // the interface of AsyncPacketSocket, which may use UDP or TCP under the
+ // covers.
+ virtual int Send(const void* data, size_t size,
+ const rtc::PacketOptions& options) = 0;
+
+ // Error if Send() returns < 0
+ virtual int GetError() = 0;
+
+ sigslot::signal4<Connection*, const char*, size_t,
+ const rtc::PacketTime&> SignalReadPacket;
+
+ sigslot::signal1<Connection*> SignalReadyToSend;
+
+ // Called when a packet is received on this connection.
+ void OnReadPacket(const char* data, size_t size,
+ const rtc::PacketTime& packet_time);
+
+ // Called when the socket is currently able to send.
+ void OnReadyToSend();
+
+ // Called when a connection is determined to be no longer useful to us. We
+ // still keep it around in case the other side wants to use it. But we can
+ // safely stop pinging on it and we can allow it to time out if the other
+ // side stops using it as well.
+ bool pruned() const { return pruned_; }
+ void Prune();
+
+ bool use_candidate_attr() const { return use_candidate_attr_; }
+ void set_use_candidate_attr(bool enable);
+
+ void set_remote_ice_mode(IceMode mode) {
+ remote_ice_mode_ = mode;
+ }
+
+ // Makes the connection go away.
+ void Destroy();
+
+ // Checks that the state of this connection is up-to-date. The argument is
+ // the current time, which is compared against various timeouts.
+ void UpdateState(uint32 now);
+
+ // Called when this connection should try checking writability again.
+ uint32 last_ping_sent() const { return last_ping_sent_; }
+ void Ping(uint32 now);
+
+ // Called whenever a valid ping is received on this connection. This is
+ // public because the connection intercepts the first ping for us.
+ uint32 last_ping_received() const { return last_ping_received_; }
+ void ReceivedPing();
+
+ // Debugging description of this connection
+ std::string ToString() const;
+ std::string ToSensitiveString() const;
+
+ bool reported() const { return reported_; }
+ void set_reported(bool reported) { reported_ = reported;}
+
+ // This flag will be set if this connection is the chosen one for media
+ // transmission. This connection will send STUN ping with USE-CANDIDATE
+ // attribute.
+ sigslot::signal1<Connection*> SignalUseCandidate;
+ // Invoked when Connection receives STUN error response with 487 code.
+ void HandleRoleConflictFromPeer();
+
+ State state() const { return state_; }
+
+ IceMode remote_ice_mode() const { return remote_ice_mode_; }
+
+ protected:
+ // Constructs a new connection to the given remote port.
+ Connection(Port* port, size_t index, const Candidate& candidate);
+
+ // Called back when StunRequestManager has a stun packet to send
+ void OnSendStunPacket(const void* data, size_t size, StunRequest* req);
+
+ // Callbacks from ConnectionRequest
+ void OnConnectionRequestResponse(ConnectionRequest* req,
+ StunMessage* response);
+ void OnConnectionRequestErrorResponse(ConnectionRequest* req,
+ StunMessage* response);
+ void OnConnectionRequestTimeout(ConnectionRequest* req);
+
+ // Changes the state and signals if necessary.
+ void set_read_state(ReadState value);
+ void set_write_state(WriteState value);
+ void set_state(State state);
+ void set_connected(bool value);
+
+ // Checks if this connection is useless, and hence, should be destroyed.
+ void CheckTimeout();
+
+ void OnMessage(rtc::Message *pmsg);
+
+ Port* port_;
+ size_t local_candidate_index_;
+ Candidate remote_candidate_;
+ ReadState read_state_;
+ WriteState write_state_;
+ bool connected_;
+ bool pruned_;
+ // By default |use_candidate_attr_| flag will be true,
+ // as we will be using agrressive nomination.
+ // But when peer is ice-lite, this flag "must" be initialized to false and
+ // turn on when connection becomes "best connection".
+ bool use_candidate_attr_;
+ IceMode remote_ice_mode_;
+ StunRequestManager requests_;
+ uint32 rtt_;
+ uint32 last_ping_sent_; // last time we sent a ping to the other side
+ uint32 last_ping_received_; // last time we received a ping from the other
+ // side
+ uint32 last_data_received_;
+ uint32 last_ping_response_received_;
+ std::vector<uint32> pings_since_last_response_;
+
+ rtc::RateTracker recv_rate_tracker_;
+ rtc::RateTracker send_rate_tracker_;
+
+ private:
+ void MaybeAddPrflxCandidate(ConnectionRequest* request,
+ StunMessage* response);
+
+ bool reported_;
+ State state_;
+
+ friend class Port;
+ friend class ConnectionRequest;
+};
+
+// ProxyConnection defers all the interesting work to the port
+class ProxyConnection : public Connection {
+ public:
+ ProxyConnection(Port* port, size_t index, const Candidate& candidate);
+
+ virtual int Send(const void* data, size_t size,
+ const rtc::PacketOptions& options);
+ virtual int GetError() { return error_; }
+
+ private:
+ int error_;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_PORT_H_
diff --git a/p2p/base/port_unittest.cc b/p2p/base/port_unittest.cc
new file mode 100644
index 00000000..8805709a
--- /dev/null
+++ b/p2p/base/port_unittest.cc
@@ -0,0 +1,2494 @@
+/*
+ * 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 "webrtc/p2p/base/basicpacketsocketfactory.h"
+#include "webrtc/p2p/base/portproxy.h"
+#include "webrtc/p2p/base/relayport.h"
+#include "webrtc/p2p/base/stunport.h"
+#include "webrtc/p2p/base/tcpport.h"
+#include "webrtc/p2p/base/testrelayserver.h"
+#include "webrtc/p2p/base/teststunserver.h"
+#include "webrtc/p2p/base/testturnserver.h"
+#include "webrtc/p2p/base/transport.h"
+#include "webrtc/p2p/base/turnport.h"
+#include "webrtc/base/crc32.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/natserver.h"
+#include "webrtc/base/natsocketfactory.h"
+#include "webrtc/base/physicalsocketserver.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/socketaddress.h"
+#include "webrtc/base/ssladapter.h"
+#include "webrtc/base/stringutils.h"
+#include "webrtc/base/thread.h"
+#include "webrtc/base/virtualsocketserver.h"
+
+using rtc::AsyncPacketSocket;
+using rtc::ByteBuffer;
+using rtc::NATType;
+using rtc::NAT_OPEN_CONE;
+using rtc::NAT_ADDR_RESTRICTED;
+using rtc::NAT_PORT_RESTRICTED;
+using rtc::NAT_SYMMETRIC;
+using rtc::PacketSocketFactory;
+using rtc::scoped_ptr;
+using rtc::Socket;
+using rtc::SocketAddress;
+using namespace cricket;
+
+static const int kTimeout = 1000;
+static const SocketAddress kLocalAddr1("192.168.1.2", 0);
+static const SocketAddress kLocalAddr2("192.168.1.3", 0);
+static const SocketAddress kNatAddr1("77.77.77.77", rtc::NAT_SERVER_PORT);
+static const SocketAddress kNatAddr2("88.88.88.88", rtc::NAT_SERVER_PORT);
+static const SocketAddress kStunAddr("99.99.99.1", STUN_SERVER_PORT);
+static const SocketAddress kRelayUdpIntAddr("99.99.99.2", 5000);
+static const SocketAddress kRelayUdpExtAddr("99.99.99.3", 5001);
+static const SocketAddress kRelayTcpIntAddr("99.99.99.2", 5002);
+static const SocketAddress kRelayTcpExtAddr("99.99.99.3", 5003);
+static const SocketAddress kRelaySslTcpIntAddr("99.99.99.2", 5004);
+static const SocketAddress kRelaySslTcpExtAddr("99.99.99.3", 5005);
+static const SocketAddress kTurnUdpIntAddr("99.99.99.4", STUN_SERVER_PORT);
+static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
+static const RelayCredentials kRelayCredentials("test", "test");
+
+// TODO: Update these when RFC5245 is completely supported.
+// Magic value of 30 is from RFC3484, for IPv4 addresses.
+static const uint32 kDefaultPrflxPriority = ICE_TYPE_PREFERENCE_PRFLX << 24 |
+ 30 << 8 | (256 - ICE_CANDIDATE_COMPONENT_DEFAULT);
+static const int STUN_ERROR_BAD_REQUEST_AS_GICE =
+ STUN_ERROR_BAD_REQUEST / 256 * 100 + STUN_ERROR_BAD_REQUEST % 256;
+static const int STUN_ERROR_UNAUTHORIZED_AS_GICE =
+ STUN_ERROR_UNAUTHORIZED / 256 * 100 + STUN_ERROR_UNAUTHORIZED % 256;
+static const int STUN_ERROR_SERVER_ERROR_AS_GICE =
+ STUN_ERROR_SERVER_ERROR / 256 * 100 + STUN_ERROR_SERVER_ERROR % 256;
+
+static const int kTiebreaker1 = 11111;
+static const int kTiebreaker2 = 22222;
+
+static Candidate GetCandidate(Port* port) {
+ assert(port->Candidates().size() == 1);
+ return port->Candidates()[0];
+}
+
+static SocketAddress GetAddress(Port* port) {
+ return GetCandidate(port).address();
+}
+
+static IceMessage* CopyStunMessage(const IceMessage* src) {
+ IceMessage* dst = new IceMessage();
+ ByteBuffer buf;
+ src->Write(&buf);
+ dst->Read(&buf);
+ return dst;
+}
+
+static bool WriteStunMessage(const StunMessage* msg, ByteBuffer* buf) {
+ buf->Resize(0); // clear out any existing buffer contents
+ return msg->Write(buf);
+}
+
+// Stub port class for testing STUN generation and processing.
+class TestPort : public Port {
+ public:
+ TestPort(rtc::Thread* thread, const std::string& type,
+ rtc::PacketSocketFactory* factory, rtc::Network* network,
+ const rtc::IPAddress& ip, int min_port, int max_port,
+ const std::string& username_fragment, const std::string& password)
+ : Port(thread, type, factory, network, ip,
+ min_port, max_port, username_fragment, password) {
+ }
+ ~TestPort() {}
+
+ // Expose GetStunMessage so that we can test it.
+ using cricket::Port::GetStunMessage;
+
+ // The last StunMessage that was sent on this Port.
+ // TODO: Make these const; requires changes to SendXXXXResponse.
+ ByteBuffer* last_stun_buf() { return last_stun_buf_.get(); }
+ IceMessage* last_stun_msg() { return last_stun_msg_.get(); }
+ int last_stun_error_code() {
+ int code = 0;
+ if (last_stun_msg_) {
+ const StunErrorCodeAttribute* error_attr = last_stun_msg_->GetErrorCode();
+ if (error_attr) {
+ code = error_attr->code();
+ }
+ }
+ return code;
+ }
+
+ virtual void PrepareAddress() {
+ rtc::SocketAddress addr(ip(), min_port());
+ AddAddress(addr, addr, rtc::SocketAddress(), "udp", "", Type(),
+ ICE_TYPE_PREFERENCE_HOST, 0, true);
+ }
+
+ // Exposed for testing candidate building.
+ void AddCandidateAddress(const rtc::SocketAddress& addr) {
+ AddAddress(addr, addr, rtc::SocketAddress(), "udp", "", Type(),
+ type_preference_, 0, false);
+ }
+ void AddCandidateAddress(const rtc::SocketAddress& addr,
+ const rtc::SocketAddress& base_address,
+ const std::string& type,
+ int type_preference,
+ bool final) {
+ AddAddress(addr, base_address, rtc::SocketAddress(), "udp", "", type,
+ type_preference, 0, final);
+ }
+
+ virtual Connection* CreateConnection(const Candidate& remote_candidate,
+ CandidateOrigin origin) {
+ Connection* conn = new ProxyConnection(this, 0, remote_candidate);
+ AddConnection(conn);
+ // Set use-candidate attribute flag as this will add USE-CANDIDATE attribute
+ // in STUN binding requests.
+ conn->set_use_candidate_attr(true);
+ return conn;
+ }
+ virtual int SendTo(
+ const void* data, size_t size, const rtc::SocketAddress& addr,
+ const rtc::PacketOptions& options, bool payload) {
+ if (!payload) {
+ IceMessage* msg = new IceMessage;
+ ByteBuffer* buf = new ByteBuffer(static_cast<const char*>(data), size);
+ ByteBuffer::ReadPosition pos(buf->GetReadPosition());
+ if (!msg->Read(buf)) {
+ delete msg;
+ delete buf;
+ return -1;
+ }
+ buf->SetReadPosition(pos);
+ last_stun_buf_.reset(buf);
+ last_stun_msg_.reset(msg);
+ }
+ return static_cast<int>(size);
+ }
+ virtual int SetOption(rtc::Socket::Option opt, int value) {
+ return 0;
+ }
+ virtual int GetOption(rtc::Socket::Option opt, int* value) {
+ return -1;
+ }
+ virtual int GetError() {
+ return 0;
+ }
+ void Reset() {
+ last_stun_buf_.reset();
+ last_stun_msg_.reset();
+ }
+ void set_type_preference(int type_preference) {
+ type_preference_ = type_preference;
+ }
+
+ private:
+ rtc::scoped_ptr<ByteBuffer> last_stun_buf_;
+ rtc::scoped_ptr<IceMessage> last_stun_msg_;
+ int type_preference_;
+};
+
+class TestChannel : public sigslot::has_slots<> {
+ public:
+ // Takes ownership of |p1| (but not |p2|).
+ TestChannel(Port* p1, Port* p2)
+ : ice_mode_(ICEMODE_FULL), src_(p1), dst_(p2), complete_count_(0),
+ conn_(NULL), remote_request_(), nominated_(false) {
+ src_->SignalPortComplete.connect(
+ this, &TestChannel::OnPortComplete);
+ src_->SignalUnknownAddress.connect(this, &TestChannel::OnUnknownAddress);
+ src_->SignalDestroyed.connect(this, &TestChannel::OnSrcPortDestroyed);
+ }
+
+ int complete_count() { return complete_count_; }
+ Connection* conn() { return conn_; }
+ const SocketAddress& remote_address() { return remote_address_; }
+ const std::string remote_fragment() { return remote_frag_; }
+
+ void Start() {
+ src_->PrepareAddress();
+ }
+ void CreateConnection() {
+ conn_ = src_->CreateConnection(GetCandidate(dst_), Port::ORIGIN_MESSAGE);
+ IceMode remote_ice_mode =
+ (ice_mode_ == ICEMODE_FULL) ? ICEMODE_LITE : ICEMODE_FULL;
+ conn_->set_remote_ice_mode(remote_ice_mode);
+ conn_->set_use_candidate_attr(remote_ice_mode == ICEMODE_FULL);
+ conn_->SignalStateChange.connect(
+ this, &TestChannel::OnConnectionStateChange);
+ }
+ void OnConnectionStateChange(Connection* conn) {
+ if (conn->write_state() == Connection::STATE_WRITABLE) {
+ conn->set_use_candidate_attr(true);
+ nominated_ = true;
+ }
+ }
+ void AcceptConnection() {
+ ASSERT_TRUE(remote_request_.get() != NULL);
+ Candidate c = GetCandidate(dst_);
+ c.set_address(remote_address_);
+ conn_ = src_->CreateConnection(c, Port::ORIGIN_MESSAGE);
+ src_->SendBindingResponse(remote_request_.get(), remote_address_);
+ remote_request_.reset();
+ }
+ void Ping() {
+ Ping(0);
+ }
+ void Ping(uint32 now) {
+ conn_->Ping(now);
+ }
+ void Stop() {
+ conn_->SignalDestroyed.connect(this, &TestChannel::OnDestroyed);
+ conn_->Destroy();
+ }
+
+ void OnPortComplete(Port* port) {
+ complete_count_++;
+ }
+ void SetIceMode(IceMode ice_mode) {
+ ice_mode_ = ice_mode;
+ }
+
+ void OnUnknownAddress(PortInterface* port, const SocketAddress& addr,
+ ProtocolType proto,
+ IceMessage* msg, const std::string& rf,
+ bool /*port_muxed*/) {
+ ASSERT_EQ(src_.get(), port);
+ if (!remote_address_.IsNil()) {
+ ASSERT_EQ(remote_address_, addr);
+ }
+ // MI and PRIORITY attribute should be present in ping requests when port
+ // is in ICEPROTO_RFC5245 mode.
+ const cricket::StunUInt32Attribute* priority_attr =
+ msg->GetUInt32(STUN_ATTR_PRIORITY);
+ const cricket::StunByteStringAttribute* mi_attr =
+ msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
+ const cricket::StunUInt32Attribute* fingerprint_attr =
+ msg->GetUInt32(STUN_ATTR_FINGERPRINT);
+ if (src_->IceProtocol() == cricket::ICEPROTO_RFC5245) {
+ EXPECT_TRUE(priority_attr != NULL);
+ EXPECT_TRUE(mi_attr != NULL);
+ EXPECT_TRUE(fingerprint_attr != NULL);
+ } else {
+ EXPECT_TRUE(priority_attr == NULL);
+ EXPECT_TRUE(mi_attr == NULL);
+ EXPECT_TRUE(fingerprint_attr == NULL);
+ }
+ remote_address_ = addr;
+ remote_request_.reset(CopyStunMessage(msg));
+ remote_frag_ = rf;
+ }
+
+ void OnDestroyed(Connection* conn) {
+ ASSERT_EQ(conn_, conn);
+ conn_ = NULL;
+ }
+
+ void OnSrcPortDestroyed(PortInterface* port) {
+ Port* destroyed_src = src_.release();
+ ASSERT_EQ(destroyed_src, port);
+ }
+
+ bool nominated() const { return nominated_; }
+
+ private:
+ IceMode ice_mode_;
+ rtc::scoped_ptr<Port> src_;
+ Port* dst_;
+
+ int complete_count_;
+ Connection* conn_;
+ SocketAddress remote_address_;
+ rtc::scoped_ptr<StunMessage> remote_request_;
+ std::string remote_frag_;
+ bool nominated_;
+};
+
+class PortTest : public testing::Test, public sigslot::has_slots<> {
+ public:
+ PortTest()
+ : main_(rtc::Thread::Current()),
+ pss_(new rtc::PhysicalSocketServer),
+ ss_(new rtc::VirtualSocketServer(pss_.get())),
+ ss_scope_(ss_.get()),
+ network_("unittest", "unittest", rtc::IPAddress(INADDR_ANY), 32),
+ socket_factory_(rtc::Thread::Current()),
+ nat_factory1_(ss_.get(), kNatAddr1),
+ nat_factory2_(ss_.get(), kNatAddr2),
+ nat_socket_factory1_(&nat_factory1_),
+ nat_socket_factory2_(&nat_factory2_),
+ stun_server_(TestStunServer::Create(main_, kStunAddr)),
+ turn_server_(main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
+ relay_server_(main_, kRelayUdpIntAddr, kRelayUdpExtAddr,
+ kRelayTcpIntAddr, kRelayTcpExtAddr,
+ kRelaySslTcpIntAddr, kRelaySslTcpExtAddr),
+ username_(rtc::CreateRandomString(ICE_UFRAG_LENGTH)),
+ password_(rtc::CreateRandomString(ICE_PWD_LENGTH)),
+ ice_protocol_(cricket::ICEPROTO_GOOGLE),
+ role_conflict_(false),
+ destroyed_(false) {
+ network_.AddIP(rtc::IPAddress(INADDR_ANY));
+ }
+
+ protected:
+ void TestLocalToLocal() {
+ Port* port1 = CreateUdpPort(kLocalAddr1);
+ Port* port2 = CreateUdpPort(kLocalAddr2);
+ TestConnectivity("udp", port1, "udp", port2, true, true, true, true);
+ }
+ void TestLocalToStun(NATType ntype) {
+ Port* port1 = CreateUdpPort(kLocalAddr1);
+ nat_server2_.reset(CreateNatServer(kNatAddr2, ntype));
+ Port* port2 = CreateStunPort(kLocalAddr2, &nat_socket_factory2_);
+ TestConnectivity("udp", port1, StunName(ntype), port2,
+ ntype == NAT_OPEN_CONE, true,
+ ntype != NAT_SYMMETRIC, true);
+ }
+ void TestLocalToRelay(RelayType rtype, ProtocolType proto) {
+ Port* port1 = CreateUdpPort(kLocalAddr1);
+ Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_UDP);
+ TestConnectivity("udp", port1, RelayName(rtype, proto), port2,
+ rtype == RELAY_GTURN, true, true, true);
+ }
+ void TestStunToLocal(NATType ntype) {
+ nat_server1_.reset(CreateNatServer(kNatAddr1, ntype));
+ Port* port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
+ Port* port2 = CreateUdpPort(kLocalAddr2);
+ TestConnectivity(StunName(ntype), port1, "udp", port2,
+ true, ntype != NAT_SYMMETRIC, true, true);
+ }
+ void TestStunToStun(NATType ntype1, NATType ntype2) {
+ nat_server1_.reset(CreateNatServer(kNatAddr1, ntype1));
+ Port* port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
+ nat_server2_.reset(CreateNatServer(kNatAddr2, ntype2));
+ Port* port2 = CreateStunPort(kLocalAddr2, &nat_socket_factory2_);
+ TestConnectivity(StunName(ntype1), port1, StunName(ntype2), port2,
+ ntype2 == NAT_OPEN_CONE,
+ ntype1 != NAT_SYMMETRIC, ntype2 != NAT_SYMMETRIC,
+ ntype1 + ntype2 < (NAT_PORT_RESTRICTED + NAT_SYMMETRIC));
+ }
+ void TestStunToRelay(NATType ntype, RelayType rtype, ProtocolType proto) {
+ nat_server1_.reset(CreateNatServer(kNatAddr1, ntype));
+ Port* port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
+ Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_UDP);
+ TestConnectivity(StunName(ntype), port1, RelayName(rtype, proto), port2,
+ rtype == RELAY_GTURN, ntype != NAT_SYMMETRIC, true, true);
+ }
+ void TestTcpToTcp() {
+ Port* port1 = CreateTcpPort(kLocalAddr1);
+ Port* port2 = CreateTcpPort(kLocalAddr2);
+ TestConnectivity("tcp", port1, "tcp", port2, true, false, true, true);
+ }
+ void TestTcpToRelay(RelayType rtype, ProtocolType proto) {
+ Port* port1 = CreateTcpPort(kLocalAddr1);
+ Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_TCP);
+ TestConnectivity("tcp", port1, RelayName(rtype, proto), port2,
+ rtype == RELAY_GTURN, false, true, true);
+ }
+ void TestSslTcpToRelay(RelayType rtype, ProtocolType proto) {
+ Port* port1 = CreateTcpPort(kLocalAddr1);
+ Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_SSLTCP);
+ TestConnectivity("ssltcp", port1, RelayName(rtype, proto), port2,
+ rtype == RELAY_GTURN, false, true, true);
+ }
+
+ // helpers for above functions
+ UDPPort* CreateUdpPort(const SocketAddress& addr) {
+ return CreateUdpPort(addr, &socket_factory_);
+ }
+ UDPPort* CreateUdpPort(const SocketAddress& addr,
+ PacketSocketFactory* socket_factory) {
+ UDPPort* port = UDPPort::Create(main_, socket_factory, &network_,
+ addr.ipaddr(), 0, 0, username_, password_);
+ port->SetIceProtocolType(ice_protocol_);
+ return port;
+ }
+ TCPPort* CreateTcpPort(const SocketAddress& addr) {
+ TCPPort* port = CreateTcpPort(addr, &socket_factory_);
+ port->SetIceProtocolType(ice_protocol_);
+ return port;
+ }
+ TCPPort* CreateTcpPort(const SocketAddress& addr,
+ PacketSocketFactory* socket_factory) {
+ TCPPort* port = TCPPort::Create(main_, socket_factory, &network_,
+ addr.ipaddr(), 0, 0, username_, password_,
+ true);
+ port->SetIceProtocolType(ice_protocol_);
+ return port;
+ }
+ StunPort* CreateStunPort(const SocketAddress& addr,
+ rtc::PacketSocketFactory* factory) {
+ ServerAddresses stun_servers;
+ stun_servers.insert(kStunAddr);
+ StunPort* port = StunPort::Create(main_, factory, &network_,
+ addr.ipaddr(), 0, 0,
+ username_, password_, stun_servers);
+ port->SetIceProtocolType(ice_protocol_);
+ return port;
+ }
+ Port* CreateRelayPort(const SocketAddress& addr, RelayType rtype,
+ ProtocolType int_proto, ProtocolType ext_proto) {
+ if (rtype == RELAY_TURN) {
+ return CreateTurnPort(addr, &socket_factory_, int_proto, ext_proto);
+ } else {
+ return CreateGturnPort(addr, int_proto, ext_proto);
+ }
+ }
+ TurnPort* CreateTurnPort(const SocketAddress& addr,
+ PacketSocketFactory* socket_factory,
+ ProtocolType int_proto, ProtocolType ext_proto) {
+ return CreateTurnPort(addr, socket_factory,
+ int_proto, ext_proto, kTurnUdpIntAddr);
+ }
+ TurnPort* CreateTurnPort(const SocketAddress& addr,
+ PacketSocketFactory* socket_factory,
+ ProtocolType int_proto, ProtocolType ext_proto,
+ const rtc::SocketAddress& server_addr) {
+ TurnPort* port = TurnPort::Create(main_, socket_factory, &network_,
+ addr.ipaddr(), 0, 0,
+ username_, password_, ProtocolAddress(
+ server_addr, PROTO_UDP),
+ kRelayCredentials, 0);
+ port->SetIceProtocolType(ice_protocol_);
+ return port;
+ }
+ RelayPort* CreateGturnPort(const SocketAddress& addr,
+ ProtocolType int_proto, ProtocolType ext_proto) {
+ RelayPort* port = CreateGturnPort(addr);
+ SocketAddress addrs[] =
+ { kRelayUdpIntAddr, kRelayTcpIntAddr, kRelaySslTcpIntAddr };
+ port->AddServerAddress(ProtocolAddress(addrs[int_proto], int_proto));
+ return port;
+ }
+ RelayPort* CreateGturnPort(const SocketAddress& addr) {
+ RelayPort* port = RelayPort::Create(main_, &socket_factory_, &network_,
+ addr.ipaddr(), 0, 0,
+ username_, password_);
+ // TODO: Add an external address for ext_proto, so that the
+ // other side can connect to this port using a non-UDP protocol.
+ port->SetIceProtocolType(ice_protocol_);
+ return port;
+ }
+ rtc::NATServer* CreateNatServer(const SocketAddress& addr,
+ rtc::NATType type) {
+ return new rtc::NATServer(type, ss_.get(), addr, ss_.get(), addr);
+ }
+ static const char* StunName(NATType type) {
+ switch (type) {
+ case NAT_OPEN_CONE: return "stun(open cone)";
+ case NAT_ADDR_RESTRICTED: return "stun(addr restricted)";
+ case NAT_PORT_RESTRICTED: return "stun(port restricted)";
+ case NAT_SYMMETRIC: return "stun(symmetric)";
+ default: return "stun(?)";
+ }
+ }
+ static const char* RelayName(RelayType type, ProtocolType proto) {
+ if (type == RELAY_TURN) {
+ switch (proto) {
+ case PROTO_UDP: return "turn(udp)";
+ case PROTO_TCP: return "turn(tcp)";
+ case PROTO_SSLTCP: return "turn(ssltcp)";
+ default: return "turn(?)";
+ }
+ } else {
+ switch (proto) {
+ case PROTO_UDP: return "gturn(udp)";
+ case PROTO_TCP: return "gturn(tcp)";
+ case PROTO_SSLTCP: return "gturn(ssltcp)";
+ default: return "gturn(?)";
+ }
+ }
+ }
+
+ void TestCrossFamilyPorts(int type);
+
+ // This does all the work and then deletes |port1| and |port2|.
+ void TestConnectivity(const char* name1, Port* port1,
+ const char* name2, Port* port2,
+ bool accept, bool same_addr1,
+ bool same_addr2, bool possible);
+
+ // This connects and disconnects the provided channels in the same sequence as
+ // TestConnectivity with all options set to |true|. It does not delete either
+ // channel.
+ void ConnectAndDisconnectChannels(TestChannel* ch1, TestChannel* ch2);
+
+ void SetIceProtocolType(cricket::IceProtocolType protocol) {
+ ice_protocol_ = protocol;
+ }
+
+ IceMessage* CreateStunMessage(int type) {
+ IceMessage* msg = new IceMessage();
+ msg->SetType(type);
+ msg->SetTransactionID("TESTTESTTEST");
+ return msg;
+ }
+ IceMessage* CreateStunMessageWithUsername(int type,
+ const std::string& username) {
+ IceMessage* msg = CreateStunMessage(type);
+ msg->AddAttribute(
+ new StunByteStringAttribute(STUN_ATTR_USERNAME, username));
+ return msg;
+ }
+ TestPort* CreateTestPort(const rtc::SocketAddress& addr,
+ const std::string& username,
+ const std::string& password) {
+ TestPort* port = new TestPort(main_, "test", &socket_factory_, &network_,
+ addr.ipaddr(), 0, 0, username, password);
+ port->SignalRoleConflict.connect(this, &PortTest::OnRoleConflict);
+ return port;
+ }
+ TestPort* CreateTestPort(const rtc::SocketAddress& addr,
+ const std::string& username,
+ const std::string& password,
+ cricket::IceProtocolType type,
+ cricket::IceRole role,
+ int tiebreaker) {
+ TestPort* port = CreateTestPort(addr, username, password);
+ port->SetIceProtocolType(type);
+ port->SetIceRole(role);
+ port->SetIceTiebreaker(tiebreaker);
+ return port;
+ }
+
+ void OnRoleConflict(PortInterface* port) {
+ role_conflict_ = true;
+ }
+ bool role_conflict() const { return role_conflict_; }
+
+ void ConnectToSignalDestroyed(PortInterface* port) {
+ port->SignalDestroyed.connect(this, &PortTest::OnDestroyed);
+ }
+
+ void OnDestroyed(PortInterface* port) {
+ destroyed_ = true;
+ }
+ bool destroyed() const { return destroyed_; }
+
+ rtc::BasicPacketSocketFactory* nat_socket_factory1() {
+ return &nat_socket_factory1_;
+ }
+
+ private:
+ rtc::Thread* main_;
+ rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
+ rtc::scoped_ptr<rtc::VirtualSocketServer> ss_;
+ rtc::SocketServerScope ss_scope_;
+ rtc::Network network_;
+ rtc::BasicPacketSocketFactory socket_factory_;
+ rtc::scoped_ptr<rtc::NATServer> nat_server1_;
+ rtc::scoped_ptr<rtc::NATServer> nat_server2_;
+ rtc::NATSocketFactory nat_factory1_;
+ rtc::NATSocketFactory nat_factory2_;
+ rtc::BasicPacketSocketFactory nat_socket_factory1_;
+ rtc::BasicPacketSocketFactory nat_socket_factory2_;
+ scoped_ptr<TestStunServer> stun_server_;
+ TestTurnServer turn_server_;
+ TestRelayServer relay_server_;
+ std::string username_;
+ std::string password_;
+ cricket::IceProtocolType ice_protocol_;
+ bool role_conflict_;
+ bool destroyed_;
+};
+
+void PortTest::TestConnectivity(const char* name1, Port* port1,
+ const char* name2, Port* port2,
+ bool accept, bool same_addr1,
+ bool same_addr2, bool possible) {
+ LOG(LS_INFO) << "Test: " << name1 << " to " << name2 << ": ";
+ port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
+ port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
+
+ // Set up channels and ensure both ports will be deleted.
+ TestChannel ch1(port1, port2);
+ TestChannel ch2(port2, port1);
+ EXPECT_EQ(0, ch1.complete_count());
+ EXPECT_EQ(0, ch2.complete_count());
+
+ // Acquire addresses.
+ ch1.Start();
+ ch2.Start();
+ ASSERT_EQ_WAIT(1, ch1.complete_count(), kTimeout);
+ ASSERT_EQ_WAIT(1, ch2.complete_count(), kTimeout);
+
+ // Send a ping from src to dst. This may or may not make it.
+ ch1.CreateConnection();
+ ASSERT_TRUE(ch1.conn() != NULL);
+ EXPECT_TRUE_WAIT(ch1.conn()->connected(), kTimeout); // for TCP connect
+ ch1.Ping();
+ WAIT(!ch2.remote_address().IsNil(), kTimeout);
+
+ if (accept) {
+ // We are able to send a ping from src to dst. This is the case when
+ // sending to UDP ports and cone NATs.
+ EXPECT_TRUE(ch1.remote_address().IsNil());
+ EXPECT_EQ(ch2.remote_fragment(), port1->username_fragment());
+
+ // Ensure the ping came from the same address used for src.
+ // This is the case unless the source NAT was symmetric.
+ if (same_addr1) EXPECT_EQ(ch2.remote_address(), GetAddress(port1));
+ EXPECT_TRUE(same_addr2);
+
+ // Send a ping from dst to src.
+ ch2.AcceptConnection();
+ ASSERT_TRUE(ch2.conn() != NULL);
+ ch2.Ping();
+ EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch2.conn()->write_state(),
+ kTimeout);
+ } else {
+ // We can't send a ping from src to dst, so flip it around. This will happen
+ // when the destination NAT is addr/port restricted or symmetric.
+ EXPECT_TRUE(ch1.remote_address().IsNil());
+ EXPECT_TRUE(ch2.remote_address().IsNil());
+
+ // Send a ping from dst to src. Again, this may or may not make it.
+ ch2.CreateConnection();
+ ASSERT_TRUE(ch2.conn() != NULL);
+ ch2.Ping();
+ WAIT(ch2.conn()->write_state() == Connection::STATE_WRITABLE, kTimeout);
+
+ if (same_addr1 && same_addr2) {
+ // The new ping got back to the source.
+ EXPECT_EQ(Connection::STATE_READABLE, ch1.conn()->read_state());
+ EXPECT_EQ(Connection::STATE_WRITABLE, ch2.conn()->write_state());
+
+ // First connection may not be writable if the first ping did not get
+ // through. So we will have to do another.
+ if (ch1.conn()->write_state() == Connection::STATE_WRITE_INIT) {
+ ch1.Ping();
+ EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
+ kTimeout);
+ }
+ } else if (!same_addr1 && possible) {
+ // The new ping went to the candidate address, but that address was bad.
+ // This will happen when the source NAT is symmetric.
+ EXPECT_TRUE(ch1.remote_address().IsNil());
+ EXPECT_TRUE(ch2.remote_address().IsNil());
+
+ // However, since we have now sent a ping to the source IP, we should be
+ // able to get a ping from it. This gives us the real source address.
+ ch1.Ping();
+ EXPECT_TRUE_WAIT(!ch2.remote_address().IsNil(), kTimeout);
+ EXPECT_EQ(Connection::STATE_READ_INIT, ch2.conn()->read_state());
+ EXPECT_TRUE(ch1.remote_address().IsNil());
+
+ // Pick up the actual address and establish the connection.
+ ch2.AcceptConnection();
+ ASSERT_TRUE(ch2.conn() != NULL);
+ ch2.Ping();
+ EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch2.conn()->write_state(),
+ kTimeout);
+ } else if (!same_addr2 && possible) {
+ // The new ping came in, but from an unexpected address. This will happen
+ // when the destination NAT is symmetric.
+ EXPECT_FALSE(ch1.remote_address().IsNil());
+ EXPECT_EQ(Connection::STATE_READ_INIT, ch1.conn()->read_state());
+
+ // Update our address and complete the connection.
+ ch1.AcceptConnection();
+ ch1.Ping();
+ EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
+ kTimeout);
+ } else { // (!possible)
+ // There should be s no way for the pings to reach each other. Check it.
+ EXPECT_TRUE(ch1.remote_address().IsNil());
+ EXPECT_TRUE(ch2.remote_address().IsNil());
+ ch1.Ping();
+ WAIT(!ch2.remote_address().IsNil(), kTimeout);
+ EXPECT_TRUE(ch1.remote_address().IsNil());
+ EXPECT_TRUE(ch2.remote_address().IsNil());
+ }
+ }
+
+ // Everything should be good, unless we know the situation is impossible.
+ ASSERT_TRUE(ch1.conn() != NULL);
+ ASSERT_TRUE(ch2.conn() != NULL);
+ if (possible) {
+ EXPECT_EQ(Connection::STATE_READABLE, ch1.conn()->read_state());
+ EXPECT_EQ(Connection::STATE_WRITABLE, ch1.conn()->write_state());
+ EXPECT_EQ(Connection::STATE_READABLE, ch2.conn()->read_state());
+ EXPECT_EQ(Connection::STATE_WRITABLE, ch2.conn()->write_state());
+ } else {
+ EXPECT_NE(Connection::STATE_READABLE, ch1.conn()->read_state());
+ EXPECT_NE(Connection::STATE_WRITABLE, ch1.conn()->write_state());
+ EXPECT_NE(Connection::STATE_READABLE, ch2.conn()->read_state());
+ EXPECT_NE(Connection::STATE_WRITABLE, ch2.conn()->write_state());
+ }
+
+ // Tear down and ensure that goes smoothly.
+ ch1.Stop();
+ ch2.Stop();
+ EXPECT_TRUE_WAIT(ch1.conn() == NULL, kTimeout);
+ EXPECT_TRUE_WAIT(ch2.conn() == NULL, kTimeout);
+}
+
+void PortTest::ConnectAndDisconnectChannels(TestChannel* ch1,
+ TestChannel* ch2) {
+ // Acquire addresses.
+ ch1->Start();
+ ch2->Start();
+
+ // Send a ping from src to dst.
+ ch1->CreateConnection();
+ EXPECT_TRUE_WAIT(ch1->conn()->connected(), kTimeout); // for TCP connect
+ ch1->Ping();
+ WAIT(!ch2->remote_address().IsNil(), kTimeout);
+
+ // Send a ping from dst to src.
+ ch2->AcceptConnection();
+ ch2->Ping();
+ EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch2->conn()->write_state(),
+ kTimeout);
+
+ // Destroy the connections.
+ ch1->Stop();
+ ch2->Stop();
+}
+
+class FakePacketSocketFactory : public rtc::PacketSocketFactory {
+ public:
+ FakePacketSocketFactory()
+ : next_udp_socket_(NULL),
+ next_server_tcp_socket_(NULL),
+ next_client_tcp_socket_(NULL) {
+ }
+ virtual ~FakePacketSocketFactory() { }
+
+ virtual AsyncPacketSocket* CreateUdpSocket(
+ const SocketAddress& address, int min_port, int max_port) {
+ EXPECT_TRUE(next_udp_socket_ != NULL);
+ AsyncPacketSocket* result = next_udp_socket_;
+ next_udp_socket_ = NULL;
+ return result;
+ }
+
+ virtual AsyncPacketSocket* CreateServerTcpSocket(
+ const SocketAddress& local_address, int min_port, int max_port,
+ int opts) {
+ EXPECT_TRUE(next_server_tcp_socket_ != NULL);
+ AsyncPacketSocket* result = next_server_tcp_socket_;
+ next_server_tcp_socket_ = NULL;
+ return result;
+ }
+
+ // TODO: |proxy_info| and |user_agent| should be set
+ // per-factory and not when socket is created.
+ virtual AsyncPacketSocket* CreateClientTcpSocket(
+ const SocketAddress& local_address, const SocketAddress& remote_address,
+ const rtc::ProxyInfo& proxy_info,
+ const std::string& user_agent, int opts) {
+ EXPECT_TRUE(next_client_tcp_socket_ != NULL);
+ AsyncPacketSocket* result = next_client_tcp_socket_;
+ next_client_tcp_socket_ = NULL;
+ return result;
+ }
+
+ void set_next_udp_socket(AsyncPacketSocket* next_udp_socket) {
+ next_udp_socket_ = next_udp_socket;
+ }
+ void set_next_server_tcp_socket(AsyncPacketSocket* next_server_tcp_socket) {
+ next_server_tcp_socket_ = next_server_tcp_socket;
+ }
+ void set_next_client_tcp_socket(AsyncPacketSocket* next_client_tcp_socket) {
+ next_client_tcp_socket_ = next_client_tcp_socket;
+ }
+ rtc::AsyncResolverInterface* CreateAsyncResolver() {
+ return NULL;
+ }
+
+ private:
+ AsyncPacketSocket* next_udp_socket_;
+ AsyncPacketSocket* next_server_tcp_socket_;
+ AsyncPacketSocket* next_client_tcp_socket_;
+};
+
+class FakeAsyncPacketSocket : public AsyncPacketSocket {
+ public:
+ // Returns current local address. Address may be set to NULL if the
+ // socket is not bound yet (GetState() returns STATE_BINDING).
+ virtual SocketAddress GetLocalAddress() const {
+ return SocketAddress();
+ }
+
+ // Returns remote address. Returns zeroes if this is not a client TCP socket.
+ virtual SocketAddress GetRemoteAddress() const {
+ return SocketAddress();
+ }
+
+ // Send a packet.
+ virtual int Send(const void *pv, size_t cb,
+ const rtc::PacketOptions& options) {
+ return static_cast<int>(cb);
+ }
+ virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr,
+ const rtc::PacketOptions& options) {
+ return static_cast<int>(cb);
+ }
+ virtual int Close() {
+ return 0;
+ }
+
+ virtual State GetState() const { return state_; }
+ virtual int GetOption(Socket::Option opt, int* value) { return 0; }
+ virtual int SetOption(Socket::Option opt, int value) { return 0; }
+ virtual int GetError() const { return 0; }
+ virtual void SetError(int error) { }
+
+ void set_state(State state) { state_ = state; }
+
+ private:
+ State state_;
+};
+
+// Local -> XXXX
+TEST_F(PortTest, TestLocalToLocal) {
+ TestLocalToLocal();
+}
+
+TEST_F(PortTest, TestLocalToConeNat) {
+ TestLocalToStun(NAT_OPEN_CONE);
+}
+
+TEST_F(PortTest, TestLocalToARNat) {
+ TestLocalToStun(NAT_ADDR_RESTRICTED);
+}
+
+TEST_F(PortTest, TestLocalToPRNat) {
+ TestLocalToStun(NAT_PORT_RESTRICTED);
+}
+
+TEST_F(PortTest, TestLocalToSymNat) {
+ TestLocalToStun(NAT_SYMMETRIC);
+}
+
+// Flaky: https://code.google.com/p/webrtc/issues/detail?id=3316.
+TEST_F(PortTest, DISABLED_TestLocalToTurn) {
+ TestLocalToRelay(RELAY_TURN, PROTO_UDP);
+}
+
+TEST_F(PortTest, TestLocalToGturn) {
+ TestLocalToRelay(RELAY_GTURN, PROTO_UDP);
+}
+
+TEST_F(PortTest, TestLocalToTcpGturn) {
+ TestLocalToRelay(RELAY_GTURN, PROTO_TCP);
+}
+
+TEST_F(PortTest, TestLocalToSslTcpGturn) {
+ TestLocalToRelay(RELAY_GTURN, PROTO_SSLTCP);
+}
+
+// Cone NAT -> XXXX
+TEST_F(PortTest, TestConeNatToLocal) {
+ TestStunToLocal(NAT_OPEN_CONE);
+}
+
+TEST_F(PortTest, TestConeNatToConeNat) {
+ TestStunToStun(NAT_OPEN_CONE, NAT_OPEN_CONE);
+}
+
+TEST_F(PortTest, TestConeNatToARNat) {
+ TestStunToStun(NAT_OPEN_CONE, NAT_ADDR_RESTRICTED);
+}
+
+TEST_F(PortTest, TestConeNatToPRNat) {
+ TestStunToStun(NAT_OPEN_CONE, NAT_PORT_RESTRICTED);
+}
+
+TEST_F(PortTest, TestConeNatToSymNat) {
+ TestStunToStun(NAT_OPEN_CONE, NAT_SYMMETRIC);
+}
+
+TEST_F(PortTest, TestConeNatToTurn) {
+ TestStunToRelay(NAT_OPEN_CONE, RELAY_TURN, PROTO_UDP);
+}
+
+TEST_F(PortTest, TestConeNatToGturn) {
+ TestStunToRelay(NAT_OPEN_CONE, RELAY_GTURN, PROTO_UDP);
+}
+
+TEST_F(PortTest, TestConeNatToTcpGturn) {
+ TestStunToRelay(NAT_OPEN_CONE, RELAY_GTURN, PROTO_TCP);
+}
+
+// Address-restricted NAT -> XXXX
+TEST_F(PortTest, TestARNatToLocal) {
+ TestStunToLocal(NAT_ADDR_RESTRICTED);
+}
+
+TEST_F(PortTest, TestARNatToConeNat) {
+ TestStunToStun(NAT_ADDR_RESTRICTED, NAT_OPEN_CONE);
+}
+
+TEST_F(PortTest, TestARNatToARNat) {
+ TestStunToStun(NAT_ADDR_RESTRICTED, NAT_ADDR_RESTRICTED);
+}
+
+TEST_F(PortTest, TestARNatToPRNat) {
+ TestStunToStun(NAT_ADDR_RESTRICTED, NAT_PORT_RESTRICTED);
+}
+
+TEST_F(PortTest, TestARNatToSymNat) {
+ TestStunToStun(NAT_ADDR_RESTRICTED, NAT_SYMMETRIC);
+}
+
+TEST_F(PortTest, TestARNatToTurn) {
+ TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_TURN, PROTO_UDP);
+}
+
+TEST_F(PortTest, TestARNatToGturn) {
+ TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_GTURN, PROTO_UDP);
+}
+
+TEST_F(PortTest, TestARNATNatToTcpGturn) {
+ TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_GTURN, PROTO_TCP);
+}
+
+// Port-restricted NAT -> XXXX
+TEST_F(PortTest, TestPRNatToLocal) {
+ TestStunToLocal(NAT_PORT_RESTRICTED);
+}
+
+TEST_F(PortTest, TestPRNatToConeNat) {
+ TestStunToStun(NAT_PORT_RESTRICTED, NAT_OPEN_CONE);
+}
+
+TEST_F(PortTest, TestPRNatToARNat) {
+ TestStunToStun(NAT_PORT_RESTRICTED, NAT_ADDR_RESTRICTED);
+}
+
+TEST_F(PortTest, TestPRNatToPRNat) {
+ TestStunToStun(NAT_PORT_RESTRICTED, NAT_PORT_RESTRICTED);
+}
+
+TEST_F(PortTest, TestPRNatToSymNat) {
+ // Will "fail"
+ TestStunToStun(NAT_PORT_RESTRICTED, NAT_SYMMETRIC);
+}
+
+TEST_F(PortTest, TestPRNatToTurn) {
+ TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_TURN, PROTO_UDP);
+}
+
+TEST_F(PortTest, TestPRNatToGturn) {
+ TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_GTURN, PROTO_UDP);
+}
+
+TEST_F(PortTest, TestPRNatToTcpGturn) {
+ TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_GTURN, PROTO_TCP);
+}
+
+// Symmetric NAT -> XXXX
+TEST_F(PortTest, TestSymNatToLocal) {
+ TestStunToLocal(NAT_SYMMETRIC);
+}
+
+TEST_F(PortTest, TestSymNatToConeNat) {
+ TestStunToStun(NAT_SYMMETRIC, NAT_OPEN_CONE);
+}
+
+TEST_F(PortTest, TestSymNatToARNat) {
+ TestStunToStun(NAT_SYMMETRIC, NAT_ADDR_RESTRICTED);
+}
+
+TEST_F(PortTest, TestSymNatToPRNat) {
+ // Will "fail"
+ TestStunToStun(NAT_SYMMETRIC, NAT_PORT_RESTRICTED);
+}
+
+TEST_F(PortTest, TestSymNatToSymNat) {
+ // Will "fail"
+ TestStunToStun(NAT_SYMMETRIC, NAT_SYMMETRIC);
+}
+
+TEST_F(PortTest, TestSymNatToTurn) {
+ TestStunToRelay(NAT_SYMMETRIC, RELAY_TURN, PROTO_UDP);
+}
+
+TEST_F(PortTest, TestSymNatToGturn) {
+ TestStunToRelay(NAT_SYMMETRIC, RELAY_GTURN, PROTO_UDP);
+}
+
+TEST_F(PortTest, TestSymNatToTcpGturn) {
+ TestStunToRelay(NAT_SYMMETRIC, RELAY_GTURN, PROTO_TCP);
+}
+
+// Outbound TCP -> XXXX
+TEST_F(PortTest, TestTcpToTcp) {
+ TestTcpToTcp();
+}
+
+/* TODO: Enable these once testrelayserver can accept external TCP.
+TEST_F(PortTest, TestTcpToTcpRelay) {
+ TestTcpToRelay(PROTO_TCP);
+}
+
+TEST_F(PortTest, TestTcpToSslTcpRelay) {
+ TestTcpToRelay(PROTO_SSLTCP);
+}
+*/
+
+// Outbound SSLTCP -> XXXX
+/* TODO: Enable these once testrelayserver can accept external SSL.
+TEST_F(PortTest, TestSslTcpToTcpRelay) {
+ TestSslTcpToRelay(PROTO_TCP);
+}
+
+TEST_F(PortTest, TestSslTcpToSslTcpRelay) {
+ TestSslTcpToRelay(PROTO_SSLTCP);
+}
+*/
+
+// This test case verifies standard ICE features in STUN messages. Currently it
+// verifies Message Integrity attribute in STUN messages and username in STUN
+// binding request will have colon (":") between remote and local username.
+TEST_F(PortTest, TestLocalToLocalAsIce) {
+ SetIceProtocolType(cricket::ICEPROTO_RFC5245);
+ UDPPort* port1 = CreateUdpPort(kLocalAddr1);
+ port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
+ port1->SetIceTiebreaker(kTiebreaker1);
+ ASSERT_EQ(cricket::ICEPROTO_RFC5245, port1->IceProtocol());
+ UDPPort* port2 = CreateUdpPort(kLocalAddr2);
+ port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
+ port2->SetIceTiebreaker(kTiebreaker2);
+ ASSERT_EQ(cricket::ICEPROTO_RFC5245, port2->IceProtocol());
+ // Same parameters as TestLocalToLocal above.
+ TestConnectivity("udp", port1, "udp", port2, true, true, true, true);
+}
+
+// This test is trying to validate a successful and failure scenario in a
+// loopback test when protocol is RFC5245. For success IceTiebreaker, username
+// should remain equal to the request generated by the port and role of port
+// must be in controlling.
+TEST_F(PortTest, TestLoopbackCallAsIce) {
+ rtc::scoped_ptr<TestPort> lport(
+ CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
+ lport->SetIceProtocolType(ICEPROTO_RFC5245);
+ lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
+ lport->SetIceTiebreaker(kTiebreaker1);
+ lport->PrepareAddress();
+ ASSERT_FALSE(lport->Candidates().empty());
+ Connection* conn = lport->CreateConnection(lport->Candidates()[0],
+ Port::ORIGIN_MESSAGE);
+ conn->Ping(0);
+
+ ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
+ IceMessage* msg = lport->last_stun_msg();
+ EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
+ conn->OnReadPacket(lport->last_stun_buf()->Data(),
+ lport->last_stun_buf()->Length(),
+ rtc::PacketTime());
+ ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
+ msg = lport->last_stun_msg();
+ EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
+
+ // If the tiebreaker value is different from port, we expect a error
+ // response.
+ lport->Reset();
+ lport->AddCandidateAddress(kLocalAddr2);
+ // Creating a different connection as |conn| is in STATE_READABLE.
+ Connection* conn1 = lport->CreateConnection(lport->Candidates()[1],
+ Port::ORIGIN_MESSAGE);
+ conn1->Ping(0);
+
+ ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
+ msg = lport->last_stun_msg();
+ EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
+ rtc::scoped_ptr<IceMessage> modified_req(
+ CreateStunMessage(STUN_BINDING_REQUEST));
+ const StunByteStringAttribute* username_attr = msg->GetByteString(
+ STUN_ATTR_USERNAME);
+ modified_req->AddAttribute(new StunByteStringAttribute(
+ STUN_ATTR_USERNAME, username_attr->GetString()));
+ // To make sure we receive error response, adding tiebreaker less than
+ // what's present in request.
+ modified_req->AddAttribute(new StunUInt64Attribute(
+ STUN_ATTR_ICE_CONTROLLING, kTiebreaker1 - 1));
+ modified_req->AddMessageIntegrity("lpass");
+ modified_req->AddFingerprint();
+
+ lport->Reset();
+ rtc::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
+ WriteStunMessage(modified_req.get(), buf.get());
+ conn1->OnReadPacket(buf->Data(), buf->Length(), rtc::PacketTime());
+ ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
+ msg = lport->last_stun_msg();
+ EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, msg->type());
+}
+
+// This test verifies role conflict signal is received when there is
+// conflict in the role. In this case both ports are in controlling and
+// |rport| has higher tiebreaker value than |lport|. Since |lport| has lower
+// value of tiebreaker, when it receives ping request from |rport| it will
+// send role conflict signal.
+TEST_F(PortTest, TestIceRoleConflict) {
+ rtc::scoped_ptr<TestPort> lport(
+ CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
+ lport->SetIceProtocolType(ICEPROTO_RFC5245);
+ lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
+ lport->SetIceTiebreaker(kTiebreaker1);
+ rtc::scoped_ptr<TestPort> rport(
+ CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
+ rport->SetIceProtocolType(ICEPROTO_RFC5245);
+ rport->SetIceRole(cricket::ICEROLE_CONTROLLING);
+ rport->SetIceTiebreaker(kTiebreaker2);
+
+ lport->PrepareAddress();
+ rport->PrepareAddress();
+ ASSERT_FALSE(lport->Candidates().empty());
+ ASSERT_FALSE(rport->Candidates().empty());
+ Connection* lconn = lport->CreateConnection(rport->Candidates()[0],
+ Port::ORIGIN_MESSAGE);
+ Connection* rconn = rport->CreateConnection(lport->Candidates()[0],
+ Port::ORIGIN_MESSAGE);
+ rconn->Ping(0);
+
+ ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, 1000);
+ IceMessage* msg = rport->last_stun_msg();
+ EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
+ // Send rport binding request to lport.
+ lconn->OnReadPacket(rport->last_stun_buf()->Data(),
+ rport->last_stun_buf()->Length(),
+ rtc::PacketTime());
+
+ ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
+ EXPECT_EQ(STUN_BINDING_RESPONSE, lport->last_stun_msg()->type());
+ EXPECT_TRUE(role_conflict());
+}
+
+TEST_F(PortTest, TestTcpNoDelay) {
+ TCPPort* port1 = CreateTcpPort(kLocalAddr1);
+ int option_value = -1;
+ int success = port1->GetOption(rtc::Socket::OPT_NODELAY,
+ &option_value);
+ ASSERT_EQ(0, success); // GetOption() should complete successfully w/ 0
+ ASSERT_EQ(1, option_value);
+ delete port1;
+}
+
+TEST_F(PortTest, TestDelayedBindingUdp) {
+ FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
+ FakePacketSocketFactory socket_factory;
+
+ socket_factory.set_next_udp_socket(socket);
+ scoped_ptr<UDPPort> port(
+ CreateUdpPort(kLocalAddr1, &socket_factory));
+
+ socket->set_state(AsyncPacketSocket::STATE_BINDING);
+ port->PrepareAddress();
+
+ EXPECT_EQ(0U, port->Candidates().size());
+ socket->SignalAddressReady(socket, kLocalAddr2);
+
+ EXPECT_EQ(1U, port->Candidates().size());
+}
+
+TEST_F(PortTest, TestDelayedBindingTcp) {
+ FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
+ FakePacketSocketFactory socket_factory;
+
+ socket_factory.set_next_server_tcp_socket(socket);
+ scoped_ptr<TCPPort> port(
+ CreateTcpPort(kLocalAddr1, &socket_factory));
+
+ socket->set_state(AsyncPacketSocket::STATE_BINDING);
+ port->PrepareAddress();
+
+ EXPECT_EQ(0U, port->Candidates().size());
+ socket->SignalAddressReady(socket, kLocalAddr2);
+
+ EXPECT_EQ(1U, port->Candidates().size());
+}
+
+void PortTest::TestCrossFamilyPorts(int type) {
+ FakePacketSocketFactory factory;
+ scoped_ptr<Port> ports[4];
+ SocketAddress addresses[4] = {SocketAddress("192.168.1.3", 0),
+ SocketAddress("192.168.1.4", 0),
+ SocketAddress("2001:db8::1", 0),
+ SocketAddress("2001:db8::2", 0)};
+ for (int i = 0; i < 4; i++) {
+ FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
+ if (type == SOCK_DGRAM) {
+ factory.set_next_udp_socket(socket);
+ ports[i].reset(CreateUdpPort(addresses[i], &factory));
+ } else if (type == SOCK_STREAM) {
+ factory.set_next_server_tcp_socket(socket);
+ ports[i].reset(CreateTcpPort(addresses[i], &factory));
+ }
+ socket->set_state(AsyncPacketSocket::STATE_BINDING);
+ socket->SignalAddressReady(socket, addresses[i]);
+ ports[i]->PrepareAddress();
+ }
+
+ // IPv4 Port, connects to IPv6 candidate and then to IPv4 candidate.
+ if (type == SOCK_STREAM) {
+ FakeAsyncPacketSocket* clientsocket = new FakeAsyncPacketSocket();
+ factory.set_next_client_tcp_socket(clientsocket);
+ }
+ Connection* c = ports[0]->CreateConnection(GetCandidate(ports[2].get()),
+ Port::ORIGIN_MESSAGE);
+ EXPECT_TRUE(NULL == c);
+ EXPECT_EQ(0U, ports[0]->connections().size());
+ c = ports[0]->CreateConnection(GetCandidate(ports[1].get()),
+ Port::ORIGIN_MESSAGE);
+ EXPECT_FALSE(NULL == c);
+ EXPECT_EQ(1U, ports[0]->connections().size());
+
+ // IPv6 Port, connects to IPv4 candidate and to IPv6 candidate.
+ if (type == SOCK_STREAM) {
+ FakeAsyncPacketSocket* clientsocket = new FakeAsyncPacketSocket();
+ factory.set_next_client_tcp_socket(clientsocket);
+ }
+ c = ports[2]->CreateConnection(GetCandidate(ports[0].get()),
+ Port::ORIGIN_MESSAGE);
+ EXPECT_TRUE(NULL == c);
+ EXPECT_EQ(0U, ports[2]->connections().size());
+ c = ports[2]->CreateConnection(GetCandidate(ports[3].get()),
+ Port::ORIGIN_MESSAGE);
+ EXPECT_FALSE(NULL == c);
+ EXPECT_EQ(1U, ports[2]->connections().size());
+}
+
+TEST_F(PortTest, TestSkipCrossFamilyTcp) {
+ TestCrossFamilyPorts(SOCK_STREAM);
+}
+
+TEST_F(PortTest, TestSkipCrossFamilyUdp) {
+ TestCrossFamilyPorts(SOCK_DGRAM);
+}
+
+// This test verifies DSCP value set through SetOption interface can be
+// get through DefaultDscpValue.
+TEST_F(PortTest, TestDefaultDscpValue) {
+ int dscp;
+ rtc::scoped_ptr<UDPPort> udpport(CreateUdpPort(kLocalAddr1));
+ EXPECT_EQ(0, udpport->SetOption(rtc::Socket::OPT_DSCP,
+ rtc::DSCP_CS6));
+ EXPECT_EQ(0, udpport->GetOption(rtc::Socket::OPT_DSCP, &dscp));
+ rtc::scoped_ptr<TCPPort> tcpport(CreateTcpPort(kLocalAddr1));
+ EXPECT_EQ(0, tcpport->SetOption(rtc::Socket::OPT_DSCP,
+ rtc::DSCP_AF31));
+ EXPECT_EQ(0, tcpport->GetOption(rtc::Socket::OPT_DSCP, &dscp));
+ EXPECT_EQ(rtc::DSCP_AF31, dscp);
+ rtc::scoped_ptr<StunPort> stunport(
+ CreateStunPort(kLocalAddr1, nat_socket_factory1()));
+ EXPECT_EQ(0, stunport->SetOption(rtc::Socket::OPT_DSCP,
+ rtc::DSCP_AF41));
+ EXPECT_EQ(0, stunport->GetOption(rtc::Socket::OPT_DSCP, &dscp));
+ EXPECT_EQ(rtc::DSCP_AF41, dscp);
+ rtc::scoped_ptr<TurnPort> turnport1(CreateTurnPort(
+ kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
+ // Socket is created in PrepareAddress.
+ turnport1->PrepareAddress();
+ EXPECT_EQ(0, turnport1->SetOption(rtc::Socket::OPT_DSCP,
+ rtc::DSCP_CS7));
+ EXPECT_EQ(0, turnport1->GetOption(rtc::Socket::OPT_DSCP, &dscp));
+ EXPECT_EQ(rtc::DSCP_CS7, dscp);
+ // This will verify correct value returned without the socket.
+ rtc::scoped_ptr<TurnPort> turnport2(CreateTurnPort(
+ kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
+ EXPECT_EQ(0, turnport2->SetOption(rtc::Socket::OPT_DSCP,
+ rtc::DSCP_CS6));
+ EXPECT_EQ(0, turnport2->GetOption(rtc::Socket::OPT_DSCP, &dscp));
+ EXPECT_EQ(rtc::DSCP_CS6, dscp);
+}
+
+// Test sending STUN messages in GICE format.
+TEST_F(PortTest, TestSendStunMessageAsGice) {
+ rtc::scoped_ptr<TestPort> lport(
+ CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
+ rtc::scoped_ptr<TestPort> rport(
+ CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
+ lport->SetIceProtocolType(ICEPROTO_GOOGLE);
+ rport->SetIceProtocolType(ICEPROTO_GOOGLE);
+
+ // Send a fake ping from lport to rport.
+ lport->PrepareAddress();
+ rport->PrepareAddress();
+ ASSERT_FALSE(rport->Candidates().empty());
+ Connection* conn = lport->CreateConnection(rport->Candidates()[0],
+ Port::ORIGIN_MESSAGE);
+ rport->CreateConnection(lport->Candidates()[0], Port::ORIGIN_MESSAGE);
+ conn->Ping(0);
+
+ // Check that it's a proper BINDING-REQUEST.
+ ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
+ IceMessage* msg = lport->last_stun_msg();
+ EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
+ EXPECT_FALSE(msg->IsLegacy());
+ const StunByteStringAttribute* username_attr = msg->GetByteString(
+ STUN_ATTR_USERNAME);
+ ASSERT_TRUE(username_attr != NULL);
+ EXPECT_EQ("rfraglfrag", username_attr->GetString());
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) == NULL);
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_FINGERPRINT) == NULL);
+
+ // Save a copy of the BINDING-REQUEST for use below.
+ rtc::scoped_ptr<IceMessage> request(CopyStunMessage(msg));
+
+ // Respond with a BINDING-RESPONSE.
+ rport->SendBindingResponse(request.get(), lport->Candidates()[0].address());
+ msg = rport->last_stun_msg();
+ ASSERT_TRUE(msg != NULL);
+ EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
+ EXPECT_FALSE(msg->IsLegacy());
+ username_attr = msg->GetByteString(STUN_ATTR_USERNAME);
+ ASSERT_TRUE(username_attr != NULL); // GICE has a username in the response.
+ EXPECT_EQ("rfraglfrag", username_attr->GetString());
+ const StunAddressAttribute* addr_attr = msg->GetAddress(
+ STUN_ATTR_MAPPED_ADDRESS);
+ ASSERT_TRUE(addr_attr != NULL);
+ EXPECT_EQ(lport->Candidates()[0].address(), addr_attr->GetAddress());
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_XOR_MAPPED_ADDRESS) == NULL);
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) == NULL);
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_FINGERPRINT) == NULL);
+
+ // Respond with a BINDING-ERROR-RESPONSE. This wouldn't happen in real life,
+ // but we can do it here.
+ rport->SendBindingErrorResponse(request.get(),
+ rport->Candidates()[0].address(),
+ STUN_ERROR_SERVER_ERROR,
+ STUN_ERROR_REASON_SERVER_ERROR);
+ msg = rport->last_stun_msg();
+ ASSERT_TRUE(msg != NULL);
+ EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, msg->type());
+ EXPECT_FALSE(msg->IsLegacy());
+ username_attr = msg->GetByteString(STUN_ATTR_USERNAME);
+ ASSERT_TRUE(username_attr != NULL); // GICE has a username in the response.
+ EXPECT_EQ("rfraglfrag", username_attr->GetString());
+ const StunErrorCodeAttribute* error_attr = msg->GetErrorCode();
+ ASSERT_TRUE(error_attr != NULL);
+ // The GICE wire format for error codes is incorrect.
+ EXPECT_EQ(STUN_ERROR_SERVER_ERROR_AS_GICE, error_attr->code());
+ EXPECT_EQ(STUN_ERROR_SERVER_ERROR / 256, error_attr->eclass());
+ EXPECT_EQ(STUN_ERROR_SERVER_ERROR % 256, error_attr->number());
+ EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR), error_attr->reason());
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) == NULL);
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_FINGERPRINT) == NULL);
+}
+
+// Test sending STUN messages in ICE format.
+TEST_F(PortTest, TestSendStunMessageAsIce) {
+ rtc::scoped_ptr<TestPort> lport(
+ CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
+ rtc::scoped_ptr<TestPort> rport(
+ CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
+ lport->SetIceProtocolType(ICEPROTO_RFC5245);
+ lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
+ lport->SetIceTiebreaker(kTiebreaker1);
+ rport->SetIceProtocolType(ICEPROTO_RFC5245);
+ rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
+ rport->SetIceTiebreaker(kTiebreaker2);
+
+ // Send a fake ping from lport to rport.
+ lport->PrepareAddress();
+ rport->PrepareAddress();
+ ASSERT_FALSE(rport->Candidates().empty());
+ Connection* lconn = lport->CreateConnection(
+ rport->Candidates()[0], Port::ORIGIN_MESSAGE);
+ Connection* rconn = rport->CreateConnection(
+ lport->Candidates()[0], Port::ORIGIN_MESSAGE);
+ lconn->Ping(0);
+
+ // Check that it's a proper BINDING-REQUEST.
+ ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
+ IceMessage* msg = lport->last_stun_msg();
+ EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
+ EXPECT_FALSE(msg->IsLegacy());
+ const StunByteStringAttribute* username_attr =
+ msg->GetByteString(STUN_ATTR_USERNAME);
+ ASSERT_TRUE(username_attr != NULL);
+ const StunUInt32Attribute* priority_attr = msg->GetUInt32(STUN_ATTR_PRIORITY);
+ ASSERT_TRUE(priority_attr != NULL);
+ EXPECT_EQ(kDefaultPrflxPriority, priority_attr->value());
+ EXPECT_EQ("rfrag:lfrag", username_attr->GetString());
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
+ EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
+ lport->last_stun_buf()->Data(), lport->last_stun_buf()->Length(),
+ "rpass"));
+ const StunUInt64Attribute* ice_controlling_attr =
+ msg->GetUInt64(STUN_ATTR_ICE_CONTROLLING);
+ ASSERT_TRUE(ice_controlling_attr != NULL);
+ EXPECT_EQ(lport->IceTiebreaker(), ice_controlling_attr->value());
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLED) == NULL);
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) != NULL);
+ EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
+ EXPECT_TRUE(StunMessage::ValidateFingerprint(
+ lport->last_stun_buf()->Data(), lport->last_stun_buf()->Length()));
+
+ // Request should not include ping count.
+ ASSERT_TRUE(msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT) == NULL);
+
+ // Save a copy of the BINDING-REQUEST for use below.
+ rtc::scoped_ptr<IceMessage> request(CopyStunMessage(msg));
+
+ // Respond with a BINDING-RESPONSE.
+ rport->SendBindingResponse(request.get(), lport->Candidates()[0].address());
+ msg = rport->last_stun_msg();
+ ASSERT_TRUE(msg != NULL);
+ EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
+
+
+ EXPECT_FALSE(msg->IsLegacy());
+ const StunAddressAttribute* addr_attr = msg->GetAddress(
+ STUN_ATTR_XOR_MAPPED_ADDRESS);
+ ASSERT_TRUE(addr_attr != NULL);
+ EXPECT_EQ(lport->Candidates()[0].address(), addr_attr->GetAddress());
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
+ EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
+ rport->last_stun_buf()->Data(), rport->last_stun_buf()->Length(),
+ "rpass"));
+ EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
+ EXPECT_TRUE(StunMessage::ValidateFingerprint(
+ lport->last_stun_buf()->Data(), lport->last_stun_buf()->Length()));
+ // No USERNAME or PRIORITY in ICE responses.
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USERNAME) == NULL);
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MAPPED_ADDRESS) == NULL);
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLING) == NULL);
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLED) == NULL);
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
+
+ // Response should not include ping count.
+ ASSERT_TRUE(msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT) == NULL);
+
+ // Respond with a BINDING-ERROR-RESPONSE. This wouldn't happen in real life,
+ // but we can do it here.
+ rport->SendBindingErrorResponse(request.get(),
+ lport->Candidates()[0].address(),
+ STUN_ERROR_SERVER_ERROR,
+ STUN_ERROR_REASON_SERVER_ERROR);
+ msg = rport->last_stun_msg();
+ ASSERT_TRUE(msg != NULL);
+ EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, msg->type());
+ EXPECT_FALSE(msg->IsLegacy());
+ const StunErrorCodeAttribute* error_attr = msg->GetErrorCode();
+ ASSERT_TRUE(error_attr != NULL);
+ EXPECT_EQ(STUN_ERROR_SERVER_ERROR, error_attr->code());
+ EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR), error_attr->reason());
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
+ EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
+ rport->last_stun_buf()->Data(), rport->last_stun_buf()->Length(),
+ "rpass"));
+ EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
+ EXPECT_TRUE(StunMessage::ValidateFingerprint(
+ lport->last_stun_buf()->Data(), lport->last_stun_buf()->Length()));
+ // No USERNAME with ICE.
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USERNAME) == NULL);
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
+
+ // Testing STUN binding requests from rport --> lport, having ICE_CONTROLLED
+ // and (incremented) RETRANSMIT_COUNT attributes.
+ rport->Reset();
+ rport->set_send_retransmit_count_attribute(true);
+ rconn->Ping(0);
+ rconn->Ping(0);
+ rconn->Ping(0);
+ ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, 1000);
+ msg = rport->last_stun_msg();
+ EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
+ const StunUInt64Attribute* ice_controlled_attr =
+ msg->GetUInt64(STUN_ATTR_ICE_CONTROLLED);
+ ASSERT_TRUE(ice_controlled_attr != NULL);
+ EXPECT_EQ(rport->IceTiebreaker(), ice_controlled_attr->value());
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
+
+ // Request should include ping count.
+ const StunUInt32Attribute* retransmit_attr =
+ msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT);
+ ASSERT_TRUE(retransmit_attr != NULL);
+ EXPECT_EQ(2U, retransmit_attr->value());
+
+ // Respond with a BINDING-RESPONSE.
+ request.reset(CopyStunMessage(msg));
+ lport->SendBindingResponse(request.get(), rport->Candidates()[0].address());
+ msg = lport->last_stun_msg();
+
+ // Response should include same ping count.
+ retransmit_attr = msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT);
+ ASSERT_TRUE(retransmit_attr != NULL);
+ EXPECT_EQ(2U, retransmit_attr->value());
+}
+
+TEST_F(PortTest, TestUseCandidateAttribute) {
+ rtc::scoped_ptr<TestPort> lport(
+ CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
+ rtc::scoped_ptr<TestPort> rport(
+ CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
+ lport->SetIceProtocolType(ICEPROTO_RFC5245);
+ lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
+ lport->SetIceTiebreaker(kTiebreaker1);
+ rport->SetIceProtocolType(ICEPROTO_RFC5245);
+ rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
+ rport->SetIceTiebreaker(kTiebreaker2);
+
+ // Send a fake ping from lport to rport.
+ lport->PrepareAddress();
+ rport->PrepareAddress();
+ ASSERT_FALSE(rport->Candidates().empty());
+ Connection* lconn = lport->CreateConnection(
+ rport->Candidates()[0], Port::ORIGIN_MESSAGE);
+ lconn->Ping(0);
+ ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
+ IceMessage* msg = lport->last_stun_msg();
+ const StunUInt64Attribute* ice_controlling_attr =
+ msg->GetUInt64(STUN_ATTR_ICE_CONTROLLING);
+ ASSERT_TRUE(ice_controlling_attr != NULL);
+ const StunByteStringAttribute* use_candidate_attr = msg->GetByteString(
+ STUN_ATTR_USE_CANDIDATE);
+ ASSERT_TRUE(use_candidate_attr != NULL);
+}
+
+// Test handling STUN messages in GICE format.
+TEST_F(PortTest, TestHandleStunMessageAsGice) {
+ // Our port will act as the "remote" port.
+ rtc::scoped_ptr<TestPort> port(
+ CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
+ port->SetIceProtocolType(ICEPROTO_GOOGLE);
+
+ rtc::scoped_ptr<IceMessage> in_msg, out_msg;
+ rtc::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
+ rtc::SocketAddress addr(kLocalAddr1);
+ std::string username;
+
+ // BINDING-REQUEST from local to remote with valid GICE username and no M-I.
+ in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
+ "rfraglfrag"));
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() != NULL); // Succeeds, since this is GICE.
+ EXPECT_EQ("lfrag", username);
+
+ // Add M-I; should be ignored and rest of message parsed normally.
+ in_msg->AddMessageIntegrity("password");
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() != NULL);
+ EXPECT_EQ("lfrag", username);
+
+ // BINDING-RESPONSE with username, as done in GICE. Should succeed.
+ in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_RESPONSE,
+ "rfraglfrag"));
+ in_msg->AddAttribute(
+ new StunAddressAttribute(STUN_ATTR_MAPPED_ADDRESS, kLocalAddr2));
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() != NULL);
+ EXPECT_EQ("", username);
+
+ // BINDING-RESPONSE without username. Should be tolerated as well.
+ in_msg.reset(CreateStunMessage(STUN_BINDING_RESPONSE));
+ in_msg->AddAttribute(
+ new StunAddressAttribute(STUN_ATTR_MAPPED_ADDRESS, kLocalAddr2));
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() != NULL);
+ EXPECT_EQ("", username);
+
+ // BINDING-ERROR-RESPONSE with username and error code.
+ in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_ERROR_RESPONSE,
+ "rfraglfrag"));
+ in_msg->AddAttribute(new StunErrorCodeAttribute(STUN_ATTR_ERROR_CODE,
+ STUN_ERROR_SERVER_ERROR_AS_GICE, STUN_ERROR_REASON_SERVER_ERROR));
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ ASSERT_TRUE(out_msg.get() != NULL);
+ EXPECT_EQ("", username);
+ ASSERT_TRUE(out_msg->GetErrorCode() != NULL);
+ // GetStunMessage doesn't unmunge the GICE error code (happens downstream).
+ EXPECT_EQ(STUN_ERROR_SERVER_ERROR_AS_GICE, out_msg->GetErrorCode()->code());
+ EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR),
+ out_msg->GetErrorCode()->reason());
+}
+
+// Test handling STUN messages in ICE format.
+TEST_F(PortTest, TestHandleStunMessageAsIce) {
+ // Our port will act as the "remote" port.
+ rtc::scoped_ptr<TestPort> port(
+ CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
+ port->SetIceProtocolType(ICEPROTO_RFC5245);
+
+ rtc::scoped_ptr<IceMessage> in_msg, out_msg;
+ rtc::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
+ rtc::SocketAddress addr(kLocalAddr1);
+ std::string username;
+
+ // BINDING-REQUEST from local to remote with valid ICE username,
+ // MESSAGE-INTEGRITY, and FINGERPRINT.
+ in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
+ "rfrag:lfrag"));
+ in_msg->AddMessageIntegrity("rpass");
+ in_msg->AddFingerprint();
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() != NULL);
+ EXPECT_EQ("lfrag", username);
+
+ // BINDING-RESPONSE without username, with MESSAGE-INTEGRITY and FINGERPRINT.
+ in_msg.reset(CreateStunMessage(STUN_BINDING_RESPONSE));
+ in_msg->AddAttribute(
+ new StunXorAddressAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, kLocalAddr2));
+ in_msg->AddMessageIntegrity("rpass");
+ in_msg->AddFingerprint();
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() != NULL);
+ EXPECT_EQ("", username);
+
+ // BINDING-ERROR-RESPONSE without username, with error, M-I, and FINGERPRINT.
+ in_msg.reset(CreateStunMessage(STUN_BINDING_ERROR_RESPONSE));
+ in_msg->AddAttribute(new StunErrorCodeAttribute(STUN_ATTR_ERROR_CODE,
+ STUN_ERROR_SERVER_ERROR, STUN_ERROR_REASON_SERVER_ERROR));
+ in_msg->AddFingerprint();
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() != NULL);
+ EXPECT_EQ("", username);
+ ASSERT_TRUE(out_msg->GetErrorCode() != NULL);
+ EXPECT_EQ(STUN_ERROR_SERVER_ERROR, out_msg->GetErrorCode()->code());
+ EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR),
+ out_msg->GetErrorCode()->reason());
+}
+
+// This test verifies port can handle ICE messages in Hybrid mode and switches
+// ICEPROTO_RFC5245 mode after successfully handling the message.
+TEST_F(PortTest, TestHandleStunMessageAsIceInHybridMode) {
+ // Our port will act as the "remote" port.
+ rtc::scoped_ptr<TestPort> port(
+ CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
+ port->SetIceProtocolType(ICEPROTO_HYBRID);
+
+ rtc::scoped_ptr<IceMessage> in_msg, out_msg;
+ rtc::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
+ rtc::SocketAddress addr(kLocalAddr1);
+ std::string username;
+
+ // BINDING-REQUEST from local to remote with valid ICE username,
+ // MESSAGE-INTEGRITY, and FINGERPRINT.
+ in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
+ "rfrag:lfrag"));
+ in_msg->AddMessageIntegrity("rpass");
+ in_msg->AddFingerprint();
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() != NULL);
+ EXPECT_EQ("lfrag", username);
+ EXPECT_EQ(ICEPROTO_RFC5245, port->IceProtocol());
+}
+
+// This test verifies port can handle GICE messages in Hybrid mode and switches
+// ICEPROTO_GOOGLE mode after successfully handling the message.
+TEST_F(PortTest, TestHandleStunMessageAsGiceInHybridMode) {
+ // Our port will act as the "remote" port.
+ rtc::scoped_ptr<TestPort> port(
+ CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
+ port->SetIceProtocolType(ICEPROTO_HYBRID);
+
+ rtc::scoped_ptr<IceMessage> in_msg, out_msg;
+ rtc::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
+ rtc::SocketAddress addr(kLocalAddr1);
+ std::string username;
+
+ // BINDING-REQUEST from local to remote with valid GICE username and no M-I.
+ in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
+ "rfraglfrag"));
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() != NULL); // Succeeds, since this is GICE.
+ EXPECT_EQ("lfrag", username);
+ EXPECT_EQ(ICEPROTO_GOOGLE, port->IceProtocol());
+}
+
+// Verify port is not switched out of RFC5245 mode if GICE message is received
+// in that mode.
+TEST_F(PortTest, TestHandleStunMessageAsGiceInIceMode) {
+ // Our port will act as the "remote" port.
+ rtc::scoped_ptr<TestPort> port(
+ CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
+ port->SetIceProtocolType(ICEPROTO_RFC5245);
+
+ rtc::scoped_ptr<IceMessage> in_msg, out_msg;
+ rtc::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
+ rtc::SocketAddress addr(kLocalAddr1);
+ std::string username;
+
+ // BINDING-REQUEST from local to remote with valid GICE username and no M-I.
+ in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
+ "rfraglfrag"));
+ WriteStunMessage(in_msg.get(), buf.get());
+ // Should fail as there is no MI and fingerprint.
+ EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_EQ(ICEPROTO_RFC5245, port->IceProtocol());
+}
+
+
+// Tests handling of GICE binding requests with missing or incorrect usernames.
+TEST_F(PortTest, TestHandleStunMessageAsGiceBadUsername) {
+ rtc::scoped_ptr<TestPort> port(
+ CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
+ port->SetIceProtocolType(ICEPROTO_GOOGLE);
+
+ rtc::scoped_ptr<IceMessage> in_msg, out_msg;
+ rtc::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
+ rtc::SocketAddress addr(kLocalAddr1);
+ std::string username;
+
+ // BINDING-REQUEST with no username.
+ in_msg.reset(CreateStunMessage(STUN_BINDING_REQUEST));
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() == NULL);
+ EXPECT_EQ("", username);
+ EXPECT_EQ(STUN_ERROR_BAD_REQUEST_AS_GICE, port->last_stun_error_code());
+
+ // BINDING-REQUEST with empty username.
+ in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST, ""));
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() == NULL);
+ EXPECT_EQ("", username);
+ EXPECT_EQ(STUN_ERROR_UNAUTHORIZED_AS_GICE, port->last_stun_error_code());
+
+ // BINDING-REQUEST with too-short username.
+ in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST, "lfra"));
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() == NULL);
+ EXPECT_EQ("", username);
+ EXPECT_EQ(STUN_ERROR_UNAUTHORIZED_AS_GICE, port->last_stun_error_code());
+
+ // BINDING-REQUEST with reversed username.
+ in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
+ "lfragrfrag"));
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() == NULL);
+ EXPECT_EQ("", username);
+ EXPECT_EQ(STUN_ERROR_UNAUTHORIZED_AS_GICE, port->last_stun_error_code());
+
+ // BINDING-REQUEST with garbage username.
+ in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
+ "abcdefgh"));
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() == NULL);
+ EXPECT_EQ("", username);
+ EXPECT_EQ(STUN_ERROR_UNAUTHORIZED_AS_GICE, port->last_stun_error_code());
+}
+
+// Tests handling of ICE binding requests with missing or incorrect usernames.
+TEST_F(PortTest, TestHandleStunMessageAsIceBadUsername) {
+ rtc::scoped_ptr<TestPort> port(
+ CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
+ port->SetIceProtocolType(ICEPROTO_RFC5245);
+
+ rtc::scoped_ptr<IceMessage> in_msg, out_msg;
+ rtc::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
+ rtc::SocketAddress addr(kLocalAddr1);
+ std::string username;
+
+ // BINDING-REQUEST with no username.
+ in_msg.reset(CreateStunMessage(STUN_BINDING_REQUEST));
+ in_msg->AddMessageIntegrity("rpass");
+ in_msg->AddFingerprint();
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() == NULL);
+ EXPECT_EQ("", username);
+ EXPECT_EQ(STUN_ERROR_BAD_REQUEST, port->last_stun_error_code());
+
+ // BINDING-REQUEST with empty username.
+ in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST, ""));
+ in_msg->AddMessageIntegrity("rpass");
+ in_msg->AddFingerprint();
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() == NULL);
+ EXPECT_EQ("", username);
+ EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
+
+ // BINDING-REQUEST with too-short username.
+ in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST, "rfra"));
+ in_msg->AddMessageIntegrity("rpass");
+ in_msg->AddFingerprint();
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() == NULL);
+ EXPECT_EQ("", username);
+ EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
+
+ // BINDING-REQUEST with reversed username.
+ in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
+ "lfrag:rfrag"));
+ in_msg->AddMessageIntegrity("rpass");
+ in_msg->AddFingerprint();
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() == NULL);
+ EXPECT_EQ("", username);
+ EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
+
+ // BINDING-REQUEST with garbage username.
+ in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
+ "abcd:efgh"));
+ in_msg->AddMessageIntegrity("rpass");
+ in_msg->AddFingerprint();
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() == NULL);
+ EXPECT_EQ("", username);
+ EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
+}
+
+// Test handling STUN messages (as ICE) with missing or malformed M-I.
+TEST_F(PortTest, TestHandleStunMessageAsIceBadMessageIntegrity) {
+ // Our port will act as the "remote" port.
+ rtc::scoped_ptr<TestPort> port(
+ CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
+ port->SetIceProtocolType(ICEPROTO_RFC5245);
+
+ rtc::scoped_ptr<IceMessage> in_msg, out_msg;
+ rtc::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
+ rtc::SocketAddress addr(kLocalAddr1);
+ std::string username;
+
+ // BINDING-REQUEST from local to remote with valid ICE username and
+ // FINGERPRINT, but no MESSAGE-INTEGRITY.
+ in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
+ "rfrag:lfrag"));
+ in_msg->AddFingerprint();
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() == NULL);
+ EXPECT_EQ("", username);
+ EXPECT_EQ(STUN_ERROR_BAD_REQUEST, port->last_stun_error_code());
+
+ // BINDING-REQUEST from local to remote with valid ICE username and
+ // FINGERPRINT, but invalid MESSAGE-INTEGRITY.
+ in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
+ "rfrag:lfrag"));
+ in_msg->AddMessageIntegrity("invalid");
+ in_msg->AddFingerprint();
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() == NULL);
+ EXPECT_EQ("", username);
+ EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
+
+ // TODO: BINDING-RESPONSES and BINDING-ERROR-RESPONSES are checked
+ // by the Connection, not the Port, since they require the remote username.
+ // Change this test to pass in data via Connection::OnReadPacket instead.
+}
+
+// Test handling STUN messages (as ICE) with missing or malformed FINGERPRINT.
+TEST_F(PortTest, TestHandleStunMessageAsIceBadFingerprint) {
+ // Our port will act as the "remote" port.
+ rtc::scoped_ptr<TestPort> port(
+ CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
+ port->SetIceProtocolType(ICEPROTO_RFC5245);
+
+ rtc::scoped_ptr<IceMessage> in_msg, out_msg;
+ rtc::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
+ rtc::SocketAddress addr(kLocalAddr1);
+ std::string username;
+
+ // BINDING-REQUEST from local to remote with valid ICE username and
+ // MESSAGE-INTEGRITY, but no FINGERPRINT; GetStunMessage should fail.
+ in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
+ "rfrag:lfrag"));
+ in_msg->AddMessageIntegrity("rpass");
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_EQ(0, port->last_stun_error_code());
+
+ // Now, add a fingerprint, but munge the message so it's not valid.
+ in_msg->AddFingerprint();
+ in_msg->SetTransactionID("TESTTESTBADD");
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_EQ(0, port->last_stun_error_code());
+
+ // Valid BINDING-RESPONSE, except no FINGERPRINT.
+ in_msg.reset(CreateStunMessage(STUN_BINDING_RESPONSE));
+ in_msg->AddAttribute(
+ new StunXorAddressAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, kLocalAddr2));
+ in_msg->AddMessageIntegrity("rpass");
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_EQ(0, port->last_stun_error_code());
+
+ // Now, add a fingerprint, but munge the message so it's not valid.
+ in_msg->AddFingerprint();
+ in_msg->SetTransactionID("TESTTESTBADD");
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_EQ(0, port->last_stun_error_code());
+
+ // Valid BINDING-ERROR-RESPONSE, except no FINGERPRINT.
+ in_msg.reset(CreateStunMessage(STUN_BINDING_ERROR_RESPONSE));
+ in_msg->AddAttribute(new StunErrorCodeAttribute(STUN_ATTR_ERROR_CODE,
+ STUN_ERROR_SERVER_ERROR, STUN_ERROR_REASON_SERVER_ERROR));
+ in_msg->AddMessageIntegrity("rpass");
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_EQ(0, port->last_stun_error_code());
+
+ // Now, add a fingerprint, but munge the message so it's not valid.
+ in_msg->AddFingerprint();
+ in_msg->SetTransactionID("TESTTESTBADD");
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_EQ(0, port->last_stun_error_code());
+}
+
+// Test handling of STUN binding indication messages (as ICE). STUN binding
+// indications are allowed only to the connection which is in read mode.
+TEST_F(PortTest, TestHandleStunBindingIndication) {
+ rtc::scoped_ptr<TestPort> lport(
+ CreateTestPort(kLocalAddr2, "lfrag", "lpass"));
+ lport->SetIceProtocolType(ICEPROTO_RFC5245);
+ lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
+ lport->SetIceTiebreaker(kTiebreaker1);
+
+ // Verifying encoding and decoding STUN indication message.
+ rtc::scoped_ptr<IceMessage> in_msg, out_msg;
+ rtc::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
+ rtc::SocketAddress addr(kLocalAddr1);
+ std::string username;
+
+ in_msg.reset(CreateStunMessage(STUN_BINDING_INDICATION));
+ in_msg->AddFingerprint();
+ WriteStunMessage(in_msg.get(), buf.get());
+ EXPECT_TRUE(lport->GetStunMessage(buf->Data(), buf->Length(), addr,
+ out_msg.accept(), &username));
+ EXPECT_TRUE(out_msg.get() != NULL);
+ EXPECT_EQ(out_msg->type(), STUN_BINDING_INDICATION);
+ EXPECT_EQ("", username);
+
+ // Verify connection can handle STUN indication and updates
+ // last_ping_received.
+ rtc::scoped_ptr<TestPort> rport(
+ CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
+ rport->SetIceProtocolType(ICEPROTO_RFC5245);
+ rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
+ rport->SetIceTiebreaker(kTiebreaker2);
+
+ lport->PrepareAddress();
+ rport->PrepareAddress();
+ ASSERT_FALSE(lport->Candidates().empty());
+ ASSERT_FALSE(rport->Candidates().empty());
+
+ Connection* lconn = lport->CreateConnection(rport->Candidates()[0],
+ Port::ORIGIN_MESSAGE);
+ Connection* rconn = rport->CreateConnection(lport->Candidates()[0],
+ Port::ORIGIN_MESSAGE);
+ rconn->Ping(0);
+
+ ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, 1000);
+ IceMessage* msg = rport->last_stun_msg();
+ EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
+ // Send rport binding request to lport.
+ lconn->OnReadPacket(rport->last_stun_buf()->Data(),
+ rport->last_stun_buf()->Length(),
+ rtc::PacketTime());
+ ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
+ EXPECT_EQ(STUN_BINDING_RESPONSE, lport->last_stun_msg()->type());
+ uint32 last_ping_received1 = lconn->last_ping_received();
+
+ // Adding a delay of 100ms.
+ rtc::Thread::Current()->ProcessMessages(100);
+ // Pinging lconn using stun indication message.
+ lconn->OnReadPacket(buf->Data(), buf->Length(), rtc::PacketTime());
+ uint32 last_ping_received2 = lconn->last_ping_received();
+ EXPECT_GT(last_ping_received2, last_ping_received1);
+}
+
+TEST_F(PortTest, TestComputeCandidatePriority) {
+ rtc::scoped_ptr<TestPort> port(
+ CreateTestPort(kLocalAddr1, "name", "pass"));
+ port->set_type_preference(90);
+ port->set_component(177);
+ port->AddCandidateAddress(SocketAddress("192.168.1.4", 1234));
+ port->AddCandidateAddress(SocketAddress("2001:db8::1234", 1234));
+ port->AddCandidateAddress(SocketAddress("fc12:3456::1234", 1234));
+ port->AddCandidateAddress(SocketAddress("::ffff:192.168.1.4", 1234));
+ port->AddCandidateAddress(SocketAddress("::192.168.1.4", 1234));
+ port->AddCandidateAddress(SocketAddress("2002::1234:5678", 1234));
+ port->AddCandidateAddress(SocketAddress("2001::1234:5678", 1234));
+ port->AddCandidateAddress(SocketAddress("fecf::1234:5678", 1234));
+ port->AddCandidateAddress(SocketAddress("3ffe::1234:5678", 1234));
+ // These should all be:
+ // (90 << 24) | ([rfc3484 pref value] << 8) | (256 - 177)
+ uint32 expected_priority_v4 = 1509957199U;
+ uint32 expected_priority_v6 = 1509959759U;
+ uint32 expected_priority_ula = 1509962319U;
+ uint32 expected_priority_v4mapped = expected_priority_v4;
+ uint32 expected_priority_v4compat = 1509949775U;
+ uint32 expected_priority_6to4 = 1509954639U;
+ uint32 expected_priority_teredo = 1509952079U;
+ uint32 expected_priority_sitelocal = 1509949775U;
+ uint32 expected_priority_6bone = 1509949775U;
+ ASSERT_EQ(expected_priority_v4, port->Candidates()[0].priority());
+ ASSERT_EQ(expected_priority_v6, port->Candidates()[1].priority());
+ ASSERT_EQ(expected_priority_ula, port->Candidates()[2].priority());
+ ASSERT_EQ(expected_priority_v4mapped, port->Candidates()[3].priority());
+ ASSERT_EQ(expected_priority_v4compat, port->Candidates()[4].priority());
+ ASSERT_EQ(expected_priority_6to4, port->Candidates()[5].priority());
+ ASSERT_EQ(expected_priority_teredo, port->Candidates()[6].priority());
+ ASSERT_EQ(expected_priority_sitelocal, port->Candidates()[7].priority());
+ ASSERT_EQ(expected_priority_6bone, port->Candidates()[8].priority());
+}
+
+TEST_F(PortTest, TestPortProxyProperties) {
+ rtc::scoped_ptr<TestPort> port(
+ CreateTestPort(kLocalAddr1, "name", "pass"));
+ port->SetIceRole(cricket::ICEROLE_CONTROLLING);
+ port->SetIceTiebreaker(kTiebreaker1);
+
+ // Create a proxy port.
+ rtc::scoped_ptr<PortProxy> proxy(new PortProxy());
+ proxy->set_impl(port.get());
+ EXPECT_EQ(port->Type(), proxy->Type());
+ EXPECT_EQ(port->Network(), proxy->Network());
+ EXPECT_EQ(port->GetIceRole(), proxy->GetIceRole());
+ EXPECT_EQ(port->IceTiebreaker(), proxy->IceTiebreaker());
+}
+
+// In the case of shared socket, one port may be shared by local and stun.
+// Test that candidates with different types will have different foundation.
+TEST_F(PortTest, TestFoundation) {
+ rtc::scoped_ptr<TestPort> testport(
+ CreateTestPort(kLocalAddr1, "name", "pass"));
+ testport->AddCandidateAddress(kLocalAddr1, kLocalAddr1,
+ LOCAL_PORT_TYPE,
+ cricket::ICE_TYPE_PREFERENCE_HOST, false);
+ testport->AddCandidateAddress(kLocalAddr2, kLocalAddr1,
+ STUN_PORT_TYPE,
+ cricket::ICE_TYPE_PREFERENCE_SRFLX, true);
+ EXPECT_NE(testport->Candidates()[0].foundation(),
+ testport->Candidates()[1].foundation());
+}
+
+// This test verifies the foundation of different types of ICE candidates.
+TEST_F(PortTest, TestCandidateFoundation) {
+ rtc::scoped_ptr<rtc::NATServer> nat_server(
+ CreateNatServer(kNatAddr1, NAT_OPEN_CONE));
+ rtc::scoped_ptr<UDPPort> udpport1(CreateUdpPort(kLocalAddr1));
+ udpport1->PrepareAddress();
+ rtc::scoped_ptr<UDPPort> udpport2(CreateUdpPort(kLocalAddr1));
+ udpport2->PrepareAddress();
+ EXPECT_EQ(udpport1->Candidates()[0].foundation(),
+ udpport2->Candidates()[0].foundation());
+ rtc::scoped_ptr<TCPPort> tcpport1(CreateTcpPort(kLocalAddr1));
+ tcpport1->PrepareAddress();
+ rtc::scoped_ptr<TCPPort> tcpport2(CreateTcpPort(kLocalAddr1));
+ tcpport2->PrepareAddress();
+ EXPECT_EQ(tcpport1->Candidates()[0].foundation(),
+ tcpport2->Candidates()[0].foundation());
+ rtc::scoped_ptr<Port> stunport(
+ CreateStunPort(kLocalAddr1, nat_socket_factory1()));
+ stunport->PrepareAddress();
+ ASSERT_EQ_WAIT(1U, stunport->Candidates().size(), kTimeout);
+ EXPECT_NE(tcpport1->Candidates()[0].foundation(),
+ stunport->Candidates()[0].foundation());
+ EXPECT_NE(tcpport2->Candidates()[0].foundation(),
+ stunport->Candidates()[0].foundation());
+ EXPECT_NE(udpport1->Candidates()[0].foundation(),
+ stunport->Candidates()[0].foundation());
+ EXPECT_NE(udpport2->Candidates()[0].foundation(),
+ stunport->Candidates()[0].foundation());
+ // Verify GTURN candidate foundation.
+ rtc::scoped_ptr<RelayPort> relayport(
+ CreateGturnPort(kLocalAddr1));
+ relayport->AddServerAddress(
+ cricket::ProtocolAddress(kRelayUdpIntAddr, cricket::PROTO_UDP));
+ relayport->PrepareAddress();
+ ASSERT_EQ_WAIT(1U, relayport->Candidates().size(), kTimeout);
+ EXPECT_NE(udpport1->Candidates()[0].foundation(),
+ relayport->Candidates()[0].foundation());
+ EXPECT_NE(udpport2->Candidates()[0].foundation(),
+ relayport->Candidates()[0].foundation());
+ // Verifying TURN candidate foundation.
+ rtc::scoped_ptr<Port> turnport1(CreateTurnPort(
+ kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
+ turnport1->PrepareAddress();
+ ASSERT_EQ_WAIT(1U, turnport1->Candidates().size(), kTimeout);
+ EXPECT_NE(udpport1->Candidates()[0].foundation(),
+ turnport1->Candidates()[0].foundation());
+ EXPECT_NE(udpport2->Candidates()[0].foundation(),
+ turnport1->Candidates()[0].foundation());
+ EXPECT_NE(stunport->Candidates()[0].foundation(),
+ turnport1->Candidates()[0].foundation());
+ rtc::scoped_ptr<Port> turnport2(CreateTurnPort(
+ kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
+ turnport2->PrepareAddress();
+ ASSERT_EQ_WAIT(1U, turnport2->Candidates().size(), kTimeout);
+ EXPECT_EQ(turnport1->Candidates()[0].foundation(),
+ turnport2->Candidates()[0].foundation());
+
+ // Running a second turn server, to get different base IP address.
+ SocketAddress kTurnUdpIntAddr2("99.99.98.4", STUN_SERVER_PORT);
+ SocketAddress kTurnUdpExtAddr2("99.99.98.5", 0);
+ TestTurnServer turn_server2(
+ rtc::Thread::Current(), kTurnUdpIntAddr2, kTurnUdpExtAddr2);
+ rtc::scoped_ptr<Port> turnport3(CreateTurnPort(
+ kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP,
+ kTurnUdpIntAddr2));
+ turnport3->PrepareAddress();
+ ASSERT_EQ_WAIT(1U, turnport3->Candidates().size(), kTimeout);
+ EXPECT_NE(turnport3->Candidates()[0].foundation(),
+ turnport2->Candidates()[0].foundation());
+}
+
+// This test verifies the related addresses of different types of
+// ICE candiates.
+TEST_F(PortTest, TestCandidateRelatedAddress) {
+ rtc::scoped_ptr<rtc::NATServer> nat_server(
+ CreateNatServer(kNatAddr1, NAT_OPEN_CONE));
+ rtc::scoped_ptr<UDPPort> udpport(CreateUdpPort(kLocalAddr1));
+ udpport->PrepareAddress();
+ // For UDPPort, related address will be empty.
+ EXPECT_TRUE(udpport->Candidates()[0].related_address().IsNil());
+ // Testing related address for stun candidates.
+ // For stun candidate related address must be equal to the base
+ // socket address.
+ rtc::scoped_ptr<StunPort> stunport(
+ CreateStunPort(kLocalAddr1, nat_socket_factory1()));
+ stunport->PrepareAddress();
+ ASSERT_EQ_WAIT(1U, stunport->Candidates().size(), kTimeout);
+ // Check STUN candidate address.
+ EXPECT_EQ(stunport->Candidates()[0].address().ipaddr(),
+ kNatAddr1.ipaddr());
+ // Check STUN candidate related address.
+ EXPECT_EQ(stunport->Candidates()[0].related_address(),
+ stunport->GetLocalAddress());
+ // Verifying the related address for the GTURN candidates.
+ // NOTE: In case of GTURN related address will be equal to the mapped
+ // address, but address(mapped) will not be XOR.
+ rtc::scoped_ptr<RelayPort> relayport(
+ CreateGturnPort(kLocalAddr1));
+ relayport->AddServerAddress(
+ cricket::ProtocolAddress(kRelayUdpIntAddr, cricket::PROTO_UDP));
+ relayport->PrepareAddress();
+ ASSERT_EQ_WAIT(1U, relayport->Candidates().size(), kTimeout);
+ // For Gturn related address is set to "0.0.0.0:0"
+ EXPECT_EQ(rtc::SocketAddress(),
+ relayport->Candidates()[0].related_address());
+ // Verifying the related address for TURN candidate.
+ // For TURN related address must be equal to the mapped address.
+ rtc::scoped_ptr<Port> turnport(CreateTurnPort(
+ kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
+ turnport->PrepareAddress();
+ ASSERT_EQ_WAIT(1U, turnport->Candidates().size(), kTimeout);
+ EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
+ turnport->Candidates()[0].address().ipaddr());
+ EXPECT_EQ(kNatAddr1.ipaddr(),
+ turnport->Candidates()[0].related_address().ipaddr());
+}
+
+// Test priority value overflow handling when preference is set to 3.
+TEST_F(PortTest, TestCandidatePreference) {
+ cricket::Candidate cand1;
+ cand1.set_preference(3);
+ cricket::Candidate cand2;
+ cand2.set_preference(1);
+ EXPECT_TRUE(cand1.preference() > cand2.preference());
+}
+
+// Test the Connection priority is calculated correctly.
+TEST_F(PortTest, TestConnectionPriority) {
+ rtc::scoped_ptr<TestPort> lport(
+ CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
+ lport->set_type_preference(cricket::ICE_TYPE_PREFERENCE_HOST);
+ rtc::scoped_ptr<TestPort> rport(
+ CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
+ rport->set_type_preference(cricket::ICE_TYPE_PREFERENCE_RELAY);
+ lport->set_component(123);
+ lport->AddCandidateAddress(SocketAddress("192.168.1.4", 1234));
+ rport->set_component(23);
+ rport->AddCandidateAddress(SocketAddress("10.1.1.100", 1234));
+
+ EXPECT_EQ(0x7E001E85U, lport->Candidates()[0].priority());
+ EXPECT_EQ(0x2001EE9U, rport->Candidates()[0].priority());
+
+ // RFC 5245
+ // pair priority = 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0)
+ lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
+ rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
+ Connection* lconn = lport->CreateConnection(
+ rport->Candidates()[0], Port::ORIGIN_MESSAGE);
+#if defined(WEBRTC_WIN)
+ EXPECT_EQ(0x2001EE9FC003D0BU, lconn->priority());
+#else
+ EXPECT_EQ(0x2001EE9FC003D0BLLU, lconn->priority());
+#endif
+
+ lport->SetIceRole(cricket::ICEROLE_CONTROLLED);
+ rport->SetIceRole(cricket::ICEROLE_CONTROLLING);
+ Connection* rconn = rport->CreateConnection(
+ lport->Candidates()[0], Port::ORIGIN_MESSAGE);
+#if defined(WEBRTC_WIN)
+ EXPECT_EQ(0x2001EE9FC003D0AU, rconn->priority());
+#else
+ EXPECT_EQ(0x2001EE9FC003D0ALLU, rconn->priority());
+#endif
+}
+
+TEST_F(PortTest, TestWritableState) {
+ UDPPort* port1 = CreateUdpPort(kLocalAddr1);
+ UDPPort* port2 = CreateUdpPort(kLocalAddr2);
+
+ // Set up channels.
+ TestChannel ch1(port1, port2);
+ TestChannel ch2(port2, port1);
+
+ // Acquire addresses.
+ ch1.Start();
+ ch2.Start();
+ ASSERT_EQ_WAIT(1, ch1.complete_count(), kTimeout);
+ ASSERT_EQ_WAIT(1, ch2.complete_count(), kTimeout);
+
+ // Send a ping from src to dst.
+ ch1.CreateConnection();
+ ASSERT_TRUE(ch1.conn() != NULL);
+ EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
+ EXPECT_TRUE_WAIT(ch1.conn()->connected(), kTimeout); // for TCP connect
+ ch1.Ping();
+ WAIT(!ch2.remote_address().IsNil(), kTimeout);
+
+ // Data should be unsendable until the connection is accepted.
+ char data[] = "abcd";
+ int data_size = ARRAY_SIZE(data);
+ rtc::PacketOptions options;
+ EXPECT_EQ(SOCKET_ERROR, ch1.conn()->Send(data, data_size, options));
+
+ // Accept the connection to return the binding response, transition to
+ // writable, and allow data to be sent.
+ ch2.AcceptConnection();
+ EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
+ kTimeout);
+ EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
+
+ // Ask the connection to update state as if enough time has passed to lose
+ // full writability and 5 pings went unresponded to. We'll accomplish the
+ // latter by sending pings but not pumping messages.
+ for (uint32 i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
+ ch1.Ping(i);
+ }
+ uint32 unreliable_timeout_delay = CONNECTION_WRITE_CONNECT_TIMEOUT + 500u;
+ ch1.conn()->UpdateState(unreliable_timeout_delay);
+ EXPECT_EQ(Connection::STATE_WRITE_UNRELIABLE, ch1.conn()->write_state());
+
+ // Data should be able to be sent in this state.
+ EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
+
+ // And now allow the other side to process the pings and send binding
+ // responses.
+ EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
+ kTimeout);
+
+ // Wait long enough for a full timeout (past however long we've already
+ // waited).
+ for (uint32 i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
+ ch1.Ping(unreliable_timeout_delay + i);
+ }
+ ch1.conn()->UpdateState(unreliable_timeout_delay + CONNECTION_WRITE_TIMEOUT +
+ 500u);
+ EXPECT_EQ(Connection::STATE_WRITE_TIMEOUT, ch1.conn()->write_state());
+
+ // Now that the connection has completely timed out, data send should fail.
+ EXPECT_EQ(SOCKET_ERROR, ch1.conn()->Send(data, data_size, options));
+
+ ch1.Stop();
+ ch2.Stop();
+}
+
+TEST_F(PortTest, TestTimeoutForNeverWritable) {
+ UDPPort* port1 = CreateUdpPort(kLocalAddr1);
+ UDPPort* port2 = CreateUdpPort(kLocalAddr2);
+
+ // Set up channels.
+ TestChannel ch1(port1, port2);
+ TestChannel ch2(port2, port1);
+
+ // Acquire addresses.
+ ch1.Start();
+ ch2.Start();
+
+ ch1.CreateConnection();
+ ASSERT_TRUE(ch1.conn() != NULL);
+ EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
+
+ // Attempt to go directly to write timeout.
+ for (uint32 i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
+ ch1.Ping(i);
+ }
+ ch1.conn()->UpdateState(CONNECTION_WRITE_TIMEOUT + 500u);
+ EXPECT_EQ(Connection::STATE_WRITE_TIMEOUT, ch1.conn()->write_state());
+}
+
+// This test verifies the connection setup between ICEMODE_FULL
+// and ICEMODE_LITE.
+// In this test |ch1| behaves like FULL mode client and we have created
+// port which responds to the ping message just like LITE client.
+TEST_F(PortTest, TestIceLiteConnectivity) {
+ TestPort* ice_full_port = CreateTestPort(
+ kLocalAddr1, "lfrag", "lpass", cricket::ICEPROTO_RFC5245,
+ cricket::ICEROLE_CONTROLLING, kTiebreaker1);
+
+ rtc::scoped_ptr<TestPort> ice_lite_port(CreateTestPort(
+ kLocalAddr2, "rfrag", "rpass", cricket::ICEPROTO_RFC5245,
+ cricket::ICEROLE_CONTROLLED, kTiebreaker2));
+ // Setup TestChannel. This behaves like FULL mode client.
+ TestChannel ch1(ice_full_port, ice_lite_port.get());
+ ch1.SetIceMode(ICEMODE_FULL);
+
+ // Start gathering candidates.
+ ch1.Start();
+ ice_lite_port->PrepareAddress();
+
+ ASSERT_EQ_WAIT(1, ch1.complete_count(), kTimeout);
+ ASSERT_FALSE(ice_lite_port->Candidates().empty());
+
+ ch1.CreateConnection();
+ ASSERT_TRUE(ch1.conn() != NULL);
+ EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
+
+ // Send ping from full mode client.
+ // This ping must not have USE_CANDIDATE_ATTR.
+ ch1.Ping();
+
+ // Verify stun ping is without USE_CANDIDATE_ATTR. Getting message directly
+ // from port.
+ ASSERT_TRUE_WAIT(ice_full_port->last_stun_msg() != NULL, 1000);
+ IceMessage* msg = ice_full_port->last_stun_msg();
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
+
+ // Respond with a BINDING-RESPONSE from litemode client.
+ // NOTE: Ideally we should't create connection at this stage from lite
+ // port, as it should be done only after receiving ping with USE_CANDIDATE.
+ // But we need a connection to send a response message.
+ ice_lite_port->CreateConnection(
+ ice_full_port->Candidates()[0], cricket::Port::ORIGIN_MESSAGE);
+ rtc::scoped_ptr<IceMessage> request(CopyStunMessage(msg));
+ ice_lite_port->SendBindingResponse(
+ request.get(), ice_full_port->Candidates()[0].address());
+
+ // Feeding the respone message from litemode to the full mode connection.
+ ch1.conn()->OnReadPacket(ice_lite_port->last_stun_buf()->Data(),
+ ice_lite_port->last_stun_buf()->Length(),
+ rtc::PacketTime());
+ // Verifying full mode connection becomes writable from the response.
+ EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
+ kTimeout);
+ EXPECT_TRUE_WAIT(ch1.nominated(), kTimeout);
+
+ // Clear existing stun messsages. Otherwise we will process old stun
+ // message right after we send ping.
+ ice_full_port->Reset();
+ // Send ping. This must have USE_CANDIDATE_ATTR.
+ ch1.Ping();
+ ASSERT_TRUE_WAIT(ice_full_port->last_stun_msg() != NULL, 1000);
+ msg = ice_full_port->last_stun_msg();
+ EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) != NULL);
+ ch1.Stop();
+}
+
+// This test case verifies that the CONTROLLING port does not time out.
+TEST_F(PortTest, TestControllingNoTimeout) {
+ SetIceProtocolType(cricket::ICEPROTO_RFC5245);
+ UDPPort* port1 = CreateUdpPort(kLocalAddr1);
+ ConnectToSignalDestroyed(port1);
+ port1->set_timeout_delay(10); // milliseconds
+ port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
+ port1->SetIceTiebreaker(kTiebreaker1);
+
+ UDPPort* port2 = CreateUdpPort(kLocalAddr2);
+ port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
+ port2->SetIceTiebreaker(kTiebreaker2);
+
+ // Set up channels and ensure both ports will be deleted.
+ TestChannel ch1(port1, port2);
+ TestChannel ch2(port2, port1);
+
+ // Simulate a connection that succeeds, and then is destroyed.
+ ConnectAndDisconnectChannels(&ch1, &ch2);
+
+ // After the connection is destroyed, the port should not be destroyed.
+ rtc::Thread::Current()->ProcessMessages(kTimeout);
+ EXPECT_FALSE(destroyed());
+}
+
+// This test case verifies that the CONTROLLED port does time out, but only
+// after connectivity is lost.
+TEST_F(PortTest, TestControlledTimeout) {
+ SetIceProtocolType(cricket::ICEPROTO_RFC5245);
+ UDPPort* port1 = CreateUdpPort(kLocalAddr1);
+ port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
+ port1->SetIceTiebreaker(kTiebreaker1);
+
+ UDPPort* port2 = CreateUdpPort(kLocalAddr2);
+ ConnectToSignalDestroyed(port2);
+ port2->set_timeout_delay(10); // milliseconds
+ port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
+ port2->SetIceTiebreaker(kTiebreaker2);
+
+ // The connection must not be destroyed before a connection is attempted.
+ EXPECT_FALSE(destroyed());
+
+ port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
+ port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
+
+ // Set up channels and ensure both ports will be deleted.
+ TestChannel ch1(port1, port2);
+ TestChannel ch2(port2, port1);
+
+ // Simulate a connection that succeeds, and then is destroyed.
+ ConnectAndDisconnectChannels(&ch1, &ch2);
+
+ // The controlled port should be destroyed after 10 milliseconds.
+ EXPECT_TRUE_WAIT(destroyed(), kTimeout);
+}
diff --git a/p2p/base/portallocator.cc b/p2p/base/portallocator.cc
new file mode 100644
index 00000000..86133474
--- /dev/null
+++ b/p2p/base/portallocator.cc
@@ -0,0 +1,92 @@
+/*
+ * 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 "webrtc/p2p/base/portallocator.h"
+
+#include "webrtc/p2p/base/portallocatorsessionproxy.h"
+
+namespace cricket {
+
+PortAllocatorSession::PortAllocatorSession(const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd,
+ uint32 flags)
+ : content_name_(content_name),
+ component_(component),
+ flags_(flags),
+ generation_(0),
+ // If PORTALLOCATOR_ENABLE_SHARED_UFRAG flag is not enabled, ignore the
+ // incoming ufrag and pwd, which will cause each Port to generate one
+ // by itself.
+ username_(flags_ & PORTALLOCATOR_ENABLE_SHARED_UFRAG ? ice_ufrag : ""),
+ password_(flags_ & PORTALLOCATOR_ENABLE_SHARED_UFRAG ? ice_pwd : "") {
+}
+
+PortAllocator::~PortAllocator() {
+ for (SessionMuxerMap::iterator iter = muxers_.begin();
+ iter != muxers_.end(); ++iter) {
+ delete iter->second;
+ }
+}
+
+PortAllocatorSession* PortAllocator::CreateSession(
+ const std::string& sid,
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd) {
+ if (flags_ & PORTALLOCATOR_ENABLE_BUNDLE) {
+ // If we just use |sid| as key in identifying PortAllocatorSessionMuxer,
+ // ICE restart will not result in different candidates, as |sid| will
+ // be same. To yield different candiates we are using combination of
+ // |ice_ufrag| and |ice_pwd|.
+ // Ideally |ice_ufrag| and |ice_pwd| should change together, but
+ // there can be instances where only ice_pwd will be changed.
+ std::string key_str = ice_ufrag + ":" + ice_pwd;
+ PortAllocatorSessionMuxer* muxer = GetSessionMuxer(key_str);
+ if (!muxer) {
+ PortAllocatorSession* session_impl = CreateSessionInternal(
+ content_name, component, ice_ufrag, ice_pwd);
+ // Create PortAllocatorSessionMuxer object for |session_impl|.
+ muxer = new PortAllocatorSessionMuxer(session_impl);
+ muxer->SignalDestroyed.connect(
+ this, &PortAllocator::OnSessionMuxerDestroyed);
+ // Add PortAllocatorSession to the map.
+ muxers_[key_str] = muxer;
+ }
+ PortAllocatorSessionProxy* proxy =
+ new PortAllocatorSessionProxy(content_name, component, flags_);
+ muxer->RegisterSessionProxy(proxy);
+ return proxy;
+ }
+ return CreateSessionInternal(content_name, component, ice_ufrag, ice_pwd);
+}
+
+PortAllocatorSessionMuxer* PortAllocator::GetSessionMuxer(
+ const std::string& key) const {
+ SessionMuxerMap::const_iterator iter = muxers_.find(key);
+ if (iter != muxers_.end())
+ return iter->second;
+ return NULL;
+}
+
+void PortAllocator::OnSessionMuxerDestroyed(
+ PortAllocatorSessionMuxer* session) {
+ SessionMuxerMap::iterator iter;
+ for (iter = muxers_.begin(); iter != muxers_.end(); ++iter) {
+ if (iter->second == session)
+ break;
+ }
+ if (iter != muxers_.end())
+ muxers_.erase(iter);
+}
+
+} // namespace cricket
diff --git a/p2p/base/portallocator.h b/p2p/base/portallocator.h
new file mode 100644
index 00000000..65aab44c
--- /dev/null
+++ b/p2p/base/portallocator.h
@@ -0,0 +1,192 @@
+/*
+ * 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 WEBRTC_P2P_BASE_PORTALLOCATOR_H_
+#define WEBRTC_P2P_BASE_PORTALLOCATOR_H_
+
+#include <string>
+#include <vector>
+
+#include "webrtc/p2p/base/portinterface.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/proxyinfo.h"
+#include "webrtc/base/sigslot.h"
+
+namespace cricket {
+
+// PortAllocator is responsible for allocating Port types for a given
+// P2PSocket. It also handles port freeing.
+//
+// Clients can override this class to control port allocation, including
+// what kinds of ports are allocated.
+
+enum {
+ PORTALLOCATOR_DISABLE_UDP = 0x01,
+ PORTALLOCATOR_DISABLE_STUN = 0x02,
+ PORTALLOCATOR_DISABLE_RELAY = 0x04,
+ PORTALLOCATOR_DISABLE_TCP = 0x08,
+ PORTALLOCATOR_ENABLE_SHAKER = 0x10,
+ PORTALLOCATOR_ENABLE_BUNDLE = 0x20,
+ PORTALLOCATOR_ENABLE_IPV6 = 0x40,
+ PORTALLOCATOR_ENABLE_SHARED_UFRAG = 0x80,
+ PORTALLOCATOR_ENABLE_SHARED_SOCKET = 0x100,
+ PORTALLOCATOR_ENABLE_STUN_RETRANSMIT_ATTRIBUTE = 0x200,
+};
+
+const uint32 kDefaultPortAllocatorFlags = 0;
+
+const uint32 kDefaultStepDelay = 1000; // 1 sec step delay.
+// As per RFC 5245 Appendix B.1, STUN transactions need to be paced at certain
+// internal. Less than 20ms is not acceptable. We choose 50ms as our default.
+const uint32 kMinimumStepDelay = 50;
+
+// CF = CANDIDATE FILTER
+enum {
+ CF_NONE = 0x0,
+ CF_HOST = 0x1,
+ CF_REFLEXIVE = 0x2,
+ CF_RELAY = 0x4,
+ CF_ALL = 0x7,
+};
+
+class PortAllocatorSessionMuxer;
+
+class PortAllocatorSession : public sigslot::has_slots<> {
+ public:
+ // Content name passed in mostly for logging and debugging.
+ // TODO(mallinath) - Change username and password to ice_ufrag and ice_pwd.
+ PortAllocatorSession(const std::string& content_name,
+ int component,
+ const std::string& username,
+ const std::string& password,
+ uint32 flags);
+
+ // Subclasses should clean up any ports created.
+ virtual ~PortAllocatorSession() {}
+
+ uint32 flags() const { return flags_; }
+ void set_flags(uint32 flags) { flags_ = flags; }
+ std::string content_name() const { return content_name_; }
+ int component() const { return component_; }
+
+ // Starts gathering STUN and Relay configurations.
+ virtual void StartGettingPorts() = 0;
+ virtual void StopGettingPorts() = 0;
+ virtual bool IsGettingPorts() = 0;
+
+ sigslot::signal2<PortAllocatorSession*, PortInterface*> SignalPortReady;
+ sigslot::signal2<PortAllocatorSession*,
+ const std::vector<Candidate>&> SignalCandidatesReady;
+ sigslot::signal1<PortAllocatorSession*> SignalCandidatesAllocationDone;
+
+ virtual uint32 generation() { return generation_; }
+ virtual void set_generation(uint32 generation) { generation_ = generation; }
+ sigslot::signal1<PortAllocatorSession*> SignalDestroyed;
+
+ protected:
+ const std::string& username() const { return username_; }
+ const std::string& password() const { return password_; }
+
+ std::string content_name_;
+ int component_;
+
+ private:
+ uint32 flags_;
+ uint32 generation_;
+ std::string username_;
+ std::string password_;
+};
+
+class PortAllocator : public sigslot::has_slots<> {
+ public:
+ PortAllocator() :
+ flags_(kDefaultPortAllocatorFlags),
+ min_port_(0),
+ max_port_(0),
+ step_delay_(kDefaultStepDelay),
+ allow_tcp_listen_(true),
+ candidate_filter_(CF_ALL) {
+ // This will allow us to have old behavior on non webrtc clients.
+ }
+ virtual ~PortAllocator();
+
+ PortAllocatorSession* CreateSession(
+ const std::string& sid,
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd);
+
+ PortAllocatorSessionMuxer* GetSessionMuxer(const std::string& key) const;
+ void OnSessionMuxerDestroyed(PortAllocatorSessionMuxer* session);
+
+ uint32 flags() const { return flags_; }
+ void set_flags(uint32 flags) { flags_ = flags; }
+
+ const std::string& user_agent() const { return agent_; }
+ const rtc::ProxyInfo& proxy() const { return proxy_; }
+ void set_proxy(const std::string& agent, const rtc::ProxyInfo& proxy) {
+ agent_ = agent;
+ proxy_ = proxy;
+ }
+
+ // Gets/Sets the port range to use when choosing client ports.
+ int min_port() const { return min_port_; }
+ int max_port() const { return max_port_; }
+ bool SetPortRange(int min_port, int max_port) {
+ if (min_port > max_port) {
+ return false;
+ }
+
+ min_port_ = min_port;
+ max_port_ = max_port;
+ return true;
+ }
+
+ uint32 step_delay() const { return step_delay_; }
+ void set_step_delay(uint32 delay) {
+ step_delay_ = delay;
+ }
+
+ bool allow_tcp_listen() const { return allow_tcp_listen_; }
+ void set_allow_tcp_listen(bool allow_tcp_listen) {
+ allow_tcp_listen_ = allow_tcp_listen;
+ }
+
+ uint32 candidate_filter() { return candidate_filter_; }
+ bool set_candidate_filter(uint32 filter) {
+ // TODO(mallinath) - Do transition check?
+ candidate_filter_ = filter;
+ return true;
+ }
+
+ protected:
+ virtual PortAllocatorSession* CreateSessionInternal(
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd) = 0;
+
+ typedef std::map<std::string, PortAllocatorSessionMuxer*> SessionMuxerMap;
+
+ uint32 flags_;
+ std::string agent_;
+ rtc::ProxyInfo proxy_;
+ int min_port_;
+ int max_port_;
+ uint32 step_delay_;
+ SessionMuxerMap muxers_;
+ bool allow_tcp_listen_;
+ uint32 candidate_filter_;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_PORTALLOCATOR_H_
diff --git a/p2p/base/portallocatorsessionproxy.cc b/p2p/base/portallocatorsessionproxy.cc
new file mode 100644
index 00000000..f5ce9a4a
--- /dev/null
+++ b/p2p/base/portallocatorsessionproxy.cc
@@ -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.
+ */
+
+#include "webrtc/p2p/base/portallocatorsessionproxy.h"
+
+#include "webrtc/p2p/base/portallocator.h"
+#include "webrtc/p2p/base/portproxy.h"
+#include "webrtc/base/thread.h"
+
+namespace cricket {
+
+enum {
+ MSG_SEND_ALLOCATION_DONE = 1,
+ MSG_SEND_ALLOCATED_PORTS,
+};
+
+typedef rtc::TypedMessageData<PortAllocatorSessionProxy*> ProxyObjData;
+
+PortAllocatorSessionMuxer::PortAllocatorSessionMuxer(
+ PortAllocatorSession* session)
+ : worker_thread_(rtc::Thread::Current()),
+ session_(session),
+ candidate_done_signal_received_(false) {
+ session_->SignalPortReady.connect(
+ this, &PortAllocatorSessionMuxer::OnPortReady);
+ session_->SignalCandidatesAllocationDone.connect(
+ this, &PortAllocatorSessionMuxer::OnCandidatesAllocationDone);
+}
+
+PortAllocatorSessionMuxer::~PortAllocatorSessionMuxer() {
+ for (size_t i = 0; i < session_proxies_.size(); ++i)
+ delete session_proxies_[i];
+
+ SignalDestroyed(this);
+}
+
+void PortAllocatorSessionMuxer::RegisterSessionProxy(
+ PortAllocatorSessionProxy* session_proxy) {
+ session_proxies_.push_back(session_proxy);
+ session_proxy->SignalDestroyed.connect(
+ this, &PortAllocatorSessionMuxer::OnSessionProxyDestroyed);
+ session_proxy->set_impl(session_.get());
+
+ // Populate new proxy session with the information available in the actual
+ // implementation.
+ if (!ports_.empty()) {
+ worker_thread_->Post(
+ this, MSG_SEND_ALLOCATED_PORTS, new ProxyObjData(session_proxy));
+ }
+
+ if (candidate_done_signal_received_) {
+ worker_thread_->Post(
+ this, MSG_SEND_ALLOCATION_DONE, new ProxyObjData(session_proxy));
+ }
+}
+
+void PortAllocatorSessionMuxer::OnCandidatesAllocationDone(
+ PortAllocatorSession* session) {
+ candidate_done_signal_received_ = true;
+}
+
+void PortAllocatorSessionMuxer::OnPortReady(PortAllocatorSession* session,
+ PortInterface* port) {
+ ASSERT(session == session_.get());
+ ports_.push_back(port);
+ port->SignalDestroyed.connect(
+ this, &PortAllocatorSessionMuxer::OnPortDestroyed);
+}
+
+void PortAllocatorSessionMuxer::OnPortDestroyed(PortInterface* port) {
+ std::vector<PortInterface*>::iterator it =
+ std::find(ports_.begin(), ports_.end(), port);
+ if (it != ports_.end())
+ ports_.erase(it);
+}
+
+void PortAllocatorSessionMuxer::OnSessionProxyDestroyed(
+ PortAllocatorSession* proxy) {
+
+ std::vector<PortAllocatorSessionProxy*>::iterator it =
+ std::find(session_proxies_.begin(), session_proxies_.end(), proxy);
+ if (it != session_proxies_.end()) {
+ session_proxies_.erase(it);
+ }
+
+ if (session_proxies_.empty()) {
+ // Destroy PortAllocatorSession and its associated muxer object if all
+ // proxies belonging to this session are already destroyed.
+ delete this;
+ }
+}
+
+void PortAllocatorSessionMuxer::OnMessage(rtc::Message *pmsg) {
+ ProxyObjData* proxy = static_cast<ProxyObjData*>(pmsg->pdata);
+ switch (pmsg->message_id) {
+ case MSG_SEND_ALLOCATION_DONE:
+ SendAllocationDone_w(proxy->data());
+ delete proxy;
+ break;
+ case MSG_SEND_ALLOCATED_PORTS:
+ SendAllocatedPorts_w(proxy->data());
+ delete proxy;
+ break;
+ default:
+ ASSERT(false);
+ break;
+ }
+}
+
+void PortAllocatorSessionMuxer::SendAllocationDone_w(
+ PortAllocatorSessionProxy* proxy) {
+ std::vector<PortAllocatorSessionProxy*>::iterator iter =
+ std::find(session_proxies_.begin(), session_proxies_.end(), proxy);
+ if (iter != session_proxies_.end()) {
+ proxy->OnCandidatesAllocationDone(session_.get());
+ }
+}
+
+void PortAllocatorSessionMuxer::SendAllocatedPorts_w(
+ PortAllocatorSessionProxy* proxy) {
+ std::vector<PortAllocatorSessionProxy*>::iterator iter =
+ std::find(session_proxies_.begin(), session_proxies_.end(), proxy);
+ if (iter != session_proxies_.end()) {
+ for (size_t i = 0; i < ports_.size(); ++i) {
+ PortInterface* port = ports_[i];
+ proxy->OnPortReady(session_.get(), port);
+ // If port already has candidates, send this to the clients of proxy
+ // session. This can happen if proxy is created later than the actual
+ // implementation.
+ if (!port->Candidates().empty()) {
+ proxy->OnCandidatesReady(session_.get(), port->Candidates());
+ }
+ }
+ }
+}
+
+PortAllocatorSessionProxy::~PortAllocatorSessionProxy() {
+ std::map<PortInterface*, PortProxy*>::iterator it;
+ for (it = proxy_ports_.begin(); it != proxy_ports_.end(); it++)
+ delete it->second;
+
+ SignalDestroyed(this);
+}
+
+void PortAllocatorSessionProxy::set_impl(
+ PortAllocatorSession* session) {
+ impl_ = session;
+
+ impl_->SignalCandidatesReady.connect(
+ this, &PortAllocatorSessionProxy::OnCandidatesReady);
+ impl_->SignalPortReady.connect(
+ this, &PortAllocatorSessionProxy::OnPortReady);
+ impl_->SignalCandidatesAllocationDone.connect(
+ this, &PortAllocatorSessionProxy::OnCandidatesAllocationDone);
+}
+
+void PortAllocatorSessionProxy::StartGettingPorts() {
+ ASSERT(impl_ != NULL);
+ // Since all proxies share a common PortAllocatorSession, this check will
+ // prohibit sending multiple STUN ping messages to the stun server, which
+ // is a problem on Chrome. GetInitialPorts() and StartGetAllPorts() called
+ // from the worker thread and are called together from TransportChannel,
+ // checking for IsGettingAllPorts() for GetInitialPorts() will not be a
+ // problem.
+ if (!impl_->IsGettingPorts()) {
+ impl_->StartGettingPorts();
+ }
+}
+
+void PortAllocatorSessionProxy::StopGettingPorts() {
+ ASSERT(impl_ != NULL);
+ if (impl_->IsGettingPorts()) {
+ impl_->StopGettingPorts();
+ }
+}
+
+bool PortAllocatorSessionProxy::IsGettingPorts() {
+ ASSERT(impl_ != NULL);
+ return impl_->IsGettingPorts();
+}
+
+void PortAllocatorSessionProxy::OnPortReady(PortAllocatorSession* session,
+ PortInterface* port) {
+ ASSERT(session == impl_);
+
+ PortProxy* proxy_port = new PortProxy();
+ proxy_port->set_impl(port);
+ proxy_ports_[port] = proxy_port;
+ SignalPortReady(this, proxy_port);
+}
+
+void PortAllocatorSessionProxy::OnCandidatesReady(
+ PortAllocatorSession* session,
+ const std::vector<Candidate>& candidates) {
+ ASSERT(session == impl_);
+
+ // Since all proxy sessions share a common PortAllocatorSession,
+ // all Candidates will have name associated with the common PAS.
+ // Change Candidate name with the PortAllocatorSessionProxy name.
+ std::vector<Candidate> our_candidates;
+ for (size_t i = 0; i < candidates.size(); ++i) {
+ Candidate new_local_candidate = candidates[i];
+ new_local_candidate.set_component(component_);
+ our_candidates.push_back(new_local_candidate);
+ }
+ SignalCandidatesReady(this, our_candidates);
+}
+
+void PortAllocatorSessionProxy::OnCandidatesAllocationDone(
+ PortAllocatorSession* session) {
+ ASSERT(session == impl_);
+ SignalCandidatesAllocationDone(this);
+}
+
+} // namespace cricket
diff --git a/p2p/base/portallocatorsessionproxy.h b/p2p/base/portallocatorsessionproxy.h
new file mode 100644
index 00000000..94ae19d9
--- /dev/null
+++ b/p2p/base/portallocatorsessionproxy.h
@@ -0,0 +1,106 @@
+/*
+ * 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 WEBRTC_P2P_BASE_PORTALLOCATORSESSIONPROXY_H_
+#define WEBRTC_P2P_BASE_PORTALLOCATORSESSIONPROXY_H_
+
+#include <string>
+
+#include "webrtc/p2p/base/candidate.h"
+#include "webrtc/p2p/base/portallocator.h"
+
+namespace cricket {
+class PortAllocator;
+class PortAllocatorSessionProxy;
+class PortProxy;
+
+// This class maintains the list of cricket::Port* objects. Ports will be
+// deleted upon receiving SignalDestroyed signal. This class is used when
+// PORTALLOCATOR_ENABLE_BUNDLE flag is set.
+
+class PortAllocatorSessionMuxer : public rtc::MessageHandler,
+ public sigslot::has_slots<> {
+ public:
+ explicit PortAllocatorSessionMuxer(PortAllocatorSession* session);
+ virtual ~PortAllocatorSessionMuxer();
+
+ void RegisterSessionProxy(PortAllocatorSessionProxy* session_proxy);
+
+ void OnPortReady(PortAllocatorSession* session, PortInterface* port);
+ void OnPortDestroyed(PortInterface* port);
+ void OnCandidatesAllocationDone(PortAllocatorSession* session);
+
+ const std::vector<PortInterface*>& ports() { return ports_; }
+
+ sigslot::signal1<PortAllocatorSessionMuxer*> SignalDestroyed;
+
+ private:
+ virtual void OnMessage(rtc::Message *pmsg);
+ void OnSessionProxyDestroyed(PortAllocatorSession* proxy);
+ void SendAllocationDone_w(PortAllocatorSessionProxy* proxy);
+ void SendAllocatedPorts_w(PortAllocatorSessionProxy* proxy);
+
+ // Port will be deleted when SignalDestroyed received, otherwise delete
+ // happens when PortAllocatorSession dtor is called.
+ rtc::Thread* worker_thread_;
+ std::vector<PortInterface*> ports_;
+ rtc::scoped_ptr<PortAllocatorSession> session_;
+ std::vector<PortAllocatorSessionProxy*> session_proxies_;
+ bool candidate_done_signal_received_;
+};
+
+class PortAllocatorSessionProxy : public PortAllocatorSession {
+ public:
+ PortAllocatorSessionProxy(const std::string& content_name,
+ int component,
+ uint32 flags)
+ // Use empty string as the ufrag and pwd because the proxy always uses
+ // the ufrag and pwd from the underlying implementation.
+ : PortAllocatorSession(content_name, component, "", "", flags),
+ impl_(NULL) {
+ }
+
+ virtual ~PortAllocatorSessionProxy();
+
+ PortAllocatorSession* impl() { return impl_; }
+ void set_impl(PortAllocatorSession* session);
+
+ // Forwards call to the actual PortAllocatorSession.
+ virtual void StartGettingPorts();
+ virtual void StopGettingPorts();
+ virtual bool IsGettingPorts();
+
+ virtual void set_generation(uint32 generation) {
+ ASSERT(impl_ != NULL);
+ impl_->set_generation(generation);
+ }
+
+ virtual uint32 generation() {
+ ASSERT(impl_ != NULL);
+ return impl_->generation();
+ }
+
+ private:
+ void OnPortReady(PortAllocatorSession* session, PortInterface* port);
+ void OnCandidatesReady(PortAllocatorSession* session,
+ const std::vector<Candidate>& candidates);
+ void OnPortDestroyed(PortInterface* port);
+ void OnCandidatesAllocationDone(PortAllocatorSession* session);
+
+ // This is the actual PortAllocatorSession, owned by PortAllocator.
+ PortAllocatorSession* impl_;
+ std::map<PortInterface*, PortProxy*> proxy_ports_;
+
+ friend class PortAllocatorSessionMuxer;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_PORTALLOCATORSESSIONPROXY_H_
diff --git a/p2p/base/portallocatorsessionproxy_unittest.cc b/p2p/base/portallocatorsessionproxy_unittest.cc
new file mode 100644
index 00000000..61a9e989
--- /dev/null
+++ b/p2p/base/portallocatorsessionproxy_unittest.cc
@@ -0,0 +1,146 @@
+/*
+ * 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.
+ */
+
+#include <vector>
+
+#include "webrtc/p2p/base/basicpacketsocketfactory.h"
+#include "webrtc/p2p/base/portallocatorsessionproxy.h"
+#include "webrtc/p2p/client/basicportallocator.h"
+#include "webrtc/p2p/client/fakeportallocator.h"
+#include "webrtc/base/fakenetwork.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/thread.h"
+
+using cricket::Candidate;
+using cricket::PortAllocatorSession;
+using cricket::PortAllocatorSessionMuxer;
+using cricket::PortAllocatorSessionProxy;
+
+// Based on ICE_UFRAG_LENGTH
+static const char kIceUfrag0[] = "TESTICEUFRAG0000";
+// Based on ICE_PWD_LENGTH
+static const char kIcePwd0[] = "TESTICEPWD00000000000000";
+
+class TestSessionChannel : public sigslot::has_slots<> {
+ public:
+ explicit TestSessionChannel(PortAllocatorSessionProxy* proxy)
+ : proxy_session_(proxy),
+ candidates_count_(0),
+ allocation_complete_(false),
+ ports_count_(0) {
+ proxy_session_->SignalCandidatesAllocationDone.connect(
+ this, &TestSessionChannel::OnCandidatesAllocationDone);
+ proxy_session_->SignalCandidatesReady.connect(
+ this, &TestSessionChannel::OnCandidatesReady);
+ proxy_session_->SignalPortReady.connect(
+ this, &TestSessionChannel::OnPortReady);
+ }
+ virtual ~TestSessionChannel() {
+ delete proxy_session_;
+ }
+ void OnCandidatesReady(PortAllocatorSession* session,
+ const std::vector<Candidate>& candidates) {
+ EXPECT_EQ(proxy_session_, session);
+ candidates_count_ += static_cast<int>(candidates.size());
+ }
+ void OnCandidatesAllocationDone(PortAllocatorSession* session) {
+ EXPECT_EQ(proxy_session_, session);
+ allocation_complete_ = true;
+ }
+ void OnPortReady(PortAllocatorSession* session,
+ cricket::PortInterface* port) {
+ EXPECT_EQ(proxy_session_, session);
+ ++ports_count_;
+ }
+ int candidates_count() { return candidates_count_; }
+ bool allocation_complete() { return allocation_complete_; }
+ int ports_count() { return ports_count_; }
+
+ void StartGettingPorts() {
+ proxy_session_->StartGettingPorts();
+ }
+
+ void StopGettingPorts() {
+ proxy_session_->StopGettingPorts();
+ }
+
+ bool IsGettingPorts() {
+ return proxy_session_->IsGettingPorts();
+ }
+
+ private:
+ PortAllocatorSessionProxy* proxy_session_;
+ int candidates_count_;
+ bool allocation_complete_;
+ int ports_count_;
+};
+
+class PortAllocatorSessionProxyTest : public testing::Test {
+ public:
+ PortAllocatorSessionProxyTest()
+ : socket_factory_(rtc::Thread::Current()),
+ allocator_(rtc::Thread::Current(), NULL),
+ session_(new cricket::FakePortAllocatorSession(
+ rtc::Thread::Current(), &socket_factory_,
+ "test content", 1,
+ kIceUfrag0, kIcePwd0)),
+ session_muxer_(new PortAllocatorSessionMuxer(session_)) {
+ }
+ virtual ~PortAllocatorSessionProxyTest() {}
+ void RegisterSessionProxy(PortAllocatorSessionProxy* proxy) {
+ session_muxer_->RegisterSessionProxy(proxy);
+ }
+
+ TestSessionChannel* CreateChannel() {
+ PortAllocatorSessionProxy* proxy =
+ new PortAllocatorSessionProxy("test content", 1, 0);
+ TestSessionChannel* channel = new TestSessionChannel(proxy);
+ session_muxer_->RegisterSessionProxy(proxy);
+ channel->StartGettingPorts();
+ return channel;
+ }
+
+ protected:
+ rtc::BasicPacketSocketFactory socket_factory_;
+ cricket::FakePortAllocator allocator_;
+ cricket::FakePortAllocatorSession* session_;
+ // Muxer object will be delete itself after all registered session proxies
+ // are deleted.
+ PortAllocatorSessionMuxer* session_muxer_;
+};
+
+TEST_F(PortAllocatorSessionProxyTest, TestBasic) {
+ TestSessionChannel* channel = CreateChannel();
+ EXPECT_EQ_WAIT(1, channel->candidates_count(), 1000);
+ EXPECT_EQ(1, channel->ports_count());
+ EXPECT_TRUE(channel->allocation_complete());
+ delete channel;
+}
+
+TEST_F(PortAllocatorSessionProxyTest, TestLateBinding) {
+ TestSessionChannel* channel1 = CreateChannel();
+ EXPECT_EQ_WAIT(1, channel1->candidates_count(), 1000);
+ EXPECT_EQ(1, channel1->ports_count());
+ EXPECT_TRUE(channel1->allocation_complete());
+ EXPECT_EQ(1, session_->port_config_count());
+ // Creating another PortAllocatorSessionProxy and it also should receive
+ // already happened events.
+ PortAllocatorSessionProxy* proxy =
+ new PortAllocatorSessionProxy("test content", 2, 0);
+ TestSessionChannel* channel2 = new TestSessionChannel(proxy);
+ session_muxer_->RegisterSessionProxy(proxy);
+ EXPECT_TRUE(channel2->IsGettingPorts());
+ EXPECT_EQ_WAIT(1, channel2->candidates_count(), 1000);
+ EXPECT_EQ(1, channel2->ports_count());
+ EXPECT_TRUE_WAIT(channel2->allocation_complete(), 1000);
+ EXPECT_EQ(1, session_->port_config_count());
+ delete channel1;
+ delete channel2;
+}
diff --git a/p2p/base/portinterface.h b/p2p/base/portinterface.h
new file mode 100644
index 00000000..ee6835eb
--- /dev/null
+++ b/p2p/base/portinterface.h
@@ -0,0 +1,126 @@
+/*
+ * 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 WEBRTC_P2P_BASE_PORTINTERFACE_H_
+#define WEBRTC_P2P_BASE_PORTINTERFACE_H_
+
+#include <string>
+
+#include "webrtc/p2p/base/transport.h"
+#include "webrtc/base/socketaddress.h"
+
+namespace rtc {
+class Network;
+struct PacketOptions;
+}
+
+namespace cricket {
+class Connection;
+class IceMessage;
+class StunMessage;
+
+enum ProtocolType {
+ PROTO_UDP,
+ PROTO_TCP,
+ PROTO_SSLTCP,
+ PROTO_LAST = PROTO_SSLTCP
+};
+
+// Defines the interface for a port, which represents a local communication
+// mechanism that can be used to create connections to similar mechanisms of
+// the other client. Various types of ports will implement this interface.
+class PortInterface {
+ public:
+ virtual ~PortInterface() {}
+
+ virtual const std::string& Type() const = 0;
+ virtual rtc::Network* Network() const = 0;
+
+ virtual void SetIceProtocolType(IceProtocolType protocol) = 0;
+ virtual IceProtocolType IceProtocol() const = 0;
+
+ // Methods to set/get ICE role and tiebreaker values.
+ virtual void SetIceRole(IceRole role) = 0;
+ virtual IceRole GetIceRole() const = 0;
+
+ virtual void SetIceTiebreaker(uint64 tiebreaker) = 0;
+ virtual uint64 IceTiebreaker() const = 0;
+
+ virtual bool SharedSocket() const = 0;
+
+ // PrepareAddress will attempt to get an address for this port that other
+ // clients can send to. It may take some time before the address is ready.
+ // Once it is ready, we will send SignalAddressReady. If errors are
+ // preventing the port from getting an address, it may send
+ // SignalAddressError.
+ virtual void PrepareAddress() = 0;
+
+ // Returns the connection to the given address or NULL if none exists.
+ virtual Connection* GetConnection(
+ const rtc::SocketAddress& remote_addr) = 0;
+
+ // Creates a new connection to the given address.
+ enum CandidateOrigin { ORIGIN_THIS_PORT, ORIGIN_OTHER_PORT, ORIGIN_MESSAGE };
+ virtual Connection* CreateConnection(
+ const Candidate& remote_candidate, CandidateOrigin origin) = 0;
+
+ // Functions on the underlying socket(s).
+ virtual int SetOption(rtc::Socket::Option opt, int value) = 0;
+ virtual int GetOption(rtc::Socket::Option opt, int* value) = 0;
+ virtual int GetError() = 0;
+
+ virtual const std::vector<Candidate>& Candidates() const = 0;
+
+ // Sends the given packet to the given address, provided that the address is
+ // that of a connection or an address that has sent to us already.
+ virtual int SendTo(const void* data, size_t size,
+ const rtc::SocketAddress& addr,
+ const rtc::PacketOptions& options, bool payload) = 0;
+
+ // Indicates that we received a successful STUN binding request from an
+ // address that doesn't correspond to any current connection. To turn this
+ // into a real connection, call CreateConnection.
+ sigslot::signal6<PortInterface*, const rtc::SocketAddress&,
+ ProtocolType, IceMessage*, const std::string&,
+ bool> SignalUnknownAddress;
+
+ // Sends a response message (normal or error) to the given request. One of
+ // these methods should be called as a response to SignalUnknownAddress.
+ // NOTE: You MUST call CreateConnection BEFORE SendBindingResponse.
+ virtual void SendBindingResponse(StunMessage* request,
+ const rtc::SocketAddress& addr) = 0;
+ virtual void SendBindingErrorResponse(
+ StunMessage* request, const rtc::SocketAddress& addr,
+ int error_code, const std::string& reason) = 0;
+
+ // Signaled when this port decides to delete itself because it no longer has
+ // any usefulness.
+ sigslot::signal1<PortInterface*> SignalDestroyed;
+
+ // Signaled when Port discovers ice role conflict with the peer.
+ sigslot::signal1<PortInterface*> SignalRoleConflict;
+
+ // Normally, packets arrive through a connection (or they result signaling of
+ // unknown address). Calling this method turns off delivery of packets
+ // through their respective connection and instead delivers every packet
+ // through this port.
+ virtual void EnablePortPackets() = 0;
+ sigslot::signal4<PortInterface*, const char*, size_t,
+ const rtc::SocketAddress&> SignalReadPacket;
+
+ virtual std::string ToString() const = 0;
+
+ protected:
+ PortInterface() {}
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_PORTINTERFACE_H_
diff --git a/p2p/base/portproxy.cc b/p2p/base/portproxy.cc
new file mode 100644
index 00000000..e28af279
--- /dev/null
+++ b/p2p/base/portproxy.cc
@@ -0,0 +1,163 @@
+/*
+ * 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 "webrtc/p2p/base/portproxy.h"
+
+namespace cricket {
+
+void PortProxy::set_impl(PortInterface* port) {
+ impl_ = port;
+ impl_->SignalUnknownAddress.connect(
+ this, &PortProxy::OnUnknownAddress);
+ impl_->SignalDestroyed.connect(this, &PortProxy::OnPortDestroyed);
+ impl_->SignalRoleConflict.connect(this, &PortProxy::OnRoleConflict);
+}
+
+const std::string& PortProxy::Type() const {
+ ASSERT(impl_ != NULL);
+ return impl_->Type();
+}
+
+rtc::Network* PortProxy::Network() const {
+ ASSERT(impl_ != NULL);
+ return impl_->Network();
+}
+
+void PortProxy::SetIceProtocolType(IceProtocolType protocol) {
+ ASSERT(impl_ != NULL);
+ impl_->SetIceProtocolType(protocol);
+}
+
+IceProtocolType PortProxy::IceProtocol() const {
+ ASSERT(impl_ != NULL);
+ return impl_->IceProtocol();
+}
+
+// Methods to set/get ICE role and tiebreaker values.
+void PortProxy::SetIceRole(IceRole role) {
+ ASSERT(impl_ != NULL);
+ impl_->SetIceRole(role);
+}
+
+IceRole PortProxy::GetIceRole() const {
+ ASSERT(impl_ != NULL);
+ return impl_->GetIceRole();
+}
+
+void PortProxy::SetIceTiebreaker(uint64 tiebreaker) {
+ ASSERT(impl_ != NULL);
+ impl_->SetIceTiebreaker(tiebreaker);
+}
+
+uint64 PortProxy::IceTiebreaker() const {
+ ASSERT(impl_ != NULL);
+ return impl_->IceTiebreaker();
+}
+
+bool PortProxy::SharedSocket() const {
+ ASSERT(impl_ != NULL);
+ return impl_->SharedSocket();
+}
+
+void PortProxy::PrepareAddress() {
+ ASSERT(impl_ != NULL);
+ impl_->PrepareAddress();
+}
+
+Connection* PortProxy::CreateConnection(const Candidate& remote_candidate,
+ CandidateOrigin origin) {
+ ASSERT(impl_ != NULL);
+ return impl_->CreateConnection(remote_candidate, origin);
+}
+
+int PortProxy::SendTo(const void* data,
+ size_t size,
+ const rtc::SocketAddress& addr,
+ const rtc::PacketOptions& options,
+ bool payload) {
+ ASSERT(impl_ != NULL);
+ return impl_->SendTo(data, size, addr, options, payload);
+}
+
+int PortProxy::SetOption(rtc::Socket::Option opt,
+ int value) {
+ ASSERT(impl_ != NULL);
+ return impl_->SetOption(opt, value);
+}
+
+int PortProxy::GetOption(rtc::Socket::Option opt,
+ int* value) {
+ ASSERT(impl_ != NULL);
+ return impl_->GetOption(opt, value);
+}
+
+int PortProxy::GetError() {
+ ASSERT(impl_ != NULL);
+ return impl_->GetError();
+}
+
+const std::vector<Candidate>& PortProxy::Candidates() const {
+ ASSERT(impl_ != NULL);
+ return impl_->Candidates();
+}
+
+void PortProxy::SendBindingResponse(
+ StunMessage* request, const rtc::SocketAddress& addr) {
+ ASSERT(impl_ != NULL);
+ impl_->SendBindingResponse(request, addr);
+}
+
+Connection* PortProxy::GetConnection(
+ const rtc::SocketAddress& remote_addr) {
+ ASSERT(impl_ != NULL);
+ return impl_->GetConnection(remote_addr);
+}
+
+void PortProxy::SendBindingErrorResponse(
+ StunMessage* request, const rtc::SocketAddress& addr,
+ int error_code, const std::string& reason) {
+ ASSERT(impl_ != NULL);
+ impl_->SendBindingErrorResponse(request, addr, error_code, reason);
+}
+
+void PortProxy::EnablePortPackets() {
+ ASSERT(impl_ != NULL);
+ impl_->EnablePortPackets();
+}
+
+std::string PortProxy::ToString() const {
+ ASSERT(impl_ != NULL);
+ return impl_->ToString();
+}
+
+void PortProxy::OnUnknownAddress(
+ PortInterface *port,
+ const rtc::SocketAddress &addr,
+ ProtocolType proto,
+ IceMessage *stun_msg,
+ const std::string &remote_username,
+ bool port_muxed) {
+ ASSERT(port == impl_);
+ ASSERT(!port_muxed);
+ SignalUnknownAddress(this, addr, proto, stun_msg, remote_username, true);
+}
+
+void PortProxy::OnRoleConflict(PortInterface* port) {
+ ASSERT(port == impl_);
+ SignalRoleConflict(this);
+}
+
+void PortProxy::OnPortDestroyed(PortInterface* port) {
+ ASSERT(port == impl_);
+ // |port| will be destroyed in PortAllocatorSessionMuxer.
+ SignalDestroyed(this);
+}
+
+} // namespace cricket
diff --git a/p2p/base/portproxy.h b/p2p/base/portproxy.h
new file mode 100644
index 00000000..79507fea
--- /dev/null
+++ b/p2p/base/portproxy.h
@@ -0,0 +1,87 @@
+/*
+ * 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 WEBRTC_P2P_BASE_PORTPROXY_H_
+#define WEBRTC_P2P_BASE_PORTPROXY_H_
+
+#include "webrtc/p2p/base/portinterface.h"
+#include "webrtc/base/sigslot.h"
+
+namespace rtc {
+class Network;
+}
+
+namespace cricket {
+
+class PortProxy : public PortInterface, public sigslot::has_slots<> {
+ public:
+ PortProxy() {}
+ virtual ~PortProxy() {}
+
+ PortInterface* impl() { return impl_; }
+ void set_impl(PortInterface* port);
+
+ virtual const std::string& Type() const;
+ virtual rtc::Network* Network() const;
+
+ virtual void SetIceProtocolType(IceProtocolType protocol);
+ virtual IceProtocolType IceProtocol() const;
+
+ // Methods to set/get ICE role and tiebreaker values.
+ virtual void SetIceRole(IceRole role);
+ virtual IceRole GetIceRole() const;
+
+ virtual void SetIceTiebreaker(uint64 tiebreaker);
+ virtual uint64 IceTiebreaker() const;
+
+ virtual bool SharedSocket() const;
+
+ // Forwards call to the actual Port.
+ virtual void PrepareAddress();
+ virtual Connection* CreateConnection(const Candidate& remote_candidate,
+ CandidateOrigin origin);
+ virtual Connection* GetConnection(
+ const rtc::SocketAddress& remote_addr);
+
+ virtual int SendTo(const void* data, size_t size,
+ const rtc::SocketAddress& addr,
+ const rtc::PacketOptions& options,
+ bool payload);
+ virtual int SetOption(rtc::Socket::Option opt, int value);
+ virtual int GetOption(rtc::Socket::Option opt, int* value);
+ virtual int GetError();
+
+ virtual const std::vector<Candidate>& Candidates() const;
+
+ virtual void SendBindingResponse(StunMessage* request,
+ const rtc::SocketAddress& addr);
+ virtual void SendBindingErrorResponse(
+ StunMessage* request, const rtc::SocketAddress& addr,
+ int error_code, const std::string& reason);
+
+ virtual void EnablePortPackets();
+ virtual std::string ToString() const;
+
+ private:
+ void OnUnknownAddress(PortInterface *port,
+ const rtc::SocketAddress &addr,
+ ProtocolType proto,
+ IceMessage *stun_msg,
+ const std::string &remote_username,
+ bool port_muxed);
+ void OnRoleConflict(PortInterface* port);
+ void OnPortDestroyed(PortInterface* port);
+
+ PortInterface* impl_;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_PORTPROXY_H_
diff --git a/p2p/base/pseudotcp.cc b/p2p/base/pseudotcp.cc
new file mode 100644
index 00000000..0dfe7d82
--- /dev/null
+++ b/p2p/base/pseudotcp.cc
@@ -0,0 +1,1274 @@
+/*
+ * 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 "webrtc/p2p/base/pseudotcp.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <set>
+
+#include "webrtc/base/basictypes.h"
+#include "webrtc/base/bytebuffer.h"
+#include "webrtc/base/byteorder.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/socket.h"
+#include "webrtc/base/stringutils.h"
+#include "webrtc/base/timeutils.h"
+
+// The following logging is for detailed (packet-level) analysis only.
+#define _DBG_NONE 0
+#define _DBG_NORMAL 1
+#define _DBG_VERBOSE 2
+#define _DEBUGMSG _DBG_NONE
+
+namespace cricket {
+
+//////////////////////////////////////////////////////////////////////
+// Network Constants
+//////////////////////////////////////////////////////////////////////
+
+// Standard MTUs
+const uint16 PACKET_MAXIMUMS[] = {
+ 65535, // Theoretical maximum, Hyperchannel
+ 32000, // Nothing
+ 17914, // 16Mb IBM Token Ring
+ 8166, // IEEE 802.4
+ //4464, // IEEE 802.5 (4Mb max)
+ 4352, // FDDI
+ //2048, // Wideband Network
+ 2002, // IEEE 802.5 (4Mb recommended)
+ //1536, // Expermental Ethernet Networks
+ //1500, // Ethernet, Point-to-Point (default)
+ 1492, // IEEE 802.3
+ 1006, // SLIP, ARPANET
+ //576, // X.25 Networks
+ //544, // DEC IP Portal
+ //512, // NETBIOS
+ 508, // IEEE 802/Source-Rt Bridge, ARCNET
+ 296, // Point-to-Point (low delay)
+ //68, // Official minimum
+ 0, // End of list marker
+};
+
+const uint32 MAX_PACKET = 65535;
+// Note: we removed lowest level because packet overhead was larger!
+const uint32 MIN_PACKET = 296;
+
+const uint32 IP_HEADER_SIZE = 20; // (+ up to 40 bytes of options?)
+const uint32 UDP_HEADER_SIZE = 8;
+// TODO: Make JINGLE_HEADER_SIZE transparent to this code?
+const uint32 JINGLE_HEADER_SIZE = 64; // when relay framing is in use
+
+// Default size for receive and send buffer.
+const uint32 DEFAULT_RCV_BUF_SIZE = 60 * 1024;
+const uint32 DEFAULT_SND_BUF_SIZE = 90 * 1024;
+
+//////////////////////////////////////////////////////////////////////
+// Global Constants and Functions
+//////////////////////////////////////////////////////////////////////
+//
+// 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 | Conversation Number |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 4 | Sequence Number |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 8 | Acknowledgment Number |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | | |U|A|P|R|S|F| |
+// 12 | Control | |R|C|S|S|Y|I| Window |
+// | | |G|K|H|T|N|N| |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 16 | Timestamp sending |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 20 | Timestamp receiving |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 24 | data |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+//
+//////////////////////////////////////////////////////////////////////
+
+#define PSEUDO_KEEPALIVE 0
+
+const uint32 HEADER_SIZE = 24;
+const uint32 PACKET_OVERHEAD = HEADER_SIZE + UDP_HEADER_SIZE + IP_HEADER_SIZE + JINGLE_HEADER_SIZE;
+
+const uint32 MIN_RTO = 250; // 250 ms (RFC1122, Sec 4.2.3.1 "fractions of a second")
+const uint32 DEF_RTO = 3000; // 3 seconds (RFC1122, Sec 4.2.3.1)
+const uint32 MAX_RTO = 60000; // 60 seconds
+const uint32 DEF_ACK_DELAY = 100; // 100 milliseconds
+
+const uint8 FLAG_CTL = 0x02;
+const uint8 FLAG_RST = 0x04;
+
+const uint8 CTL_CONNECT = 0;
+
+// TCP options.
+const uint8 TCP_OPT_EOL = 0; // End of list.
+const uint8 TCP_OPT_NOOP = 1; // No-op.
+const uint8 TCP_OPT_MSS = 2; // Maximum segment size.
+const uint8 TCP_OPT_WND_SCALE = 3; // Window scale factor.
+
+const long DEFAULT_TIMEOUT = 4000; // If there are no pending clocks, wake up every 4 seconds
+const long CLOSED_TIMEOUT = 60 * 1000; // If the connection is closed, once per minute
+
+#if PSEUDO_KEEPALIVE
+// !?! Rethink these times
+const uint32 IDLE_PING = 20 * 1000; // 20 seconds (note: WinXP SP2 firewall udp timeout is 90 seconds)
+const uint32 IDLE_TIMEOUT = 90 * 1000; // 90 seconds;
+#endif // PSEUDO_KEEPALIVE
+
+//////////////////////////////////////////////////////////////////////
+// Helper Functions
+//////////////////////////////////////////////////////////////////////
+
+inline void long_to_bytes(uint32 val, void* buf) {
+ *static_cast<uint32*>(buf) = rtc::HostToNetwork32(val);
+}
+
+inline void short_to_bytes(uint16 val, void* buf) {
+ *static_cast<uint16*>(buf) = rtc::HostToNetwork16(val);
+}
+
+inline uint32 bytes_to_long(const void* buf) {
+ return rtc::NetworkToHost32(*static_cast<const uint32*>(buf));
+}
+
+inline uint16 bytes_to_short(const void* buf) {
+ return rtc::NetworkToHost16(*static_cast<const uint16*>(buf));
+}
+
+uint32 bound(uint32 lower, uint32 middle, uint32 upper) {
+ return rtc::_min(rtc::_max(lower, middle), upper);
+}
+
+//////////////////////////////////////////////////////////////////////
+// Debugging Statistics
+//////////////////////////////////////////////////////////////////////
+
+#if 0 // Not used yet
+
+enum Stat {
+ S_SENT_PACKET, // All packet sends
+ S_RESENT_PACKET, // All packet sends that are retransmits
+ S_RECV_PACKET, // All packet receives
+ S_RECV_NEW, // All packet receives that are too new
+ S_RECV_OLD, // All packet receives that are too old
+ S_NUM_STATS
+};
+
+const char* const STAT_NAMES[S_NUM_STATS] = {
+ "snt",
+ "snt-r",
+ "rcv"
+ "rcv-n",
+ "rcv-o"
+};
+
+int g_stats[S_NUM_STATS];
+inline void Incr(Stat s) { ++g_stats[s]; }
+void ReportStats() {
+ char buffer[256];
+ size_t len = 0;
+ for (int i = 0; i < S_NUM_STATS; ++i) {
+ len += rtc::sprintfn(buffer, ARRAY_SIZE(buffer), "%s%s:%d",
+ (i == 0) ? "" : ",", STAT_NAMES[i], g_stats[i]);
+ g_stats[i] = 0;
+ }
+ LOG(LS_INFO) << "Stats[" << buffer << "]";
+}
+
+#endif
+
+//////////////////////////////////////////////////////////////////////
+// PseudoTcp
+//////////////////////////////////////////////////////////////////////
+
+uint32 PseudoTcp::Now() {
+#if 0 // Use this to synchronize timers with logging timestamps (easier debug)
+ return rtc::TimeSince(StartTime());
+#else
+ return rtc::Time();
+#endif
+}
+
+PseudoTcp::PseudoTcp(IPseudoTcpNotify* notify, uint32 conv)
+ : m_notify(notify),
+ m_shutdown(SD_NONE),
+ m_error(0),
+ m_rbuf_len(DEFAULT_RCV_BUF_SIZE),
+ m_rbuf(m_rbuf_len),
+ m_sbuf_len(DEFAULT_SND_BUF_SIZE),
+ m_sbuf(m_sbuf_len) {
+
+ // Sanity check on buffer sizes (needed for OnTcpWriteable notification logic)
+ ASSERT(m_rbuf_len + MIN_PACKET < m_sbuf_len);
+
+ uint32 now = Now();
+
+ m_state = TCP_LISTEN;
+ m_conv = conv;
+ m_rcv_wnd = m_rbuf_len;
+ m_rwnd_scale = m_swnd_scale = 0;
+ m_snd_nxt = 0;
+ m_snd_wnd = 1;
+ m_snd_una = m_rcv_nxt = 0;
+ m_bReadEnable = true;
+ m_bWriteEnable = false;
+ m_t_ack = 0;
+
+ m_msslevel = 0;
+ m_largest = 0;
+ ASSERT(MIN_PACKET > PACKET_OVERHEAD);
+ m_mss = MIN_PACKET - PACKET_OVERHEAD;
+ m_mtu_advise = MAX_PACKET;
+
+ m_rto_base = 0;
+
+ m_cwnd = 2 * m_mss;
+ m_ssthresh = m_rbuf_len;
+ m_lastrecv = m_lastsend = m_lasttraffic = now;
+ m_bOutgoing = false;
+
+ m_dup_acks = 0;
+ m_recover = 0;
+
+ m_ts_recent = m_ts_lastack = 0;
+
+ m_rx_rto = DEF_RTO;
+ m_rx_srtt = m_rx_rttvar = 0;
+
+ m_use_nagling = true;
+ m_ack_delay = DEF_ACK_DELAY;
+ m_support_wnd_scale = true;
+}
+
+PseudoTcp::~PseudoTcp() {
+}
+
+int PseudoTcp::Connect() {
+ if (m_state != TCP_LISTEN) {
+ m_error = EINVAL;
+ return -1;
+ }
+
+ m_state = TCP_SYN_SENT;
+ LOG(LS_INFO) << "State: TCP_SYN_SENT";
+
+ queueConnectMessage();
+ attemptSend();
+
+ return 0;
+}
+
+void PseudoTcp::NotifyMTU(uint16 mtu) {
+ m_mtu_advise = mtu;
+ if (m_state == TCP_ESTABLISHED) {
+ adjustMTU();
+ }
+}
+
+void PseudoTcp::NotifyClock(uint32 now) {
+ if (m_state == TCP_CLOSED)
+ return;
+
+ // Check if it's time to retransmit a segment
+ if (m_rto_base && (rtc::TimeDiff(m_rto_base + m_rx_rto, now) <= 0)) {
+ if (m_slist.empty()) {
+ ASSERT(false);
+ } else {
+ // Note: (m_slist.front().xmit == 0)) {
+ // retransmit segments
+#if _DEBUGMSG >= _DBG_NORMAL
+ LOG(LS_INFO) << "timeout retransmit (rto: " << m_rx_rto
+ << ") (rto_base: " << m_rto_base
+ << ") (now: " << now
+ << ") (dup_acks: " << static_cast<unsigned>(m_dup_acks)
+ << ")";
+#endif // _DEBUGMSG
+ if (!transmit(m_slist.begin(), now)) {
+ closedown(ECONNABORTED);
+ return;
+ }
+
+ uint32 nInFlight = m_snd_nxt - m_snd_una;
+ m_ssthresh = rtc::_max(nInFlight / 2, 2 * m_mss);
+ //LOG(LS_INFO) << "m_ssthresh: " << m_ssthresh << " nInFlight: " << nInFlight << " m_mss: " << m_mss;
+ m_cwnd = m_mss;
+
+ // Back off retransmit timer. Note: the limit is lower when connecting.
+ uint32 rto_limit = (m_state < TCP_ESTABLISHED) ? DEF_RTO : MAX_RTO;
+ m_rx_rto = rtc::_min(rto_limit, m_rx_rto * 2);
+ m_rto_base = now;
+ }
+ }
+
+ // Check if it's time to probe closed windows
+ if ((m_snd_wnd == 0)
+ && (rtc::TimeDiff(m_lastsend + m_rx_rto, now) <= 0)) {
+ if (rtc::TimeDiff(now, m_lastrecv) >= 15000) {
+ closedown(ECONNABORTED);
+ return;
+ }
+
+ // probe the window
+ packet(m_snd_nxt - 1, 0, 0, 0);
+ m_lastsend = now;
+
+ // back off retransmit timer
+ m_rx_rto = rtc::_min(MAX_RTO, m_rx_rto * 2);
+ }
+
+ // Check if it's time to send delayed acks
+ if (m_t_ack && (rtc::TimeDiff(m_t_ack + m_ack_delay, now) <= 0)) {
+ packet(m_snd_nxt, 0, 0, 0);
+ }
+
+#if PSEUDO_KEEPALIVE
+ // Check for idle timeout
+ if ((m_state == TCP_ESTABLISHED) && (TimeDiff(m_lastrecv + IDLE_TIMEOUT, now) <= 0)) {
+ closedown(ECONNABORTED);
+ return;
+ }
+
+ // Check for ping timeout (to keep udp mapping open)
+ if ((m_state == TCP_ESTABLISHED) && (TimeDiff(m_lasttraffic + (m_bOutgoing ? IDLE_PING * 3/2 : IDLE_PING), now) <= 0)) {
+ packet(m_snd_nxt, 0, 0, 0);
+ }
+#endif // PSEUDO_KEEPALIVE
+}
+
+bool PseudoTcp::NotifyPacket(const char* buffer, size_t len) {
+ if (len > MAX_PACKET) {
+ LOG_F(WARNING) << "packet too large";
+ return false;
+ }
+ return parse(reinterpret_cast<const uint8 *>(buffer), uint32(len));
+}
+
+bool PseudoTcp::GetNextClock(uint32 now, long& timeout) {
+ return clock_check(now, timeout);
+}
+
+void PseudoTcp::GetOption(Option opt, int* value) {
+ if (opt == OPT_NODELAY) {
+ *value = m_use_nagling ? 0 : 1;
+ } else if (opt == OPT_ACKDELAY) {
+ *value = m_ack_delay;
+ } else if (opt == OPT_SNDBUF) {
+ *value = m_sbuf_len;
+ } else if (opt == OPT_RCVBUF) {
+ *value = m_rbuf_len;
+ } else {
+ ASSERT(false);
+ }
+}
+void PseudoTcp::SetOption(Option opt, int value) {
+ if (opt == OPT_NODELAY) {
+ m_use_nagling = value == 0;
+ } else if (opt == OPT_ACKDELAY) {
+ m_ack_delay = value;
+ } else if (opt == OPT_SNDBUF) {
+ ASSERT(m_state == TCP_LISTEN);
+ resizeSendBuffer(value);
+ } else if (opt == OPT_RCVBUF) {
+ ASSERT(m_state == TCP_LISTEN);
+ resizeReceiveBuffer(value);
+ } else {
+ ASSERT(false);
+ }
+}
+
+uint32 PseudoTcp::GetCongestionWindow() const {
+ return m_cwnd;
+}
+
+uint32 PseudoTcp::GetBytesInFlight() const {
+ return m_snd_nxt - m_snd_una;
+}
+
+uint32 PseudoTcp::GetBytesBufferedNotSent() const {
+ size_t buffered_bytes = 0;
+ m_sbuf.GetBuffered(&buffered_bytes);
+ return static_cast<uint32>(m_snd_una + buffered_bytes - m_snd_nxt);
+}
+
+uint32 PseudoTcp::GetRoundTripTimeEstimateMs() const {
+ return m_rx_srtt;
+}
+
+//
+// IPStream Implementation
+//
+
+int PseudoTcp::Recv(char* buffer, size_t len) {
+ if (m_state != TCP_ESTABLISHED) {
+ m_error = ENOTCONN;
+ return SOCKET_ERROR;
+ }
+
+ size_t read = 0;
+ rtc::StreamResult result = m_rbuf.Read(buffer, len, &read, NULL);
+
+ // If there's no data in |m_rbuf|.
+ if (result == rtc::SR_BLOCK) {
+ m_bReadEnable = true;
+ m_error = EWOULDBLOCK;
+ return SOCKET_ERROR;
+ }
+ ASSERT(result == rtc::SR_SUCCESS);
+
+ size_t available_space = 0;
+ m_rbuf.GetWriteRemaining(&available_space);
+
+ if (uint32(available_space) - m_rcv_wnd >=
+ rtc::_min<uint32>(m_rbuf_len / 2, m_mss)) {
+ // TODO(jbeda): !?! Not sure about this was closed business
+ bool bWasClosed = (m_rcv_wnd == 0);
+ m_rcv_wnd = static_cast<uint32>(available_space);
+
+ if (bWasClosed) {
+ attemptSend(sfImmediateAck);
+ }
+ }
+
+ return static_cast<int>(read);
+}
+
+int PseudoTcp::Send(const char* buffer, size_t len) {
+ if (m_state != TCP_ESTABLISHED) {
+ m_error = ENOTCONN;
+ return SOCKET_ERROR;
+ }
+
+ size_t available_space = 0;
+ m_sbuf.GetWriteRemaining(&available_space);
+
+ if (!available_space) {
+ m_bWriteEnable = true;
+ m_error = EWOULDBLOCK;
+ return SOCKET_ERROR;
+ }
+
+ int written = queue(buffer, uint32(len), false);
+ attemptSend();
+ return written;
+}
+
+void PseudoTcp::Close(bool force) {
+ LOG_F(LS_VERBOSE) << "(" << (force ? "true" : "false") << ")";
+ m_shutdown = force ? SD_FORCEFUL : SD_GRACEFUL;
+}
+
+int PseudoTcp::GetError() {
+ return m_error;
+}
+
+//
+// Internal Implementation
+//
+
+uint32 PseudoTcp::queue(const char* data, uint32 len, bool bCtrl) {
+ size_t available_space = 0;
+ m_sbuf.GetWriteRemaining(&available_space);
+
+ if (len > static_cast<uint32>(available_space)) {
+ ASSERT(!bCtrl);
+ len = static_cast<uint32>(available_space);
+ }
+
+ // We can concatenate data if the last segment is the same type
+ // (control v. regular data), and has not been transmitted yet
+ if (!m_slist.empty() && (m_slist.back().bCtrl == bCtrl) &&
+ (m_slist.back().xmit == 0)) {
+ m_slist.back().len += len;
+ } else {
+ size_t snd_buffered = 0;
+ m_sbuf.GetBuffered(&snd_buffered);
+ SSegment sseg(static_cast<uint32>(m_snd_una + snd_buffered), len, bCtrl);
+ m_slist.push_back(sseg);
+ }
+
+ size_t written = 0;
+ m_sbuf.Write(data, len, &written, NULL);
+ return static_cast<uint32>(written);
+}
+
+IPseudoTcpNotify::WriteResult PseudoTcp::packet(uint32 seq, uint8 flags,
+ uint32 offset, uint32 len) {
+ ASSERT(HEADER_SIZE + len <= MAX_PACKET);
+
+ uint32 now = Now();
+
+ rtc::scoped_ptr<uint8[]> buffer(new uint8[MAX_PACKET]);
+ long_to_bytes(m_conv, buffer.get());
+ long_to_bytes(seq, buffer.get() + 4);
+ long_to_bytes(m_rcv_nxt, buffer.get() + 8);
+ buffer[12] = 0;
+ buffer[13] = flags;
+ short_to_bytes(
+ static_cast<uint16>(m_rcv_wnd >> m_rwnd_scale), buffer.get() + 14);
+
+ // Timestamp computations
+ long_to_bytes(now, buffer.get() + 16);
+ long_to_bytes(m_ts_recent, buffer.get() + 20);
+ m_ts_lastack = m_rcv_nxt;
+
+ if (len) {
+ size_t bytes_read = 0;
+ rtc::StreamResult result = m_sbuf.ReadOffset(
+ buffer.get() + HEADER_SIZE, len, offset, &bytes_read);
+ RTC_UNUSED(result);
+ ASSERT(result == rtc::SR_SUCCESS);
+ ASSERT(static_cast<uint32>(bytes_read) == len);
+ }
+
+#if _DEBUGMSG >= _DBG_VERBOSE
+ LOG(LS_INFO) << "<-- <CONV=" << m_conv
+ << "><FLG=" << static_cast<unsigned>(flags)
+ << "><SEQ=" << seq << ":" << seq + len
+ << "><ACK=" << m_rcv_nxt
+ << "><WND=" << m_rcv_wnd
+ << "><TS=" << (now % 10000)
+ << "><TSR=" << (m_ts_recent % 10000)
+ << "><LEN=" << len << ">";
+#endif // _DEBUGMSG
+
+ IPseudoTcpNotify::WriteResult wres = m_notify->TcpWritePacket(
+ this, reinterpret_cast<char *>(buffer.get()), len + HEADER_SIZE);
+ // Note: When len is 0, this is an ACK packet. We don't read the return value for those,
+ // and thus we won't retry. So go ahead and treat the packet as a success (basically simulate
+ // as if it were dropped), which will prevent our timers from being messed up.
+ if ((wres != IPseudoTcpNotify::WR_SUCCESS) && (0 != len))
+ return wres;
+
+ m_t_ack = 0;
+ if (len > 0) {
+ m_lastsend = now;
+ }
+ m_lasttraffic = now;
+ m_bOutgoing = true;
+
+ return IPseudoTcpNotify::WR_SUCCESS;
+}
+
+bool PseudoTcp::parse(const uint8* buffer, uint32 size) {
+ if (size < 12)
+ return false;
+
+ Segment seg;
+ seg.conv = bytes_to_long(buffer);
+ seg.seq = bytes_to_long(buffer + 4);
+ seg.ack = bytes_to_long(buffer + 8);
+ seg.flags = buffer[13];
+ seg.wnd = bytes_to_short(buffer + 14);
+
+ seg.tsval = bytes_to_long(buffer + 16);
+ seg.tsecr = bytes_to_long(buffer + 20);
+
+ seg.data = reinterpret_cast<const char *>(buffer) + HEADER_SIZE;
+ seg.len = size - HEADER_SIZE;
+
+#if _DEBUGMSG >= _DBG_VERBOSE
+ LOG(LS_INFO) << "--> <CONV=" << seg.conv
+ << "><FLG=" << static_cast<unsigned>(seg.flags)
+ << "><SEQ=" << seg.seq << ":" << seg.seq + seg.len
+ << "><ACK=" << seg.ack
+ << "><WND=" << seg.wnd
+ << "><TS=" << (seg.tsval % 10000)
+ << "><TSR=" << (seg.tsecr % 10000)
+ << "><LEN=" << seg.len << ">";
+#endif // _DEBUGMSG
+
+ return process(seg);
+}
+
+bool PseudoTcp::clock_check(uint32 now, long& nTimeout) {
+ if (m_shutdown == SD_FORCEFUL)
+ return false;
+
+ size_t snd_buffered = 0;
+ m_sbuf.GetBuffered(&snd_buffered);
+ if ((m_shutdown == SD_GRACEFUL)
+ && ((m_state != TCP_ESTABLISHED)
+ || ((snd_buffered == 0) && (m_t_ack == 0)))) {
+ return false;
+ }
+
+ if (m_state == TCP_CLOSED) {
+ nTimeout = CLOSED_TIMEOUT;
+ return true;
+ }
+
+ nTimeout = DEFAULT_TIMEOUT;
+
+ if (m_t_ack) {
+ nTimeout = rtc::_min<int32>(nTimeout,
+ rtc::TimeDiff(m_t_ack + m_ack_delay, now));
+ }
+ if (m_rto_base) {
+ nTimeout = rtc::_min<int32>(nTimeout,
+ rtc::TimeDiff(m_rto_base + m_rx_rto, now));
+ }
+ if (m_snd_wnd == 0) {
+ nTimeout = rtc::_min<int32>(nTimeout, rtc::TimeDiff(m_lastsend + m_rx_rto, now));
+ }
+#if PSEUDO_KEEPALIVE
+ if (m_state == TCP_ESTABLISHED) {
+ nTimeout = rtc::_min<int32>(nTimeout,
+ rtc::TimeDiff(m_lasttraffic + (m_bOutgoing ? IDLE_PING * 3/2 : IDLE_PING), now));
+ }
+#endif // PSEUDO_KEEPALIVE
+ return true;
+}
+
+bool PseudoTcp::process(Segment& seg) {
+ // If this is the wrong conversation, send a reset!?! (with the correct conversation?)
+ if (seg.conv != m_conv) {
+ //if ((seg.flags & FLAG_RST) == 0) {
+ // packet(tcb, seg.ack, 0, FLAG_RST, 0, 0);
+ //}
+ LOG_F(LS_ERROR) << "wrong conversation";
+ return false;
+ }
+
+ uint32 now = Now();
+ m_lasttraffic = m_lastrecv = now;
+ m_bOutgoing = false;
+
+ if (m_state == TCP_CLOSED) {
+ // !?! send reset?
+ LOG_F(LS_ERROR) << "closed";
+ return false;
+ }
+
+ // Check if this is a reset segment
+ if (seg.flags & FLAG_RST) {
+ closedown(ECONNRESET);
+ return false;
+ }
+
+ // Check for control data
+ bool bConnect = false;
+ if (seg.flags & FLAG_CTL) {
+ if (seg.len == 0) {
+ LOG_F(LS_ERROR) << "Missing control code";
+ return false;
+ } else if (seg.data[0] == CTL_CONNECT) {
+ bConnect = true;
+
+ // TCP options are in the remainder of the payload after CTL_CONNECT.
+ parseOptions(&seg.data[1], seg.len - 1);
+
+ if (m_state == TCP_LISTEN) {
+ m_state = TCP_SYN_RECEIVED;
+ LOG(LS_INFO) << "State: TCP_SYN_RECEIVED";
+ //m_notify->associate(addr);
+ queueConnectMessage();
+ } else if (m_state == TCP_SYN_SENT) {
+ m_state = TCP_ESTABLISHED;
+ LOG(LS_INFO) << "State: TCP_ESTABLISHED";
+ adjustMTU();
+ if (m_notify) {
+ m_notify->OnTcpOpen(this);
+ }
+ //notify(evOpen);
+ }
+ } else {
+ LOG_F(LS_WARNING) << "Unknown control code: " << seg.data[0];
+ return false;
+ }
+ }
+
+ // Update timestamp
+ if ((seg.seq <= m_ts_lastack) && (m_ts_lastack < seg.seq + seg.len)) {
+ m_ts_recent = seg.tsval;
+ }
+
+ // Check if this is a valuable ack
+ if ((seg.ack > m_snd_una) && (seg.ack <= m_snd_nxt)) {
+ // Calculate round-trip time
+ if (seg.tsecr) {
+ int32 rtt = rtc::TimeDiff(now, seg.tsecr);
+ if (rtt >= 0) {
+ if (m_rx_srtt == 0) {
+ m_rx_srtt = rtt;
+ m_rx_rttvar = rtt / 2;
+ } else {
+ uint32 unsigned_rtt = static_cast<uint32>(rtt);
+ uint32 abs_err = unsigned_rtt > m_rx_srtt ? unsigned_rtt - m_rx_srtt
+ : m_rx_srtt - unsigned_rtt;
+ m_rx_rttvar = (3 * m_rx_rttvar + abs_err) / 4;
+ m_rx_srtt = (7 * m_rx_srtt + rtt) / 8;
+ }
+ m_rx_rto = bound(MIN_RTO, m_rx_srtt +
+ rtc::_max<uint32>(1, 4 * m_rx_rttvar), MAX_RTO);
+#if _DEBUGMSG >= _DBG_VERBOSE
+ LOG(LS_INFO) << "rtt: " << rtt
+ << " srtt: " << m_rx_srtt
+ << " rto: " << m_rx_rto;
+#endif // _DEBUGMSG
+ } else {
+ ASSERT(false);
+ }
+ }
+
+ m_snd_wnd = static_cast<uint32>(seg.wnd) << m_swnd_scale;
+
+ uint32 nAcked = seg.ack - m_snd_una;
+ m_snd_una = seg.ack;
+
+ m_rto_base = (m_snd_una == m_snd_nxt) ? 0 : now;
+
+ m_sbuf.ConsumeReadData(nAcked);
+
+ for (uint32 nFree = nAcked; nFree > 0; ) {
+ ASSERT(!m_slist.empty());
+ if (nFree < m_slist.front().len) {
+ m_slist.front().len -= nFree;
+ nFree = 0;
+ } else {
+ if (m_slist.front().len > m_largest) {
+ m_largest = m_slist.front().len;
+ }
+ nFree -= m_slist.front().len;
+ m_slist.pop_front();
+ }
+ }
+
+ if (m_dup_acks >= 3) {
+ if (m_snd_una >= m_recover) { // NewReno
+ uint32 nInFlight = m_snd_nxt - m_snd_una;
+ m_cwnd = rtc::_min(m_ssthresh, nInFlight + m_mss); // (Fast Retransmit)
+#if _DEBUGMSG >= _DBG_NORMAL
+ LOG(LS_INFO) << "exit recovery";
+#endif // _DEBUGMSG
+ m_dup_acks = 0;
+ } else {
+#if _DEBUGMSG >= _DBG_NORMAL
+ LOG(LS_INFO) << "recovery retransmit";
+#endif // _DEBUGMSG
+ if (!transmit(m_slist.begin(), now)) {
+ closedown(ECONNABORTED);
+ return false;
+ }
+ m_cwnd += m_mss - rtc::_min(nAcked, m_cwnd);
+ }
+ } else {
+ m_dup_acks = 0;
+ // Slow start, congestion avoidance
+ if (m_cwnd < m_ssthresh) {
+ m_cwnd += m_mss;
+ } else {
+ m_cwnd += rtc::_max<uint32>(1, m_mss * m_mss / m_cwnd);
+ }
+ }
+ } else if (seg.ack == m_snd_una) {
+ // !?! Note, tcp says don't do this... but otherwise how does a closed window become open?
+ m_snd_wnd = static_cast<uint32>(seg.wnd) << m_swnd_scale;
+
+ // Check duplicate acks
+ if (seg.len > 0) {
+ // it's a dup ack, but with a data payload, so don't modify m_dup_acks
+ } else if (m_snd_una != m_snd_nxt) {
+ m_dup_acks += 1;
+ if (m_dup_acks == 3) { // (Fast Retransmit)
+#if _DEBUGMSG >= _DBG_NORMAL
+ LOG(LS_INFO) << "enter recovery";
+ LOG(LS_INFO) << "recovery retransmit";
+#endif // _DEBUGMSG
+ if (!transmit(m_slist.begin(), now)) {
+ closedown(ECONNABORTED);
+ return false;
+ }
+ m_recover = m_snd_nxt;
+ uint32 nInFlight = m_snd_nxt - m_snd_una;
+ m_ssthresh = rtc::_max(nInFlight / 2, 2 * m_mss);
+ //LOG(LS_INFO) << "m_ssthresh: " << m_ssthresh << " nInFlight: " << nInFlight << " m_mss: " << m_mss;
+ m_cwnd = m_ssthresh + 3 * m_mss;
+ } else if (m_dup_acks > 3) {
+ m_cwnd += m_mss;
+ }
+ } else {
+ m_dup_acks = 0;
+ }
+ }
+
+ // !?! A bit hacky
+ if ((m_state == TCP_SYN_RECEIVED) && !bConnect) {
+ m_state = TCP_ESTABLISHED;
+ LOG(LS_INFO) << "State: TCP_ESTABLISHED";
+ adjustMTU();
+ if (m_notify) {
+ m_notify->OnTcpOpen(this);
+ }
+ //notify(evOpen);
+ }
+
+ // If we make room in the send queue, notify the user
+ // The goal it to make sure we always have at least enough data to fill the
+ // window. We'd like to notify the app when we are halfway to that point.
+ const uint32 kIdealRefillSize = (m_sbuf_len + m_rbuf_len) / 2;
+ size_t snd_buffered = 0;
+ m_sbuf.GetBuffered(&snd_buffered);
+ if (m_bWriteEnable && static_cast<uint32>(snd_buffered) < kIdealRefillSize) {
+ m_bWriteEnable = false;
+ if (m_notify) {
+ m_notify->OnTcpWriteable(this);
+ }
+ //notify(evWrite);
+ }
+
+ // Conditions were acks must be sent:
+ // 1) Segment is too old (they missed an ACK) (immediately)
+ // 2) Segment is too new (we missed a segment) (immediately)
+ // 3) Segment has data (so we need to ACK!) (delayed)
+ // ... so the only time we don't need to ACK, is an empty segment that points to rcv_nxt!
+
+ SendFlags sflags = sfNone;
+ if (seg.seq != m_rcv_nxt) {
+ sflags = sfImmediateAck; // (Fast Recovery)
+ } else if (seg.len != 0) {
+ if (m_ack_delay == 0) {
+ sflags = sfImmediateAck;
+ } else {
+ sflags = sfDelayedAck;
+ }
+ }
+#if _DEBUGMSG >= _DBG_NORMAL
+ if (sflags == sfImmediateAck) {
+ if (seg.seq > m_rcv_nxt) {
+ LOG_F(LS_INFO) << "too new";
+ } else if (seg.seq + seg.len <= m_rcv_nxt) {
+ LOG_F(LS_INFO) << "too old";
+ }
+ }
+#endif // _DEBUGMSG
+
+ // Adjust the incoming segment to fit our receive buffer
+ if (seg.seq < m_rcv_nxt) {
+ uint32 nAdjust = m_rcv_nxt - seg.seq;
+ if (nAdjust < seg.len) {
+ seg.seq += nAdjust;
+ seg.data += nAdjust;
+ seg.len -= nAdjust;
+ } else {
+ seg.len = 0;
+ }
+ }
+
+ size_t available_space = 0;
+ m_rbuf.GetWriteRemaining(&available_space);
+
+ if ((seg.seq + seg.len - m_rcv_nxt) > static_cast<uint32>(available_space)) {
+ uint32 nAdjust = seg.seq + seg.len - m_rcv_nxt - static_cast<uint32>(available_space);
+ if (nAdjust < seg.len) {
+ seg.len -= nAdjust;
+ } else {
+ seg.len = 0;
+ }
+ }
+
+ bool bIgnoreData = (seg.flags & FLAG_CTL) || (m_shutdown != SD_NONE);
+ bool bNewData = false;
+
+ if (seg.len > 0) {
+ if (bIgnoreData) {
+ if (seg.seq == m_rcv_nxt) {
+ m_rcv_nxt += seg.len;
+ }
+ } else {
+ uint32 nOffset = seg.seq - m_rcv_nxt;
+
+ rtc::StreamResult result = m_rbuf.WriteOffset(seg.data, seg.len,
+ nOffset, NULL);
+ ASSERT(result == rtc::SR_SUCCESS);
+ RTC_UNUSED(result);
+
+ if (seg.seq == m_rcv_nxt) {
+ m_rbuf.ConsumeWriteBuffer(seg.len);
+ m_rcv_nxt += seg.len;
+ m_rcv_wnd -= seg.len;
+ bNewData = true;
+
+ RList::iterator it = m_rlist.begin();
+ while ((it != m_rlist.end()) && (it->seq <= m_rcv_nxt)) {
+ if (it->seq + it->len > m_rcv_nxt) {
+ sflags = sfImmediateAck; // (Fast Recovery)
+ uint32 nAdjust = (it->seq + it->len) - m_rcv_nxt;
+#if _DEBUGMSG >= _DBG_NORMAL
+ LOG(LS_INFO) << "Recovered " << nAdjust << " bytes (" << m_rcv_nxt << " -> " << m_rcv_nxt + nAdjust << ")";
+#endif // _DEBUGMSG
+ m_rbuf.ConsumeWriteBuffer(nAdjust);
+ m_rcv_nxt += nAdjust;
+ m_rcv_wnd -= nAdjust;
+ }
+ it = m_rlist.erase(it);
+ }
+ } else {
+#if _DEBUGMSG >= _DBG_NORMAL
+ LOG(LS_INFO) << "Saving " << seg.len << " bytes (" << seg.seq << " -> " << seg.seq + seg.len << ")";
+#endif // _DEBUGMSG
+ RSegment rseg;
+ rseg.seq = seg.seq;
+ rseg.len = seg.len;
+ RList::iterator it = m_rlist.begin();
+ while ((it != m_rlist.end()) && (it->seq < rseg.seq)) {
+ ++it;
+ }
+ m_rlist.insert(it, rseg);
+ }
+ }
+ }
+
+ attemptSend(sflags);
+
+ // If we have new data, notify the user
+ if (bNewData && m_bReadEnable) {
+ m_bReadEnable = false;
+ if (m_notify) {
+ m_notify->OnTcpReadable(this);
+ }
+ //notify(evRead);
+ }
+
+ return true;
+}
+
+bool PseudoTcp::transmit(const SList::iterator& seg, uint32 now) {
+ if (seg->xmit >= ((m_state == TCP_ESTABLISHED) ? 15 : 30)) {
+ LOG_F(LS_VERBOSE) << "too many retransmits";
+ return false;
+ }
+
+ uint32 nTransmit = rtc::_min(seg->len, m_mss);
+
+ while (true) {
+ uint32 seq = seg->seq;
+ uint8 flags = (seg->bCtrl ? FLAG_CTL : 0);
+ IPseudoTcpNotify::WriteResult wres = packet(seq,
+ flags,
+ seg->seq - m_snd_una,
+ nTransmit);
+
+ if (wres == IPseudoTcpNotify::WR_SUCCESS)
+ break;
+
+ if (wres == IPseudoTcpNotify::WR_FAIL) {
+ LOG_F(LS_VERBOSE) << "packet failed";
+ return false;
+ }
+
+ ASSERT(wres == IPseudoTcpNotify::WR_TOO_LARGE);
+
+ while (true) {
+ if (PACKET_MAXIMUMS[m_msslevel + 1] == 0) {
+ LOG_F(LS_VERBOSE) << "MTU too small";
+ return false;
+ }
+ // !?! We need to break up all outstanding and pending packets and then retransmit!?!
+
+ m_mss = PACKET_MAXIMUMS[++m_msslevel] - PACKET_OVERHEAD;
+ m_cwnd = 2 * m_mss; // I added this... haven't researched actual formula
+ if (m_mss < nTransmit) {
+ nTransmit = m_mss;
+ break;
+ }
+ }
+#if _DEBUGMSG >= _DBG_NORMAL
+ LOG(LS_INFO) << "Adjusting mss to " << m_mss << " bytes";
+#endif // _DEBUGMSG
+ }
+
+ if (nTransmit < seg->len) {
+ LOG_F(LS_VERBOSE) << "mss reduced to " << m_mss;
+
+ SSegment subseg(seg->seq + nTransmit, seg->len - nTransmit, seg->bCtrl);
+ //subseg.tstamp = seg->tstamp;
+ subseg.xmit = seg->xmit;
+ seg->len = nTransmit;
+
+ SList::iterator next = seg;
+ m_slist.insert(++next, subseg);
+ }
+
+ if (seg->xmit == 0) {
+ m_snd_nxt += seg->len;
+ }
+ seg->xmit += 1;
+ //seg->tstamp = now;
+ if (m_rto_base == 0) {
+ m_rto_base = now;
+ }
+
+ return true;
+}
+
+void PseudoTcp::attemptSend(SendFlags sflags) {
+ uint32 now = Now();
+
+ if (rtc::TimeDiff(now, m_lastsend) > static_cast<long>(m_rx_rto)) {
+ m_cwnd = m_mss;
+ }
+
+#if _DEBUGMSG
+ bool bFirst = true;
+ RTC_UNUSED(bFirst);
+#endif // _DEBUGMSG
+
+ while (true) {
+ uint32 cwnd = m_cwnd;
+ if ((m_dup_acks == 1) || (m_dup_acks == 2)) { // Limited Transmit
+ cwnd += m_dup_acks * m_mss;
+ }
+ uint32 nWindow = rtc::_min(m_snd_wnd, cwnd);
+ uint32 nInFlight = m_snd_nxt - m_snd_una;
+ uint32 nUseable = (nInFlight < nWindow) ? (nWindow - nInFlight) : 0;
+
+ size_t snd_buffered = 0;
+ m_sbuf.GetBuffered(&snd_buffered);
+ uint32 nAvailable =
+ rtc::_min(static_cast<uint32>(snd_buffered) - nInFlight, m_mss);
+
+ if (nAvailable > nUseable) {
+ if (nUseable * 4 < nWindow) {
+ // RFC 813 - avoid SWS
+ nAvailable = 0;
+ } else {
+ nAvailable = nUseable;
+ }
+ }
+
+#if _DEBUGMSG >= _DBG_VERBOSE
+ if (bFirst) {
+ size_t available_space = 0;
+ m_sbuf.GetWriteRemaining(&available_space);
+
+ bFirst = false;
+ LOG(LS_INFO) << "[cwnd: " << m_cwnd
+ << " nWindow: " << nWindow
+ << " nInFlight: " << nInFlight
+ << " nAvailable: " << nAvailable
+ << " nQueued: " << snd_buffered
+ << " nEmpty: " << available_space
+ << " ssthresh: " << m_ssthresh << "]";
+ }
+#endif // _DEBUGMSG
+
+ if (nAvailable == 0) {
+ if (sflags == sfNone)
+ return;
+
+ // If this is an immediate ack, or the second delayed ack
+ if ((sflags == sfImmediateAck) || m_t_ack) {
+ packet(m_snd_nxt, 0, 0, 0);
+ } else {
+ m_t_ack = Now();
+ }
+ return;
+ }
+
+ // Nagle's algorithm.
+ // If there is data already in-flight, and we haven't a full segment of
+ // data ready to send then hold off until we get more to send, or the
+ // in-flight data is acknowledged.
+ if (m_use_nagling && (m_snd_nxt > m_snd_una) && (nAvailable < m_mss)) {
+ return;
+ }
+
+ // Find the next segment to transmit
+ SList::iterator it = m_slist.begin();
+ while (it->xmit > 0) {
+ ++it;
+ ASSERT(it != m_slist.end());
+ }
+ SList::iterator seg = it;
+
+ // If the segment is too large, break it into two
+ if (seg->len > nAvailable) {
+ SSegment subseg(seg->seq + nAvailable, seg->len - nAvailable, seg->bCtrl);
+ seg->len = nAvailable;
+ m_slist.insert(++it, subseg);
+ }
+
+ if (!transmit(seg, now)) {
+ LOG_F(LS_VERBOSE) << "transmit failed";
+ // TODO: consider closing socket
+ return;
+ }
+
+ sflags = sfNone;
+ }
+}
+
+void
+PseudoTcp::closedown(uint32 err) {
+ LOG(LS_INFO) << "State: TCP_CLOSED";
+ m_state = TCP_CLOSED;
+ if (m_notify) {
+ m_notify->OnTcpClosed(this, err);
+ }
+ //notify(evClose, err);
+}
+
+void
+PseudoTcp::adjustMTU() {
+ // Determine our current mss level, so that we can adjust appropriately later
+ for (m_msslevel = 0; PACKET_MAXIMUMS[m_msslevel + 1] > 0; ++m_msslevel) {
+ if (static_cast<uint16>(PACKET_MAXIMUMS[m_msslevel]) <= m_mtu_advise) {
+ break;
+ }
+ }
+ m_mss = m_mtu_advise - PACKET_OVERHEAD;
+ // !?! Should we reset m_largest here?
+#if _DEBUGMSG >= _DBG_NORMAL
+ LOG(LS_INFO) << "Adjusting mss to " << m_mss << " bytes";
+#endif // _DEBUGMSG
+ // Enforce minimums on ssthresh and cwnd
+ m_ssthresh = rtc::_max(m_ssthresh, 2 * m_mss);
+ m_cwnd = rtc::_max(m_cwnd, m_mss);
+}
+
+bool
+PseudoTcp::isReceiveBufferFull() const {
+ size_t available_space = 0;
+ m_rbuf.GetWriteRemaining(&available_space);
+ return !available_space;
+}
+
+void
+PseudoTcp::disableWindowScale() {
+ m_support_wnd_scale = false;
+}
+
+void
+PseudoTcp::queueConnectMessage() {
+ rtc::ByteBuffer buf(rtc::ByteBuffer::ORDER_NETWORK);
+
+ buf.WriteUInt8(CTL_CONNECT);
+ if (m_support_wnd_scale) {
+ buf.WriteUInt8(TCP_OPT_WND_SCALE);
+ buf.WriteUInt8(1);
+ buf.WriteUInt8(m_rwnd_scale);
+ }
+ m_snd_wnd = static_cast<uint32>(buf.Length());
+ queue(buf.Data(), static_cast<uint32>(buf.Length()), true);
+}
+
+void
+PseudoTcp::parseOptions(const char* data, uint32 len) {
+ std::set<uint8> options_specified;
+
+ // See http://www.freesoft.org/CIE/Course/Section4/8.htm for
+ // parsing the options list.
+ rtc::ByteBuffer buf(data, len);
+ while (buf.Length()) {
+ uint8 kind = TCP_OPT_EOL;
+ buf.ReadUInt8(&kind);
+
+ if (kind == TCP_OPT_EOL) {
+ // End of option list.
+ break;
+ } else if (kind == TCP_OPT_NOOP) {
+ // No op.
+ continue;
+ }
+
+ // Length of this option.
+ ASSERT(len != 0);
+ RTC_UNUSED(len);
+ uint8 opt_len = 0;
+ buf.ReadUInt8(&opt_len);
+
+ // Content of this option.
+ if (opt_len <= buf.Length()) {
+ applyOption(kind, buf.Data(), opt_len);
+ buf.Consume(opt_len);
+ } else {
+ LOG(LS_ERROR) << "Invalid option length received.";
+ return;
+ }
+ options_specified.insert(kind);
+ }
+
+ if (options_specified.find(TCP_OPT_WND_SCALE) == options_specified.end()) {
+ LOG(LS_WARNING) << "Peer doesn't support window scaling";
+
+ if (m_rwnd_scale > 0) {
+ // Peer doesn't support TCP options and window scaling.
+ // Revert receive buffer size to default value.
+ resizeReceiveBuffer(DEFAULT_RCV_BUF_SIZE);
+ m_swnd_scale = 0;
+ }
+ }
+}
+
+void
+PseudoTcp::applyOption(char kind, const char* data, uint32 len) {
+ if (kind == TCP_OPT_MSS) {
+ LOG(LS_WARNING) << "Peer specified MSS option which is not supported.";
+ // TODO: Implement.
+ } else if (kind == TCP_OPT_WND_SCALE) {
+ // Window scale factor.
+ // http://www.ietf.org/rfc/rfc1323.txt
+ if (len != 1) {
+ LOG_F(WARNING) << "Invalid window scale option received.";
+ return;
+ }
+ applyWindowScaleOption(data[0]);
+ }
+}
+
+void
+PseudoTcp::applyWindowScaleOption(uint8 scale_factor) {
+ m_swnd_scale = scale_factor;
+}
+
+void
+PseudoTcp::resizeSendBuffer(uint32 new_size) {
+ m_sbuf_len = new_size;
+ m_sbuf.SetCapacity(new_size);
+}
+
+void
+PseudoTcp::resizeReceiveBuffer(uint32 new_size) {
+ uint8 scale_factor = 0;
+
+ // Determine the scale factor such that the scaled window size can fit
+ // in a 16-bit unsigned integer.
+ while (new_size > 0xFFFF) {
+ ++scale_factor;
+ new_size >>= 1;
+ }
+
+ // Determine the proper size of the buffer.
+ new_size <<= scale_factor;
+ bool result = m_rbuf.SetCapacity(new_size);
+
+ // Make sure the new buffer is large enough to contain data in the old
+ // buffer. This should always be true because this method is called either
+ // before connection is established or when peers are exchanging connect
+ // messages.
+ ASSERT(result);
+ RTC_UNUSED(result);
+ m_rbuf_len = new_size;
+ m_rwnd_scale = scale_factor;
+ m_ssthresh = new_size;
+
+ size_t available_space = 0;
+ m_rbuf.GetWriteRemaining(&available_space);
+ m_rcv_wnd = static_cast<uint32>(available_space);
+}
+
+} // namespace cricket
diff --git a/p2p/base/pseudotcp.h b/p2p/base/pseudotcp.h
new file mode 100644
index 00000000..b2cfcb79
--- /dev/null
+++ b/p2p/base/pseudotcp.h
@@ -0,0 +1,241 @@
+/*
+ * 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 WEBRTC_P2P_BASE_PSEUDOTCP_H_
+#define WEBRTC_P2P_BASE_PSEUDOTCP_H_
+
+#include <list>
+
+#include "webrtc/base/basictypes.h"
+#include "webrtc/base/stream.h"
+
+namespace cricket {
+
+//////////////////////////////////////////////////////////////////////
+// IPseudoTcpNotify
+//////////////////////////////////////////////////////////////////////
+
+class PseudoTcp;
+
+class IPseudoTcpNotify {
+ public:
+ // Notification of tcp events
+ virtual void OnTcpOpen(PseudoTcp* tcp) = 0;
+ virtual void OnTcpReadable(PseudoTcp* tcp) = 0;
+ virtual void OnTcpWriteable(PseudoTcp* tcp) = 0;
+ virtual void OnTcpClosed(PseudoTcp* tcp, uint32 error) = 0;
+
+ // Write the packet onto the network
+ enum WriteResult { WR_SUCCESS, WR_TOO_LARGE, WR_FAIL };
+ virtual WriteResult TcpWritePacket(PseudoTcp* tcp,
+ const char* buffer, size_t len) = 0;
+
+ protected:
+ virtual ~IPseudoTcpNotify() {}
+};
+
+//////////////////////////////////////////////////////////////////////
+// PseudoTcp
+//////////////////////////////////////////////////////////////////////
+
+class PseudoTcp {
+ public:
+ static uint32 Now();
+
+ PseudoTcp(IPseudoTcpNotify* notify, uint32 conv);
+ virtual ~PseudoTcp();
+
+ int Connect();
+ int Recv(char* buffer, size_t len);
+ int Send(const char* buffer, size_t len);
+ void Close(bool force);
+ int GetError();
+
+ enum TcpState {
+ TCP_LISTEN, TCP_SYN_SENT, TCP_SYN_RECEIVED, TCP_ESTABLISHED, TCP_CLOSED
+ };
+ TcpState State() const { return m_state; }
+
+ // Call this when the PMTU changes.
+ void NotifyMTU(uint16 mtu);
+
+ // Call this based on timeout value returned from GetNextClock.
+ // It's ok to call this too frequently.
+ void NotifyClock(uint32 now);
+
+ // Call this whenever a packet arrives.
+ // Returns true if the packet was processed successfully.
+ bool NotifyPacket(const char * buffer, size_t len);
+
+ // Call this to determine the next time NotifyClock should be called.
+ // Returns false if the socket is ready to be destroyed.
+ bool GetNextClock(uint32 now, long& timeout);
+
+ // Call these to get/set option values to tailor this PseudoTcp
+ // instance's behaviour for the kind of data it will carry.
+ // If an unrecognized option is set or got, an assertion will fire.
+ //
+ // Setting options for OPT_RCVBUF or OPT_SNDBUF after Connect() is called
+ // will result in an assertion.
+ enum Option {
+ OPT_NODELAY, // Whether to enable Nagle's algorithm (0 == off)
+ OPT_ACKDELAY, // The Delayed ACK timeout (0 == off).
+ OPT_RCVBUF, // Set the receive buffer size, in bytes.
+ OPT_SNDBUF, // Set the send buffer size, in bytes.
+ };
+ void GetOption(Option opt, int* value);
+ void SetOption(Option opt, int value);
+
+ // Returns current congestion window in bytes.
+ uint32 GetCongestionWindow() const;
+
+ // Returns amount of data in bytes that has been sent, but haven't
+ // been acknowledged.
+ uint32 GetBytesInFlight() const;
+
+ // Returns number of bytes that were written in buffer and haven't
+ // been sent.
+ uint32 GetBytesBufferedNotSent() const;
+
+ // Returns current round-trip time estimate in milliseconds.
+ uint32 GetRoundTripTimeEstimateMs() const;
+
+ protected:
+ enum SendFlags { sfNone, sfDelayedAck, sfImmediateAck };
+
+ struct Segment {
+ uint32 conv, seq, ack;
+ uint8 flags;
+ uint16 wnd;
+ const char * data;
+ uint32 len;
+ uint32 tsval, tsecr;
+ };
+
+ struct SSegment {
+ SSegment(uint32 s, uint32 l, bool c)
+ : seq(s), len(l), /*tstamp(0),*/ xmit(0), bCtrl(c) {
+ }
+ uint32 seq, len;
+ //uint32 tstamp;
+ uint8 xmit;
+ bool bCtrl;
+ };
+ typedef std::list<SSegment> SList;
+
+ struct RSegment {
+ uint32 seq, len;
+ };
+
+ uint32 queue(const char* data, uint32 len, bool bCtrl);
+
+ // Creates a packet and submits it to the network. This method can either
+ // send payload or just an ACK packet.
+ //
+ // |seq| is the sequence number of this packet.
+ // |flags| is the flags for sending this packet.
+ // |offset| is the offset to read from |m_sbuf|.
+ // |len| is the number of bytes to read from |m_sbuf| as payload. If this
+ // value is 0 then this is an ACK packet, otherwise this packet has payload.
+ IPseudoTcpNotify::WriteResult packet(uint32 seq, uint8 flags,
+ uint32 offset, uint32 len);
+ bool parse(const uint8* buffer, uint32 size);
+
+ void attemptSend(SendFlags sflags = sfNone);
+
+ void closedown(uint32 err = 0);
+
+ bool clock_check(uint32 now, long& nTimeout);
+
+ bool process(Segment& seg);
+ bool transmit(const SList::iterator& seg, uint32 now);
+
+ void adjustMTU();
+
+ protected:
+ // This method is used in test only to query receive buffer state.
+ bool isReceiveBufferFull() const;
+
+ // This method is only used in tests, to disable window scaling
+ // support for testing backward compatibility.
+ void disableWindowScale();
+
+ private:
+ // Queue the connect message with TCP options.
+ void queueConnectMessage();
+
+ // Parse TCP options in the header.
+ void parseOptions(const char* data, uint32 len);
+
+ // Apply a TCP option that has been read from the header.
+ void applyOption(char kind, const char* data, uint32 len);
+
+ // Apply window scale option.
+ void applyWindowScaleOption(uint8 scale_factor);
+
+ // Resize the send buffer with |new_size| in bytes.
+ void resizeSendBuffer(uint32 new_size);
+
+ // Resize the receive buffer with |new_size| in bytes. This call adjusts
+ // window scale factor |m_swnd_scale| accordingly.
+ void resizeReceiveBuffer(uint32 new_size);
+
+ IPseudoTcpNotify* m_notify;
+ enum Shutdown { SD_NONE, SD_GRACEFUL, SD_FORCEFUL } m_shutdown;
+ int m_error;
+
+ // TCB data
+ TcpState m_state;
+ uint32 m_conv;
+ bool m_bReadEnable, m_bWriteEnable, m_bOutgoing;
+ uint32 m_lasttraffic;
+
+ // Incoming data
+ typedef std::list<RSegment> RList;
+ RList m_rlist;
+ uint32 m_rbuf_len, m_rcv_nxt, m_rcv_wnd, m_lastrecv;
+ uint8 m_rwnd_scale; // Window scale factor.
+ rtc::FifoBuffer m_rbuf;
+
+ // Outgoing data
+ SList m_slist;
+ uint32 m_sbuf_len, m_snd_nxt, m_snd_wnd, m_lastsend, m_snd_una;
+ uint8 m_swnd_scale; // Window scale factor.
+ rtc::FifoBuffer m_sbuf;
+
+ // Maximum segment size, estimated protocol level, largest segment sent
+ uint32 m_mss, m_msslevel, m_largest, m_mtu_advise;
+ // Retransmit timer
+ uint32 m_rto_base;
+
+ // Timestamp tracking
+ uint32 m_ts_recent, m_ts_lastack;
+
+ // Round-trip calculation
+ uint32 m_rx_rttvar, m_rx_srtt, m_rx_rto;
+
+ // Congestion avoidance, Fast retransmit/recovery, Delayed ACKs
+ uint32 m_ssthresh, m_cwnd;
+ uint8 m_dup_acks;
+ uint32 m_recover;
+ uint32 m_t_ack;
+
+ // Configuration options
+ bool m_use_nagling;
+ uint32 m_ack_delay;
+
+ // This is used by unit tests to test backward compatibility of
+ // PseudoTcp implementations that don't support window scaling.
+ bool m_support_wnd_scale;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_PSEUDOTCP_H_
diff --git a/p2p/base/pseudotcp_unittest.cc b/p2p/base/pseudotcp_unittest.cc
new file mode 100644
index 00000000..f5ea7ace
--- /dev/null
+++ b/p2p/base/pseudotcp_unittest.cc
@@ -0,0 +1,841 @@
+/*
+ * 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.
+ */
+
+#include <vector>
+
+#include "webrtc/p2p/base/pseudotcp.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/messagehandler.h"
+#include "webrtc/base/stream.h"
+#include "webrtc/base/thread.h"
+#include "webrtc/base/timeutils.h"
+
+using cricket::PseudoTcp;
+
+static const int kConnectTimeoutMs = 10000; // ~3 * default RTO of 3000ms
+static const int kTransferTimeoutMs = 15000;
+static const int kBlockSize = 4096;
+
+class PseudoTcpForTest : public cricket::PseudoTcp {
+ public:
+ PseudoTcpForTest(cricket::IPseudoTcpNotify* notify, uint32 conv)
+ : PseudoTcp(notify, conv) {
+ }
+
+ bool isReceiveBufferFull() const {
+ return PseudoTcp::isReceiveBufferFull();
+ }
+
+ void disableWindowScale() {
+ PseudoTcp::disableWindowScale();
+ }
+};
+
+class PseudoTcpTestBase : public testing::Test,
+ public rtc::MessageHandler,
+ public cricket::IPseudoTcpNotify {
+ public:
+ PseudoTcpTestBase()
+ : local_(this, 1),
+ remote_(this, 1),
+ have_connected_(false),
+ have_disconnected_(false),
+ local_mtu_(65535),
+ remote_mtu_(65535),
+ delay_(0),
+ loss_(0) {
+ // Set use of the test RNG to get predictable loss patterns.
+ rtc::SetRandomTestMode(true);
+ }
+ ~PseudoTcpTestBase() {
+ // Put it back for the next test.
+ rtc::SetRandomTestMode(false);
+ }
+ void SetLocalMtu(int mtu) {
+ local_.NotifyMTU(mtu);
+ local_mtu_ = mtu;
+ }
+ void SetRemoteMtu(int mtu) {
+ remote_.NotifyMTU(mtu);
+ remote_mtu_ = mtu;
+ }
+ void SetDelay(int delay) {
+ delay_ = delay;
+ }
+ void SetLoss(int percent) {
+ loss_ = percent;
+ }
+ void SetOptNagling(bool enable_nagles) {
+ local_.SetOption(PseudoTcp::OPT_NODELAY, !enable_nagles);
+ remote_.SetOption(PseudoTcp::OPT_NODELAY, !enable_nagles);
+ }
+ void SetOptAckDelay(int ack_delay) {
+ local_.SetOption(PseudoTcp::OPT_ACKDELAY, ack_delay);
+ remote_.SetOption(PseudoTcp::OPT_ACKDELAY, ack_delay);
+ }
+ void SetOptSndBuf(int size) {
+ local_.SetOption(PseudoTcp::OPT_SNDBUF, size);
+ remote_.SetOption(PseudoTcp::OPT_SNDBUF, size);
+ }
+ void SetRemoteOptRcvBuf(int size) {
+ remote_.SetOption(PseudoTcp::OPT_RCVBUF, size);
+ }
+ void SetLocalOptRcvBuf(int size) {
+ local_.SetOption(PseudoTcp::OPT_RCVBUF, size);
+ }
+ void DisableRemoteWindowScale() {
+ remote_.disableWindowScale();
+ }
+ void DisableLocalWindowScale() {
+ local_.disableWindowScale();
+ }
+
+ protected:
+ int Connect() {
+ int ret = local_.Connect();
+ if (ret == 0) {
+ UpdateLocalClock();
+ }
+ return ret;
+ }
+ void Close() {
+ local_.Close(false);
+ UpdateLocalClock();
+ }
+
+ enum { MSG_LPACKET, MSG_RPACKET, MSG_LCLOCK, MSG_RCLOCK, MSG_IOCOMPLETE,
+ MSG_WRITE};
+ virtual void OnTcpOpen(PseudoTcp* tcp) {
+ // Consider ourselves connected when the local side gets OnTcpOpen.
+ // OnTcpWriteable isn't fired at open, so we trigger it now.
+ LOG(LS_VERBOSE) << "Opened";
+ if (tcp == &local_) {
+ have_connected_ = true;
+ OnTcpWriteable(tcp);
+ }
+ }
+ // Test derived from the base should override
+ // virtual void OnTcpReadable(PseudoTcp* tcp)
+ // and
+ // virtual void OnTcpWritable(PseudoTcp* tcp)
+ virtual void OnTcpClosed(PseudoTcp* tcp, uint32 error) {
+ // Consider ourselves closed when the remote side gets OnTcpClosed.
+ // TODO: OnTcpClosed is only ever notified in case of error in
+ // the current implementation. Solicited close is not (yet) supported.
+ LOG(LS_VERBOSE) << "Closed";
+ EXPECT_EQ(0U, error);
+ if (tcp == &remote_) {
+ have_disconnected_ = true;
+ }
+ }
+ virtual WriteResult TcpWritePacket(PseudoTcp* tcp,
+ const char* buffer, size_t len) {
+ // Randomly drop the desired percentage of packets.
+ // Also drop packets that are larger than the configured MTU.
+ if (rtc::CreateRandomId() % 100 < static_cast<uint32>(loss_)) {
+ LOG(LS_VERBOSE) << "Randomly dropping packet, size=" << len;
+ } else if (len > static_cast<size_t>(
+ rtc::_min(local_mtu_, remote_mtu_))) {
+ LOG(LS_VERBOSE) << "Dropping packet that exceeds path MTU, size=" << len;
+ } else {
+ int id = (tcp == &local_) ? MSG_RPACKET : MSG_LPACKET;
+ std::string packet(buffer, len);
+ rtc::Thread::Current()->PostDelayed(delay_, this, id,
+ rtc::WrapMessageData(packet));
+ }
+ return WR_SUCCESS;
+ }
+
+ void UpdateLocalClock() { UpdateClock(&local_, MSG_LCLOCK); }
+ void UpdateRemoteClock() { UpdateClock(&remote_, MSG_RCLOCK); }
+ void UpdateClock(PseudoTcp* tcp, uint32 message) {
+ long interval = 0; // NOLINT
+ tcp->GetNextClock(PseudoTcp::Now(), interval);
+ interval = rtc::_max<int>(interval, 0L); // sometimes interval is < 0
+ rtc::Thread::Current()->Clear(this, message);
+ rtc::Thread::Current()->PostDelayed(interval, this, message);
+ }
+
+ virtual void OnMessage(rtc::Message* message) {
+ switch (message->message_id) {
+ case MSG_LPACKET: {
+ const std::string& s(
+ rtc::UseMessageData<std::string>(message->pdata));
+ local_.NotifyPacket(s.c_str(), s.size());
+ UpdateLocalClock();
+ break;
+ }
+ case MSG_RPACKET: {
+ const std::string& s(
+ rtc::UseMessageData<std::string>(message->pdata));
+ remote_.NotifyPacket(s.c_str(), s.size());
+ UpdateRemoteClock();
+ break;
+ }
+ case MSG_LCLOCK:
+ local_.NotifyClock(PseudoTcp::Now());
+ UpdateLocalClock();
+ break;
+ case MSG_RCLOCK:
+ remote_.NotifyClock(PseudoTcp::Now());
+ UpdateRemoteClock();
+ break;
+ default:
+ break;
+ }
+ delete message->pdata;
+ }
+
+ PseudoTcpForTest local_;
+ PseudoTcpForTest remote_;
+ rtc::MemoryStream send_stream_;
+ rtc::MemoryStream recv_stream_;
+ bool have_connected_;
+ bool have_disconnected_;
+ int local_mtu_;
+ int remote_mtu_;
+ int delay_;
+ int loss_;
+};
+
+class PseudoTcpTest : public PseudoTcpTestBase {
+ public:
+ void TestTransfer(int size) {
+ uint32 start, elapsed;
+ size_t received;
+ // Create some dummy data to send.
+ send_stream_.ReserveSize(size);
+ for (int i = 0; i < size; ++i) {
+ char ch = static_cast<char>(i);
+ send_stream_.Write(&ch, 1, NULL, NULL);
+ }
+ send_stream_.Rewind();
+ // Prepare the receive stream.
+ recv_stream_.ReserveSize(size);
+ // Connect and wait until connected.
+ start = rtc::Time();
+ EXPECT_EQ(0, Connect());
+ EXPECT_TRUE_WAIT(have_connected_, kConnectTimeoutMs);
+ // Sending will start from OnTcpWriteable and complete when all data has
+ // been received.
+ EXPECT_TRUE_WAIT(have_disconnected_, kTransferTimeoutMs);
+ elapsed = rtc::TimeSince(start);
+ recv_stream_.GetSize(&received);
+ // Ensure we closed down OK and we got the right data.
+ // TODO: Ensure the errors are cleared properly.
+ //EXPECT_EQ(0, local_.GetError());
+ //EXPECT_EQ(0, remote_.GetError());
+ EXPECT_EQ(static_cast<size_t>(size), received);
+ EXPECT_EQ(0, memcmp(send_stream_.GetBuffer(),
+ recv_stream_.GetBuffer(), size));
+ LOG(LS_INFO) << "Transferred " << received << " bytes in " << elapsed
+ << " ms (" << size * 8 / elapsed << " Kbps)";
+ }
+
+ private:
+ // IPseudoTcpNotify interface
+
+ virtual void OnTcpReadable(PseudoTcp* tcp) {
+ // Stream bytes to the recv stream as they arrive.
+ if (tcp == &remote_) {
+ ReadData();
+
+ // TODO: OnTcpClosed() is currently only notified on error -
+ // there is no on-the-wire equivalent of TCP FIN.
+ // So we fake the notification when all the data has been read.
+ size_t received, required;
+ recv_stream_.GetPosition(&received);
+ send_stream_.GetSize(&required);
+ if (received == required)
+ OnTcpClosed(&remote_, 0);
+ }
+ }
+ virtual void OnTcpWriteable(PseudoTcp* tcp) {
+ // Write bytes from the send stream when we can.
+ // Shut down when we've sent everything.
+ if (tcp == &local_) {
+ LOG(LS_VERBOSE) << "Flow Control Lifted";
+ bool done;
+ WriteData(&done);
+ if (done) {
+ Close();
+ }
+ }
+ }
+
+ void ReadData() {
+ char block[kBlockSize];
+ size_t position;
+ int rcvd;
+ do {
+ rcvd = remote_.Recv(block, sizeof(block));
+ if (rcvd != -1) {
+ recv_stream_.Write(block, rcvd, NULL, NULL);
+ recv_stream_.GetPosition(&position);
+ LOG(LS_VERBOSE) << "Received: " << position;
+ }
+ } while (rcvd > 0);
+ }
+ void WriteData(bool* done) {
+ size_t position, tosend;
+ int sent;
+ char block[kBlockSize];
+ do {
+ send_stream_.GetPosition(&position);
+ if (send_stream_.Read(block, sizeof(block), &tosend, NULL) !=
+ rtc::SR_EOS) {
+ sent = local_.Send(block, tosend);
+ UpdateLocalClock();
+ if (sent != -1) {
+ send_stream_.SetPosition(position + sent);
+ LOG(LS_VERBOSE) << "Sent: " << position + sent;
+ } else {
+ send_stream_.SetPosition(position);
+ LOG(LS_VERBOSE) << "Flow Controlled";
+ }
+ } else {
+ sent = static_cast<int>(tosend = 0);
+ }
+ } while (sent > 0);
+ *done = (tosend == 0);
+ }
+
+ private:
+ rtc::MemoryStream send_stream_;
+ rtc::MemoryStream recv_stream_;
+};
+
+
+class PseudoTcpTestPingPong : public PseudoTcpTestBase {
+ public:
+ PseudoTcpTestPingPong()
+ : iterations_remaining_(0),
+ sender_(NULL),
+ receiver_(NULL),
+ bytes_per_send_(0) {
+ }
+ void SetBytesPerSend(int bytes) {
+ bytes_per_send_ = bytes;
+ }
+ void TestPingPong(int size, int iterations) {
+ uint32 start, elapsed;
+ iterations_remaining_ = iterations;
+ receiver_ = &remote_;
+ sender_ = &local_;
+ // Create some dummy data to send.
+ send_stream_.ReserveSize(size);
+ for (int i = 0; i < size; ++i) {
+ char ch = static_cast<char>(i);
+ send_stream_.Write(&ch, 1, NULL, NULL);
+ }
+ send_stream_.Rewind();
+ // Prepare the receive stream.
+ recv_stream_.ReserveSize(size);
+ // Connect and wait until connected.
+ start = rtc::Time();
+ EXPECT_EQ(0, Connect());
+ EXPECT_TRUE_WAIT(have_connected_, kConnectTimeoutMs);
+ // Sending will start from OnTcpWriteable and stop when the required
+ // number of iterations have completed.
+ EXPECT_TRUE_WAIT(have_disconnected_, kTransferTimeoutMs);
+ elapsed = rtc::TimeSince(start);
+ LOG(LS_INFO) << "Performed " << iterations << " pings in "
+ << elapsed << " ms";
+ }
+
+ private:
+ // IPseudoTcpNotify interface
+
+ virtual void OnTcpReadable(PseudoTcp* tcp) {
+ if (tcp != receiver_) {
+ LOG_F(LS_ERROR) << "unexpected OnTcpReadable";
+ return;
+ }
+ // Stream bytes to the recv stream as they arrive.
+ ReadData();
+ // If we've received the desired amount of data, rewind things
+ // and send it back the other way!
+ size_t position, desired;
+ recv_stream_.GetPosition(&position);
+ send_stream_.GetSize(&desired);
+ if (position == desired) {
+ if (receiver_ == &local_ && --iterations_remaining_ == 0) {
+ Close();
+ // TODO: Fake OnTcpClosed() on the receiver for now.
+ OnTcpClosed(&remote_, 0);
+ return;
+ }
+ PseudoTcp* tmp = receiver_;
+ receiver_ = sender_;
+ sender_ = tmp;
+ recv_stream_.Rewind();
+ send_stream_.Rewind();
+ OnTcpWriteable(sender_);
+ }
+ }
+ virtual void OnTcpWriteable(PseudoTcp* tcp) {
+ if (tcp != sender_)
+ return;
+ // Write bytes from the send stream when we can.
+ // Shut down when we've sent everything.
+ LOG(LS_VERBOSE) << "Flow Control Lifted";
+ WriteData();
+ }
+
+ void ReadData() {
+ char block[kBlockSize];
+ size_t position;
+ int rcvd;
+ do {
+ rcvd = receiver_->Recv(block, sizeof(block));
+ if (rcvd != -1) {
+ recv_stream_.Write(block, rcvd, NULL, NULL);
+ recv_stream_.GetPosition(&position);
+ LOG(LS_VERBOSE) << "Received: " << position;
+ }
+ } while (rcvd > 0);
+ }
+ void WriteData() {
+ size_t position, tosend;
+ int sent;
+ char block[kBlockSize];
+ do {
+ send_stream_.GetPosition(&position);
+ tosend = bytes_per_send_ ? bytes_per_send_ : sizeof(block);
+ if (send_stream_.Read(block, tosend, &tosend, NULL) !=
+ rtc::SR_EOS) {
+ sent = sender_->Send(block, tosend);
+ UpdateLocalClock();
+ if (sent != -1) {
+ send_stream_.SetPosition(position + sent);
+ LOG(LS_VERBOSE) << "Sent: " << position + sent;
+ } else {
+ send_stream_.SetPosition(position);
+ LOG(LS_VERBOSE) << "Flow Controlled";
+ }
+ } else {
+ sent = static_cast<int>(tosend = 0);
+ }
+ } while (sent > 0);
+ }
+
+ private:
+ int iterations_remaining_;
+ PseudoTcp* sender_;
+ PseudoTcp* receiver_;
+ int bytes_per_send_;
+};
+
+// Fill the receiver window until it is full, drain it and then
+// fill it with the same amount. This is to test that receiver window
+// contracts and enlarges correctly.
+class PseudoTcpTestReceiveWindow : public PseudoTcpTestBase {
+ public:
+ // Not all the data are transfered, |size| just need to be big enough
+ // to fill up the receiver window twice.
+ void TestTransfer(int size) {
+ // Create some dummy data to send.
+ send_stream_.ReserveSize(size);
+ for (int i = 0; i < size; ++i) {
+ char ch = static_cast<char>(i);
+ send_stream_.Write(&ch, 1, NULL, NULL);
+ }
+ send_stream_.Rewind();
+
+ // Prepare the receive stream.
+ recv_stream_.ReserveSize(size);
+
+ // Connect and wait until connected.
+ EXPECT_EQ(0, Connect());
+ EXPECT_TRUE_WAIT(have_connected_, kConnectTimeoutMs);
+
+ rtc::Thread::Current()->Post(this, MSG_WRITE);
+ EXPECT_TRUE_WAIT(have_disconnected_, kTransferTimeoutMs);
+
+ ASSERT_EQ(2u, send_position_.size());
+ ASSERT_EQ(2u, recv_position_.size());
+
+ const size_t estimated_recv_window = EstimateReceiveWindowSize();
+
+ // The difference in consecutive send positions should equal the
+ // receive window size or match very closely. This verifies that receive
+ // window is open after receiver drained all the data.
+ const size_t send_position_diff = send_position_[1] - send_position_[0];
+ EXPECT_GE(1024u, estimated_recv_window - send_position_diff);
+
+ // Receiver drained the receive window twice.
+ EXPECT_EQ(2 * estimated_recv_window, recv_position_[1]);
+ }
+
+ virtual void OnMessage(rtc::Message* message) {
+ int message_id = message->message_id;
+ PseudoTcpTestBase::OnMessage(message);
+
+ switch (message_id) {
+ case MSG_WRITE: {
+ WriteData();
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ uint32 EstimateReceiveWindowSize() const {
+ return static_cast<uint32>(recv_position_[0]);
+ }
+
+ uint32 EstimateSendWindowSize() const {
+ return static_cast<uint32>(send_position_[0] - recv_position_[0]);
+ }
+
+ private:
+ // IPseudoTcpNotify interface
+ virtual void OnTcpReadable(PseudoTcp* tcp) {
+ }
+
+ virtual void OnTcpWriteable(PseudoTcp* tcp) {
+ }
+
+ void ReadUntilIOPending() {
+ char block[kBlockSize];
+ size_t position;
+ int rcvd;
+
+ do {
+ rcvd = remote_.Recv(block, sizeof(block));
+ if (rcvd != -1) {
+ recv_stream_.Write(block, rcvd, NULL, NULL);
+ recv_stream_.GetPosition(&position);
+ LOG(LS_VERBOSE) << "Received: " << position;
+ }
+ } while (rcvd > 0);
+
+ recv_stream_.GetPosition(&position);
+ recv_position_.push_back(position);
+
+ // Disconnect if we have done two transfers.
+ if (recv_position_.size() == 2u) {
+ Close();
+ OnTcpClosed(&remote_, 0);
+ } else {
+ WriteData();
+ }
+ }
+
+ void WriteData() {
+ size_t position, tosend;
+ int sent;
+ char block[kBlockSize];
+ do {
+ send_stream_.GetPosition(&position);
+ if (send_stream_.Read(block, sizeof(block), &tosend, NULL) !=
+ rtc::SR_EOS) {
+ sent = local_.Send(block, tosend);
+ UpdateLocalClock();
+ if (sent != -1) {
+ send_stream_.SetPosition(position + sent);
+ LOG(LS_VERBOSE) << "Sent: " << position + sent;
+ } else {
+ send_stream_.SetPosition(position);
+ LOG(LS_VERBOSE) << "Flow Controlled";
+ }
+ } else {
+ sent = static_cast<int>(tosend = 0);
+ }
+ } while (sent > 0);
+ // At this point, we've filled up the available space in the send queue.
+
+ int message_queue_size =
+ static_cast<int>(rtc::Thread::Current()->size());
+ // The message queue will always have at least 2 messages, an RCLOCK and
+ // an LCLOCK, since they are added back on the delay queue at the same time
+ // they are pulled off and therefore are never really removed.
+ if (message_queue_size > 2) {
+ // If there are non-clock messages remaining, attempt to continue sending
+ // after giving those messages time to process, which should free up the
+ // send buffer.
+ rtc::Thread::Current()->PostDelayed(10, this, MSG_WRITE);
+ } else {
+ if (!remote_.isReceiveBufferFull()) {
+ LOG(LS_ERROR) << "This shouldn't happen - the send buffer is full, "
+ << "the receive buffer is not, and there are no "
+ << "remaining messages to process.";
+ }
+ send_stream_.GetPosition(&position);
+ send_position_.push_back(position);
+
+ // Drain the receiver buffer.
+ ReadUntilIOPending();
+ }
+ }
+
+ private:
+ rtc::MemoryStream send_stream_;
+ rtc::MemoryStream recv_stream_;
+
+ std::vector<size_t> send_position_;
+ std::vector<size_t> recv_position_;
+};
+
+// Basic end-to-end data transfer tests
+
+// Test the normal case of sending data from one side to the other.
+TEST_F(PseudoTcpTest, TestSend) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ TestTransfer(1000000);
+}
+
+// Test sending data with a 50 ms RTT. Transmission should take longer due
+// to a slower ramp-up in send rate.
+TEST_F(PseudoTcpTest, TestSendWithDelay) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetDelay(50);
+ TestTransfer(1000000);
+}
+
+// Test sending data with packet loss. Transmission should take much longer due
+// to send back-off when loss occurs.
+TEST_F(PseudoTcpTest, TestSendWithLoss) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetLoss(10);
+ TestTransfer(100000); // less data so test runs faster
+}
+
+// Test sending data with a 50 ms RTT and 10% packet loss. Transmission should
+// take much longer due to send back-off and slower detection of loss.
+TEST_F(PseudoTcpTest, TestSendWithDelayAndLoss) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetDelay(50);
+ SetLoss(10);
+ TestTransfer(100000); // less data so test runs faster
+}
+
+// Test sending data with 10% packet loss and Nagling disabled. Transmission
+// should take about the same time as with Nagling enabled.
+TEST_F(PseudoTcpTest, TestSendWithLossAndOptNaglingOff) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetLoss(10);
+ SetOptNagling(false);
+ TestTransfer(100000); // less data so test runs faster
+}
+
+// Test sending data with 10% packet loss and Delayed ACK disabled.
+// Transmission should be slightly faster than with it enabled.
+TEST_F(PseudoTcpTest, TestSendWithLossAndOptAckDelayOff) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetLoss(10);
+ SetOptAckDelay(0);
+ TestTransfer(100000);
+}
+
+// Test sending data with 50ms delay and Nagling disabled.
+TEST_F(PseudoTcpTest, TestSendWithDelayAndOptNaglingOff) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetDelay(50);
+ SetOptNagling(false);
+ TestTransfer(100000); // less data so test runs faster
+}
+
+// Test sending data with 50ms delay and Delayed ACK disabled.
+TEST_F(PseudoTcpTest, TestSendWithDelayAndOptAckDelayOff) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetDelay(50);
+ SetOptAckDelay(0);
+ TestTransfer(100000); // less data so test runs faster
+}
+
+// Test a large receive buffer with a sender that doesn't support scaling.
+TEST_F(PseudoTcpTest, TestSendRemoteNoWindowScale) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetLocalOptRcvBuf(100000);
+ DisableRemoteWindowScale();
+ TestTransfer(1000000);
+}
+
+// Test a large sender-side receive buffer with a receiver that doesn't support
+// scaling.
+TEST_F(PseudoTcpTest, TestSendLocalNoWindowScale) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetRemoteOptRcvBuf(100000);
+ DisableLocalWindowScale();
+ TestTransfer(1000000);
+}
+
+// Test when both sides use window scaling.
+TEST_F(PseudoTcpTest, TestSendBothUseWindowScale) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetRemoteOptRcvBuf(100000);
+ SetLocalOptRcvBuf(100000);
+ TestTransfer(1000000);
+}
+
+// Test using a large window scale value.
+TEST_F(PseudoTcpTest, TestSendLargeInFlight) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetRemoteOptRcvBuf(100000);
+ SetLocalOptRcvBuf(100000);
+ SetOptSndBuf(150000);
+ TestTransfer(1000000);
+}
+
+TEST_F(PseudoTcpTest, TestSendBothUseLargeWindowScale) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetRemoteOptRcvBuf(1000000);
+ SetLocalOptRcvBuf(1000000);
+ TestTransfer(10000000);
+}
+
+// Test using a small receive buffer.
+TEST_F(PseudoTcpTest, TestSendSmallReceiveBuffer) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetRemoteOptRcvBuf(10000);
+ SetLocalOptRcvBuf(10000);
+ TestTransfer(1000000);
+}
+
+// Test using a very small receive buffer.
+TEST_F(PseudoTcpTest, TestSendVerySmallReceiveBuffer) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetRemoteOptRcvBuf(100);
+ SetLocalOptRcvBuf(100);
+ TestTransfer(100000);
+}
+
+// Ping-pong (request/response) tests
+
+// Test sending <= 1x MTU of data in each ping/pong. Should take <10ms.
+TEST_F(PseudoTcpTestPingPong, TestPingPong1xMtu) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ TestPingPong(100, 100);
+}
+
+// Test sending 2x-3x MTU of data in each ping/pong. Should take <10ms.
+TEST_F(PseudoTcpTestPingPong, TestPingPong3xMtu) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ TestPingPong(400, 100);
+}
+
+// Test sending 1x-2x MTU of data in each ping/pong.
+// Should take ~1s, due to interaction between Nagling and Delayed ACK.
+TEST_F(PseudoTcpTestPingPong, TestPingPong2xMtu) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ TestPingPong(2000, 5);
+}
+
+// Test sending 1x-2x MTU of data in each ping/pong with Delayed ACK off.
+// Should take <10ms.
+TEST_F(PseudoTcpTestPingPong, TestPingPong2xMtuWithAckDelayOff) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetOptAckDelay(0);
+ TestPingPong(2000, 100);
+}
+
+// Test sending 1x-2x MTU of data in each ping/pong with Nagling off.
+// Should take <10ms.
+TEST_F(PseudoTcpTestPingPong, TestPingPong2xMtuWithNaglingOff) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetOptNagling(false);
+ TestPingPong(2000, 5);
+}
+
+// Test sending a ping as pair of short (non-full) segments.
+// Should take ~1s, due to Delayed ACK interaction with Nagling.
+TEST_F(PseudoTcpTestPingPong, TestPingPongShortSegments) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetOptAckDelay(5000);
+ SetBytesPerSend(50); // i.e. two Send calls per payload
+ TestPingPong(100, 5);
+}
+
+// Test sending ping as a pair of short (non-full) segments, with Nagling off.
+// Should take <10ms.
+TEST_F(PseudoTcpTestPingPong, TestPingPongShortSegmentsWithNaglingOff) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetOptNagling(false);
+ SetBytesPerSend(50); // i.e. two Send calls per payload
+ TestPingPong(100, 5);
+}
+
+// Test sending <= 1x MTU of data ping/pong, in two segments, no Delayed ACK.
+// Should take ~1s.
+TEST_F(PseudoTcpTestPingPong, TestPingPongShortSegmentsWithAckDelayOff) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetBytesPerSend(50); // i.e. two Send calls per payload
+ SetOptAckDelay(0);
+ TestPingPong(100, 5);
+}
+
+// Test that receive window expands and contract correctly.
+TEST_F(PseudoTcpTestReceiveWindow, TestReceiveWindow) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetOptNagling(false);
+ SetOptAckDelay(0);
+ TestTransfer(1024 * 1000);
+}
+
+// Test setting send window size to a very small value.
+TEST_F(PseudoTcpTestReceiveWindow, TestSetVerySmallSendWindowSize) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetOptNagling(false);
+ SetOptAckDelay(0);
+ SetOptSndBuf(900);
+ TestTransfer(1024 * 1000);
+ EXPECT_EQ(900u, EstimateSendWindowSize());
+}
+
+// Test setting receive window size to a value other than default.
+TEST_F(PseudoTcpTestReceiveWindow, TestSetReceiveWindowSize) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1500);
+ SetOptNagling(false);
+ SetOptAckDelay(0);
+ SetRemoteOptRcvBuf(100000);
+ SetLocalOptRcvBuf(100000);
+ TestTransfer(1024 * 1000);
+ EXPECT_EQ(100000u, EstimateReceiveWindowSize());
+}
+
+/* Test sending data with mismatched MTUs. We should detect this and reduce
+// our packet size accordingly.
+// TODO: This doesn't actually work right now. The current code
+// doesn't detect if the MTU is set too high on either side.
+TEST_F(PseudoTcpTest, TestSendWithMismatchedMtus) {
+ SetLocalMtu(1500);
+ SetRemoteMtu(1280);
+ TestTransfer(1000000);
+}
+*/
diff --git a/p2p/base/rawtransport.cc b/p2p/base/rawtransport.cc
new file mode 100644
index 00000000..374ed984
--- /dev/null
+++ b/p2p/base/rawtransport.cc
@@ -0,0 +1,115 @@
+/*
+ * 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 <string>
+#include <vector>
+#include "webrtc/p2p/base/constants.h"
+#include "webrtc/p2p/base/parsing.h"
+#include "webrtc/p2p/base/rawtransport.h"
+#include "webrtc/p2p/base/rawtransportchannel.h"
+#include "webrtc/p2p/base/sessionmanager.h"
+#include "webrtc/libjingle/xmllite/qname.h"
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/base/common.h"
+
+#if defined(FEATURE_ENABLE_PSTN)
+namespace cricket {
+
+RawTransport::RawTransport(rtc::Thread* signaling_thread,
+ rtc::Thread* worker_thread,
+ const std::string& content_name,
+ PortAllocator* allocator)
+ : Transport(signaling_thread, worker_thread,
+ content_name, NS_GINGLE_RAW, allocator) {
+}
+
+RawTransport::~RawTransport() {
+ DestroyAllChannels();
+}
+
+bool RawTransport::ParseCandidates(SignalingProtocol protocol,
+ const buzz::XmlElement* elem,
+ const CandidateTranslator* translator,
+ Candidates* candidates,
+ ParseError* error) {
+ for (const buzz::XmlElement* cand_elem = elem->FirstElement();
+ cand_elem != NULL;
+ cand_elem = cand_elem->NextElement()) {
+ if (cand_elem->Name() == QN_GINGLE_RAW_CHANNEL) {
+ if (!cand_elem->HasAttr(buzz::QN_NAME)) {
+ return BadParse("no channel name given", error);
+ }
+ if (type() != cand_elem->Attr(buzz::QN_NAME)) {
+ return BadParse("channel named does not exist", error);
+ }
+ rtc::SocketAddress addr;
+ if (!ParseRawAddress(cand_elem, &addr, error))
+ return false;
+
+ Candidate candidate;
+ candidate.set_component(1);
+ candidate.set_address(addr);
+ candidates->push_back(candidate);
+ }
+ }
+ return true;
+}
+
+bool RawTransport::WriteCandidates(SignalingProtocol protocol,
+ const Candidates& candidates,
+ const CandidateTranslator* translator,
+ XmlElements* candidate_elems,
+ WriteError* error) {
+ for (std::vector<Candidate>::const_iterator
+ cand = candidates.begin();
+ cand != candidates.end();
+ ++cand) {
+ ASSERT(cand->component() == 1);
+ ASSERT(cand->protocol() == "udp");
+ rtc::SocketAddress addr = cand->address();
+
+ buzz::XmlElement* elem = new buzz::XmlElement(QN_GINGLE_RAW_CHANNEL);
+ elem->SetAttr(buzz::QN_NAME, type());
+ elem->SetAttr(QN_ADDRESS, addr.ipaddr().ToString());
+ elem->SetAttr(QN_PORT, addr.PortAsString());
+ candidate_elems->push_back(elem);
+ }
+ return true;
+}
+
+bool RawTransport::ParseRawAddress(const buzz::XmlElement* elem,
+ rtc::SocketAddress* addr,
+ ParseError* error) {
+ // Make sure the required attributes exist
+ if (!elem->HasAttr(QN_ADDRESS) ||
+ !elem->HasAttr(QN_PORT)) {
+ return BadParse("channel missing required attribute", error);
+ }
+
+ // Parse the address.
+ if (!ParseAddress(elem, QN_ADDRESS, QN_PORT, addr, error))
+ return false;
+
+ return true;
+}
+
+TransportChannelImpl* RawTransport::CreateTransportChannel(int component) {
+ return new RawTransportChannel(content_name(), component, this,
+ worker_thread(),
+ port_allocator());
+}
+
+void RawTransport::DestroyTransportChannel(TransportChannelImpl* channel) {
+ delete channel;
+}
+
+} // namespace cricket
+#endif // defined(FEATURE_ENABLE_PSTN)
diff --git a/p2p/base/rawtransport.h b/p2p/base/rawtransport.h
new file mode 100644
index 00000000..dbe8f986
--- /dev/null
+++ b/p2p/base/rawtransport.h
@@ -0,0 +1,64 @@
+/*
+ * 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 WEBRTC_P2P_BASE_RAWTRANSPORT_H_
+#define WEBRTC_P2P_BASE_RAWTRANSPORT_H_
+
+#include <string>
+#include "webrtc/p2p/base/transport.h"
+
+#if defined(FEATURE_ENABLE_PSTN)
+namespace cricket {
+
+// Implements a transport that only sends raw packets, no STUN. As a result,
+// it cannot do pings to determine connectivity, so it only uses a single port
+// that it thinks will work.
+class RawTransport : public Transport, public TransportParser {
+ public:
+ RawTransport(rtc::Thread* signaling_thread,
+ rtc::Thread* worker_thread,
+ const std::string& content_name,
+ PortAllocator* allocator);
+ virtual ~RawTransport();
+
+ virtual bool ParseCandidates(SignalingProtocol protocol,
+ const buzz::XmlElement* elem,
+ const CandidateTranslator* translator,
+ Candidates* candidates,
+ ParseError* error);
+ virtual bool WriteCandidates(SignalingProtocol protocol,
+ const Candidates& candidates,
+ const CandidateTranslator* translator,
+ XmlElements* candidate_elems,
+ WriteError* error);
+
+ protected:
+ // Creates and destroys raw channels.
+ virtual TransportChannelImpl* CreateTransportChannel(int component);
+ virtual void DestroyTransportChannel(TransportChannelImpl* channel);
+
+ private:
+ // Parses the given element, which should describe the address to use for a
+ // given channel. This will return false and signal an error if the address
+ // or channel name is bad.
+ bool ParseRawAddress(const buzz::XmlElement* elem,
+ rtc::SocketAddress* addr,
+ ParseError* error);
+
+ friend class RawTransportChannel; // For ParseAddress.
+
+ DISALLOW_EVIL_CONSTRUCTORS(RawTransport);
+};
+
+} // namespace cricket
+
+#endif // defined(FEATURE_ENABLE_PSTN)
+
+#endif // WEBRTC_P2P_BASE_RAWTRANSPORT_H_
diff --git a/p2p/base/rawtransportchannel.cc b/p2p/base/rawtransportchannel.cc
new file mode 100644
index 00000000..5779c6e5
--- /dev/null
+++ b/p2p/base/rawtransportchannel.cc
@@ -0,0 +1,260 @@
+/*
+ * 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 "webrtc/p2p/base/rawtransportchannel.h"
+
+#include <string>
+#include <vector>
+#include "webrtc/p2p/base/constants.h"
+#include "webrtc/p2p/base/portallocator.h"
+#include "webrtc/p2p/base/portinterface.h"
+#include "webrtc/p2p/base/rawtransport.h"
+#include "webrtc/p2p/base/relayport.h"
+#include "webrtc/p2p/base/sessionmanager.h"
+#include "webrtc/p2p/base/stunport.h"
+#include "webrtc/libjingle/xmllite/qname.h"
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/base/common.h"
+
+#if defined(FEATURE_ENABLE_PSTN)
+
+namespace {
+
+const uint32 MSG_DESTROY_RTC_UNUSED_PORTS = 1;
+
+} // namespace
+
+namespace cricket {
+
+RawTransportChannel::RawTransportChannel(const std::string& content_name,
+ int component,
+ RawTransport* transport,
+ rtc::Thread *worker_thread,
+ PortAllocator *allocator)
+ : TransportChannelImpl(content_name, component),
+ raw_transport_(transport),
+ allocator_(allocator),
+ allocator_session_(NULL),
+ stun_port_(NULL),
+ relay_port_(NULL),
+ port_(NULL),
+ use_relay_(false) {
+ if (worker_thread == NULL)
+ worker_thread_ = raw_transport_->worker_thread();
+ else
+ worker_thread_ = worker_thread;
+}
+
+RawTransportChannel::~RawTransportChannel() {
+ delete allocator_session_;
+}
+
+int RawTransportChannel::SendPacket(const char *data, size_t size,
+ const rtc::PacketOptions& options,
+ int flags) {
+ if (port_ == NULL)
+ return -1;
+ if (remote_address_.IsNil())
+ return -1;
+ if (flags != 0)
+ return -1;
+ return port_->SendTo(data, size, remote_address_, options, true);
+}
+
+int RawTransportChannel::SetOption(rtc::Socket::Option opt, int value) {
+ // TODO: allow these to be set before we have a port
+ if (port_ == NULL)
+ return -1;
+ return port_->SetOption(opt, value);
+}
+
+int RawTransportChannel::GetError() {
+ return (port_ != NULL) ? port_->GetError() : 0;
+}
+
+void RawTransportChannel::Connect() {
+ // Create an allocator that only returns stun and relay ports.
+ // Use empty string for ufrag and pwd here. There won't be any STUN or relay
+ // interactions when using RawTC.
+ // TODO: Change raw to only use local udp ports.
+ allocator_session_ = allocator_->CreateSession(
+ SessionId(), content_name(), component(), "", "");
+
+ uint32 flags = PORTALLOCATOR_DISABLE_UDP | PORTALLOCATOR_DISABLE_TCP;
+
+#if !defined(FEATURE_ENABLE_STUN_CLASSIFICATION)
+ flags |= PORTALLOCATOR_DISABLE_RELAY;
+#endif
+ allocator_session_->set_flags(flags);
+ allocator_session_->SignalPortReady.connect(
+ this, &RawTransportChannel::OnPortReady);
+ allocator_session_->SignalCandidatesReady.connect(
+ this, &RawTransportChannel::OnCandidatesReady);
+
+ // The initial ports will include stun.
+ allocator_session_->StartGettingPorts();
+}
+
+void RawTransportChannel::Reset() {
+ set_readable(false);
+ set_writable(false);
+
+ delete allocator_session_;
+
+ allocator_session_ = NULL;
+ stun_port_ = NULL;
+ relay_port_ = NULL;
+ port_ = NULL;
+ remote_address_ = rtc::SocketAddress();
+}
+
+void RawTransportChannel::OnCandidate(const Candidate& candidate) {
+ remote_address_ = candidate.address();
+ ASSERT(!remote_address_.IsNil());
+ set_readable(true);
+
+ // We can write once we have a port and a remote address.
+ if (port_ != NULL)
+ SetWritable();
+}
+
+void RawTransportChannel::OnRemoteAddress(
+ const rtc::SocketAddress& remote_address) {
+ remote_address_ = remote_address;
+ set_readable(true);
+
+ if (port_ != NULL)
+ SetWritable();
+}
+
+// Note about stun classification
+// Code to classify our NAT type and use the relay port if we are behind an
+// asymmetric NAT is under a FEATURE_ENABLE_STUN_CLASSIFICATION #define.
+// To turn this one we will have to enable a second stun address and make sure
+// that the relay server works for raw UDP.
+//
+// Another option is to classify the NAT type early and not offer the raw
+// transport type at all if we can't support it.
+
+void RawTransportChannel::OnPortReady(
+ PortAllocatorSession* session, PortInterface* port) {
+ ASSERT(session == allocator_session_);
+
+ if (port->Type() == STUN_PORT_TYPE) {
+ stun_port_ = static_cast<StunPort*>(port);
+ } else if (port->Type() == RELAY_PORT_TYPE) {
+ relay_port_ = static_cast<RelayPort*>(port);
+ } else {
+ ASSERT(false);
+ }
+}
+
+void RawTransportChannel::OnCandidatesReady(
+ PortAllocatorSession *session, const std::vector<Candidate>& candidates) {
+ ASSERT(session == allocator_session_);
+ ASSERT(candidates.size() >= 1);
+
+ // The most recent candidate is the one we haven't seen yet.
+ Candidate c = candidates[candidates.size() - 1];
+
+ if (c.type() == STUN_PORT_TYPE) {
+ ASSERT(stun_port_ != NULL);
+
+#if defined(FEATURE_ENABLE_STUN_CLASSIFICATION)
+ // We need to wait until we have two addresses.
+ if (stun_port_->candidates().size() < 2)
+ return;
+
+ // This is the second address. If these addresses are the same, then we
+ // are not behind a symmetric NAT. Hence, a stun port should be sufficient.
+ if (stun_port_->candidates()[0].address() ==
+ stun_port_->candidates()[1].address()) {
+ SetPort(stun_port_);
+ return;
+ }
+
+ // We will need to use relay.
+ use_relay_ = true;
+
+ // If we already have a relay address, we're good. Otherwise, we will need
+ // to wait until one arrives.
+ if (relay_port_->candidates().size() > 0)
+ SetPort(relay_port_);
+#else // defined(FEATURE_ENABLE_STUN_CLASSIFICATION)
+ // Always use the stun port. We don't classify right now so just assume it
+ // will work fine.
+ SetPort(stun_port_);
+#endif
+ } else if (c.type() == RELAY_PORT_TYPE) {
+ if (use_relay_)
+ SetPort(relay_port_);
+ } else {
+ ASSERT(false);
+ }
+}
+
+void RawTransportChannel::SetPort(PortInterface* port) {
+ ASSERT(port_ == NULL);
+ port_ = port;
+
+ // We don't need any ports other than the one we picked.
+ allocator_session_->StopGettingPorts();
+ worker_thread_->Post(
+ this, MSG_DESTROY_RTC_UNUSED_PORTS, NULL);
+
+ // Send a message to the other client containing our address.
+
+ ASSERT(port_->Candidates().size() >= 1);
+ ASSERT(port_->Candidates()[0].protocol() == "udp");
+ SignalCandidateReady(this, port_->Candidates()[0]);
+
+ // Read all packets from this port.
+ port_->EnablePortPackets();
+ port_->SignalReadPacket.connect(this, &RawTransportChannel::OnReadPacket);
+
+ // We can write once we have a port and a remote address.
+ if (!remote_address_.IsAny())
+ SetWritable();
+}
+
+void RawTransportChannel::SetWritable() {
+ ASSERT(port_ != NULL);
+ ASSERT(!remote_address_.IsAny());
+
+ set_writable(true);
+
+ Candidate remote_candidate;
+ remote_candidate.set_address(remote_address_);
+ SignalRouteChange(this, remote_candidate);
+}
+
+void RawTransportChannel::OnReadPacket(
+ PortInterface* port, const char* data, size_t size,
+ const rtc::SocketAddress& addr) {
+ ASSERT(port_ == port);
+ SignalReadPacket(this, data, size, rtc::CreatePacketTime(0), 0);
+}
+
+void RawTransportChannel::OnMessage(rtc::Message* msg) {
+ ASSERT(msg->message_id == MSG_DESTROY_RTC_UNUSED_PORTS);
+ ASSERT(port_ != NULL);
+ if (port_ != stun_port_) {
+ stun_port_->Destroy();
+ stun_port_ = NULL;
+ }
+ if (port_ != relay_port_ && relay_port_ != NULL) {
+ relay_port_->Destroy();
+ relay_port_ = NULL;
+ }
+}
+
+} // namespace cricket
+#endif // defined(FEATURE_ENABLE_PSTN)
diff --git a/p2p/base/rawtransportchannel.h b/p2p/base/rawtransportchannel.h
new file mode 100644
index 00000000..3041cad2
--- /dev/null
+++ b/p2p/base/rawtransportchannel.h
@@ -0,0 +1,189 @@
+/*
+ * 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 WEBRTC_P2P_BASE_RAWTRANSPORTCHANNEL_H_
+#define WEBRTC_P2P_BASE_RAWTRANSPORTCHANNEL_H_
+
+#include <string>
+#include <vector>
+#include "webrtc/p2p/base/candidate.h"
+#include "webrtc/p2p/base/rawtransport.h"
+#include "webrtc/p2p/base/transportchannelimpl.h"
+#include "webrtc/base/messagequeue.h"
+
+#if defined(FEATURE_ENABLE_PSTN)
+
+namespace rtc {
+class Thread;
+}
+
+namespace cricket {
+
+class Connection;
+class PortAllocator;
+class PortAllocatorSession;
+class PortInterface;
+class RelayPort;
+class StunPort;
+
+// Implements a channel that just sends bare packets once we have received the
+// address of the other side. We pick a single address to send them based on
+// a simple investigation of NAT type.
+class RawTransportChannel : public TransportChannelImpl,
+ public rtc::MessageHandler {
+ public:
+ RawTransportChannel(const std::string& content_name,
+ int component,
+ RawTransport* transport,
+ rtc::Thread *worker_thread,
+ PortAllocator *allocator);
+ virtual ~RawTransportChannel();
+
+ // Implementation of normal channel packet sending.
+ virtual int SendPacket(const char *data, size_t len,
+ const rtc::PacketOptions& options, int flags);
+ virtual int SetOption(rtc::Socket::Option opt, int value);
+ virtual int GetError();
+
+ // Implements TransportChannelImpl.
+ virtual Transport* GetTransport() { return raw_transport_; }
+ virtual void SetIceCredentials(const std::string& ice_ufrag,
+ const std::string& ice_pwd) {}
+ virtual void SetRemoteIceCredentials(const std::string& ice_ufrag,
+ const std::string& ice_pwd) {}
+
+ // Creates an allocator session to start figuring out which type of
+ // port we should send to the other client. This will send
+ // SignalAvailableCandidate once we have decided.
+ virtual void Connect();
+
+ // Resets state back to unconnected.
+ virtual void Reset();
+
+ // We don't actually worry about signaling since we can't send new candidates.
+ virtual void OnSignalingReady() {}
+
+ // Handles a message setting the remote address. We are writable once we
+ // have this since we now know where to send.
+ virtual void OnCandidate(const Candidate& candidate);
+
+ void OnRemoteAddress(const rtc::SocketAddress& remote_address);
+
+ // Below ICE specific virtual methods not implemented.
+ virtual IceRole GetIceRole() const { return ICEROLE_UNKNOWN; }
+ virtual void SetIceRole(IceRole role) {}
+ virtual void SetIceTiebreaker(uint64 tiebreaker) {}
+
+ virtual bool GetIceProtocolType(IceProtocolType* type) const { return false; }
+ virtual void SetIceProtocolType(IceProtocolType type) {}
+
+ virtual void SetIceUfrag(const std::string& ice_ufrag) {}
+ virtual void SetIcePwd(const std::string& ice_pwd) {}
+ virtual void SetRemoteIceMode(IceMode mode) {}
+ virtual size_t GetConnectionCount() const { return 1; }
+
+ virtual bool GetStats(ConnectionInfos* infos) {
+ return false;
+ }
+
+ // DTLS methods.
+ virtual bool IsDtlsActive() const { return false; }
+
+ // Default implementation.
+ virtual bool GetSslRole(rtc::SSLRole* role) const {
+ return false;
+ }
+
+ virtual bool SetSslRole(rtc::SSLRole role) {
+ return false;
+ }
+
+ // Set up the ciphers to use for DTLS-SRTP.
+ virtual bool SetSrtpCiphers(const std::vector<std::string>& ciphers) {
+ return false;
+ }
+
+ // Find out which DTLS-SRTP cipher was negotiated
+ virtual bool GetSrtpCipher(std::string* cipher) {
+ return false;
+ }
+
+ // Returns false because the channel is not DTLS.
+ virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const {
+ return false;
+ }
+
+ virtual bool GetRemoteCertificate(rtc::SSLCertificate** cert) const {
+ return false;
+ }
+
+ // Allows key material to be extracted for external encryption.
+ virtual bool ExportKeyingMaterial(
+ const std::string& label,
+ const uint8* context,
+ size_t context_len,
+ bool use_context,
+ uint8* result,
+ size_t result_len) {
+ return false;
+ }
+
+ virtual bool SetLocalIdentity(rtc::SSLIdentity* identity) {
+ return false;
+ }
+
+ // Set DTLS Remote fingerprint. Must be after local identity set.
+ virtual bool SetRemoteFingerprint(
+ const std::string& digest_alg,
+ const uint8* digest,
+ size_t digest_len) {
+ return false;
+ }
+
+ private:
+ RawTransport* raw_transport_;
+ rtc::Thread *worker_thread_;
+ PortAllocator* allocator_;
+ PortAllocatorSession* allocator_session_;
+ StunPort* stun_port_;
+ RelayPort* relay_port_;
+ PortInterface* port_;
+ bool use_relay_;
+ rtc::SocketAddress remote_address_;
+
+ // Called when the allocator creates another port.
+ void OnPortReady(PortAllocatorSession* session, PortInterface* port);
+
+ // Called when one of the ports we are using has determined its address.
+ void OnCandidatesReady(PortAllocatorSession *session,
+ const std::vector<Candidate>& candidates);
+
+ // Called once we have chosen the port to use for communication with the
+ // other client. This will send its address and prepare the port for use.
+ void SetPort(PortInterface* port);
+
+ // Called once we have a port and a remote address. This will set mark the
+ // channel as writable and signal the route to the client.
+ void SetWritable();
+
+ // Called when we receive a packet from the other client.
+ void OnReadPacket(PortInterface* port, const char* data, size_t size,
+ const rtc::SocketAddress& addr);
+
+ // Handles a message to destroy unused ports.
+ virtual void OnMessage(rtc::Message *msg);
+
+ DISALLOW_EVIL_CONSTRUCTORS(RawTransportChannel);
+};
+
+} // namespace cricket
+
+#endif // defined(FEATURE_ENABLE_PSTN)
+#endif // WEBRTC_P2P_BASE_RAWTRANSPORTCHANNEL_H_
diff --git a/p2p/base/relayport.cc b/p2p/base/relayport.cc
new file mode 100644
index 00000000..4c40b3da
--- /dev/null
+++ b/p2p/base/relayport.cc
@@ -0,0 +1,818 @@
+/*
+ * 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 "webrtc/p2p/base/relayport.h"
+#include "webrtc/base/asyncpacketsocket.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/logging.h"
+
+namespace cricket {
+
+static const uint32 kMessageConnectTimeout = 1;
+static const int kKeepAliveDelay = 10 * 60 * 1000;
+static const int kRetryTimeout = 50 * 1000; // ICE says 50 secs
+// How long to wait for a socket to connect to remote host in milliseconds
+// before trying another connection.
+static const int kSoftConnectTimeoutMs = 3 * 1000;
+
+// Handles a connection to one address/port/protocol combination for a
+// particular RelayEntry.
+class RelayConnection : public sigslot::has_slots<> {
+ public:
+ RelayConnection(const ProtocolAddress* protocol_address,
+ rtc::AsyncPacketSocket* socket,
+ rtc::Thread* thread);
+ ~RelayConnection();
+ rtc::AsyncPacketSocket* socket() const { return socket_; }
+
+ const ProtocolAddress* protocol_address() {
+ return protocol_address_;
+ }
+
+ rtc::SocketAddress GetAddress() const {
+ return protocol_address_->address;
+ }
+
+ ProtocolType GetProtocol() const {
+ return protocol_address_->proto;
+ }
+
+ int SetSocketOption(rtc::Socket::Option opt, int value);
+
+ // Validates a response to a STUN allocate request.
+ bool CheckResponse(StunMessage* msg);
+
+ // Sends data to the relay server.
+ int Send(const void* pv, size_t cb, const rtc::PacketOptions& options);
+
+ // Sends a STUN allocate request message to the relay server.
+ void SendAllocateRequest(RelayEntry* entry, int delay);
+
+ // Return the latest error generated by the socket.
+ int GetError() { return socket_->GetError(); }
+
+ // Called on behalf of a StunRequest to write data to the socket. This is
+ // already STUN intended for the server, so no wrapping is necessary.
+ void OnSendPacket(const void* data, size_t size, StunRequest* req);
+
+ private:
+ rtc::AsyncPacketSocket* socket_;
+ const ProtocolAddress* protocol_address_;
+ StunRequestManager *request_manager_;
+};
+
+// Manages a number of connections to the relayserver, one for each
+// available protocol. We aim to use each connection for only a
+// specific destination address so that we can avoid wrapping every
+// packet in a STUN send / data indication.
+class RelayEntry : public rtc::MessageHandler,
+ public sigslot::has_slots<> {
+ public:
+ RelayEntry(RelayPort* port, const rtc::SocketAddress& ext_addr);
+ ~RelayEntry();
+
+ RelayPort* port() { return port_; }
+
+ const rtc::SocketAddress& address() const { return ext_addr_; }
+ void set_address(const rtc::SocketAddress& addr) { ext_addr_ = addr; }
+
+ bool connected() const { return connected_; }
+ bool locked() const { return locked_; }
+
+ // Returns the last error on the socket of this entry.
+ int GetError();
+
+ // Returns the most preferred connection of the given
+ // ones. Connections are rated based on protocol in the order of:
+ // UDP, TCP and SSLTCP, where UDP is the most preferred protocol
+ static RelayConnection* GetBestConnection(RelayConnection* conn1,
+ RelayConnection* conn2);
+
+ // Sends the STUN requests to the server to initiate this connection.
+ void Connect();
+
+ // Called when this entry becomes connected. The address given is the one
+ // exposed to the outside world on the relay server.
+ void OnConnect(const rtc::SocketAddress& mapped_addr,
+ RelayConnection* socket);
+
+ // Sends a packet to the given destination address using the socket of this
+ // entry. This will wrap the packet in STUN if necessary.
+ int SendTo(const void* data, size_t size,
+ const rtc::SocketAddress& addr,
+ const rtc::PacketOptions& options);
+
+ // Schedules a keep-alive allocate request.
+ void ScheduleKeepAlive();
+
+ void SetServerIndex(size_t sindex) { server_index_ = sindex; }
+
+ // Sets this option on the socket of each connection.
+ int SetSocketOption(rtc::Socket::Option opt, int value);
+
+ size_t ServerIndex() const { return server_index_; }
+
+ // Try a different server address
+ void HandleConnectFailure(rtc::AsyncPacketSocket* socket);
+
+ // Implementation of the MessageHandler Interface.
+ virtual void OnMessage(rtc::Message *pmsg);
+
+ private:
+ RelayPort* port_;
+ rtc::SocketAddress ext_addr_;
+ size_t server_index_;
+ bool connected_;
+ bool locked_;
+ RelayConnection* current_connection_;
+
+ // Called when a TCP connection is established or fails
+ void OnSocketConnect(rtc::AsyncPacketSocket* socket);
+ void OnSocketClose(rtc::AsyncPacketSocket* socket, int error);
+
+ // Called when a packet is received on this socket.
+ void OnReadPacket(
+ rtc::AsyncPacketSocket* socket,
+ const char* data, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time);
+ // Called when the socket is currently able to send.
+ void OnReadyToSend(rtc::AsyncPacketSocket* socket);
+
+ // Sends the given data on the socket to the server with no wrapping. This
+ // returns the number of bytes written or -1 if an error occurred.
+ int SendPacket(const void* data, size_t size,
+ const rtc::PacketOptions& options);
+};
+
+// Handles an allocate request for a particular RelayEntry.
+class AllocateRequest : public StunRequest {
+ public:
+ AllocateRequest(RelayEntry* entry, RelayConnection* connection);
+ virtual ~AllocateRequest() {}
+
+ virtual void Prepare(StunMessage* request);
+
+ virtual int GetNextDelay();
+
+ virtual void OnResponse(StunMessage* response);
+ virtual void OnErrorResponse(StunMessage* response);
+ virtual void OnTimeout();
+
+ private:
+ RelayEntry* entry_;
+ RelayConnection* connection_;
+ uint32 start_time_;
+};
+
+RelayPort::RelayPort(
+ rtc::Thread* thread, rtc::PacketSocketFactory* factory,
+ rtc::Network* network, const rtc::IPAddress& ip,
+ int min_port, int max_port, const std::string& username,
+ const std::string& password)
+ : Port(thread, RELAY_PORT_TYPE, factory, network, ip, min_port, max_port,
+ username, password),
+ ready_(false),
+ error_(0) {
+ entries_.push_back(
+ new RelayEntry(this, rtc::SocketAddress()));
+ // TODO: set local preference value for TCP based candidates.
+}
+
+RelayPort::~RelayPort() {
+ for (size_t i = 0; i < entries_.size(); ++i)
+ delete entries_[i];
+ thread()->Clear(this);
+}
+
+void RelayPort::AddServerAddress(const ProtocolAddress& addr) {
+ // Since HTTP proxies usually only allow 443,
+ // let's up the priority on PROTO_SSLTCP
+ if (addr.proto == PROTO_SSLTCP &&
+ (proxy().type == rtc::PROXY_HTTPS ||
+ proxy().type == rtc::PROXY_UNKNOWN)) {
+ server_addr_.push_front(addr);
+ } else {
+ server_addr_.push_back(addr);
+ }
+}
+
+void RelayPort::AddExternalAddress(const ProtocolAddress& addr) {
+ std::string proto_name = ProtoToString(addr.proto);
+ for (std::vector<ProtocolAddress>::iterator it = external_addr_.begin();
+ it != external_addr_.end(); ++it) {
+ if ((it->address == addr.address) && (it->proto == addr.proto)) {
+ LOG(INFO) << "Redundant relay address: " << proto_name
+ << " @ " << addr.address.ToSensitiveString();
+ return;
+ }
+ }
+ external_addr_.push_back(addr);
+}
+
+void RelayPort::SetReady() {
+ if (!ready_) {
+ std::vector<ProtocolAddress>::iterator iter;
+ for (iter = external_addr_.begin();
+ iter != external_addr_.end(); ++iter) {
+ std::string proto_name = ProtoToString(iter->proto);
+ // In case of Gturn, related address is set to null socket address.
+ // This is due to as mapped address stun attribute is used for allocated
+ // address.
+ AddAddress(iter->address, iter->address, rtc::SocketAddress(),
+ proto_name, "", RELAY_PORT_TYPE,
+ ICE_TYPE_PREFERENCE_RELAY, 0, false);
+ }
+ ready_ = true;
+ SignalPortComplete(this);
+ }
+}
+
+const ProtocolAddress * RelayPort::ServerAddress(size_t index) const {
+ if (index < server_addr_.size())
+ return &server_addr_[index];
+ return NULL;
+}
+
+bool RelayPort::HasMagicCookie(const char* data, size_t size) {
+ if (size < 24 + sizeof(TURN_MAGIC_COOKIE_VALUE)) {
+ return false;
+ } else {
+ return memcmp(data + 24,
+ TURN_MAGIC_COOKIE_VALUE,
+ sizeof(TURN_MAGIC_COOKIE_VALUE)) == 0;
+ }
+}
+
+void RelayPort::PrepareAddress() {
+ // We initiate a connect on the first entry. If this completes, it will fill
+ // in the server address as the address of this port.
+ ASSERT(entries_.size() == 1);
+ entries_[0]->Connect();
+ ready_ = false;
+}
+
+Connection* RelayPort::CreateConnection(const Candidate& address,
+ CandidateOrigin origin) {
+ // We only create conns to non-udp sockets if they are incoming on this port
+ if ((address.protocol() != UDP_PROTOCOL_NAME) &&
+ (origin != ORIGIN_THIS_PORT)) {
+ return 0;
+ }
+
+ // We don't support loopback on relays
+ if (address.type() == Type()) {
+ return 0;
+ }
+
+ if (!IsCompatibleAddress(address.address())) {
+ return 0;
+ }
+
+ size_t index = 0;
+ for (size_t i = 0; i < Candidates().size(); ++i) {
+ const Candidate& local = Candidates()[i];
+ if (local.protocol() == address.protocol()) {
+ index = i;
+ break;
+ }
+ }
+
+ Connection * conn = new ProxyConnection(this, index, address);
+ AddConnection(conn);
+ return conn;
+}
+
+int RelayPort::SendTo(const void* data, size_t size,
+ const rtc::SocketAddress& addr,
+ const rtc::PacketOptions& options,
+ bool payload) {
+ // Try to find an entry for this specific address. Note that the first entry
+ // created was not given an address initially, so it can be set to the first
+ // address that comes along.
+ RelayEntry* entry = 0;
+
+ for (size_t i = 0; i < entries_.size(); ++i) {
+ if (entries_[i]->address().IsNil() && payload) {
+ entry = entries_[i];
+ entry->set_address(addr);
+ break;
+ } else if (entries_[i]->address() == addr) {
+ entry = entries_[i];
+ break;
+ }
+ }
+
+ // If we did not find one, then we make a new one. This will not be useable
+ // until it becomes connected, however.
+ if (!entry && payload) {
+ entry = new RelayEntry(this, addr);
+ if (!entries_.empty()) {
+ entry->SetServerIndex(entries_[0]->ServerIndex());
+ }
+ entry->Connect();
+ entries_.push_back(entry);
+ }
+
+ // If the entry is connected, then we can send on it (though wrapping may
+ // still be necessary). Otherwise, we can't yet use this connection, so we
+ // default to the first one.
+ if (!entry || !entry->connected()) {
+ ASSERT(!entries_.empty());
+ entry = entries_[0];
+ if (!entry->connected()) {
+ error_ = EWOULDBLOCK;
+ return SOCKET_ERROR;
+ }
+ }
+
+ // Send the actual contents to the server using the usual mechanism.
+ int sent = entry->SendTo(data, size, addr, options);
+ if (sent <= 0) {
+ ASSERT(sent < 0);
+ error_ = entry->GetError();
+ return SOCKET_ERROR;
+ }
+ // The caller of the function is expecting the number of user data bytes,
+ // rather than the size of the packet.
+ return static_cast<int>(size);
+}
+
+int RelayPort::SetOption(rtc::Socket::Option opt, int value) {
+ int result = 0;
+ for (size_t i = 0; i < entries_.size(); ++i) {
+ if (entries_[i]->SetSocketOption(opt, value) < 0) {
+ result = -1;
+ error_ = entries_[i]->GetError();
+ }
+ }
+ options_.push_back(OptionValue(opt, value));
+ return result;
+}
+
+int RelayPort::GetOption(rtc::Socket::Option opt, int* value) {
+ std::vector<OptionValue>::iterator it;
+ for (it = options_.begin(); it < options_.end(); ++it) {
+ if (it->first == opt) {
+ *value = it->second;
+ return 0;
+ }
+ }
+ return SOCKET_ERROR;
+}
+
+int RelayPort::GetError() {
+ return error_;
+}
+
+void RelayPort::OnReadPacket(
+ const char* data, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ ProtocolType proto,
+ const rtc::PacketTime& packet_time) {
+ if (Connection* conn = GetConnection(remote_addr)) {
+ conn->OnReadPacket(data, size, packet_time);
+ } else {
+ Port::OnReadPacket(data, size, remote_addr, proto);
+ }
+}
+
+RelayConnection::RelayConnection(const ProtocolAddress* protocol_address,
+ rtc::AsyncPacketSocket* socket,
+ rtc::Thread* thread)
+ : socket_(socket),
+ protocol_address_(protocol_address) {
+ request_manager_ = new StunRequestManager(thread);
+ request_manager_->SignalSendPacket.connect(this,
+ &RelayConnection::OnSendPacket);
+}
+
+RelayConnection::~RelayConnection() {
+ delete request_manager_;
+ delete socket_;
+}
+
+int RelayConnection::SetSocketOption(rtc::Socket::Option opt,
+ int value) {
+ if (socket_) {
+ return socket_->SetOption(opt, value);
+ }
+ return 0;
+}
+
+bool RelayConnection::CheckResponse(StunMessage* msg) {
+ return request_manager_->CheckResponse(msg);
+}
+
+void RelayConnection::OnSendPacket(const void* data, size_t size,
+ StunRequest* req) {
+ // TODO(mallinath) Find a way to get DSCP value from Port.
+ rtc::PacketOptions options; // Default dscp set to NO_CHANGE.
+ int sent = socket_->SendTo(data, size, GetAddress(), options);
+ if (sent <= 0) {
+ LOG(LS_VERBOSE) << "OnSendPacket: failed sending to " << GetAddress() <<
+ strerror(socket_->GetError());
+ ASSERT(sent < 0);
+ }
+}
+
+int RelayConnection::Send(const void* pv, size_t cb,
+ const rtc::PacketOptions& options) {
+ return socket_->SendTo(pv, cb, GetAddress(), options);
+}
+
+void RelayConnection::SendAllocateRequest(RelayEntry* entry, int delay) {
+ request_manager_->SendDelayed(new AllocateRequest(entry, this), delay);
+}
+
+RelayEntry::RelayEntry(RelayPort* port,
+ const rtc::SocketAddress& ext_addr)
+ : port_(port), ext_addr_(ext_addr),
+ server_index_(0), connected_(false), locked_(false),
+ current_connection_(NULL) {
+}
+
+RelayEntry::~RelayEntry() {
+ // Remove all RelayConnections and dispose sockets.
+ delete current_connection_;
+ current_connection_ = NULL;
+}
+
+void RelayEntry::Connect() {
+ // If we're already connected, return.
+ if (connected_)
+ return;
+
+ // If we've exhausted all options, bail out.
+ const ProtocolAddress* ra = port()->ServerAddress(server_index_);
+ if (!ra) {
+ LOG(LS_WARNING) << "No more relay addresses left to try";
+ return;
+ }
+
+ // Remove any previous connection.
+ if (current_connection_) {
+ port()->thread()->Dispose(current_connection_);
+ current_connection_ = NULL;
+ }
+
+ // Try to set up our new socket.
+ LOG(LS_INFO) << "Connecting to relay via " << ProtoToString(ra->proto) <<
+ " @ " << ra->address.ToSensitiveString();
+
+ rtc::AsyncPacketSocket* socket = NULL;
+
+ if (ra->proto == PROTO_UDP) {
+ // UDP sockets are simple.
+ socket = port_->socket_factory()->CreateUdpSocket(
+ rtc::SocketAddress(port_->ip(), 0),
+ port_->min_port(), port_->max_port());
+ } else if (ra->proto == PROTO_TCP || ra->proto == PROTO_SSLTCP) {
+ int opts = (ra->proto == PROTO_SSLTCP) ?
+ rtc::PacketSocketFactory::OPT_SSLTCP : 0;
+ socket = port_->socket_factory()->CreateClientTcpSocket(
+ rtc::SocketAddress(port_->ip(), 0), ra->address,
+ port_->proxy(), port_->user_agent(), opts);
+ } else {
+ LOG(LS_WARNING) << "Unknown protocol (" << ra->proto << ")";
+ }
+
+ if (!socket) {
+ LOG(LS_WARNING) << "Socket creation failed";
+ }
+
+ // If we failed to get a socket, move on to the next protocol.
+ if (!socket) {
+ port()->thread()->Post(this, kMessageConnectTimeout);
+ return;
+ }
+
+ // Otherwise, create the new connection and configure any socket options.
+ socket->SignalReadPacket.connect(this, &RelayEntry::OnReadPacket);
+ socket->SignalReadyToSend.connect(this, &RelayEntry::OnReadyToSend);
+ current_connection_ = new RelayConnection(ra, socket, port()->thread());
+ for (size_t i = 0; i < port_->options().size(); ++i) {
+ current_connection_->SetSocketOption(port_->options()[i].first,
+ port_->options()[i].second);
+ }
+
+ // If we're trying UDP, start binding requests.
+ // If we're trying TCP, wait for connection with a fixed timeout.
+ if ((ra->proto == PROTO_TCP) || (ra->proto == PROTO_SSLTCP)) {
+ socket->SignalClose.connect(this, &RelayEntry::OnSocketClose);
+ socket->SignalConnect.connect(this, &RelayEntry::OnSocketConnect);
+ port()->thread()->PostDelayed(kSoftConnectTimeoutMs, this,
+ kMessageConnectTimeout);
+ } else {
+ current_connection_->SendAllocateRequest(this, 0);
+ }
+}
+
+int RelayEntry::GetError() {
+ if (current_connection_ != NULL) {
+ return current_connection_->GetError();
+ }
+ return 0;
+}
+
+RelayConnection* RelayEntry::GetBestConnection(RelayConnection* conn1,
+ RelayConnection* conn2) {
+ return conn1->GetProtocol() <= conn2->GetProtocol() ? conn1 : conn2;
+}
+
+void RelayEntry::OnConnect(const rtc::SocketAddress& mapped_addr,
+ RelayConnection* connection) {
+ // We are connected, notify our parent.
+ ProtocolType proto = PROTO_UDP;
+ LOG(INFO) << "Relay allocate succeeded: " << ProtoToString(proto)
+ << " @ " << mapped_addr.ToSensitiveString();
+ connected_ = true;
+
+ port_->AddExternalAddress(ProtocolAddress(mapped_addr, proto));
+ port_->SetReady();
+}
+
+int RelayEntry::SendTo(const void* data, size_t size,
+ const rtc::SocketAddress& addr,
+ const rtc::PacketOptions& options) {
+ // If this connection is locked to the address given, then we can send the
+ // packet with no wrapper.
+ if (locked_ && (ext_addr_ == addr))
+ return SendPacket(data, size, options);
+
+ // Otherwise, we must wrap the given data in a STUN SEND request so that we
+ // can communicate the destination address to the server.
+ //
+ // Note that we do not use a StunRequest here. This is because there is
+ // likely no reason to resend this packet. If it is late, we just drop it.
+ // The next send to this address will try again.
+
+ RelayMessage request;
+ request.SetType(STUN_SEND_REQUEST);
+
+ StunByteStringAttribute* magic_cookie_attr =
+ StunAttribute::CreateByteString(STUN_ATTR_MAGIC_COOKIE);
+ magic_cookie_attr->CopyBytes(TURN_MAGIC_COOKIE_VALUE,
+ sizeof(TURN_MAGIC_COOKIE_VALUE));
+ VERIFY(request.AddAttribute(magic_cookie_attr));
+
+ StunByteStringAttribute* username_attr =
+ StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
+ username_attr->CopyBytes(port_->username_fragment().c_str(),
+ port_->username_fragment().size());
+ VERIFY(request.AddAttribute(username_attr));
+
+ StunAddressAttribute* addr_attr =
+ StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
+ addr_attr->SetIP(addr.ipaddr());
+ addr_attr->SetPort(addr.port());
+ VERIFY(request.AddAttribute(addr_attr));
+
+ // Attempt to lock
+ if (ext_addr_ == addr) {
+ StunUInt32Attribute* options_attr =
+ StunAttribute::CreateUInt32(STUN_ATTR_OPTIONS);
+ options_attr->SetValue(0x1);
+ VERIFY(request.AddAttribute(options_attr));
+ }
+
+ StunByteStringAttribute* data_attr =
+ StunAttribute::CreateByteString(STUN_ATTR_DATA);
+ data_attr->CopyBytes(data, size);
+ VERIFY(request.AddAttribute(data_attr));
+
+ // TODO: compute the HMAC.
+
+ rtc::ByteBuffer buf;
+ request.Write(&buf);
+
+ return SendPacket(buf.Data(), buf.Length(), options);
+}
+
+void RelayEntry::ScheduleKeepAlive() {
+ if (current_connection_) {
+ current_connection_->SendAllocateRequest(this, kKeepAliveDelay);
+ }
+}
+
+int RelayEntry::SetSocketOption(rtc::Socket::Option opt, int value) {
+ // Set the option on all available sockets.
+ int socket_error = 0;
+ if (current_connection_) {
+ socket_error = current_connection_->SetSocketOption(opt, value);
+ }
+ return socket_error;
+}
+
+void RelayEntry::HandleConnectFailure(
+ rtc::AsyncPacketSocket* socket) {
+ // Make sure it's the current connection that has failed, it might
+ // be an old socked that has not yet been disposed.
+ if (!socket ||
+ (current_connection_ && socket == current_connection_->socket())) {
+ if (current_connection_)
+ port()->SignalConnectFailure(current_connection_->protocol_address());
+
+ // Try to connect to the next server address.
+ server_index_ += 1;
+ Connect();
+ }
+}
+
+void RelayEntry::OnMessage(rtc::Message *pmsg) {
+ ASSERT(pmsg->message_id == kMessageConnectTimeout);
+ if (current_connection_) {
+ const ProtocolAddress* ra = current_connection_->protocol_address();
+ LOG(LS_WARNING) << "Relay " << ra->proto << " connection to " <<
+ ra->address << " timed out";
+
+ // Currently we connect to each server address in sequence. If we
+ // have more addresses to try, treat this is an error and move on to
+ // the next address, otherwise give this connection more time and
+ // await the real timeout.
+ //
+ // TODO: Connect to servers in parallel to speed up connect time
+ // and to avoid giving up too early.
+ port_->SignalSoftTimeout(ra);
+ HandleConnectFailure(current_connection_->socket());
+ } else {
+ HandleConnectFailure(NULL);
+ }
+}
+
+void RelayEntry::OnSocketConnect(rtc::AsyncPacketSocket* socket) {
+ LOG(INFO) << "relay tcp connected to " <<
+ socket->GetRemoteAddress().ToSensitiveString();
+ if (current_connection_ != NULL) {
+ current_connection_->SendAllocateRequest(this, 0);
+ }
+}
+
+void RelayEntry::OnSocketClose(rtc::AsyncPacketSocket* socket,
+ int error) {
+ PLOG(LERROR, error) << "Relay connection failed: socket closed";
+ HandleConnectFailure(socket);
+}
+
+void RelayEntry::OnReadPacket(
+ rtc::AsyncPacketSocket* socket,
+ const char* data, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time) {
+ // ASSERT(remote_addr == port_->server_addr());
+ // TODO: are we worried about this?
+
+ if (current_connection_ == NULL || socket != current_connection_->socket()) {
+ // This packet comes from an unknown address.
+ LOG(WARNING) << "Dropping packet: unknown address";
+ return;
+ }
+
+ // If the magic cookie is not present, then this is an unwrapped packet sent
+ // by the server, The actual remote address is the one we recorded.
+ if (!port_->HasMagicCookie(data, size)) {
+ if (locked_) {
+ port_->OnReadPacket(data, size, ext_addr_, PROTO_UDP, packet_time);
+ } else {
+ LOG(WARNING) << "Dropping packet: entry not locked";
+ }
+ return;
+ }
+
+ rtc::ByteBuffer buf(data, size);
+ RelayMessage msg;
+ if (!msg.Read(&buf)) {
+ LOG(INFO) << "Incoming packet was not STUN";
+ return;
+ }
+
+ // The incoming packet should be a STUN ALLOCATE response, SEND response, or
+ // DATA indication.
+ if (current_connection_->CheckResponse(&msg)) {
+ return;
+ } else if (msg.type() == STUN_SEND_RESPONSE) {
+ if (const StunUInt32Attribute* options_attr =
+ msg.GetUInt32(STUN_ATTR_OPTIONS)) {
+ if (options_attr->value() & 0x1) {
+ locked_ = true;
+ }
+ }
+ return;
+ } else if (msg.type() != STUN_DATA_INDICATION) {
+ LOG(INFO) << "Received BAD stun type from server: " << msg.type();
+ return;
+ }
+
+ // This must be a data indication.
+
+ const StunAddressAttribute* addr_attr =
+ msg.GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
+ if (!addr_attr) {
+ LOG(INFO) << "Data indication has no source address";
+ return;
+ } else if (addr_attr->family() != 1) {
+ LOG(INFO) << "Source address has bad family";
+ return;
+ }
+
+ rtc::SocketAddress remote_addr2(addr_attr->ipaddr(), addr_attr->port());
+
+ const StunByteStringAttribute* data_attr = msg.GetByteString(STUN_ATTR_DATA);
+ if (!data_attr) {
+ LOG(INFO) << "Data indication has no data";
+ return;
+ }
+
+ // Process the actual data and remote address in the normal manner.
+ port_->OnReadPacket(data_attr->bytes(), data_attr->length(), remote_addr2,
+ PROTO_UDP, packet_time);
+}
+
+void RelayEntry::OnReadyToSend(rtc::AsyncPacketSocket* socket) {
+ if (connected()) {
+ port_->OnReadyToSend();
+ }
+}
+
+int RelayEntry::SendPacket(const void* data, size_t size,
+ const rtc::PacketOptions& options) {
+ int sent = 0;
+ if (current_connection_) {
+ // We are connected, no need to send packets anywere else than to
+ // the current connection.
+ sent = current_connection_->Send(data, size, options);
+ }
+ return sent;
+}
+
+AllocateRequest::AllocateRequest(RelayEntry* entry,
+ RelayConnection* connection)
+ : StunRequest(new RelayMessage()),
+ entry_(entry),
+ connection_(connection) {
+ start_time_ = rtc::Time();
+}
+
+void AllocateRequest::Prepare(StunMessage* request) {
+ request->SetType(STUN_ALLOCATE_REQUEST);
+
+ StunByteStringAttribute* username_attr =
+ StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
+ username_attr->CopyBytes(
+ entry_->port()->username_fragment().c_str(),
+ entry_->port()->username_fragment().size());
+ VERIFY(request->AddAttribute(username_attr));
+}
+
+int AllocateRequest::GetNextDelay() {
+ int delay = 100 * rtc::_max(1 << count_, 2);
+ count_ += 1;
+ if (count_ == 5)
+ timeout_ = true;
+ return delay;
+}
+
+void AllocateRequest::OnResponse(StunMessage* response) {
+ const StunAddressAttribute* addr_attr =
+ response->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
+ if (!addr_attr) {
+ LOG(INFO) << "Allocate response missing mapped address.";
+ } else if (addr_attr->family() != 1) {
+ LOG(INFO) << "Mapped address has bad family";
+ } else {
+ rtc::SocketAddress addr(addr_attr->ipaddr(), addr_attr->port());
+ entry_->OnConnect(addr, connection_);
+ }
+
+ // We will do a keep-alive regardless of whether this request suceeds.
+ // This should have almost no impact on network usage.
+ entry_->ScheduleKeepAlive();
+}
+
+void AllocateRequest::OnErrorResponse(StunMessage* response) {
+ const StunErrorCodeAttribute* attr = response->GetErrorCode();
+ if (!attr) {
+ LOG(INFO) << "Bad allocate response error code";
+ } else {
+ LOG(INFO) << "Allocate error response:"
+ << " code=" << attr->code()
+ << " reason='" << attr->reason() << "'";
+ }
+
+ if (rtc::TimeSince(start_time_) <= kRetryTimeout)
+ entry_->ScheduleKeepAlive();
+}
+
+void AllocateRequest::OnTimeout() {
+ LOG(INFO) << "Allocate request timed out";
+ entry_->HandleConnectFailure(connection_->socket());
+}
+
+} // namespace cricket
diff --git a/p2p/base/relayport.h b/p2p/base/relayport.h
new file mode 100644
index 00000000..3d9538da
--- /dev/null
+++ b/p2p/base/relayport.h
@@ -0,0 +1,101 @@
+/*
+ * 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 WEBRTC_P2P_BASE_RELAYPORT_H_
+#define WEBRTC_P2P_BASE_RELAYPORT_H_
+
+#include <deque>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "webrtc/p2p/base/port.h"
+#include "webrtc/p2p/base/stunrequest.h"
+
+namespace cricket {
+
+class RelayEntry;
+class RelayConnection;
+
+// Communicates using an allocated port on the relay server. For each
+// remote candidate that we try to send data to a RelayEntry instance
+// is created. The RelayEntry will try to reach the remote destination
+// by connecting to all available server addresses in a pre defined
+// order with a small delay in between. When a connection is
+// successful all other connection attemts are aborted.
+class RelayPort : public Port {
+ public:
+ typedef std::pair<rtc::Socket::Option, int> OptionValue;
+
+ // RelayPort doesn't yet do anything fancy in the ctor.
+ static RelayPort* Create(
+ rtc::Thread* thread, rtc::PacketSocketFactory* factory,
+ rtc::Network* network, const rtc::IPAddress& ip,
+ int min_port, int max_port, const std::string& username,
+ const std::string& password) {
+ return new RelayPort(thread, factory, network, ip, min_port, max_port,
+ username, password);
+ }
+ virtual ~RelayPort();
+
+ void AddServerAddress(const ProtocolAddress& addr);
+ void AddExternalAddress(const ProtocolAddress& addr);
+
+ const std::vector<OptionValue>& options() const { return options_; }
+ bool HasMagicCookie(const char* data, size_t size);
+
+ virtual void PrepareAddress();
+ virtual Connection* CreateConnection(const Candidate& address,
+ CandidateOrigin origin);
+ virtual int SetOption(rtc::Socket::Option opt, int value);
+ virtual int GetOption(rtc::Socket::Option opt, int* value);
+ virtual int GetError();
+
+ const ProtocolAddress * ServerAddress(size_t index) const;
+ bool IsReady() { return ready_; }
+
+ // Used for testing.
+ sigslot::signal1<const ProtocolAddress*> SignalConnectFailure;
+ sigslot::signal1<const ProtocolAddress*> SignalSoftTimeout;
+
+ protected:
+ RelayPort(rtc::Thread* thread, rtc::PacketSocketFactory* factory,
+ rtc::Network*, const rtc::IPAddress& ip,
+ int min_port, int max_port, const std::string& username,
+ const std::string& password);
+ bool Init();
+
+ void SetReady();
+
+ virtual int SendTo(const void* data, size_t size,
+ const rtc::SocketAddress& addr,
+ const rtc::PacketOptions& options,
+ bool payload);
+
+ // Dispatches the given packet to the port or connection as appropriate.
+ void OnReadPacket(const char* data, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ ProtocolType proto,
+ const rtc::PacketTime& packet_time);
+
+ private:
+ friend class RelayEntry;
+
+ std::deque<ProtocolAddress> server_addr_;
+ std::vector<ProtocolAddress> external_addr_;
+ bool ready_;
+ std::vector<RelayEntry*> entries_;
+ std::vector<OptionValue> options_;
+ int error_;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_RELAYPORT_H_
diff --git a/p2p/base/relayport_unittest.cc b/p2p/base/relayport_unittest.cc
new file mode 100644
index 00000000..d644d67c
--- /dev/null
+++ b/p2p/base/relayport_unittest.cc
@@ -0,0 +1,272 @@
+/*
+ * Copyright 2009 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can 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 "webrtc/p2p/base/basicpacketsocketfactory.h"
+#include "webrtc/p2p/base/relayport.h"
+#include "webrtc/p2p/base/relayserver.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/physicalsocketserver.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/socketadapters.h"
+#include "webrtc/base/socketaddress.h"
+#include "webrtc/base/ssladapter.h"
+#include "webrtc/base/thread.h"
+#include "webrtc/base/virtualsocketserver.h"
+
+using rtc::SocketAddress;
+
+static const SocketAddress kLocalAddress = SocketAddress("192.168.1.2", 0);
+static const SocketAddress kRelayUdpAddr = SocketAddress("99.99.99.1", 5000);
+static const SocketAddress kRelayTcpAddr = SocketAddress("99.99.99.2", 5001);
+static const SocketAddress kRelaySslAddr = SocketAddress("99.99.99.3", 443);
+static const SocketAddress kRelayExtAddr = SocketAddress("99.99.99.3", 5002);
+
+static const int kTimeoutMs = 1000;
+static const int kMaxTimeoutMs = 5000;
+
+// Tests connecting a RelayPort to a fake relay server
+// (cricket::RelayServer) using all currently available protocols. The
+// network layer is faked out by using a VirtualSocketServer for
+// creating sockets. The test will monitor the current state of the
+// RelayPort and created sockets by listening for signals such as,
+// SignalConnectFailure, SignalConnectTimeout, SignalSocketClosed and
+// SignalReadPacket.
+class RelayPortTest : public testing::Test,
+ public sigslot::has_slots<> {
+ public:
+ RelayPortTest()
+ : main_(rtc::Thread::Current()),
+ physical_socket_server_(new rtc::PhysicalSocketServer),
+ virtual_socket_server_(new rtc::VirtualSocketServer(
+ physical_socket_server_.get())),
+ ss_scope_(virtual_socket_server_.get()),
+ network_("unittest", "unittest", rtc::IPAddress(INADDR_ANY), 32),
+ socket_factory_(rtc::Thread::Current()),
+ username_(rtc::CreateRandomString(16)),
+ password_(rtc::CreateRandomString(16)),
+ relay_port_(cricket::RelayPort::Create(main_, &socket_factory_,
+ &network_,
+ kLocalAddress.ipaddr(),
+ 0, 0, username_, password_)),
+ relay_server_(new cricket::RelayServer(main_)) {
+ }
+
+ void OnReadPacket(rtc::AsyncPacketSocket* socket,
+ const char* data, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time) {
+ received_packet_count_[socket]++;
+ }
+
+ void OnConnectFailure(const cricket::ProtocolAddress* addr) {
+ failed_connections_.push_back(*addr);
+ }
+
+ void OnSoftTimeout(const cricket::ProtocolAddress* addr) {
+ soft_timedout_connections_.push_back(*addr);
+ }
+
+ protected:
+ virtual void SetUp() {
+ // The relay server needs an external socket to work properly.
+ rtc::AsyncUDPSocket* ext_socket =
+ CreateAsyncUdpSocket(kRelayExtAddr);
+ relay_server_->AddExternalSocket(ext_socket);
+
+ // Listen for failures.
+ relay_port_->SignalConnectFailure.
+ connect(this, &RelayPortTest::OnConnectFailure);
+
+ // Listen for soft timeouts.
+ relay_port_->SignalSoftTimeout.
+ connect(this, &RelayPortTest::OnSoftTimeout);
+ }
+
+ // Udp has the highest 'goodness' value of the three different
+ // protocols used for connecting to the relay server. As soon as
+ // PrepareAddress is called, the RelayPort will start trying to
+ // connect to the given UDP address. As soon as a response to the
+ // sent STUN allocate request message has been received, the
+ // RelayPort will consider the connection to be complete and will
+ // abort any other connection attempts.
+ void TestConnectUdp() {
+ // Add a UDP socket to the relay server.
+ rtc::AsyncUDPSocket* internal_udp_socket =
+ CreateAsyncUdpSocket(kRelayUdpAddr);
+ rtc::AsyncSocket* server_socket = CreateServerSocket(kRelayTcpAddr);
+
+ relay_server_->AddInternalSocket(internal_udp_socket);
+ relay_server_->AddInternalServerSocket(server_socket, cricket::PROTO_TCP);
+
+ // Now add our relay addresses to the relay port and let it start.
+ relay_port_->AddServerAddress(
+ cricket::ProtocolAddress(kRelayUdpAddr, cricket::PROTO_UDP));
+ relay_port_->AddServerAddress(
+ cricket::ProtocolAddress(kRelayTcpAddr, cricket::PROTO_TCP));
+ relay_port_->PrepareAddress();
+
+ // Should be connected.
+ EXPECT_TRUE_WAIT(relay_port_->IsReady(), kTimeoutMs);
+
+ // Make sure that we are happy with UDP, ie. not continuing with
+ // TCP, SSLTCP, etc.
+ WAIT(relay_server_->HasConnection(kRelayTcpAddr), kTimeoutMs);
+
+ // Should have only one connection.
+ EXPECT_EQ(1, relay_server_->GetConnectionCount());
+
+ // Should be the UDP address.
+ EXPECT_TRUE(relay_server_->HasConnection(kRelayUdpAddr));
+ }
+
+ // TCP has the second best 'goodness' value, and as soon as UDP
+ // connection has failed, the RelayPort will attempt to connect via
+ // TCP. Here we add a fake UDP address together with a real TCP
+ // address to simulate an UDP failure. As soon as UDP has failed the
+ // RelayPort will try the TCP adress and succed.
+ void TestConnectTcp() {
+ // Create a fake UDP address for relay port to simulate a failure.
+ cricket::ProtocolAddress fake_protocol_address =
+ cricket::ProtocolAddress(kRelayUdpAddr, cricket::PROTO_UDP);
+
+ // Create a server socket for the RelayServer.
+ rtc::AsyncSocket* server_socket = CreateServerSocket(kRelayTcpAddr);
+ relay_server_->AddInternalServerSocket(server_socket, cricket::PROTO_TCP);
+
+ // Add server addresses to the relay port and let it start.
+ relay_port_->AddServerAddress(
+ cricket::ProtocolAddress(fake_protocol_address));
+ relay_port_->AddServerAddress(
+ cricket::ProtocolAddress(kRelayTcpAddr, cricket::PROTO_TCP));
+ relay_port_->PrepareAddress();
+
+ EXPECT_FALSE(relay_port_->IsReady());
+
+ // Should have timed out in 200 + 200 + 400 + 800 + 1600 ms.
+ EXPECT_TRUE_WAIT(HasFailed(&fake_protocol_address), 3600);
+
+ // Wait until relayport is ready.
+ EXPECT_TRUE_WAIT(relay_port_->IsReady(), kMaxTimeoutMs);
+
+ // Should have only one connection.
+ EXPECT_EQ(1, relay_server_->GetConnectionCount());
+
+ // Should be the TCP address.
+ EXPECT_TRUE(relay_server_->HasConnection(kRelayTcpAddr));
+ }
+
+ void TestConnectSslTcp() {
+ // Create a fake TCP address for relay port to simulate a failure.
+ // We skip UDP here since transition from UDP to TCP has been
+ // tested above.
+ cricket::ProtocolAddress fake_protocol_address =
+ cricket::ProtocolAddress(kRelayTcpAddr, cricket::PROTO_TCP);
+
+ // Create a ssl server socket for the RelayServer.
+ rtc::AsyncSocket* ssl_server_socket =
+ CreateServerSocket(kRelaySslAddr);
+ relay_server_->AddInternalServerSocket(ssl_server_socket,
+ cricket::PROTO_SSLTCP);
+
+ // Create a tcp server socket that listens on the fake address so
+ // the relay port can attempt to connect to it.
+ rtc::scoped_ptr<rtc::AsyncSocket> tcp_server_socket(
+ CreateServerSocket(kRelayTcpAddr));
+
+ // Add server addresses to the relay port and let it start.
+ relay_port_->AddServerAddress(fake_protocol_address);
+ relay_port_->AddServerAddress(
+ cricket::ProtocolAddress(kRelaySslAddr, cricket::PROTO_SSLTCP));
+ relay_port_->PrepareAddress();
+ EXPECT_FALSE(relay_port_->IsReady());
+
+ // Should have timed out in 3000 ms(relayport.cc, kSoftConnectTimeoutMs).
+ EXPECT_TRUE_WAIT_MARGIN(HasTimedOut(&fake_protocol_address), 3000, 100);
+
+ // Wait until relayport is ready.
+ EXPECT_TRUE_WAIT(relay_port_->IsReady(), kMaxTimeoutMs);
+
+ // Should have only one connection.
+ EXPECT_EQ(1, relay_server_->GetConnectionCount());
+
+ // Should be the SSLTCP address.
+ EXPECT_TRUE(relay_server_->HasConnection(kRelaySslAddr));
+ }
+
+ private:
+ rtc::AsyncUDPSocket* CreateAsyncUdpSocket(const SocketAddress addr) {
+ rtc::AsyncSocket* socket =
+ virtual_socket_server_->CreateAsyncSocket(SOCK_DGRAM);
+ rtc::AsyncUDPSocket* packet_socket =
+ rtc::AsyncUDPSocket::Create(socket, addr);
+ EXPECT_TRUE(packet_socket != NULL);
+ packet_socket->SignalReadPacket.connect(this, &RelayPortTest::OnReadPacket);
+ return packet_socket;
+ }
+
+ rtc::AsyncSocket* CreateServerSocket(const SocketAddress addr) {
+ rtc::AsyncSocket* socket =
+ virtual_socket_server_->CreateAsyncSocket(SOCK_STREAM);
+ EXPECT_GE(socket->Bind(addr), 0);
+ EXPECT_GE(socket->Listen(5), 0);
+ return socket;
+ }
+
+ bool HasFailed(cricket::ProtocolAddress* addr) {
+ for (size_t i = 0; i < failed_connections_.size(); i++) {
+ if (failed_connections_[i].address == addr->address &&
+ failed_connections_[i].proto == addr->proto) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool HasTimedOut(cricket::ProtocolAddress* addr) {
+ for (size_t i = 0; i < soft_timedout_connections_.size(); i++) {
+ if (soft_timedout_connections_[i].address == addr->address &&
+ soft_timedout_connections_[i].proto == addr->proto) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ typedef std::map<rtc::AsyncPacketSocket*, int> PacketMap;
+
+ rtc::Thread* main_;
+ rtc::scoped_ptr<rtc::PhysicalSocketServer>
+ physical_socket_server_;
+ rtc::scoped_ptr<rtc::VirtualSocketServer> virtual_socket_server_;
+ rtc::SocketServerScope ss_scope_;
+ rtc::Network network_;
+ rtc::BasicPacketSocketFactory socket_factory_;
+ std::string username_;
+ std::string password_;
+ rtc::scoped_ptr<cricket::RelayPort> relay_port_;
+ rtc::scoped_ptr<cricket::RelayServer> relay_server_;
+ std::vector<cricket::ProtocolAddress> failed_connections_;
+ std::vector<cricket::ProtocolAddress> soft_timedout_connections_;
+ PacketMap received_packet_count_;
+};
+
+TEST_F(RelayPortTest, ConnectUdp) {
+ TestConnectUdp();
+}
+
+TEST_F(RelayPortTest, ConnectTcp) {
+ TestConnectTcp();
+}
+
+TEST_F(RelayPortTest, ConnectSslTcp) {
+ TestConnectSslTcp();
+}
diff --git a/p2p/base/relayserver.cc b/p2p/base/relayserver.cc
new file mode 100644
index 00000000..e37a1680
--- /dev/null
+++ b/p2p/base/relayserver.cc
@@ -0,0 +1,746 @@
+/*
+ * 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 "webrtc/p2p/base/relayserver.h"
+
+#ifdef WEBRTC_POSIX
+#include <errno.h>
+#endif // WEBRTC_POSIX
+
+#include <algorithm>
+
+#include "webrtc/base/asynctcpsocket.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/socketadapters.h"
+
+namespace cricket {
+
+// By default, we require a ping every 90 seconds.
+const int MAX_LIFETIME = 15 * 60 * 1000;
+
+// The number of bytes in each of the usernames we use.
+const uint32 USERNAME_LENGTH = 16;
+
+// Calls SendTo on the given socket and logs any bad results.
+void Send(rtc::AsyncPacketSocket* socket, const char* bytes, size_t size,
+ const rtc::SocketAddress& addr) {
+ rtc::PacketOptions options;
+ int result = socket->SendTo(bytes, size, addr, options);
+ if (result < static_cast<int>(size)) {
+ LOG(LS_ERROR) << "SendTo wrote only " << result << " of " << size
+ << " bytes";
+ } else if (result < 0) {
+ LOG_ERR(LS_ERROR) << "SendTo";
+ }
+}
+
+// Sends the given STUN message on the given socket.
+void SendStun(const StunMessage& msg,
+ rtc::AsyncPacketSocket* socket,
+ const rtc::SocketAddress& addr) {
+ rtc::ByteBuffer buf;
+ msg.Write(&buf);
+ Send(socket, buf.Data(), buf.Length(), addr);
+}
+
+// Constructs a STUN error response and sends it on the given socket.
+void SendStunError(const StunMessage& msg, rtc::AsyncPacketSocket* socket,
+ const rtc::SocketAddress& remote_addr, int error_code,
+ const char* error_desc, const std::string& magic_cookie) {
+ RelayMessage err_msg;
+ err_msg.SetType(GetStunErrorResponseType(msg.type()));
+ err_msg.SetTransactionID(msg.transaction_id());
+
+ StunByteStringAttribute* magic_cookie_attr =
+ StunAttribute::CreateByteString(cricket::STUN_ATTR_MAGIC_COOKIE);
+ if (magic_cookie.size() == 0) {
+ magic_cookie_attr->CopyBytes(cricket::TURN_MAGIC_COOKIE_VALUE,
+ sizeof(cricket::TURN_MAGIC_COOKIE_VALUE));
+ } else {
+ magic_cookie_attr->CopyBytes(magic_cookie.c_str(), magic_cookie.size());
+ }
+ err_msg.AddAttribute(magic_cookie_attr);
+
+ StunErrorCodeAttribute* err_code = StunAttribute::CreateErrorCode();
+ err_code->SetClass(error_code / 100);
+ err_code->SetNumber(error_code % 100);
+ err_code->SetReason(error_desc);
+ err_msg.AddAttribute(err_code);
+
+ SendStun(err_msg, socket, remote_addr);
+}
+
+RelayServer::RelayServer(rtc::Thread* thread)
+ : thread_(thread), log_bindings_(true) {
+}
+
+RelayServer::~RelayServer() {
+ // Deleting the binding will cause it to be removed from the map.
+ while (!bindings_.empty())
+ delete bindings_.begin()->second;
+ for (size_t i = 0; i < internal_sockets_.size(); ++i)
+ delete internal_sockets_[i];
+ for (size_t i = 0; i < external_sockets_.size(); ++i)
+ delete external_sockets_[i];
+ for (size_t i = 0; i < removed_sockets_.size(); ++i)
+ delete removed_sockets_[i];
+ while (!server_sockets_.empty()) {
+ rtc::AsyncSocket* socket = server_sockets_.begin()->first;
+ server_sockets_.erase(server_sockets_.begin()->first);
+ delete socket;
+ }
+}
+
+void RelayServer::AddInternalSocket(rtc::AsyncPacketSocket* socket) {
+ ASSERT(internal_sockets_.end() ==
+ std::find(internal_sockets_.begin(), internal_sockets_.end(), socket));
+ internal_sockets_.push_back(socket);
+ socket->SignalReadPacket.connect(this, &RelayServer::OnInternalPacket);
+}
+
+void RelayServer::RemoveInternalSocket(rtc::AsyncPacketSocket* socket) {
+ SocketList::iterator iter =
+ std::find(internal_sockets_.begin(), internal_sockets_.end(), socket);
+ ASSERT(iter != internal_sockets_.end());
+ internal_sockets_.erase(iter);
+ removed_sockets_.push_back(socket);
+ socket->SignalReadPacket.disconnect(this);
+}
+
+void RelayServer::AddExternalSocket(rtc::AsyncPacketSocket* socket) {
+ ASSERT(external_sockets_.end() ==
+ std::find(external_sockets_.begin(), external_sockets_.end(), socket));
+ external_sockets_.push_back(socket);
+ socket->SignalReadPacket.connect(this, &RelayServer::OnExternalPacket);
+}
+
+void RelayServer::RemoveExternalSocket(rtc::AsyncPacketSocket* socket) {
+ SocketList::iterator iter =
+ std::find(external_sockets_.begin(), external_sockets_.end(), socket);
+ ASSERT(iter != external_sockets_.end());
+ external_sockets_.erase(iter);
+ removed_sockets_.push_back(socket);
+ socket->SignalReadPacket.disconnect(this);
+}
+
+void RelayServer::AddInternalServerSocket(rtc::AsyncSocket* socket,
+ cricket::ProtocolType proto) {
+ ASSERT(server_sockets_.end() ==
+ server_sockets_.find(socket));
+ server_sockets_[socket] = proto;
+ socket->SignalReadEvent.connect(this, &RelayServer::OnReadEvent);
+}
+
+void RelayServer::RemoveInternalServerSocket(
+ rtc::AsyncSocket* socket) {
+ ServerSocketMap::iterator iter = server_sockets_.find(socket);
+ ASSERT(iter != server_sockets_.end());
+ server_sockets_.erase(iter);
+ socket->SignalReadEvent.disconnect(this);
+}
+
+int RelayServer::GetConnectionCount() const {
+ return static_cast<int>(connections_.size());
+}
+
+rtc::SocketAddressPair RelayServer::GetConnection(int connection) const {
+ int i = 0;
+ for (ConnectionMap::const_iterator it = connections_.begin();
+ it != connections_.end(); ++it) {
+ if (i == connection) {
+ return it->second->addr_pair();
+ }
+ ++i;
+ }
+ return rtc::SocketAddressPair();
+}
+
+bool RelayServer::HasConnection(const rtc::SocketAddress& address) const {
+ for (ConnectionMap::const_iterator it = connections_.begin();
+ it != connections_.end(); ++it) {
+ if (it->second->addr_pair().destination() == address) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void RelayServer::OnReadEvent(rtc::AsyncSocket* socket) {
+ ASSERT(server_sockets_.find(socket) != server_sockets_.end());
+ AcceptConnection(socket);
+}
+
+void RelayServer::OnInternalPacket(
+ rtc::AsyncPacketSocket* socket, const char* bytes, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time) {
+
+ // Get the address of the connection we just received on.
+ rtc::SocketAddressPair ap(remote_addr, socket->GetLocalAddress());
+ ASSERT(!ap.destination().IsNil());
+
+ // If this did not come from an existing connection, it should be a STUN
+ // allocate request.
+ ConnectionMap::iterator piter = connections_.find(ap);
+ if (piter == connections_.end()) {
+ HandleStunAllocate(bytes, size, ap, socket);
+ return;
+ }
+
+ RelayServerConnection* int_conn = piter->second;
+
+ // Handle STUN requests to the server itself.
+ if (int_conn->binding()->HasMagicCookie(bytes, size)) {
+ HandleStun(int_conn, bytes, size);
+ return;
+ }
+
+ // Otherwise, this is a non-wrapped packet that we are to forward. Make sure
+ // that this connection has been locked. (Otherwise, we would not know what
+ // address to forward to.)
+ if (!int_conn->locked()) {
+ LOG(LS_WARNING) << "Dropping packet: connection not locked";
+ return;
+ }
+
+ // Forward this to the destination address into the connection.
+ RelayServerConnection* ext_conn = int_conn->binding()->GetExternalConnection(
+ int_conn->default_destination());
+ if (ext_conn && ext_conn->locked()) {
+ // TODO: Check the HMAC.
+ ext_conn->Send(bytes, size);
+ } else {
+ // This happens very often and is not an error.
+ LOG(LS_INFO) << "Dropping packet: no external connection";
+ }
+}
+
+void RelayServer::OnExternalPacket(
+ rtc::AsyncPacketSocket* socket, const char* bytes, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time) {
+
+ // Get the address of the connection we just received on.
+ rtc::SocketAddressPair ap(remote_addr, socket->GetLocalAddress());
+ ASSERT(!ap.destination().IsNil());
+
+ // If this connection already exists, then forward the traffic.
+ ConnectionMap::iterator piter = connections_.find(ap);
+ if (piter != connections_.end()) {
+ // TODO: Check the HMAC.
+ RelayServerConnection* ext_conn = piter->second;
+ RelayServerConnection* int_conn =
+ ext_conn->binding()->GetInternalConnection(
+ ext_conn->addr_pair().source());
+ ASSERT(int_conn != NULL);
+ int_conn->Send(bytes, size, ext_conn->addr_pair().source());
+ ext_conn->Lock(); // allow outgoing packets
+ return;
+ }
+
+ // The first packet should always be a STUN / TURN packet. If it isn't, then
+ // we should just ignore this packet.
+ RelayMessage msg;
+ rtc::ByteBuffer buf(bytes, size);
+ if (!msg.Read(&buf)) {
+ LOG(LS_WARNING) << "Dropping packet: first packet not STUN";
+ return;
+ }
+
+ // The initial packet should have a username (which identifies the binding).
+ const StunByteStringAttribute* username_attr =
+ msg.GetByteString(STUN_ATTR_USERNAME);
+ if (!username_attr) {
+ LOG(LS_WARNING) << "Dropping packet: no username";
+ return;
+ }
+
+ uint32 length = rtc::_min(static_cast<uint32>(username_attr->length()),
+ USERNAME_LENGTH);
+ std::string username(username_attr->bytes(), length);
+ // TODO: Check the HMAC.
+
+ // The binding should already be present.
+ BindingMap::iterator biter = bindings_.find(username);
+ if (biter == bindings_.end()) {
+ LOG(LS_WARNING) << "Dropping packet: no binding with username";
+ return;
+ }
+
+ // Add this authenticted connection to the binding.
+ RelayServerConnection* ext_conn =
+ new RelayServerConnection(biter->second, ap, socket);
+ ext_conn->binding()->AddExternalConnection(ext_conn);
+ AddConnection(ext_conn);
+
+ // We always know where external packets should be forwarded, so we can lock
+ // them from the beginning.
+ ext_conn->Lock();
+
+ // Send this message on the appropriate internal connection.
+ RelayServerConnection* int_conn = ext_conn->binding()->GetInternalConnection(
+ ext_conn->addr_pair().source());
+ ASSERT(int_conn != NULL);
+ int_conn->Send(bytes, size, ext_conn->addr_pair().source());
+}
+
+bool RelayServer::HandleStun(
+ const char* bytes, size_t size, const rtc::SocketAddress& remote_addr,
+ rtc::AsyncPacketSocket* socket, std::string* username,
+ StunMessage* msg) {
+
+ // Parse this into a stun message. Eat the message if this fails.
+ rtc::ByteBuffer buf(bytes, size);
+ if (!msg->Read(&buf)) {
+ return false;
+ }
+
+ // The initial packet should have a username (which identifies the binding).
+ const StunByteStringAttribute* username_attr =
+ msg->GetByteString(STUN_ATTR_USERNAME);
+ if (!username_attr) {
+ SendStunError(*msg, socket, remote_addr, 432, "Missing Username", "");
+ return false;
+ }
+
+ // Record the username if requested.
+ if (username)
+ username->append(username_attr->bytes(), username_attr->length());
+
+ // TODO: Check for unknown attributes (<= 0x7fff)
+
+ return true;
+}
+
+void RelayServer::HandleStunAllocate(
+ const char* bytes, size_t size, const rtc::SocketAddressPair& ap,
+ rtc::AsyncPacketSocket* socket) {
+
+ // Make sure this is a valid STUN request.
+ RelayMessage request;
+ std::string username;
+ if (!HandleStun(bytes, size, ap.source(), socket, &username, &request))
+ return;
+
+ // Make sure this is a an allocate request.
+ if (request.type() != STUN_ALLOCATE_REQUEST) {
+ SendStunError(request,
+ socket,
+ ap.source(),
+ 600,
+ "Operation Not Supported",
+ "");
+ return;
+ }
+
+ // TODO: Check the HMAC.
+
+ // Find or create the binding for this username.
+
+ RelayServerBinding* binding;
+
+ BindingMap::iterator biter = bindings_.find(username);
+ if (biter != bindings_.end()) {
+ binding = biter->second;
+ } else {
+ // NOTE: In the future, bindings will be created by the bot only. This
+ // else-branch will then disappear.
+
+ // Compute the appropriate lifetime for this binding.
+ uint32 lifetime = MAX_LIFETIME;
+ const StunUInt32Attribute* lifetime_attr =
+ request.GetUInt32(STUN_ATTR_LIFETIME);
+ if (lifetime_attr)
+ lifetime = rtc::_min(lifetime, lifetime_attr->value() * 1000);
+
+ binding = new RelayServerBinding(this, username, "0", lifetime);
+ binding->SignalTimeout.connect(this, &RelayServer::OnTimeout);
+ bindings_[username] = binding;
+
+ if (log_bindings_) {
+ LOG(LS_INFO) << "Added new binding " << username << ", "
+ << bindings_.size() << " total";
+ }
+ }
+
+ // Add this connection to the binding. It starts out unlocked.
+ RelayServerConnection* int_conn =
+ new RelayServerConnection(binding, ap, socket);
+ binding->AddInternalConnection(int_conn);
+ AddConnection(int_conn);
+
+ // Now that we have a connection, this other method takes over.
+ HandleStunAllocate(int_conn, request);
+}
+
+void RelayServer::HandleStun(
+ RelayServerConnection* int_conn, const char* bytes, size_t size) {
+
+ // Make sure this is a valid STUN request.
+ RelayMessage request;
+ std::string username;
+ if (!HandleStun(bytes, size, int_conn->addr_pair().source(),
+ int_conn->socket(), &username, &request))
+ return;
+
+ // Make sure the username is the one were were expecting.
+ if (username != int_conn->binding()->username()) {
+ int_conn->SendStunError(request, 430, "Stale Credentials");
+ return;
+ }
+
+ // TODO: Check the HMAC.
+
+ // Send this request to the appropriate handler.
+ if (request.type() == STUN_SEND_REQUEST)
+ HandleStunSend(int_conn, request);
+ else if (request.type() == STUN_ALLOCATE_REQUEST)
+ HandleStunAllocate(int_conn, request);
+ else
+ int_conn->SendStunError(request, 600, "Operation Not Supported");
+}
+
+void RelayServer::HandleStunAllocate(
+ RelayServerConnection* int_conn, const StunMessage& request) {
+
+ // Create a response message that includes an address with which external
+ // clients can communicate.
+
+ RelayMessage response;
+ response.SetType(STUN_ALLOCATE_RESPONSE);
+ response.SetTransactionID(request.transaction_id());
+
+ StunByteStringAttribute* magic_cookie_attr =
+ StunAttribute::CreateByteString(cricket::STUN_ATTR_MAGIC_COOKIE);
+ magic_cookie_attr->CopyBytes(int_conn->binding()->magic_cookie().c_str(),
+ int_conn->binding()->magic_cookie().size());
+ response.AddAttribute(magic_cookie_attr);
+
+ size_t index = rand() % external_sockets_.size();
+ rtc::SocketAddress ext_addr =
+ external_sockets_[index]->GetLocalAddress();
+
+ StunAddressAttribute* addr_attr =
+ StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
+ addr_attr->SetIP(ext_addr.ipaddr());
+ addr_attr->SetPort(ext_addr.port());
+ response.AddAttribute(addr_attr);
+
+ StunUInt32Attribute* res_lifetime_attr =
+ StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME);
+ res_lifetime_attr->SetValue(int_conn->binding()->lifetime() / 1000);
+ response.AddAttribute(res_lifetime_attr);
+
+ // TODO: Support transport-prefs (preallocate RTCP port).
+ // TODO: Support bandwidth restrictions.
+ // TODO: Add message integrity check.
+
+ // Send a response to the caller.
+ int_conn->SendStun(response);
+}
+
+void RelayServer::HandleStunSend(
+ RelayServerConnection* int_conn, const StunMessage& request) {
+
+ const StunAddressAttribute* addr_attr =
+ request.GetAddress(STUN_ATTR_DESTINATION_ADDRESS);
+ if (!addr_attr) {
+ int_conn->SendStunError(request, 400, "Bad Request");
+ return;
+ }
+
+ const StunByteStringAttribute* data_attr =
+ request.GetByteString(STUN_ATTR_DATA);
+ if (!data_attr) {
+ int_conn->SendStunError(request, 400, "Bad Request");
+ return;
+ }
+
+ rtc::SocketAddress ext_addr(addr_attr->ipaddr(), addr_attr->port());
+ RelayServerConnection* ext_conn =
+ int_conn->binding()->GetExternalConnection(ext_addr);
+ if (!ext_conn) {
+ // Create a new connection to establish the relationship with this binding.
+ ASSERT(external_sockets_.size() == 1);
+ rtc::AsyncPacketSocket* socket = external_sockets_[0];
+ rtc::SocketAddressPair ap(ext_addr, socket->GetLocalAddress());
+ ext_conn = new RelayServerConnection(int_conn->binding(), ap, socket);
+ ext_conn->binding()->AddExternalConnection(ext_conn);
+ AddConnection(ext_conn);
+ }
+
+ // If this connection has pinged us, then allow outgoing traffic.
+ if (ext_conn->locked())
+ ext_conn->Send(data_attr->bytes(), data_attr->length());
+
+ const StunUInt32Attribute* options_attr =
+ request.GetUInt32(STUN_ATTR_OPTIONS);
+ if (options_attr && (options_attr->value() & 0x01)) {
+ int_conn->set_default_destination(ext_addr);
+ int_conn->Lock();
+
+ RelayMessage response;
+ response.SetType(STUN_SEND_RESPONSE);
+ response.SetTransactionID(request.transaction_id());
+
+ StunByteStringAttribute* magic_cookie_attr =
+ StunAttribute::CreateByteString(cricket::STUN_ATTR_MAGIC_COOKIE);
+ magic_cookie_attr->CopyBytes(int_conn->binding()->magic_cookie().c_str(),
+ int_conn->binding()->magic_cookie().size());
+ response.AddAttribute(magic_cookie_attr);
+
+ StunUInt32Attribute* options2_attr =
+ StunAttribute::CreateUInt32(cricket::STUN_ATTR_OPTIONS);
+ options2_attr->SetValue(0x01);
+ response.AddAttribute(options2_attr);
+
+ int_conn->SendStun(response);
+ }
+}
+
+void RelayServer::AddConnection(RelayServerConnection* conn) {
+ ASSERT(connections_.find(conn->addr_pair()) == connections_.end());
+ connections_[conn->addr_pair()] = conn;
+}
+
+void RelayServer::RemoveConnection(RelayServerConnection* conn) {
+ ConnectionMap::iterator iter = connections_.find(conn->addr_pair());
+ ASSERT(iter != connections_.end());
+ connections_.erase(iter);
+}
+
+void RelayServer::RemoveBinding(RelayServerBinding* binding) {
+ BindingMap::iterator iter = bindings_.find(binding->username());
+ ASSERT(iter != bindings_.end());
+ bindings_.erase(iter);
+
+ if (log_bindings_) {
+ LOG(LS_INFO) << "Removed binding " << binding->username() << ", "
+ << bindings_.size() << " remaining";
+ }
+}
+
+void RelayServer::OnMessage(rtc::Message *pmsg) {
+#if ENABLE_DEBUG
+ static const uint32 kMessageAcceptConnection = 1;
+ ASSERT(pmsg->message_id == kMessageAcceptConnection);
+#endif
+ rtc::MessageData* data = pmsg->pdata;
+ rtc::AsyncSocket* socket =
+ static_cast <rtc::TypedMessageData<rtc::AsyncSocket*>*>
+ (data)->data();
+ AcceptConnection(socket);
+ delete data;
+}
+
+void RelayServer::OnTimeout(RelayServerBinding* binding) {
+ // This call will result in all of the necessary clean-up. We can't call
+ // delete here, because you can't delete an object that is signaling you.
+ thread_->Dispose(binding);
+}
+
+void RelayServer::AcceptConnection(rtc::AsyncSocket* server_socket) {
+ // Check if someone is trying to connect to us.
+ rtc::SocketAddress accept_addr;
+ rtc::AsyncSocket* accepted_socket =
+ server_socket->Accept(&accept_addr);
+ if (accepted_socket != NULL) {
+ // We had someone trying to connect, now check which protocol to
+ // use and create a packet socket.
+ ASSERT(server_sockets_[server_socket] == cricket::PROTO_TCP ||
+ server_sockets_[server_socket] == cricket::PROTO_SSLTCP);
+ if (server_sockets_[server_socket] == cricket::PROTO_SSLTCP) {
+ accepted_socket = new rtc::AsyncSSLServerSocket(accepted_socket);
+ }
+ rtc::AsyncTCPSocket* tcp_socket =
+ new rtc::AsyncTCPSocket(accepted_socket, false);
+
+ // Finally add the socket so it can start communicating with the client.
+ AddInternalSocket(tcp_socket);
+ }
+}
+
+RelayServerConnection::RelayServerConnection(
+ RelayServerBinding* binding, const rtc::SocketAddressPair& addrs,
+ rtc::AsyncPacketSocket* socket)
+ : binding_(binding), addr_pair_(addrs), socket_(socket), locked_(false) {
+ // The creation of a new connection constitutes a use of the binding.
+ binding_->NoteUsed();
+}
+
+RelayServerConnection::~RelayServerConnection() {
+ // Remove this connection from the server's map (if it exists there).
+ binding_->server()->RemoveConnection(this);
+}
+
+void RelayServerConnection::Send(const char* data, size_t size) {
+ // Note that the binding has been used again.
+ binding_->NoteUsed();
+
+ cricket::Send(socket_, data, size, addr_pair_.source());
+}
+
+void RelayServerConnection::Send(
+ const char* data, size_t size, const rtc::SocketAddress& from_addr) {
+ // If the from address is known to the client, we don't need to send it.
+ if (locked() && (from_addr == default_dest_)) {
+ Send(data, size);
+ return;
+ }
+
+ // Wrap the given data in a data-indication packet.
+
+ RelayMessage msg;
+ msg.SetType(STUN_DATA_INDICATION);
+
+ StunByteStringAttribute* magic_cookie_attr =
+ StunAttribute::CreateByteString(cricket::STUN_ATTR_MAGIC_COOKIE);
+ magic_cookie_attr->CopyBytes(binding_->magic_cookie().c_str(),
+ binding_->magic_cookie().size());
+ msg.AddAttribute(magic_cookie_attr);
+
+ StunAddressAttribute* addr_attr =
+ StunAttribute::CreateAddress(STUN_ATTR_SOURCE_ADDRESS2);
+ addr_attr->SetIP(from_addr.ipaddr());
+ addr_attr->SetPort(from_addr.port());
+ msg.AddAttribute(addr_attr);
+
+ StunByteStringAttribute* data_attr =
+ StunAttribute::CreateByteString(STUN_ATTR_DATA);
+ ASSERT(size <= 65536);
+ data_attr->CopyBytes(data, uint16(size));
+ msg.AddAttribute(data_attr);
+
+ SendStun(msg);
+}
+
+void RelayServerConnection::SendStun(const StunMessage& msg) {
+ // Note that the binding has been used again.
+ binding_->NoteUsed();
+
+ cricket::SendStun(msg, socket_, addr_pair_.source());
+}
+
+void RelayServerConnection::SendStunError(
+ const StunMessage& request, int error_code, const char* error_desc) {
+ // An error does not indicate use. If no legitimate use off the binding
+ // occurs, we want it to be cleaned up even if errors are still occuring.
+
+ cricket::SendStunError(
+ request, socket_, addr_pair_.source(), error_code, error_desc,
+ binding_->magic_cookie());
+}
+
+void RelayServerConnection::Lock() {
+ locked_ = true;
+}
+
+void RelayServerConnection::Unlock() {
+ locked_ = false;
+}
+
+// IDs used for posted messages:
+const uint32 MSG_LIFETIME_TIMER = 1;
+
+RelayServerBinding::RelayServerBinding(
+ RelayServer* server, const std::string& username,
+ const std::string& password, uint32 lifetime)
+ : server_(server), username_(username), password_(password),
+ lifetime_(lifetime) {
+ // For now, every connection uses the standard magic cookie value.
+ magic_cookie_.append(
+ reinterpret_cast<const char*>(TURN_MAGIC_COOKIE_VALUE),
+ sizeof(TURN_MAGIC_COOKIE_VALUE));
+
+ // Initialize the last-used time to now.
+ NoteUsed();
+
+ // Set the first timeout check.
+ server_->thread()->PostDelayed(lifetime_, this, MSG_LIFETIME_TIMER);
+}
+
+RelayServerBinding::~RelayServerBinding() {
+ // Clear the outstanding timeout check.
+ server_->thread()->Clear(this);
+
+ // Clean up all of the connections.
+ for (size_t i = 0; i < internal_connections_.size(); ++i)
+ delete internal_connections_[i];
+ for (size_t i = 0; i < external_connections_.size(); ++i)
+ delete external_connections_[i];
+
+ // Remove this binding from the server's map.
+ server_->RemoveBinding(this);
+}
+
+void RelayServerBinding::AddInternalConnection(RelayServerConnection* conn) {
+ internal_connections_.push_back(conn);
+}
+
+void RelayServerBinding::AddExternalConnection(RelayServerConnection* conn) {
+ external_connections_.push_back(conn);
+}
+
+void RelayServerBinding::NoteUsed() {
+ last_used_ = rtc::Time();
+}
+
+bool RelayServerBinding::HasMagicCookie(const char* bytes, size_t size) const {
+ if (size < 24 + magic_cookie_.size()) {
+ return false;
+ } else {
+ return memcmp(bytes + 24, magic_cookie_.c_str(), magic_cookie_.size()) == 0;
+ }
+}
+
+RelayServerConnection* RelayServerBinding::GetInternalConnection(
+ const rtc::SocketAddress& ext_addr) {
+
+ // Look for an internal connection that is locked to this address.
+ for (size_t i = 0; i < internal_connections_.size(); ++i) {
+ if (internal_connections_[i]->locked() &&
+ (ext_addr == internal_connections_[i]->default_destination()))
+ return internal_connections_[i];
+ }
+
+ // If one was not found, we send to the first connection.
+ ASSERT(internal_connections_.size() > 0);
+ return internal_connections_[0];
+}
+
+RelayServerConnection* RelayServerBinding::GetExternalConnection(
+ const rtc::SocketAddress& ext_addr) {
+ for (size_t i = 0; i < external_connections_.size(); ++i) {
+ if (ext_addr == external_connections_[i]->addr_pair().source())
+ return external_connections_[i];
+ }
+ return 0;
+}
+
+void RelayServerBinding::OnMessage(rtc::Message *pmsg) {
+ if (pmsg->message_id == MSG_LIFETIME_TIMER) {
+ ASSERT(!pmsg->pdata);
+
+ // If the lifetime timeout has been exceeded, then send a signal.
+ // Otherwise, just keep waiting.
+ if (rtc::Time() >= last_used_ + lifetime_) {
+ LOG(LS_INFO) << "Expiring binding " << username_;
+ SignalTimeout(this);
+ } else {
+ server_->thread()->PostDelayed(lifetime_, this, MSG_LIFETIME_TIMER);
+ }
+
+ } else {
+ ASSERT(false);
+ }
+}
+
+} // namespace cricket
diff --git a/p2p/base/relayserver.h b/p2p/base/relayserver.h
new file mode 100644
index 00000000..e0e45d52
--- /dev/null
+++ b/p2p/base/relayserver.h
@@ -0,0 +1,235 @@
+/*
+ * 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 WEBRTC_P2P_BASE_RELAYSERVER_H_
+#define WEBRTC_P2P_BASE_RELAYSERVER_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "webrtc/p2p/base/port.h"
+#include "webrtc/p2p/base/stun.h"
+#include "webrtc/base/asyncudpsocket.h"
+#include "webrtc/base/socketaddresspair.h"
+#include "webrtc/base/thread.h"
+#include "webrtc/base/timeutils.h"
+
+namespace cricket {
+
+class RelayServerBinding;
+class RelayServerConnection;
+
+// Relays traffic between connections to the server that are "bound" together.
+// All connections created with the same username/password are bound together.
+class RelayServer : public rtc::MessageHandler,
+ public sigslot::has_slots<> {
+ public:
+ // Creates a server, which will use this thread to post messages to itself.
+ explicit RelayServer(rtc::Thread* thread);
+ ~RelayServer();
+
+ rtc::Thread* thread() { return thread_; }
+
+ // Indicates whether we will print updates of the number of bindings.
+ bool log_bindings() const { return log_bindings_; }
+ void set_log_bindings(bool log_bindings) { log_bindings_ = log_bindings; }
+
+ // Updates the set of sockets that the server uses to talk to "internal"
+ // clients. These are clients that do the "port allocations".
+ void AddInternalSocket(rtc::AsyncPacketSocket* socket);
+ void RemoveInternalSocket(rtc::AsyncPacketSocket* socket);
+
+ // Updates the set of sockets that the server uses to talk to "external"
+ // clients. These are the clients that do not do allocations. They do not
+ // know that these addresses represent a relay server.
+ void AddExternalSocket(rtc::AsyncPacketSocket* socket);
+ void RemoveExternalSocket(rtc::AsyncPacketSocket* socket);
+
+ // Starts listening for connections on this sockets. When someone
+ // tries to connect, the connection will be accepted and a new
+ // internal socket will be added.
+ void AddInternalServerSocket(rtc::AsyncSocket* socket,
+ cricket::ProtocolType proto);
+
+ // Removes this server socket from the list.
+ void RemoveInternalServerSocket(rtc::AsyncSocket* socket);
+
+ // Methods for testing and debuging.
+ int GetConnectionCount() const;
+ rtc::SocketAddressPair GetConnection(int connection) const;
+ bool HasConnection(const rtc::SocketAddress& address) const;
+
+ private:
+ typedef std::vector<rtc::AsyncPacketSocket*> SocketList;
+ typedef std::map<rtc::AsyncSocket*,
+ cricket::ProtocolType> ServerSocketMap;
+ typedef std::map<std::string, RelayServerBinding*> BindingMap;
+ typedef std::map<rtc::SocketAddressPair,
+ RelayServerConnection*> ConnectionMap;
+
+ rtc::Thread* thread_;
+ bool log_bindings_;
+ SocketList internal_sockets_;
+ SocketList external_sockets_;
+ SocketList removed_sockets_;
+ ServerSocketMap server_sockets_;
+ BindingMap bindings_;
+ ConnectionMap connections_;
+
+ // Called when a packet is received by the server on one of its sockets.
+ void OnInternalPacket(rtc::AsyncPacketSocket* socket,
+ const char* bytes, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time);
+ void OnExternalPacket(rtc::AsyncPacketSocket* socket,
+ const char* bytes, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time);
+
+ void OnReadEvent(rtc::AsyncSocket* socket);
+
+ // Processes the relevant STUN request types from the client.
+ bool HandleStun(const char* bytes, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ rtc::AsyncPacketSocket* socket,
+ std::string* username, StunMessage* msg);
+ void HandleStunAllocate(const char* bytes, size_t size,
+ const rtc::SocketAddressPair& ap,
+ rtc::AsyncPacketSocket* socket);
+ void HandleStun(RelayServerConnection* int_conn, const char* bytes,
+ size_t size);
+ void HandleStunAllocate(RelayServerConnection* int_conn,
+ const StunMessage& msg);
+ void HandleStunSend(RelayServerConnection* int_conn, const StunMessage& msg);
+
+ // Adds/Removes the a connection or binding.
+ void AddConnection(RelayServerConnection* conn);
+ void RemoveConnection(RelayServerConnection* conn);
+ void RemoveBinding(RelayServerBinding* binding);
+
+ // Handle messages in our worker thread.
+ void OnMessage(rtc::Message *pmsg);
+
+ // Called when the timer for checking lifetime times out.
+ void OnTimeout(RelayServerBinding* binding);
+
+ // Accept connections on this server socket.
+ void AcceptConnection(rtc::AsyncSocket* server_socket);
+
+ friend class RelayServerConnection;
+ friend class RelayServerBinding;
+};
+
+// Maintains information about a connection to the server. Each connection is
+// part of one and only one binding.
+class RelayServerConnection {
+ public:
+ RelayServerConnection(RelayServerBinding* binding,
+ const rtc::SocketAddressPair& addrs,
+ rtc::AsyncPacketSocket* socket);
+ ~RelayServerConnection();
+
+ RelayServerBinding* binding() { return binding_; }
+ rtc::AsyncPacketSocket* socket() { return socket_; }
+
+ // Returns a pair where the source is the remote address and the destination
+ // is the local address.
+ const rtc::SocketAddressPair& addr_pair() { return addr_pair_; }
+
+ // Sends a packet to the connected client. If an address is provided, then
+ // we make sure the internal client receives it, wrapping if necessary.
+ void Send(const char* data, size_t size);
+ void Send(const char* data, size_t size,
+ const rtc::SocketAddress& ext_addr);
+
+ // Sends a STUN message to the connected client with no wrapping.
+ void SendStun(const StunMessage& msg);
+ void SendStunError(const StunMessage& request, int code, const char* desc);
+
+ // A locked connection is one for which we know the intended destination of
+ // any raw packet received.
+ bool locked() const { return locked_; }
+ void Lock();
+ void Unlock();
+
+ // Records the address that raw packets should be forwarded to (for internal
+ // packets only; for external, we already know where they go).
+ const rtc::SocketAddress& default_destination() const {
+ return default_dest_;
+ }
+ void set_default_destination(const rtc::SocketAddress& addr) {
+ default_dest_ = addr;
+ }
+
+ private:
+ RelayServerBinding* binding_;
+ rtc::SocketAddressPair addr_pair_;
+ rtc::AsyncPacketSocket* socket_;
+ bool locked_;
+ rtc::SocketAddress default_dest_;
+};
+
+// Records a set of internal and external connections that we relay between,
+// or in other words, that are "bound" together.
+class RelayServerBinding : public rtc::MessageHandler {
+ public:
+ RelayServerBinding(
+ RelayServer* server, const std::string& username,
+ const std::string& password, uint32 lifetime);
+ virtual ~RelayServerBinding();
+
+ RelayServer* server() { return server_; }
+ uint32 lifetime() { return lifetime_; }
+ const std::string& username() { return username_; }
+ const std::string& password() { return password_; }
+ const std::string& magic_cookie() { return magic_cookie_; }
+
+ // Adds/Removes a connection into the binding.
+ void AddInternalConnection(RelayServerConnection* conn);
+ void AddExternalConnection(RelayServerConnection* conn);
+
+ // We keep track of the use of each binding. If we detect that it was not
+ // used for longer than the lifetime, then we send a signal.
+ void NoteUsed();
+ sigslot::signal1<RelayServerBinding*> SignalTimeout;
+
+ // Determines whether the given packet has the magic cookie present (in the
+ // right place).
+ bool HasMagicCookie(const char* bytes, size_t size) const;
+
+ // Determines the connection to use to send packets to or from the given
+ // external address.
+ RelayServerConnection* GetInternalConnection(
+ const rtc::SocketAddress& ext_addr);
+ RelayServerConnection* GetExternalConnection(
+ const rtc::SocketAddress& ext_addr);
+
+ // MessageHandler:
+ void OnMessage(rtc::Message *pmsg);
+
+ private:
+ RelayServer* server_;
+
+ std::string username_;
+ std::string password_;
+ std::string magic_cookie_;
+
+ std::vector<RelayServerConnection*> internal_connections_;
+ std::vector<RelayServerConnection*> external_connections_;
+
+ uint32 lifetime_;
+ uint32 last_used_;
+ // TODO: bandwidth
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_RELAYSERVER_H_
diff --git a/p2p/base/relayserver_unittest.cc b/p2p/base/relayserver_unittest.cc
new file mode 100644
index 00000000..3349a173
--- /dev/null
+++ b/p2p/base/relayserver_unittest.cc
@@ -0,0 +1,519 @@
+/*
+ * 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 <string>
+
+#include "webrtc/p2p/base/relayserver.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/physicalsocketserver.h"
+#include "webrtc/base/socketaddress.h"
+#include "webrtc/base/ssladapter.h"
+#include "webrtc/base/testclient.h"
+#include "webrtc/base/thread.h"
+
+using rtc::SocketAddress;
+using namespace cricket;
+
+static const uint32 LIFETIME = 4; // seconds
+static const SocketAddress server_int_addr("127.0.0.1", 5000);
+static const SocketAddress server_ext_addr("127.0.0.1", 5001);
+static const SocketAddress client1_addr("127.0.0.1", 6000 + (rand() % 1000));
+static const SocketAddress client2_addr("127.0.0.1", 7000 + (rand() % 1000));
+static const char* bad = "this is a completely nonsensical message whose only "
+ "purpose is to make the parser go 'ack'. it doesn't "
+ "look anything like a normal stun message";
+static const char* msg1 = "spamspamspamspamspamspamspambakedbeansspam";
+static const char* msg2 = "Lobster Thermidor a Crevette with a mornay sauce...";
+
+class RelayServerTest : public testing::Test {
+ public:
+ RelayServerTest()
+ : main_(rtc::Thread::Current()), ss_(main_->socketserver()),
+ username_(rtc::CreateRandomString(12)),
+ password_(rtc::CreateRandomString(12)) {
+ }
+ protected:
+ virtual void SetUp() {
+ server_.reset(new RelayServer(main_));
+
+ server_->AddInternalSocket(
+ rtc::AsyncUDPSocket::Create(ss_, server_int_addr));
+ server_->AddExternalSocket(
+ rtc::AsyncUDPSocket::Create(ss_, server_ext_addr));
+
+ client1_.reset(new rtc::TestClient(
+ rtc::AsyncUDPSocket::Create(ss_, client1_addr)));
+ client2_.reset(new rtc::TestClient(
+ rtc::AsyncUDPSocket::Create(ss_, client2_addr)));
+ }
+
+ void Allocate() {
+ rtc::scoped_ptr<StunMessage> req(
+ CreateStunMessage(STUN_ALLOCATE_REQUEST));
+ AddUsernameAttr(req.get(), username_);
+ AddLifetimeAttr(req.get(), LIFETIME);
+ Send1(req.get());
+ delete Receive1();
+ }
+ void Bind() {
+ rtc::scoped_ptr<StunMessage> req(
+ CreateStunMessage(STUN_BINDING_REQUEST));
+ AddUsernameAttr(req.get(), username_);
+ Send2(req.get());
+ delete Receive1();
+ }
+
+ void Send1(const StunMessage* msg) {
+ rtc::ByteBuffer buf;
+ msg->Write(&buf);
+ SendRaw1(buf.Data(), static_cast<int>(buf.Length()));
+ }
+ void Send2(const StunMessage* msg) {
+ rtc::ByteBuffer buf;
+ msg->Write(&buf);
+ SendRaw2(buf.Data(), static_cast<int>(buf.Length()));
+ }
+ void SendRaw1(const char* data, int len) {
+ return Send(client1_.get(), data, len, server_int_addr);
+ }
+ void SendRaw2(const char* data, int len) {
+ return Send(client2_.get(), data, len, server_ext_addr);
+ }
+ void Send(rtc::TestClient* client, const char* data,
+ int len, const SocketAddress& addr) {
+ client->SendTo(data, len, addr);
+ }
+
+ StunMessage* Receive1() {
+ return Receive(client1_.get());
+ }
+ StunMessage* Receive2() {
+ return Receive(client2_.get());
+ }
+ std::string ReceiveRaw1() {
+ return ReceiveRaw(client1_.get());
+ }
+ std::string ReceiveRaw2() {
+ return ReceiveRaw(client2_.get());
+ }
+ StunMessage* Receive(rtc::TestClient* client) {
+ StunMessage* msg = NULL;
+ rtc::TestClient::Packet* packet = client->NextPacket();
+ if (packet) {
+ rtc::ByteBuffer buf(packet->buf, packet->size);
+ msg = new RelayMessage();
+ msg->Read(&buf);
+ delete packet;
+ }
+ return msg;
+ }
+ std::string ReceiveRaw(rtc::TestClient* client) {
+ std::string raw;
+ rtc::TestClient::Packet* packet = client->NextPacket();
+ if (packet) {
+ raw = std::string(packet->buf, packet->size);
+ delete packet;
+ }
+ return raw;
+ }
+
+ static StunMessage* CreateStunMessage(int type) {
+ StunMessage* msg = new RelayMessage();
+ msg->SetType(type);
+ msg->SetTransactionID(
+ rtc::CreateRandomString(kStunTransactionIdLength));
+ return msg;
+ }
+ static void AddMagicCookieAttr(StunMessage* msg) {
+ StunByteStringAttribute* attr =
+ StunAttribute::CreateByteString(STUN_ATTR_MAGIC_COOKIE);
+ attr->CopyBytes(TURN_MAGIC_COOKIE_VALUE, sizeof(TURN_MAGIC_COOKIE_VALUE));
+ msg->AddAttribute(attr);
+ }
+ static void AddUsernameAttr(StunMessage* msg, const std::string& val) {
+ StunByteStringAttribute* attr =
+ StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
+ attr->CopyBytes(val.c_str(), val.size());
+ msg->AddAttribute(attr);
+ }
+ static void AddLifetimeAttr(StunMessage* msg, int val) {
+ StunUInt32Attribute* attr =
+ StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME);
+ attr->SetValue(val);
+ msg->AddAttribute(attr);
+ }
+ static void AddDestinationAttr(StunMessage* msg, const SocketAddress& addr) {
+ StunAddressAttribute* attr =
+ StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
+ attr->SetIP(addr.ipaddr());
+ attr->SetPort(addr.port());
+ msg->AddAttribute(attr);
+ }
+
+ rtc::Thread* main_;
+ rtc::SocketServer* ss_;
+ rtc::scoped_ptr<RelayServer> server_;
+ rtc::scoped_ptr<rtc::TestClient> client1_;
+ rtc::scoped_ptr<rtc::TestClient> client2_;
+ std::string username_;
+ std::string password_;
+};
+
+// Send a complete nonsense message and verify that it is eaten.
+TEST_F(RelayServerTest, TestBadRequest) {
+ rtc::scoped_ptr<StunMessage> res;
+
+ SendRaw1(bad, static_cast<int>(strlen(bad)));
+ res.reset(Receive1());
+
+ ASSERT_TRUE(!res);
+}
+
+// Send an allocate request without a username and verify it is rejected.
+TEST_F(RelayServerTest, TestAllocateNoUsername) {
+ rtc::scoped_ptr<StunMessage> req(
+ CreateStunMessage(STUN_ALLOCATE_REQUEST)), res;
+
+ Send1(req.get());
+ res.reset(Receive1());
+
+ ASSERT_TRUE(res);
+ EXPECT_EQ(STUN_ALLOCATE_ERROR_RESPONSE, res->type());
+ EXPECT_EQ(req->transaction_id(), res->transaction_id());
+
+ const StunErrorCodeAttribute* err = res->GetErrorCode();
+ ASSERT_TRUE(err != NULL);
+ EXPECT_EQ(4, err->eclass());
+ EXPECT_EQ(32, err->number());
+ EXPECT_EQ("Missing Username", err->reason());
+}
+
+// Send a binding request and verify that it is rejected.
+TEST_F(RelayServerTest, TestBindingRequest) {
+ rtc::scoped_ptr<StunMessage> req(
+ CreateStunMessage(STUN_BINDING_REQUEST)), res;
+ AddUsernameAttr(req.get(), username_);
+
+ Send1(req.get());
+ res.reset(Receive1());
+
+ ASSERT_TRUE(res);
+ EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, res->type());
+ EXPECT_EQ(req->transaction_id(), res->transaction_id());
+
+ const StunErrorCodeAttribute* err = res->GetErrorCode();
+ ASSERT_TRUE(err != NULL);
+ EXPECT_EQ(6, err->eclass());
+ EXPECT_EQ(0, err->number());
+ EXPECT_EQ("Operation Not Supported", err->reason());
+}
+
+// Send an allocate request and verify that it is accepted.
+TEST_F(RelayServerTest, TestAllocate) {
+ rtc::scoped_ptr<StunMessage> req(
+ CreateStunMessage(STUN_ALLOCATE_REQUEST)), res;
+ AddUsernameAttr(req.get(), username_);
+ AddLifetimeAttr(req.get(), LIFETIME);
+
+ Send1(req.get());
+ res.reset(Receive1());
+
+ ASSERT_TRUE(res);
+ EXPECT_EQ(STUN_ALLOCATE_RESPONSE, res->type());
+ EXPECT_EQ(req->transaction_id(), res->transaction_id());
+
+ const StunAddressAttribute* mapped_addr =
+ res->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
+ ASSERT_TRUE(mapped_addr != NULL);
+ EXPECT_EQ(1, mapped_addr->family());
+ EXPECT_EQ(server_ext_addr.port(), mapped_addr->port());
+ EXPECT_EQ(server_ext_addr.ipaddr(), mapped_addr->ipaddr());
+
+ const StunUInt32Attribute* res_lifetime_attr =
+ res->GetUInt32(STUN_ATTR_LIFETIME);
+ ASSERT_TRUE(res_lifetime_attr != NULL);
+ EXPECT_EQ(LIFETIME, res_lifetime_attr->value());
+}
+
+// Send a second allocate request and verify that it is also accepted, though
+// the lifetime should be ignored.
+TEST_F(RelayServerTest, TestReallocate) {
+ Allocate();
+
+ rtc::scoped_ptr<StunMessage> req(
+ CreateStunMessage(STUN_ALLOCATE_REQUEST)), res;
+ AddMagicCookieAttr(req.get());
+ AddUsernameAttr(req.get(), username_);
+
+ Send1(req.get());
+ res.reset(Receive1());
+
+ ASSERT_TRUE(res);
+ EXPECT_EQ(STUN_ALLOCATE_RESPONSE, res->type());
+ EXPECT_EQ(req->transaction_id(), res->transaction_id());
+
+ const StunAddressAttribute* mapped_addr =
+ res->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
+ ASSERT_TRUE(mapped_addr != NULL);
+ EXPECT_EQ(1, mapped_addr->family());
+ EXPECT_EQ(server_ext_addr.port(), mapped_addr->port());
+ EXPECT_EQ(server_ext_addr.ipaddr(), mapped_addr->ipaddr());
+
+ const StunUInt32Attribute* lifetime_attr =
+ res->GetUInt32(STUN_ATTR_LIFETIME);
+ ASSERT_TRUE(lifetime_attr != NULL);
+ EXPECT_EQ(LIFETIME, lifetime_attr->value());
+}
+
+// Send a request from another client and see that it arrives at the first
+// client in the binding.
+TEST_F(RelayServerTest, TestRemoteBind) {
+ Allocate();
+
+ rtc::scoped_ptr<StunMessage> req(
+ CreateStunMessage(STUN_BINDING_REQUEST)), res;
+ AddUsernameAttr(req.get(), username_);
+
+ Send2(req.get());
+ res.reset(Receive1());
+
+ ASSERT_TRUE(res);
+ EXPECT_EQ(STUN_DATA_INDICATION, res->type());
+
+ const StunByteStringAttribute* recv_data =
+ res->GetByteString(STUN_ATTR_DATA);
+ ASSERT_TRUE(recv_data != NULL);
+
+ rtc::ByteBuffer buf(recv_data->bytes(), recv_data->length());
+ rtc::scoped_ptr<StunMessage> res2(new StunMessage());
+ EXPECT_TRUE(res2->Read(&buf));
+ EXPECT_EQ(STUN_BINDING_REQUEST, res2->type());
+ EXPECT_EQ(req->transaction_id(), res2->transaction_id());
+
+ const StunAddressAttribute* src_addr =
+ res->GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
+ ASSERT_TRUE(src_addr != NULL);
+ EXPECT_EQ(1, src_addr->family());
+ EXPECT_EQ(client2_addr.ipaddr(), src_addr->ipaddr());
+ EXPECT_EQ(client2_addr.port(), src_addr->port());
+
+ EXPECT_TRUE(Receive2() == NULL);
+}
+
+// Send a complete nonsense message to the established connection and verify
+// that it is dropped by the server.
+TEST_F(RelayServerTest, TestRemoteBadRequest) {
+ Allocate();
+ Bind();
+
+ SendRaw1(bad, static_cast<int>(strlen(bad)));
+ EXPECT_TRUE(Receive1() == NULL);
+ EXPECT_TRUE(Receive2() == NULL);
+}
+
+// Send a send request without a username and verify it is rejected.
+TEST_F(RelayServerTest, TestSendRequestMissingUsername) {
+ Allocate();
+ Bind();
+
+ rtc::scoped_ptr<StunMessage> req(
+ CreateStunMessage(STUN_SEND_REQUEST)), res;
+ AddMagicCookieAttr(req.get());
+
+ Send1(req.get());
+ res.reset(Receive1());
+
+ ASSERT_TRUE(res);
+ EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
+ EXPECT_EQ(req->transaction_id(), res->transaction_id());
+
+ const StunErrorCodeAttribute* err = res->GetErrorCode();
+ ASSERT_TRUE(err != NULL);
+ EXPECT_EQ(4, err->eclass());
+ EXPECT_EQ(32, err->number());
+ EXPECT_EQ("Missing Username", err->reason());
+}
+
+// Send a send request with the wrong username and verify it is rejected.
+TEST_F(RelayServerTest, TestSendRequestBadUsername) {
+ Allocate();
+ Bind();
+
+ rtc::scoped_ptr<StunMessage> req(
+ CreateStunMessage(STUN_SEND_REQUEST)), res;
+ AddMagicCookieAttr(req.get());
+ AddUsernameAttr(req.get(), "foobarbizbaz");
+
+ Send1(req.get());
+ res.reset(Receive1());
+
+ ASSERT_TRUE(res);
+ EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
+ EXPECT_EQ(req->transaction_id(), res->transaction_id());
+
+ const StunErrorCodeAttribute* err = res->GetErrorCode();
+ ASSERT_TRUE(err != NULL);
+ EXPECT_EQ(4, err->eclass());
+ EXPECT_EQ(30, err->number());
+ EXPECT_EQ("Stale Credentials", err->reason());
+}
+
+// Send a send request without a destination address and verify that it is
+// rejected.
+TEST_F(RelayServerTest, TestSendRequestNoDestinationAddress) {
+ Allocate();
+ Bind();
+
+ rtc::scoped_ptr<StunMessage> req(
+ CreateStunMessage(STUN_SEND_REQUEST)), res;
+ AddMagicCookieAttr(req.get());
+ AddUsernameAttr(req.get(), username_);
+
+ Send1(req.get());
+ res.reset(Receive1());
+
+ ASSERT_TRUE(res);
+ EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
+ EXPECT_EQ(req->transaction_id(), res->transaction_id());
+
+ const StunErrorCodeAttribute* err = res->GetErrorCode();
+ ASSERT_TRUE(err != NULL);
+ EXPECT_EQ(4, err->eclass());
+ EXPECT_EQ(0, err->number());
+ EXPECT_EQ("Bad Request", err->reason());
+}
+
+// Send a send request without data and verify that it is rejected.
+TEST_F(RelayServerTest, TestSendRequestNoData) {
+ Allocate();
+ Bind();
+
+ rtc::scoped_ptr<StunMessage> req(
+ CreateStunMessage(STUN_SEND_REQUEST)), res;
+ AddMagicCookieAttr(req.get());
+ AddUsernameAttr(req.get(), username_);
+ AddDestinationAttr(req.get(), client2_addr);
+
+ Send1(req.get());
+ res.reset(Receive1());
+
+ ASSERT_TRUE(res);
+ EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
+ EXPECT_EQ(req->transaction_id(), res->transaction_id());
+
+ const StunErrorCodeAttribute* err = res->GetErrorCode();
+ ASSERT_TRUE(err != NULL);
+ EXPECT_EQ(4, err->eclass());
+ EXPECT_EQ(00, err->number());
+ EXPECT_EQ("Bad Request", err->reason());
+}
+
+// Send a binding request after an allocate and verify that it is rejected.
+TEST_F(RelayServerTest, TestSendRequestWrongType) {
+ Allocate();
+ Bind();
+
+ rtc::scoped_ptr<StunMessage> req(
+ CreateStunMessage(STUN_BINDING_REQUEST)), res;
+ AddMagicCookieAttr(req.get());
+ AddUsernameAttr(req.get(), username_);
+
+ Send1(req.get());
+ res.reset(Receive1());
+
+ ASSERT_TRUE(res);
+ EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, res->type());
+ EXPECT_EQ(req->transaction_id(), res->transaction_id());
+
+ const StunErrorCodeAttribute* err = res->GetErrorCode();
+ ASSERT_TRUE(err != NULL);
+ EXPECT_EQ(6, err->eclass());
+ EXPECT_EQ(0, err->number());
+ EXPECT_EQ("Operation Not Supported", err->reason());
+}
+
+// Verify that we can send traffic back and forth between the clients after a
+// successful allocate and bind.
+TEST_F(RelayServerTest, TestSendRaw) {
+ Allocate();
+ Bind();
+
+ for (int i = 0; i < 10; i++) {
+ rtc::scoped_ptr<StunMessage> req(
+ CreateStunMessage(STUN_SEND_REQUEST)), res;
+ AddMagicCookieAttr(req.get());
+ AddUsernameAttr(req.get(), username_);
+ AddDestinationAttr(req.get(), client2_addr);
+
+ StunByteStringAttribute* send_data =
+ StunAttribute::CreateByteString(STUN_ATTR_DATA);
+ send_data->CopyBytes(msg1);
+ req->AddAttribute(send_data);
+
+ Send1(req.get());
+ EXPECT_EQ(msg1, ReceiveRaw2());
+ SendRaw2(msg2, static_cast<int>(strlen(msg2)));
+ res.reset(Receive1());
+
+ ASSERT_TRUE(res);
+ EXPECT_EQ(STUN_DATA_INDICATION, res->type());
+
+ const StunAddressAttribute* src_addr =
+ res->GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
+ ASSERT_TRUE(src_addr != NULL);
+ EXPECT_EQ(1, src_addr->family());
+ EXPECT_EQ(client2_addr.ipaddr(), src_addr->ipaddr());
+ EXPECT_EQ(client2_addr.port(), src_addr->port());
+
+ const StunByteStringAttribute* recv_data =
+ res->GetByteString(STUN_ATTR_DATA);
+ ASSERT_TRUE(recv_data != NULL);
+ EXPECT_EQ(strlen(msg2), recv_data->length());
+ EXPECT_EQ(0, memcmp(msg2, recv_data->bytes(), recv_data->length()));
+ }
+}
+
+// Verify that a binding expires properly, and rejects send requests.
+TEST_F(RelayServerTest, TestExpiration) {
+ Allocate();
+ Bind();
+
+ // Wait twice the lifetime to make sure the server has expired the binding.
+ rtc::Thread::Current()->ProcessMessages((LIFETIME * 2) * 1000);
+
+ rtc::scoped_ptr<StunMessage> req(
+ CreateStunMessage(STUN_SEND_REQUEST)), res;
+ AddMagicCookieAttr(req.get());
+ AddUsernameAttr(req.get(), username_);
+ AddDestinationAttr(req.get(), client2_addr);
+
+ StunByteStringAttribute* data_attr =
+ StunAttribute::CreateByteString(STUN_ATTR_DATA);
+ data_attr->CopyBytes(msg1);
+ req->AddAttribute(data_attr);
+
+ Send1(req.get());
+ res.reset(Receive1());
+
+ ASSERT_TRUE(res.get() != NULL);
+ EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
+
+ const StunErrorCodeAttribute* err = res->GetErrorCode();
+ ASSERT_TRUE(err != NULL);
+ EXPECT_EQ(6, err->eclass());
+ EXPECT_EQ(0, err->number());
+ EXPECT_EQ("Operation Not Supported", err->reason());
+
+ // Also verify that traffic from the external client is ignored.
+ SendRaw2(msg2, static_cast<int>(strlen(msg2)));
+ EXPECT_TRUE(ReceiveRaw1().empty());
+}
diff --git a/p2p/base/session.cc b/p2p/base/session.cc
new file mode 100644
index 00000000..9749b14e
--- /dev/null
+++ b/p2p/base/session.cc
@@ -0,0 +1,1760 @@
+/*
+ * 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 "webrtc/p2p/base/session.h"
+
+#include "webrtc/p2p/base/dtlstransport.h"
+#include "webrtc/p2p/base/p2ptransport.h"
+#include "webrtc/p2p/base/sessionclient.h"
+#include "webrtc/p2p/base/transport.h"
+#include "webrtc/p2p/base/transportchannelproxy.h"
+#include "webrtc/p2p/base/transportinfo.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/jid.h"
+#include "webrtc/base/bind.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/sslstreamadapter.h"
+
+#include "webrtc/p2p/base/constants.h"
+
+namespace cricket {
+
+using rtc::Bind;
+
+bool BadMessage(const buzz::QName type,
+ const std::string& text,
+ MessageError* err) {
+ err->SetType(type);
+ err->SetText(text);
+ return false;
+}
+
+TransportProxy::~TransportProxy() {
+ for (ChannelMap::iterator iter = channels_.begin();
+ iter != channels_.end(); ++iter) {
+ iter->second->SignalDestroyed(iter->second);
+ delete iter->second;
+ }
+}
+
+const std::string& TransportProxy::type() const {
+ return transport_->get()->type();
+}
+
+TransportChannel* TransportProxy::GetChannel(int component) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ return GetChannelProxy(component);
+}
+
+TransportChannel* TransportProxy::CreateChannel(
+ const std::string& name, int component) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ ASSERT(GetChannel(component) == NULL);
+ ASSERT(!transport_->get()->HasChannel(component));
+
+ // We always create a proxy in case we need to change out the transport later.
+ TransportChannelProxy* channel =
+ new TransportChannelProxy(content_name(), name, component);
+ channels_[component] = channel;
+
+ // If we're already negotiated, create an impl and hook it up to the proxy
+ // channel. If we're connecting, create an impl but don't hook it up yet.
+ if (negotiated_) {
+ SetupChannelProxy_w(component, channel);
+ } else if (connecting_) {
+ GetOrCreateChannelProxyImpl_w(component);
+ }
+ return channel;
+}
+
+bool TransportProxy::HasChannel(int component) {
+ return transport_->get()->HasChannel(component);
+}
+
+void TransportProxy::DestroyChannel(int component) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ TransportChannel* channel = GetChannel(component);
+ if (channel) {
+ // If the state of TransportProxy is not NEGOTIATED
+ // then TransportChannelProxy and its impl are not
+ // connected. Both must be connected before
+ // deletion.
+ if (!negotiated_) {
+ SetupChannelProxy_w(component, GetChannelProxy(component));
+ }
+
+ channels_.erase(component);
+ channel->SignalDestroyed(channel);
+ delete channel;
+ }
+}
+
+void TransportProxy::ConnectChannels() {
+ if (!connecting_) {
+ if (!negotiated_) {
+ for (ChannelMap::iterator iter = channels_.begin();
+ iter != channels_.end(); ++iter) {
+ GetOrCreateChannelProxyImpl(iter->first);
+ }
+ }
+ connecting_ = true;
+ }
+ // TODO(juberti): Right now Transport::ConnectChannels doesn't work if we
+ // don't have any channels yet, so we need to allow this method to be called
+ // multiple times. Once we fix Transport, we can move this call inside the
+ // if (!connecting_) block.
+ transport_->get()->ConnectChannels();
+}
+
+void TransportProxy::CompleteNegotiation() {
+ if (!negotiated_) {
+ for (ChannelMap::iterator iter = channels_.begin();
+ iter != channels_.end(); ++iter) {
+ SetupChannelProxy(iter->first, iter->second);
+ }
+ negotiated_ = true;
+ }
+}
+
+void TransportProxy::AddSentCandidates(const Candidates& candidates) {
+ for (Candidates::const_iterator cand = candidates.begin();
+ cand != candidates.end(); ++cand) {
+ sent_candidates_.push_back(*cand);
+ }
+}
+
+void TransportProxy::AddUnsentCandidates(const Candidates& candidates) {
+ for (Candidates::const_iterator cand = candidates.begin();
+ cand != candidates.end(); ++cand) {
+ unsent_candidates_.push_back(*cand);
+ }
+}
+
+bool TransportProxy::GetChannelNameFromComponent(
+ int component, std::string* channel_name) const {
+ const TransportChannelProxy* channel = GetChannelProxy(component);
+ if (channel == NULL) {
+ return false;
+ }
+
+ *channel_name = channel->name();
+ return true;
+}
+
+bool TransportProxy::GetComponentFromChannelName(
+ const std::string& channel_name, int* component) const {
+ const TransportChannelProxy* channel = GetChannelProxyByName(channel_name);
+ if (channel == NULL) {
+ return false;
+ }
+
+ *component = channel->component();
+ return true;
+}
+
+TransportChannelProxy* TransportProxy::GetChannelProxy(int component) const {
+ ChannelMap::const_iterator iter = channels_.find(component);
+ return (iter != channels_.end()) ? iter->second : NULL;
+}
+
+TransportChannelProxy* TransportProxy::GetChannelProxyByName(
+ const std::string& name) const {
+ for (ChannelMap::const_iterator iter = channels_.begin();
+ iter != channels_.end();
+ ++iter) {
+ if (iter->second->name() == name) {
+ return iter->second;
+ }
+ }
+ return NULL;
+}
+
+TransportChannelImpl* TransportProxy::GetOrCreateChannelProxyImpl(
+ int component) {
+ return worker_thread_->Invoke<TransportChannelImpl*>(Bind(
+ &TransportProxy::GetOrCreateChannelProxyImpl_w, this, component));
+}
+
+TransportChannelImpl* TransportProxy::GetOrCreateChannelProxyImpl_w(
+ int component) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ TransportChannelImpl* impl = transport_->get()->GetChannel(component);
+ if (impl == NULL) {
+ impl = transport_->get()->CreateChannel(component);
+ }
+ return impl;
+}
+
+void TransportProxy::SetupChannelProxy(
+ int component, TransportChannelProxy* transproxy) {
+ worker_thread_->Invoke<void>(Bind(
+ &TransportProxy::SetupChannelProxy_w, this, component, transproxy));
+}
+
+void TransportProxy::SetupChannelProxy_w(
+ int component, TransportChannelProxy* transproxy) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ TransportChannelImpl* impl = GetOrCreateChannelProxyImpl(component);
+ ASSERT(impl != NULL);
+ transproxy->SetImplementation(impl);
+}
+
+void TransportProxy::ReplaceChannelProxyImpl(TransportChannelProxy* proxy,
+ TransportChannelImpl* impl) {
+ worker_thread_->Invoke<void>(Bind(
+ &TransportProxy::ReplaceChannelProxyImpl_w, this, proxy, impl));
+}
+
+void TransportProxy::ReplaceChannelProxyImpl_w(TransportChannelProxy* proxy,
+ TransportChannelImpl* impl) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ ASSERT(proxy != NULL);
+ proxy->SetImplementation(impl);
+}
+
+// This function muxes |this| onto |target| by repointing |this| at
+// |target|'s transport and setting our TransportChannelProxies
+// to point to |target|'s underlying implementations.
+bool TransportProxy::SetupMux(TransportProxy* target) {
+ // Bail out if there's nothing to do.
+ if (transport_ == target->transport_) {
+ return true;
+ }
+
+ // Run through all channels and remove any non-rtp transport channels before
+ // setting target transport channels.
+ for (ChannelMap::const_iterator iter = channels_.begin();
+ iter != channels_.end(); ++iter) {
+ if (!target->transport_->get()->HasChannel(iter->first)) {
+ // Remove if channel doesn't exist in |transport_|.
+ ReplaceChannelProxyImpl(iter->second, NULL);
+ } else {
+ // Replace the impl for all the TransportProxyChannels with the channels
+ // from |target|'s transport. Fail if there's not an exact match.
+ ReplaceChannelProxyImpl(
+ iter->second, target->transport_->get()->CreateChannel(iter->first));
+ }
+ }
+
+ // Now replace our transport. Must happen afterwards because
+ // it deletes all impls as a side effect.
+ transport_ = target->transport_;
+ transport_->get()->SignalCandidatesReady.connect(
+ this, &TransportProxy::OnTransportCandidatesReady);
+ set_candidates_allocated(target->candidates_allocated());
+ return true;
+}
+
+void TransportProxy::SetIceRole(IceRole role) {
+ transport_->get()->SetIceRole(role);
+}
+
+bool TransportProxy::SetLocalTransportDescription(
+ const TransportDescription& description,
+ ContentAction action,
+ std::string* error_desc) {
+ // If this is an answer, finalize the negotiation.
+ if (action == CA_ANSWER) {
+ CompleteNegotiation();
+ }
+ bool result = transport_->get()->SetLocalTransportDescription(description,
+ action,
+ error_desc);
+ if (result)
+ local_description_set_ = true;
+ return result;
+}
+
+bool TransportProxy::SetRemoteTransportDescription(
+ const TransportDescription& description,
+ ContentAction action,
+ std::string* error_desc) {
+ // If this is an answer, finalize the negotiation.
+ if (action == CA_ANSWER) {
+ CompleteNegotiation();
+ }
+ bool result = transport_->get()->SetRemoteTransportDescription(description,
+ action,
+ error_desc);
+ if (result)
+ remote_description_set_ = true;
+ return result;
+}
+
+void TransportProxy::OnSignalingReady() {
+ // If we're starting a new allocation sequence, reset our state.
+ set_candidates_allocated(false);
+ transport_->get()->OnSignalingReady();
+}
+
+bool TransportProxy::OnRemoteCandidates(const Candidates& candidates,
+ std::string* error) {
+ // Ensure the transport is negotiated before handling candidates.
+ // TODO(juberti): Remove this once everybody calls SetLocalTD.
+ CompleteNegotiation();
+
+ // Verify each candidate before passing down to transport layer.
+ for (Candidates::const_iterator cand = candidates.begin();
+ cand != candidates.end(); ++cand) {
+ if (!transport_->get()->VerifyCandidate(*cand, error))
+ return false;
+ if (!HasChannel(cand->component())) {
+ *error = "Candidate has unknown component: " + cand->ToString() +
+ " for content: " + content_name_;
+ return false;
+ }
+ }
+ transport_->get()->OnRemoteCandidates(candidates);
+ return true;
+}
+
+void TransportProxy::SetIdentity(
+ rtc::SSLIdentity* identity) {
+ transport_->get()->SetIdentity(identity);
+}
+
+std::string BaseSession::StateToString(State state) {
+ switch (state) {
+ case Session::STATE_INIT:
+ return "STATE_INIT";
+ case Session::STATE_SENTINITIATE:
+ return "STATE_SENTINITIATE";
+ case Session::STATE_RECEIVEDINITIATE:
+ return "STATE_RECEIVEDINITIATE";
+ case Session::STATE_SENTPRACCEPT:
+ return "STATE_SENTPRACCEPT";
+ case Session::STATE_SENTACCEPT:
+ return "STATE_SENTACCEPT";
+ case Session::STATE_RECEIVEDPRACCEPT:
+ return "STATE_RECEIVEDPRACCEPT";
+ case Session::STATE_RECEIVEDACCEPT:
+ return "STATE_RECEIVEDACCEPT";
+ case Session::STATE_SENTMODIFY:
+ return "STATE_SENTMODIFY";
+ case Session::STATE_RECEIVEDMODIFY:
+ return "STATE_RECEIVEDMODIFY";
+ case Session::STATE_SENTREJECT:
+ return "STATE_SENTREJECT";
+ case Session::STATE_RECEIVEDREJECT:
+ return "STATE_RECEIVEDREJECT";
+ case Session::STATE_SENTREDIRECT:
+ return "STATE_SENTREDIRECT";
+ case Session::STATE_SENTTERMINATE:
+ return "STATE_SENTTERMINATE";
+ case Session::STATE_RECEIVEDTERMINATE:
+ return "STATE_RECEIVEDTERMINATE";
+ case Session::STATE_INPROGRESS:
+ return "STATE_INPROGRESS";
+ case Session::STATE_DEINIT:
+ return "STATE_DEINIT";
+ default:
+ break;
+ }
+ return "STATE_" + rtc::ToString(state);
+}
+
+BaseSession::BaseSession(rtc::Thread* signaling_thread,
+ rtc::Thread* worker_thread,
+ PortAllocator* port_allocator,
+ const std::string& sid,
+ const std::string& content_type,
+ bool initiator)
+ : state_(STATE_INIT),
+ error_(ERROR_NONE),
+ signaling_thread_(signaling_thread),
+ worker_thread_(worker_thread),
+ port_allocator_(port_allocator),
+ sid_(sid),
+ content_type_(content_type),
+ transport_type_(NS_GINGLE_P2P),
+ initiator_(initiator),
+ identity_(NULL),
+ ice_tiebreaker_(rtc::CreateRandomId64()),
+ role_switch_(false) {
+ ASSERT(signaling_thread->IsCurrent());
+}
+
+BaseSession::~BaseSession() {
+ ASSERT(signaling_thread()->IsCurrent());
+
+ ASSERT(state_ != STATE_DEINIT);
+ LogState(state_, STATE_DEINIT);
+ state_ = STATE_DEINIT;
+ SignalState(this, state_);
+
+ for (TransportMap::iterator iter = transports_.begin();
+ iter != transports_.end(); ++iter) {
+ delete iter->second;
+ }
+}
+
+const SessionDescription* BaseSession::local_description() const {
+ // TODO(tommi): Assert on thread correctness.
+ return local_description_.get();
+}
+
+const SessionDescription* BaseSession::remote_description() const {
+ // TODO(tommi): Assert on thread correctness.
+ return remote_description_.get();
+}
+
+SessionDescription* BaseSession::remote_description() {
+ // TODO(tommi): Assert on thread correctness.
+ return remote_description_.get();
+}
+
+void BaseSession::set_local_description(const SessionDescription* sdesc) {
+ // TODO(tommi): Assert on thread correctness.
+ if (sdesc != local_description_.get())
+ local_description_.reset(sdesc);
+}
+
+void BaseSession::set_remote_description(SessionDescription* sdesc) {
+ // TODO(tommi): Assert on thread correctness.
+ if (sdesc != remote_description_)
+ remote_description_.reset(sdesc);
+}
+
+const SessionDescription* BaseSession::initiator_description() const {
+ // TODO(tommi): Assert on thread correctness.
+ return initiator_ ? local_description_.get() : remote_description_.get();
+}
+
+bool BaseSession::SetIdentity(rtc::SSLIdentity* identity) {
+ if (identity_)
+ return false;
+ identity_ = identity;
+ for (TransportMap::iterator iter = transports_.begin();
+ iter != transports_.end(); ++iter) {
+ iter->second->SetIdentity(identity_);
+ }
+ return true;
+}
+
+bool BaseSession::PushdownTransportDescription(ContentSource source,
+ ContentAction action,
+ std::string* error_desc) {
+ if (source == CS_LOCAL) {
+ return PushdownLocalTransportDescription(local_description(),
+ action,
+ error_desc);
+ }
+ return PushdownRemoteTransportDescription(remote_description(),
+ action,
+ error_desc);
+}
+
+bool BaseSession::PushdownLocalTransportDescription(
+ const SessionDescription* sdesc,
+ ContentAction action,
+ std::string* error_desc) {
+ // Update the Transports with the right information, and trigger them to
+ // start connecting.
+ for (TransportMap::iterator iter = transports_.begin();
+ iter != transports_.end(); ++iter) {
+ // If no transport info was in this session description, ret == false
+ // and we just skip this one.
+ TransportDescription tdesc;
+ bool ret = GetTransportDescription(
+ sdesc, iter->second->content_name(), &tdesc);
+ if (ret) {
+ if (!iter->second->SetLocalTransportDescription(tdesc, action,
+ error_desc)) {
+ return false;
+ }
+
+ iter->second->ConnectChannels();
+ }
+ }
+
+ return true;
+}
+
+bool BaseSession::PushdownRemoteTransportDescription(
+ const SessionDescription* sdesc,
+ ContentAction action,
+ std::string* error_desc) {
+ // Update the Transports with the right information.
+ for (TransportMap::iterator iter = transports_.begin();
+ iter != transports_.end(); ++iter) {
+ TransportDescription tdesc;
+
+ // If no transport info was in this session description, ret == false
+ // and we just skip this one.
+ bool ret = GetTransportDescription(
+ sdesc, iter->second->content_name(), &tdesc);
+ if (ret) {
+ if (!iter->second->SetRemoteTransportDescription(tdesc, action,
+ error_desc)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+TransportChannel* BaseSession::CreateChannel(const std::string& content_name,
+ const std::string& channel_name,
+ int component) {
+ // We create the proxy "on demand" here because we need to support
+ // creating channels at any time, even before we send or receive
+ // initiate messages, which is before we create the transports.
+ TransportProxy* transproxy = GetOrCreateTransportProxy(content_name);
+ return transproxy->CreateChannel(channel_name, component);
+}
+
+TransportChannel* BaseSession::GetChannel(const std::string& content_name,
+ int component) {
+ TransportProxy* transproxy = GetTransportProxy(content_name);
+ if (transproxy == NULL)
+ return NULL;
+
+ return transproxy->GetChannel(component);
+}
+
+void BaseSession::DestroyChannel(const std::string& content_name,
+ int component) {
+ TransportProxy* transproxy = GetTransportProxy(content_name);
+ ASSERT(transproxy != NULL);
+ transproxy->DestroyChannel(component);
+}
+
+TransportProxy* BaseSession::GetOrCreateTransportProxy(
+ const std::string& content_name) {
+ TransportProxy* transproxy = GetTransportProxy(content_name);
+ if (transproxy)
+ return transproxy;
+
+ Transport* transport = CreateTransport(content_name);
+ transport->SetIceRole(initiator_ ? ICEROLE_CONTROLLING : ICEROLE_CONTROLLED);
+ transport->SetIceTiebreaker(ice_tiebreaker_);
+ // TODO: Connect all the Transport signals to TransportProxy
+ // then to the BaseSession.
+ transport->SignalConnecting.connect(
+ this, &BaseSession::OnTransportConnecting);
+ transport->SignalWritableState.connect(
+ this, &BaseSession::OnTransportWritable);
+ transport->SignalRequestSignaling.connect(
+ this, &BaseSession::OnTransportRequestSignaling);
+ transport->SignalTransportError.connect(
+ this, &BaseSession::OnTransportSendError);
+ transport->SignalRouteChange.connect(
+ this, &BaseSession::OnTransportRouteChange);
+ transport->SignalCandidatesAllocationDone.connect(
+ this, &BaseSession::OnTransportCandidatesAllocationDone);
+ transport->SignalRoleConflict.connect(
+ this, &BaseSession::OnRoleConflict);
+ transport->SignalCompleted.connect(
+ this, &BaseSession::OnTransportCompleted);
+ transport->SignalFailed.connect(
+ this, &BaseSession::OnTransportFailed);
+
+ transproxy = new TransportProxy(worker_thread_, sid_, content_name,
+ new TransportWrapper(transport));
+ transproxy->SignalCandidatesReady.connect(
+ this, &BaseSession::OnTransportProxyCandidatesReady);
+ if (identity_)
+ transproxy->SetIdentity(identity_);
+ transports_[content_name] = transproxy;
+
+ return transproxy;
+}
+
+Transport* BaseSession::GetTransport(const std::string& content_name) {
+ TransportProxy* transproxy = GetTransportProxy(content_name);
+ if (transproxy == NULL)
+ return NULL;
+ return transproxy->impl();
+}
+
+TransportProxy* BaseSession::GetTransportProxy(
+ const std::string& content_name) {
+ TransportMap::iterator iter = transports_.find(content_name);
+ return (iter != transports_.end()) ? iter->second : NULL;
+}
+
+TransportProxy* BaseSession::GetTransportProxy(const Transport* transport) {
+ for (TransportMap::iterator iter = transports_.begin();
+ iter != transports_.end(); ++iter) {
+ TransportProxy* transproxy = iter->second;
+ if (transproxy->impl() == transport) {
+ return transproxy;
+ }
+ }
+ return NULL;
+}
+
+TransportProxy* BaseSession::GetFirstTransportProxy() {
+ if (transports_.empty())
+ return NULL;
+ return transports_.begin()->second;
+}
+
+void BaseSession::DestroyTransportProxy(
+ const std::string& content_name) {
+ TransportMap::iterator iter = transports_.find(content_name);
+ if (iter != transports_.end()) {
+ delete iter->second;
+ transports_.erase(content_name);
+ }
+}
+
+cricket::Transport* BaseSession::CreateTransport(
+ const std::string& content_name) {
+ ASSERT(transport_type_ == NS_GINGLE_P2P);
+ return new cricket::DtlsTransport<P2PTransport>(
+ signaling_thread(), worker_thread(), content_name,
+ port_allocator(), identity_);
+}
+
+bool BaseSession::GetStats(SessionStats* stats) {
+ for (TransportMap::iterator iter = transports_.begin();
+ iter != transports_.end(); ++iter) {
+ std::string proxy_id = iter->second->content_name();
+ // We are ignoring not-yet-instantiated transports.
+ if (iter->second->impl()) {
+ std::string transport_id = iter->second->impl()->content_name();
+ stats->proxy_to_transport[proxy_id] = transport_id;
+ if (stats->transport_stats.find(transport_id)
+ == stats->transport_stats.end()) {
+ TransportStats subinfos;
+ if (!iter->second->impl()->GetStats(&subinfos)) {
+ return false;
+ }
+ stats->transport_stats[transport_id] = subinfos;
+ }
+ }
+ }
+ return true;
+}
+
+void BaseSession::SetState(State state) {
+ ASSERT(signaling_thread_->IsCurrent());
+ if (state != state_) {
+ LogState(state_, state);
+ state_ = state;
+ SignalState(this, state_);
+ signaling_thread_->Post(this, MSG_STATE);
+ }
+ SignalNewDescription();
+}
+
+void BaseSession::SetError(Error error, const std::string& error_desc) {
+ ASSERT(signaling_thread_->IsCurrent());
+ if (error != error_) {
+ error_ = error;
+ error_desc_ = error_desc;
+ SignalError(this, error);
+ }
+}
+
+void BaseSession::OnSignalingReady() {
+ ASSERT(signaling_thread()->IsCurrent());
+ for (TransportMap::iterator iter = transports_.begin();
+ iter != transports_.end(); ++iter) {
+ iter->second->OnSignalingReady();
+ }
+}
+
+// TODO(juberti): Since PushdownLocalTD now triggers the connection process to
+// start, remove this method once everyone calls PushdownLocalTD.
+void BaseSession::SpeculativelyConnectAllTransportChannels() {
+ // Put all transports into the connecting state.
+ for (TransportMap::iterator iter = transports_.begin();
+ iter != transports_.end(); ++iter) {
+ iter->second->ConnectChannels();
+ }
+}
+
+bool BaseSession::OnRemoteCandidates(const std::string& content_name,
+ const Candidates& candidates,
+ std::string* error) {
+ // Give candidates to the appropriate transport, and tell that transport
+ // to start connecting, if it's not already doing so.
+ TransportProxy* transproxy = GetTransportProxy(content_name);
+ if (!transproxy) {
+ *error = "Unknown content name " + content_name;
+ return false;
+ }
+ if (!transproxy->OnRemoteCandidates(candidates, error)) {
+ return false;
+ }
+ // TODO(juberti): Remove this call once we can be sure that we always have
+ // a local transport description (which will trigger the connection).
+ transproxy->ConnectChannels();
+ return true;
+}
+
+bool BaseSession::MaybeEnableMuxingSupport() {
+ // We need both a local and remote description to decide if we should mux.
+ if ((state_ == STATE_SENTINITIATE ||
+ state_ == STATE_RECEIVEDINITIATE) &&
+ ((local_description_ == NULL) ||
+ (remote_description_ == NULL))) {
+ return false;
+ }
+
+ // In order to perform the multiplexing, we need all proxies to be in the
+ // negotiated state, i.e. to have implementations underneath.
+ // Ensure that this is the case, regardless of whether we are going to mux.
+ for (TransportMap::iterator iter = transports_.begin();
+ iter != transports_.end(); ++iter) {
+ ASSERT(iter->second->negotiated());
+ if (!iter->second->negotiated())
+ return false;
+ }
+
+ // If both sides agree to BUNDLE, mux all the specified contents onto the
+ // transport belonging to the first content name in the BUNDLE group.
+ // If the contents are already muxed, this will be a no-op.
+ // TODO(juberti): Should this check that local and remote have configured
+ // BUNDLE the same way?
+ bool candidates_allocated = IsCandidateAllocationDone();
+ const ContentGroup* local_bundle_group =
+ local_description()->GetGroupByName(GROUP_TYPE_BUNDLE);
+ const ContentGroup* remote_bundle_group =
+ remote_description()->GetGroupByName(GROUP_TYPE_BUNDLE);
+ if (local_bundle_group && remote_bundle_group &&
+ local_bundle_group->FirstContentName()) {
+ const std::string* content_name = local_bundle_group->FirstContentName();
+ const ContentInfo* content =
+ local_description_->GetContentByName(*content_name);
+ ASSERT(content != NULL);
+ if (!SetSelectedProxy(content->name, local_bundle_group)) {
+ LOG(LS_WARNING) << "Failed to set up BUNDLE";
+ return false;
+ }
+
+ // If we weren't done gathering before, we might be done now, as a result
+ // of enabling mux.
+ LOG(LS_INFO) << "Enabling BUNDLE, bundling onto transport: "
+ << *content_name;
+ if (!candidates_allocated) {
+ MaybeCandidateAllocationDone();
+ }
+ } else {
+ LOG(LS_INFO) << "No BUNDLE information, not bundling.";
+ }
+ return true;
+}
+
+bool BaseSession::SetSelectedProxy(const std::string& content_name,
+ const ContentGroup* muxed_group) {
+ TransportProxy* selected_proxy = GetTransportProxy(content_name);
+ if (!selected_proxy) {
+ return false;
+ }
+
+ ASSERT(selected_proxy->negotiated());
+ for (TransportMap::iterator iter = transports_.begin();
+ iter != transports_.end(); ++iter) {
+ // If content is part of the mux group, then repoint its proxy at the
+ // transport object that we have chosen to mux onto. If the proxy
+ // is already pointing at the right object, it will be a no-op.
+ if (muxed_group->HasContentName(iter->first) &&
+ !iter->second->SetupMux(selected_proxy)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void BaseSession::OnTransportCandidatesAllocationDone(Transport* transport) {
+ // TODO(juberti): This is a clunky way of processing the done signal. Instead,
+ // TransportProxy should receive the done signal directly, set its allocated
+ // flag internally, and then reissue the done signal to Session.
+ // Overall we should make TransportProxy receive *all* the signals from
+ // Transport, since this removes the need to manually iterate over all
+ // the transports, as is needed to make sure signals are handled properly
+ // when BUNDLEing.
+ // TODO(juberti): Per b/7998978, devs and QA are hitting this assert in ways
+ // that make it prohibitively difficult to run dbg builds. Disabled for now.
+ //ASSERT(!IsCandidateAllocationDone());
+ for (TransportMap::iterator iter = transports_.begin();
+ iter != transports_.end(); ++iter) {
+ if (iter->second->impl() == transport) {
+ iter->second->set_candidates_allocated(true);
+ }
+ }
+ MaybeCandidateAllocationDone();
+}
+
+bool BaseSession::IsCandidateAllocationDone() const {
+ for (TransportMap::const_iterator iter = transports_.begin();
+ iter != transports_.end(); ++iter) {
+ if (!iter->second->candidates_allocated())
+ return false;
+ }
+ return true;
+}
+
+void BaseSession::MaybeCandidateAllocationDone() {
+ if (IsCandidateAllocationDone()) {
+ LOG(LS_INFO) << "Candidate gathering is complete.";
+ OnCandidatesAllocationDone();
+ }
+}
+
+void BaseSession::OnRoleConflict() {
+ if (role_switch_) {
+ LOG(LS_WARNING) << "Repeat of role conflict signal from Transport.";
+ return;
+ }
+
+ role_switch_ = true;
+ for (TransportMap::iterator iter = transports_.begin();
+ iter != transports_.end(); ++iter) {
+ // Role will be reverse of initial role setting.
+ IceRole role = initiator_ ? ICEROLE_CONTROLLED : ICEROLE_CONTROLLING;
+ iter->second->SetIceRole(role);
+ }
+}
+
+void BaseSession::LogState(State old_state, State new_state) {
+ LOG(LS_INFO) << "Session:" << id()
+ << " Old state:" << StateToString(old_state)
+ << " New state:" << StateToString(new_state)
+ << " Type:" << content_type()
+ << " Transport:" << transport_type();
+}
+
+// static
+bool BaseSession::GetTransportDescription(const SessionDescription* description,
+ const std::string& content_name,
+ TransportDescription* tdesc) {
+ if (!description || !tdesc) {
+ return false;
+ }
+ const TransportInfo* transport_info =
+ description->GetTransportInfoByName(content_name);
+ if (!transport_info) {
+ return false;
+ }
+ *tdesc = transport_info->description;
+ return true;
+}
+
+void BaseSession::SignalNewDescription() {
+ ContentAction action;
+ ContentSource source;
+ if (!GetContentAction(&action, &source)) {
+ return;
+ }
+ if (source == CS_LOCAL) {
+ SignalNewLocalDescription(this, action);
+ } else {
+ SignalNewRemoteDescription(this, action);
+ }
+}
+
+bool BaseSession::GetContentAction(ContentAction* action,
+ ContentSource* source) {
+ switch (state_) {
+ // new local description
+ case STATE_SENTINITIATE:
+ *action = CA_OFFER;
+ *source = CS_LOCAL;
+ break;
+ case STATE_SENTPRACCEPT:
+ *action = CA_PRANSWER;
+ *source = CS_LOCAL;
+ break;
+ case STATE_SENTACCEPT:
+ *action = CA_ANSWER;
+ *source = CS_LOCAL;
+ break;
+ // new remote description
+ case STATE_RECEIVEDINITIATE:
+ *action = CA_OFFER;
+ *source = CS_REMOTE;
+ break;
+ case STATE_RECEIVEDPRACCEPT:
+ *action = CA_PRANSWER;
+ *source = CS_REMOTE;
+ break;
+ case STATE_RECEIVEDACCEPT:
+ *action = CA_ANSWER;
+ *source = CS_REMOTE;
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+void BaseSession::OnMessage(rtc::Message *pmsg) {
+ switch (pmsg->message_id) {
+ case MSG_TIMEOUT:
+ // Session timeout has occured.
+ SetError(ERROR_TIME, "Session timeout has occured.");
+ break;
+
+ case MSG_STATE:
+ switch (state_) {
+ case STATE_SENTACCEPT:
+ case STATE_RECEIVEDACCEPT:
+ SetState(STATE_INPROGRESS);
+ break;
+
+ default:
+ // Explicitly ignoring some states here.
+ break;
+ }
+ break;
+ }
+}
+
+Session::Session(SessionManager* session_manager,
+ const std::string& local_name,
+ const std::string& initiator_name,
+ const std::string& sid,
+ const std::string& content_type,
+ SessionClient* client)
+ : BaseSession(session_manager->signaling_thread(),
+ session_manager->worker_thread(),
+ session_manager->port_allocator(),
+ sid, content_type, initiator_name == local_name) {
+ ASSERT(client != NULL);
+ session_manager_ = session_manager;
+ local_name_ = local_name;
+ initiator_name_ = initiator_name;
+ transport_parser_ = new P2PTransportParser();
+ client_ = client;
+ initiate_acked_ = false;
+ current_protocol_ = PROTOCOL_HYBRID;
+}
+
+Session::~Session() {
+ delete transport_parser_;
+}
+
+bool Session::Initiate(const std::string& to,
+ const SessionDescription* sdesc) {
+ ASSERT(signaling_thread()->IsCurrent());
+ SessionError error;
+
+ // Only from STATE_INIT
+ if (state() != STATE_INIT)
+ return false;
+
+ // Setup for signaling.
+ set_remote_name(to);
+ set_local_description(sdesc);
+ if (!CreateTransportProxies(GetEmptyTransportInfos(sdesc->contents()),
+ &error)) {
+ LOG(LS_ERROR) << "Could not create transports: " << error.text;
+ return false;
+ }
+
+ if (!SendInitiateMessage(sdesc, &error)) {
+ LOG(LS_ERROR) << "Could not send initiate message: " << error.text;
+ return false;
+ }
+
+ // We need to connect transport proxy and impl here so that we can process
+ // the TransportDescriptions.
+ SpeculativelyConnectAllTransportChannels();
+
+ PushdownTransportDescription(CS_LOCAL, CA_OFFER, NULL);
+ SetState(Session::STATE_SENTINITIATE);
+ return true;
+}
+
+bool Session::Accept(const SessionDescription* sdesc) {
+ ASSERT(signaling_thread()->IsCurrent());
+
+ // Only if just received initiate
+ if (state() != STATE_RECEIVEDINITIATE)
+ return false;
+
+ // Setup for signaling.
+ set_local_description(sdesc);
+
+ SessionError error;
+ if (!SendAcceptMessage(sdesc, &error)) {
+ LOG(LS_ERROR) << "Could not send accept message: " << error.text;
+ return false;
+ }
+ // TODO(juberti): Add BUNDLE support to transport-info messages.
+ PushdownTransportDescription(CS_LOCAL, CA_ANSWER, NULL);
+ MaybeEnableMuxingSupport(); // Enable transport channel mux if supported.
+ SetState(Session::STATE_SENTACCEPT);
+ return true;
+}
+
+bool Session::Reject(const std::string& reason) {
+ ASSERT(signaling_thread()->IsCurrent());
+
+ // Reject is sent in response to an initiate or modify, to reject the
+ // request
+ if (state() != STATE_RECEIVEDINITIATE && state() != STATE_RECEIVEDMODIFY)
+ return false;
+
+ SessionError error;
+ if (!SendRejectMessage(reason, &error)) {
+ LOG(LS_ERROR) << "Could not send reject message: " << error.text;
+ return false;
+ }
+
+ SetState(STATE_SENTREJECT);
+ return true;
+}
+
+bool Session::TerminateWithReason(const std::string& reason) {
+ ASSERT(signaling_thread()->IsCurrent());
+
+ // Either side can terminate, at any time.
+ switch (state()) {
+ case STATE_SENTTERMINATE:
+ case STATE_RECEIVEDTERMINATE:
+ return false;
+
+ case STATE_SENTREJECT:
+ case STATE_RECEIVEDREJECT:
+ // We don't need to send terminate if we sent or received a reject...
+ // it's implicit.
+ break;
+
+ default:
+ SessionError error;
+ if (!SendTerminateMessage(reason, &error)) {
+ LOG(LS_ERROR) << "Could not send terminate message: " << error.text;
+ return false;
+ }
+ break;
+ }
+
+ SetState(STATE_SENTTERMINATE);
+ return true;
+}
+
+bool Session::SendInfoMessage(const XmlElements& elems,
+ const std::string& remote_name) {
+ ASSERT(signaling_thread()->IsCurrent());
+ SessionError error;
+ if (!SendMessage(ACTION_SESSION_INFO, elems, remote_name, &error)) {
+ LOG(LS_ERROR) << "Could not send info message " << error.text;
+ return false;
+ }
+ return true;
+}
+
+bool Session::SendDescriptionInfoMessage(const ContentInfos& contents) {
+ XmlElements elems;
+ WriteError write_error;
+ if (!WriteDescriptionInfo(current_protocol_,
+ contents,
+ GetContentParsers(),
+ &elems, &write_error)) {
+ LOG(LS_ERROR) << "Could not write description info message: "
+ << write_error.text;
+ return false;
+ }
+ SessionError error;
+ if (!SendMessage(ACTION_DESCRIPTION_INFO, elems, &error)) {
+ LOG(LS_ERROR) << "Could not send description info message: "
+ << error.text;
+ return false;
+ }
+ return true;
+}
+
+TransportInfos Session::GetEmptyTransportInfos(
+ const ContentInfos& contents) const {
+ TransportInfos tinfos;
+ for (ContentInfos::const_iterator content = contents.begin();
+ content != contents.end(); ++content) {
+ tinfos.push_back(TransportInfo(content->name,
+ TransportDescription(transport_type(),
+ std::string(),
+ std::string())));
+ }
+ return tinfos;
+}
+
+bool Session::OnRemoteCandidates(
+ const TransportInfos& tinfos, ParseError* error) {
+ for (TransportInfos::const_iterator tinfo = tinfos.begin();
+ tinfo != tinfos.end(); ++tinfo) {
+ std::string str_error;
+ if (!BaseSession::OnRemoteCandidates(
+ tinfo->content_name, tinfo->description.candidates, &str_error)) {
+ return BadParse(str_error, error);
+ }
+ }
+ return true;
+}
+
+bool Session::CreateTransportProxies(const TransportInfos& tinfos,
+ SessionError* error) {
+ for (TransportInfos::const_iterator tinfo = tinfos.begin();
+ tinfo != tinfos.end(); ++tinfo) {
+ if (tinfo->description.transport_type != transport_type()) {
+ error->SetText("No supported transport in offer.");
+ return false;
+ }
+
+ GetOrCreateTransportProxy(tinfo->content_name);
+ }
+ return true;
+}
+
+TransportParserMap Session::GetTransportParsers() {
+ TransportParserMap parsers;
+ parsers[transport_type()] = transport_parser_;
+ return parsers;
+}
+
+CandidateTranslatorMap Session::GetCandidateTranslators() {
+ CandidateTranslatorMap translators;
+ // NOTE: This technique makes it impossible to parse G-ICE
+ // candidates in session-initiate messages because the channels
+ // aren't yet created at that point. Since we don't use candidates
+ // in session-initiate messages, we should be OK. Once we switch to
+ // ICE, this translation shouldn't be necessary.
+ for (TransportMap::const_iterator iter = transport_proxies().begin();
+ iter != transport_proxies().end(); ++iter) {
+ translators[iter->first] = iter->second;
+ }
+ return translators;
+}
+
+ContentParserMap Session::GetContentParsers() {
+ ContentParserMap parsers;
+ parsers[content_type()] = client_;
+ // We need to be able parse both RTP-based and SCTP-based Jingle
+ // with the same client.
+ if (content_type() == NS_JINGLE_RTP) {
+ parsers[NS_JINGLE_DRAFT_SCTP] = client_;
+ }
+ return parsers;
+}
+
+void Session::OnTransportRequestSignaling(Transport* transport) {
+ ASSERT(signaling_thread()->IsCurrent());
+ TransportProxy* transproxy = GetTransportProxy(transport);
+ ASSERT(transproxy != NULL);
+ if (transproxy) {
+ // Reset candidate allocation status for the transport proxy.
+ transproxy->set_candidates_allocated(false);
+ }
+ SignalRequestSignaling(this);
+}
+
+void Session::OnTransportConnecting(Transport* transport) {
+ // This is an indication that we should begin watching the writability
+ // state of the transport.
+ OnTransportWritable(transport);
+}
+
+void Session::OnTransportWritable(Transport* transport) {
+ ASSERT(signaling_thread()->IsCurrent());
+
+ // If the transport is not writable, start a timer to make sure that it
+ // becomes writable within a reasonable amount of time. If it does not, we
+ // terminate since we can't actually send data. If the transport is writable,
+ // cancel the timer. Note that writability transitions may occur repeatedly
+ // during the lifetime of the session.
+ signaling_thread()->Clear(this, MSG_TIMEOUT);
+ if (transport->HasChannels() && !transport->writable()) {
+ signaling_thread()->PostDelayed(
+ session_manager_->session_timeout() * 1000, this, MSG_TIMEOUT);
+ }
+}
+
+void Session::OnTransportProxyCandidatesReady(TransportProxy* transproxy,
+ const Candidates& candidates) {
+ ASSERT(signaling_thread()->IsCurrent());
+ if (transproxy != NULL) {
+ if (initiator() && !initiate_acked_) {
+ // TODO: This is to work around server re-ordering
+ // messages. We send the candidates once the session-initiate
+ // is acked. Once we have fixed the server to guarantee message
+ // order, we can remove this case.
+ transproxy->AddUnsentCandidates(candidates);
+ } else {
+ if (!transproxy->negotiated()) {
+ transproxy->AddSentCandidates(candidates);
+ }
+ SessionError error;
+ if (!SendTransportInfoMessage(transproxy, candidates, &error)) {
+ LOG(LS_ERROR) << "Could not send transport info message: "
+ << error.text;
+ return;
+ }
+ }
+ }
+}
+
+void Session::OnTransportSendError(Transport* transport,
+ const buzz::XmlElement* stanza,
+ const buzz::QName& name,
+ const std::string& type,
+ const std::string& text,
+ const buzz::XmlElement* extra_info) {
+ ASSERT(signaling_thread()->IsCurrent());
+ SignalErrorMessage(this, stanza, name, type, text, extra_info);
+}
+
+void Session::OnIncomingMessage(const SessionMessage& msg) {
+ ASSERT(signaling_thread()->IsCurrent());
+ ASSERT(state() == STATE_INIT || msg.from == remote_name());
+
+ if (current_protocol_== PROTOCOL_HYBRID) {
+ if (msg.protocol == PROTOCOL_GINGLE) {
+ current_protocol_ = PROTOCOL_GINGLE;
+ } else {
+ current_protocol_ = PROTOCOL_JINGLE;
+ }
+ }
+
+ bool valid = false;
+ MessageError error;
+ switch (msg.type) {
+ case ACTION_SESSION_INITIATE:
+ valid = OnInitiateMessage(msg, &error);
+ break;
+ case ACTION_SESSION_INFO:
+ valid = OnInfoMessage(msg);
+ break;
+ case ACTION_SESSION_ACCEPT:
+ valid = OnAcceptMessage(msg, &error);
+ break;
+ case ACTION_SESSION_REJECT:
+ valid = OnRejectMessage(msg, &error);
+ break;
+ case ACTION_SESSION_TERMINATE:
+ valid = OnTerminateMessage(msg, &error);
+ break;
+ case ACTION_TRANSPORT_INFO:
+ valid = OnTransportInfoMessage(msg, &error);
+ break;
+ case ACTION_TRANSPORT_ACCEPT:
+ valid = OnTransportAcceptMessage(msg, &error);
+ break;
+ case ACTION_DESCRIPTION_INFO:
+ valid = OnDescriptionInfoMessage(msg, &error);
+ break;
+ default:
+ valid = BadMessage(buzz::QN_STANZA_BAD_REQUEST,
+ "unknown session message type",
+ &error);
+ }
+
+ if (valid) {
+ SendAcknowledgementMessage(msg.stanza);
+ } else {
+ SignalErrorMessage(this, msg.stanza, error.type,
+ "modify", error.text, NULL);
+ }
+}
+
+void Session::OnIncomingResponse(const buzz::XmlElement* orig_stanza,
+ const buzz::XmlElement* response_stanza,
+ const SessionMessage& msg) {
+ ASSERT(signaling_thread()->IsCurrent());
+
+ if (msg.type == ACTION_SESSION_INITIATE) {
+ OnInitiateAcked();
+ }
+}
+
+void Session::OnInitiateAcked() {
+ // TODO: This is to work around server re-ordering
+ // messages. We send the candidates once the session-initiate
+ // is acked. Once we have fixed the server to guarantee message
+ // order, we can remove this case.
+ if (!initiate_acked_) {
+ initiate_acked_ = true;
+ SessionError error;
+ SendAllUnsentTransportInfoMessages(&error);
+ }
+}
+
+void Session::OnFailedSend(const buzz::XmlElement* orig_stanza,
+ const buzz::XmlElement* error_stanza) {
+ ASSERT(signaling_thread()->IsCurrent());
+
+ SessionMessage msg;
+ ParseError parse_error;
+ if (!ParseSessionMessage(orig_stanza, &msg, &parse_error)) {
+ LOG(LS_ERROR) << "Error parsing failed send: " << parse_error.text
+ << ":" << orig_stanza;
+ return;
+ }
+
+ // If the error is a session redirect, call OnRedirectError, which will
+ // continue the session with a new remote JID.
+ SessionRedirect redirect;
+ if (FindSessionRedirect(error_stanza, &redirect)) {
+ SessionError error;
+ if (!OnRedirectError(redirect, &error)) {
+ // TODO: Should we send a message back? The standard
+ // says nothing about it.
+ std::ostringstream desc;
+ desc << "Failed to redirect: " << error.text;
+ LOG(LS_ERROR) << desc.str();
+ SetError(ERROR_RESPONSE, desc.str());
+ }
+ return;
+ }
+
+ std::string error_type = "cancel";
+
+ const buzz::XmlElement* error = error_stanza->FirstNamed(buzz::QN_ERROR);
+ if (error) {
+ error_type = error->Attr(buzz::QN_TYPE);
+
+ LOG(LS_ERROR) << "Session error:\n" << error->Str() << "\n"
+ << "in response to:\n" << orig_stanza->Str();
+ } else {
+ // don't crash if <error> is missing
+ LOG(LS_ERROR) << "Session error without <error/> element, ignoring";
+ return;
+ }
+
+ if (msg.type == ACTION_TRANSPORT_INFO) {
+ // Transport messages frequently generate errors because they are sent right
+ // when we detect a network failure. For that reason, we ignore such
+ // errors, because if we do not establish writability again, we will
+ // terminate anyway. The exceptions are transport-specific error tags,
+ // which we pass on to the respective transport.
+ } else if ((error_type != "continue") && (error_type != "wait")) {
+ // We do not set an error if the other side said it is okay to continue
+ // (possibly after waiting). These errors can be ignored.
+ SetError(ERROR_RESPONSE, "");
+ }
+}
+
+bool Session::OnInitiateMessage(const SessionMessage& msg,
+ MessageError* error) {
+ if (!CheckState(STATE_INIT, error))
+ return false;
+
+ SessionInitiate init;
+ if (!ParseSessionInitiate(msg.protocol, msg.action_elem,
+ GetContentParsers(), GetTransportParsers(),
+ GetCandidateTranslators(),
+ &init, error))
+ return false;
+
+ SessionError session_error;
+ if (!CreateTransportProxies(init.transports, &session_error)) {
+ return BadMessage(buzz::QN_STANZA_NOT_ACCEPTABLE,
+ session_error.text, error);
+ }
+
+ set_remote_name(msg.from);
+ set_initiator_name(msg.initiator);
+ set_remote_description(new SessionDescription(init.ClearContents(),
+ init.transports,
+ init.groups));
+ // Updating transport with TransportDescription.
+ PushdownTransportDescription(CS_REMOTE, CA_OFFER, NULL);
+ SetState(STATE_RECEIVEDINITIATE);
+
+ // Users of Session may listen to state change and call Reject().
+ if (state() != STATE_SENTREJECT) {
+ if (!OnRemoteCandidates(init.transports, error))
+ return false;
+
+ // TODO(juberti): Auto-generate and push down the local transport answer.
+ // This is necessary for trickling to work with RFC 5245 ICE.
+ }
+ return true;
+}
+
+bool Session::OnAcceptMessage(const SessionMessage& msg, MessageError* error) {
+ if (!CheckState(STATE_SENTINITIATE, error))
+ return false;
+
+ SessionAccept accept;
+ if (!ParseSessionAccept(msg.protocol, msg.action_elem,
+ GetContentParsers(), GetTransportParsers(),
+ GetCandidateTranslators(),
+ &accept, error)) {
+ return false;
+ }
+
+ // If we get an accept, we can assume the initiate has been
+ // received, even if we haven't gotten an IQ response.
+ OnInitiateAcked();
+
+ set_remote_description(new SessionDescription(accept.ClearContents(),
+ accept.transports,
+ accept.groups));
+ // Updating transport with TransportDescription.
+ PushdownTransportDescription(CS_REMOTE, CA_ANSWER, NULL);
+ MaybeEnableMuxingSupport(); // Enable transport channel mux if supported.
+ SetState(STATE_RECEIVEDACCEPT);
+
+ if (!OnRemoteCandidates(accept.transports, error))
+ return false;
+
+ return true;
+}
+
+bool Session::OnRejectMessage(const SessionMessage& msg, MessageError* error) {
+ if (!CheckState(STATE_SENTINITIATE, error))
+ return false;
+
+ SetState(STATE_RECEIVEDREJECT);
+ return true;
+}
+
+bool Session::OnInfoMessage(const SessionMessage& msg) {
+ SignalInfoMessage(this, msg.action_elem);
+ return true;
+}
+
+bool Session::OnTerminateMessage(const SessionMessage& msg,
+ MessageError* error) {
+ SessionTerminate term;
+ if (!ParseSessionTerminate(msg.protocol, msg.action_elem, &term, error))
+ return false;
+
+ SignalReceivedTerminateReason(this, term.reason);
+ if (term.debug_reason != buzz::STR_EMPTY) {
+ LOG(LS_VERBOSE) << "Received error on call: " << term.debug_reason;
+ }
+
+ SetState(STATE_RECEIVEDTERMINATE);
+ return true;
+}
+
+bool Session::OnTransportInfoMessage(const SessionMessage& msg,
+ MessageError* error) {
+ TransportInfos tinfos;
+ if (!ParseTransportInfos(msg.protocol, msg.action_elem,
+ initiator_description()->contents(),
+ GetTransportParsers(), GetCandidateTranslators(),
+ &tinfos, error))
+ return false;
+
+ if (!OnRemoteCandidates(tinfos, error))
+ return false;
+
+ return true;
+}
+
+bool Session::OnTransportAcceptMessage(const SessionMessage& msg,
+ MessageError* error) {
+ // TODO: Currently here only for compatibility with
+ // Gingle 1.1 clients (notably, Google Voice).
+ return true;
+}
+
+bool Session::OnDescriptionInfoMessage(const SessionMessage& msg,
+ MessageError* error) {
+ if (!CheckState(STATE_INPROGRESS, error))
+ return false;
+
+ DescriptionInfo description_info;
+ if (!ParseDescriptionInfo(msg.protocol, msg.action_elem,
+ GetContentParsers(), GetTransportParsers(),
+ GetCandidateTranslators(),
+ &description_info, error)) {
+ return false;
+ }
+
+ ContentInfos& updated_contents = description_info.contents;
+
+ // TODO: Currently, reflector sends back
+ // video stream updates even for an audio-only call, which causes
+ // this to fail. Put this back once reflector is fixed.
+ //
+ // ContentInfos::iterator it;
+ // First, ensure all updates are valid before modifying remote_description_.
+ // for (it = updated_contents.begin(); it != updated_contents.end(); ++it) {
+ // if (remote_description()->GetContentByName(it->name) == NULL) {
+ // return false;
+ // }
+ // }
+
+ // TODO: We used to replace contents from an update, but
+ // that no longer works with partial updates. We need to figure out
+ // a way to merge patial updates into contents. For now, users of
+ // Session should listen to SignalRemoteDescriptionUpdate and handle
+ // updates. They should not expect remote_description to be the
+ // latest value.
+ //
+ // for (it = updated_contents.begin(); it != updated_contents.end(); ++it) {
+ // remote_description()->RemoveContentByName(it->name);
+ // remote_description()->AddContent(it->name, it->type, it->description);
+ // }
+ // }
+
+ SignalRemoteDescriptionUpdate(this, updated_contents);
+ return true;
+}
+
+bool BareJidsEqual(const std::string& name1,
+ const std::string& name2) {
+ buzz::Jid jid1(name1);
+ buzz::Jid jid2(name2);
+
+ return jid1.IsValid() && jid2.IsValid() && jid1.BareEquals(jid2);
+}
+
+bool Session::OnRedirectError(const SessionRedirect& redirect,
+ SessionError* error) {
+ MessageError message_error;
+ if (!CheckState(STATE_SENTINITIATE, &message_error)) {
+ return BadWrite(message_error.text, error);
+ }
+
+ if (!BareJidsEqual(remote_name(), redirect.target))
+ return BadWrite("Redirection not allowed: must be the same bare jid.",
+ error);
+
+ // When we receive a redirect, we point the session at the new JID
+ // and resend the candidates.
+ set_remote_name(redirect.target);
+ return (SendInitiateMessage(local_description(), error) &&
+ ResendAllTransportInfoMessages(error));
+}
+
+bool Session::CheckState(State expected, MessageError* error) {
+ if (state() != expected) {
+ // The server can deliver messages out of order/repeated for various
+ // reasons. For example, if the server does not recive our iq response,
+ // it could assume that the iq it sent was lost, and will then send
+ // it again. Ideally, we should implement reliable messaging with
+ // duplicate elimination.
+ return BadMessage(buzz::QN_STANZA_NOT_ALLOWED,
+ "message not allowed in current state",
+ error);
+ }
+ return true;
+}
+
+void Session::SetError(Error error, const std::string& error_desc) {
+ BaseSession::SetError(error, error_desc);
+ if (error != ERROR_NONE)
+ signaling_thread()->Post(this, MSG_ERROR);
+}
+
+void Session::OnMessage(rtc::Message* pmsg) {
+ // preserve this because BaseSession::OnMessage may modify it
+ State orig_state = state();
+
+ BaseSession::OnMessage(pmsg);
+
+ switch (pmsg->message_id) {
+ case MSG_ERROR:
+ TerminateWithReason(STR_TERMINATE_ERROR);
+ break;
+
+ case MSG_STATE:
+ switch (orig_state) {
+ case STATE_SENTREJECT:
+ case STATE_RECEIVEDREJECT:
+ // Assume clean termination.
+ Terminate();
+ break;
+
+ case STATE_SENTTERMINATE:
+ case STATE_RECEIVEDTERMINATE:
+ session_manager_->DestroySession(this);
+ break;
+
+ default:
+ // Explicitly ignoring some states here.
+ break;
+ }
+ break;
+ }
+}
+
+bool Session::SendInitiateMessage(const SessionDescription* sdesc,
+ SessionError* error) {
+ SessionInitiate init;
+ init.contents = sdesc->contents();
+ init.transports = GetEmptyTransportInfos(init.contents);
+ init.groups = sdesc->groups();
+ return SendMessage(ACTION_SESSION_INITIATE, init, error);
+}
+
+bool Session::WriteSessionAction(
+ SignalingProtocol protocol, const SessionInitiate& init,
+ XmlElements* elems, WriteError* error) {
+ return WriteSessionInitiate(protocol, init.contents, init.transports,
+ GetContentParsers(), GetTransportParsers(),
+ GetCandidateTranslators(), init.groups,
+ elems, error);
+}
+
+bool Session::SendAcceptMessage(const SessionDescription* sdesc,
+ SessionError* error) {
+ XmlElements elems;
+ if (!WriteSessionAccept(current_protocol_,
+ sdesc->contents(),
+ GetEmptyTransportInfos(sdesc->contents()),
+ GetContentParsers(), GetTransportParsers(),
+ GetCandidateTranslators(), sdesc->groups(),
+ &elems, error)) {
+ return false;
+ }
+ return SendMessage(ACTION_SESSION_ACCEPT, elems, error);
+}
+
+bool Session::SendRejectMessage(const std::string& reason,
+ SessionError* error) {
+ SessionTerminate term(reason);
+ return SendMessage(ACTION_SESSION_REJECT, term, error);
+}
+
+bool Session::SendTerminateMessage(const std::string& reason,
+ SessionError* error) {
+ SessionTerminate term(reason);
+ return SendMessage(ACTION_SESSION_TERMINATE, term, error);
+}
+
+bool Session::WriteSessionAction(SignalingProtocol protocol,
+ const SessionTerminate& term,
+ XmlElements* elems, WriteError* error) {
+ WriteSessionTerminate(protocol, term, elems);
+ return true;
+}
+
+bool Session::SendTransportInfoMessage(const TransportInfo& tinfo,
+ SessionError* error) {
+ return SendMessage(ACTION_TRANSPORT_INFO, tinfo, error);
+}
+
+bool Session::SendTransportInfoMessage(const TransportProxy* transproxy,
+ const Candidates& candidates,
+ SessionError* error) {
+ return SendTransportInfoMessage(TransportInfo(transproxy->content_name(),
+ TransportDescription(transproxy->type(), std::vector<std::string>(),
+ std::string(), std::string(), ICEMODE_FULL,
+ CONNECTIONROLE_NONE, NULL, candidates)), error);
+}
+
+bool Session::WriteSessionAction(SignalingProtocol protocol,
+ const TransportInfo& tinfo,
+ XmlElements* elems, WriteError* error) {
+ TransportInfos tinfos;
+ tinfos.push_back(tinfo);
+ return WriteTransportInfos(protocol, tinfos,
+ GetTransportParsers(), GetCandidateTranslators(),
+ elems, error);
+}
+
+bool Session::ResendAllTransportInfoMessages(SessionError* error) {
+ for (TransportMap::const_iterator iter = transport_proxies().begin();
+ iter != transport_proxies().end(); ++iter) {
+ TransportProxy* transproxy = iter->second;
+ if (transproxy->sent_candidates().size() > 0) {
+ if (!SendTransportInfoMessage(
+ transproxy, transproxy->sent_candidates(), error)) {
+ LOG(LS_ERROR) << "Could not resend transport info messages: "
+ << error->text;
+ return false;
+ }
+ transproxy->ClearSentCandidates();
+ }
+ }
+ return true;
+}
+
+bool Session::SendAllUnsentTransportInfoMessages(SessionError* error) {
+ for (TransportMap::const_iterator iter = transport_proxies().begin();
+ iter != transport_proxies().end(); ++iter) {
+ TransportProxy* transproxy = iter->second;
+ if (transproxy->unsent_candidates().size() > 0) {
+ if (!SendTransportInfoMessage(
+ transproxy, transproxy->unsent_candidates(), error)) {
+ LOG(LS_ERROR) << "Could not send unsent transport info messages: "
+ << error->text;
+ return false;
+ }
+ transproxy->ClearUnsentCandidates();
+ }
+ }
+ return true;
+}
+
+bool Session::SendMessage(ActionType type, const XmlElements& action_elems,
+ SessionError* error) {
+ return SendMessage(type, action_elems, remote_name(), error);
+}
+
+bool Session::SendMessage(ActionType type, const XmlElements& action_elems,
+ const std::string& remote_name, SessionError* error) {
+ rtc::scoped_ptr<buzz::XmlElement> stanza(
+ new buzz::XmlElement(buzz::QN_IQ));
+
+ SessionMessage msg(current_protocol_, type, id(), initiator_name());
+ msg.to = remote_name;
+ WriteSessionMessage(msg, action_elems, stanza.get());
+
+ SignalOutgoingMessage(this, stanza.get());
+ return true;
+}
+
+template <typename Action>
+bool Session::SendMessage(ActionType type, const Action& action,
+ SessionError* error) {
+ rtc::scoped_ptr<buzz::XmlElement> stanza(
+ new buzz::XmlElement(buzz::QN_IQ));
+ if (!WriteActionMessage(type, action, stanza.get(), error))
+ return false;
+
+ SignalOutgoingMessage(this, stanza.get());
+ return true;
+}
+
+template <typename Action>
+bool Session::WriteActionMessage(ActionType type, const Action& action,
+ buzz::XmlElement* stanza,
+ WriteError* error) {
+ if (current_protocol_ == PROTOCOL_HYBRID) {
+ if (!WriteActionMessage(PROTOCOL_JINGLE, type, action, stanza, error))
+ return false;
+ if (!WriteActionMessage(PROTOCOL_GINGLE, type, action, stanza, error))
+ return false;
+ } else {
+ if (!WriteActionMessage(current_protocol_, type, action, stanza, error))
+ return false;
+ }
+ return true;
+}
+
+template <typename Action>
+bool Session::WriteActionMessage(SignalingProtocol protocol,
+ ActionType type, const Action& action,
+ buzz::XmlElement* stanza, WriteError* error) {
+ XmlElements action_elems;
+ if (!WriteSessionAction(protocol, action, &action_elems, error))
+ return false;
+
+ SessionMessage msg(protocol, type, id(), initiator_name());
+ msg.to = remote_name();
+
+ WriteSessionMessage(msg, action_elems, stanza);
+ return true;
+}
+
+void Session::SendAcknowledgementMessage(const buzz::XmlElement* stanza) {
+ rtc::scoped_ptr<buzz::XmlElement> ack(
+ new buzz::XmlElement(buzz::QN_IQ));
+ ack->SetAttr(buzz::QN_TO, remote_name());
+ ack->SetAttr(buzz::QN_ID, stanza->Attr(buzz::QN_ID));
+ ack->SetAttr(buzz::QN_TYPE, "result");
+
+ SignalOutgoingMessage(this, ack.get());
+}
+
+} // namespace cricket
diff --git a/p2p/base/session.h b/p2p/base/session.h
new file mode 100644
index 00000000..f5eaf413
--- /dev/null
+++ b/p2p/base/session.h
@@ -0,0 +1,730 @@
+/*
+ * 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 WEBRTC_P2P_BASE_SESSION_H_
+#define WEBRTC_P2P_BASE_SESSION_H_
+
+#include <list>
+#include <map>
+#include <string>
+#include <vector>
+
+#include "webrtc/p2p/base/parsing.h"
+#include "webrtc/p2p/base/port.h"
+#include "webrtc/p2p/base/sessionclient.h"
+#include "webrtc/p2p/base/sessionmanager.h"
+#include "webrtc/p2p/base/sessionmessages.h"
+#include "webrtc/p2p/base/transport.h"
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/base/refcount.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/scoped_ref_ptr.h"
+#include "webrtc/base/socketaddress.h"
+
+namespace cricket {
+
+class BaseSession;
+class P2PTransportChannel;
+class Transport;
+class TransportChannel;
+class TransportChannelProxy;
+class TransportChannelImpl;
+
+typedef rtc::RefCountedObject<rtc::scoped_ptr<Transport> >
+TransportWrapper;
+
+// Used for errors that will send back a specific error message to the
+// remote peer. We add "type" to the errors because it's needed for
+// SignalErrorMessage.
+struct MessageError : ParseError {
+ buzz::QName type;
+
+ // if unset, assume type is a parse error
+ MessageError() : ParseError(), type(buzz::QN_STANZA_BAD_REQUEST) {}
+
+ void SetType(const buzz::QName type) {
+ this->type = type;
+ }
+};
+
+// Used for errors that may be returned by public session methods that
+// can fail.
+// TODO: Use this error in Session::Initiate and
+// Session::Accept.
+struct SessionError : WriteError {
+};
+
+// Bundles a Transport and ChannelMap together. ChannelMap is used to
+// create transport channels before receiving or sending a session
+// initiate, and for speculatively connecting channels. Previously, a
+// session had one ChannelMap and transport. Now, with multiple
+// transports per session, we need multiple ChannelMaps as well.
+
+typedef std::map<int, TransportChannelProxy*> ChannelMap;
+
+class TransportProxy : public sigslot::has_slots<>,
+ public CandidateTranslator {
+ public:
+ TransportProxy(
+ rtc::Thread* worker_thread,
+ const std::string& sid,
+ const std::string& content_name,
+ TransportWrapper* transport)
+ : worker_thread_(worker_thread),
+ sid_(sid),
+ content_name_(content_name),
+ transport_(transport),
+ connecting_(false),
+ negotiated_(false),
+ sent_candidates_(false),
+ candidates_allocated_(false),
+ local_description_set_(false),
+ remote_description_set_(false) {
+ transport_->get()->SignalCandidatesReady.connect(
+ this, &TransportProxy::OnTransportCandidatesReady);
+ }
+ ~TransportProxy();
+
+ const std::string& content_name() const { return content_name_; }
+ // TODO(juberti): It's not good form to expose the object you're wrapping,
+ // since callers can mutate it. Can we make this return a const Transport*?
+ Transport* impl() const { return transport_->get(); }
+
+ const std::string& type() const;
+ bool negotiated() const { return negotiated_; }
+ const Candidates& sent_candidates() const { return sent_candidates_; }
+ const Candidates& unsent_candidates() const { return unsent_candidates_; }
+ bool candidates_allocated() const { return candidates_allocated_; }
+ void set_candidates_allocated(bool allocated) {
+ candidates_allocated_ = allocated;
+ }
+
+ TransportChannel* GetChannel(int component);
+ TransportChannel* CreateChannel(const std::string& channel_name,
+ int component);
+ bool HasChannel(int component);
+ void DestroyChannel(int component);
+
+ void AddSentCandidates(const Candidates& candidates);
+ void AddUnsentCandidates(const Candidates& candidates);
+ void ClearSentCandidates() { sent_candidates_.clear(); }
+ void ClearUnsentCandidates() { unsent_candidates_.clear(); }
+
+ // Start the connection process for any channels, creating impls if needed.
+ void ConnectChannels();
+ // Hook up impls to the proxy channels. Doesn't change connect state.
+ void CompleteNegotiation();
+
+ // Mux this proxy onto the specified proxy's transport.
+ bool SetupMux(TransportProxy* proxy);
+
+ // Simple functions that thunk down to the same functions on Transport.
+ void SetIceRole(IceRole role);
+ void SetIdentity(rtc::SSLIdentity* identity);
+ bool SetLocalTransportDescription(const TransportDescription& description,
+ ContentAction action,
+ std::string* error_desc);
+ bool SetRemoteTransportDescription(const TransportDescription& description,
+ ContentAction action,
+ std::string* error_desc);
+ void OnSignalingReady();
+ bool OnRemoteCandidates(const Candidates& candidates, std::string* error);
+
+ // CandidateTranslator methods.
+ virtual bool GetChannelNameFromComponent(
+ int component, std::string* channel_name) const;
+ virtual bool GetComponentFromChannelName(
+ const std::string& channel_name, int* component) const;
+
+ // Called when a transport signals that it has new candidates.
+ void OnTransportCandidatesReady(cricket::Transport* transport,
+ const Candidates& candidates) {
+ SignalCandidatesReady(this, candidates);
+ }
+
+ bool local_description_set() const {
+ return local_description_set_;
+ }
+ bool remote_description_set() const {
+ return remote_description_set_;
+ }
+
+ // Handles sending of ready candidates and receiving of remote candidates.
+ sigslot::signal2<TransportProxy*,
+ const std::vector<Candidate>&> SignalCandidatesReady;
+
+ private:
+ TransportChannelProxy* GetChannelProxy(int component) const;
+ TransportChannelProxy* GetChannelProxyByName(const std::string& name) const;
+
+ TransportChannelImpl* GetOrCreateChannelProxyImpl(int component);
+ TransportChannelImpl* GetOrCreateChannelProxyImpl_w(int component);
+
+ // Manipulators of transportchannelimpl in channel proxy.
+ void SetupChannelProxy(int component,
+ TransportChannelProxy* proxy);
+ void SetupChannelProxy_w(int component,
+ TransportChannelProxy* proxy);
+ void ReplaceChannelProxyImpl(TransportChannelProxy* proxy,
+ TransportChannelImpl* impl);
+ void ReplaceChannelProxyImpl_w(TransportChannelProxy* proxy,
+ TransportChannelImpl* impl);
+
+ rtc::Thread* const worker_thread_;
+ const std::string sid_;
+ const std::string content_name_;
+ rtc::scoped_refptr<TransportWrapper> transport_;
+ bool connecting_;
+ bool negotiated_;
+ ChannelMap channels_;
+ Candidates sent_candidates_;
+ Candidates unsent_candidates_;
+ bool candidates_allocated_;
+ bool local_description_set_;
+ bool remote_description_set_;
+};
+
+typedef std::map<std::string, TransportProxy*> TransportMap;
+
+// Statistics for all the transports of this session.
+typedef std::map<std::string, TransportStats> TransportStatsMap;
+typedef std::map<std::string, std::string> ProxyTransportMap;
+
+struct SessionStats {
+ ProxyTransportMap proxy_to_transport;
+ TransportStatsMap transport_stats;
+};
+
+// A BaseSession manages general session state. This includes negotiation
+// of both the application-level and network-level protocols: the former
+// defines what will be sent and the latter defines how it will be sent. Each
+// network-level protocol is represented by a Transport object. Each Transport
+// participates in the network-level negotiation. The individual streams of
+// packets are represented by TransportChannels. The application-level protocol
+// is represented by SessionDecription objects.
+class BaseSession : public sigslot::has_slots<>,
+ public rtc::MessageHandler {
+ public:
+ enum {
+ MSG_TIMEOUT = 0,
+ MSG_ERROR,
+ MSG_STATE,
+ };
+
+ enum State {
+ STATE_INIT = 0,
+ STATE_SENTINITIATE, // sent initiate, waiting for Accept or Reject
+ STATE_RECEIVEDINITIATE, // received an initiate. Call Accept or Reject
+ STATE_SENTPRACCEPT, // sent provisional Accept
+ STATE_SENTACCEPT, // sent accept. begin connecting transport
+ STATE_RECEIVEDPRACCEPT, // received provisional Accept, waiting for Accept
+ STATE_RECEIVEDACCEPT, // received accept. begin connecting transport
+ STATE_SENTMODIFY, // sent modify, waiting for Accept or Reject
+ STATE_RECEIVEDMODIFY, // received modify, call Accept or Reject
+ STATE_SENTREJECT, // sent reject after receiving initiate
+ STATE_RECEIVEDREJECT, // received reject after sending initiate
+ STATE_SENTREDIRECT, // sent direct after receiving initiate
+ STATE_SENTTERMINATE, // sent terminate (any time / either side)
+ STATE_RECEIVEDTERMINATE, // received terminate (any time / either side)
+ STATE_INPROGRESS, // session accepted and in progress
+ STATE_DEINIT, // session is being destroyed
+ };
+
+ enum Error {
+ ERROR_NONE = 0, // no error
+ ERROR_TIME = 1, // no response to signaling
+ ERROR_RESPONSE = 2, // error during signaling
+ ERROR_NETWORK = 3, // network error, could not allocate network resources
+ ERROR_CONTENT = 4, // channel errors in SetLocalContent/SetRemoteContent
+ ERROR_TRANSPORT = 5, // transport error of some kind
+ };
+
+ // Convert State to a readable string.
+ static std::string StateToString(State state);
+
+ BaseSession(rtc::Thread* signaling_thread,
+ rtc::Thread* worker_thread,
+ PortAllocator* port_allocator,
+ const std::string& sid,
+ const std::string& content_type,
+ bool initiator);
+ virtual ~BaseSession();
+
+ // These are const to allow them to be called from const methods.
+ rtc::Thread* signaling_thread() const { return signaling_thread_; }
+ rtc::Thread* worker_thread() const { return worker_thread_; }
+ PortAllocator* port_allocator() const { return port_allocator_; }
+
+ // The ID of this session.
+ const std::string& id() const { return sid_; }
+
+ // TODO(juberti): This data is largely redundant, as it can now be obtained
+ // from local/remote_description(). Remove these functions and members.
+ // Returns the XML namespace identifying the type of this session.
+ const std::string& content_type() const { return content_type_; }
+ // Returns the XML namespace identifying the transport used for this session.
+ const std::string& transport_type() const { return transport_type_; }
+
+ // Indicates whether we initiated this session.
+ bool initiator() const { return initiator_; }
+
+ // Returns the application-level description given by our client.
+ // If we are the recipient, this will be NULL until we send an accept.
+ const SessionDescription* local_description() const;
+
+ // Returns the application-level description given by the other client.
+ // If we are the initiator, this will be NULL until we receive an accept.
+ const SessionDescription* remote_description() const;
+
+ SessionDescription* remote_description();
+
+ // Takes ownership of SessionDescription*
+ void set_local_description(const SessionDescription* sdesc);
+
+ // Takes ownership of SessionDescription*
+ void set_remote_description(SessionDescription* sdesc);
+
+ const SessionDescription* initiator_description() const;
+
+ // Returns the current state of the session. See the enum above for details.
+ // Each time the state changes, we will fire this signal.
+ State state() const { return state_; }
+ sigslot::signal2<BaseSession* , State> SignalState;
+
+ // Returns the last error in the session. See the enum above for details.
+ // Each time the an error occurs, we will fire this signal.
+ Error error() const { return error_; }
+ const std::string& error_desc() const { return error_desc_; }
+ sigslot::signal2<BaseSession* , Error> SignalError;
+
+ // Updates the state, signaling if necessary.
+ virtual void SetState(State state);
+
+ // Updates the error state, signaling if necessary.
+ // TODO(ronghuawu): remove the SetError method that doesn't take |error_desc|.
+ virtual void SetError(Error error, const std::string& error_desc);
+
+ // Fired when the remote description is updated, with the updated
+ // contents.
+ sigslot::signal2<BaseSession* , const ContentInfos&>
+ SignalRemoteDescriptionUpdate;
+
+ // Fired when SetState is called (regardless if there's a state change), which
+ // indicates the session description might have be updated.
+ sigslot::signal2<BaseSession*, ContentAction> SignalNewLocalDescription;
+
+ // Fired when SetState is called (regardless if there's a state change), which
+ // indicates the session description might have be updated.
+ sigslot::signal2<BaseSession*, ContentAction> SignalNewRemoteDescription;
+
+ // Returns the transport that has been negotiated or NULL if
+ // negotiation is still in progress.
+ virtual Transport* GetTransport(const std::string& content_name);
+
+ // Creates a new channel with the given names. This method may be called
+ // immediately after creating the session. However, the actual
+ // implementation may not be fixed until transport negotiation completes.
+ // This will usually be called from the worker thread, but that
+ // shouldn't be an issue since the main thread will be blocked in
+ // Send when doing so.
+ virtual TransportChannel* CreateChannel(const std::string& content_name,
+ const std::string& channel_name,
+ int component);
+
+ // Returns the channel with the given names.
+ virtual TransportChannel* GetChannel(const std::string& content_name,
+ int component);
+
+ // Destroys the channel with the given names.
+ // This will usually be called from the worker thread, but that
+ // shouldn't be an issue since the main thread will be blocked in
+ // Send when doing so.
+ virtual void DestroyChannel(const std::string& content_name,
+ int component);
+
+ // Returns stats for all channels of all transports.
+ // This avoids exposing the internal structures used to track them.
+ virtual bool GetStats(SessionStats* stats);
+
+ rtc::SSLIdentity* identity() { return identity_; }
+
+ protected:
+ // Specifies the identity to use in this session.
+ bool SetIdentity(rtc::SSLIdentity* identity);
+
+ bool PushdownTransportDescription(ContentSource source,
+ ContentAction action,
+ std::string* error_desc);
+ void set_initiator(bool initiator) { initiator_ = initiator; }
+
+ const TransportMap& transport_proxies() const { return transports_; }
+ // Get a TransportProxy by content_name or transport. NULL if not found.
+ TransportProxy* GetTransportProxy(const std::string& content_name);
+ TransportProxy* GetTransportProxy(const Transport* transport);
+ TransportProxy* GetFirstTransportProxy();
+ void DestroyTransportProxy(const std::string& content_name);
+ // TransportProxy is owned by session. Return proxy just for convenience.
+ TransportProxy* GetOrCreateTransportProxy(const std::string& content_name);
+ // Creates the actual transport object. Overridable for testing.
+ virtual Transport* CreateTransport(const std::string& content_name);
+
+ void OnSignalingReady();
+ void SpeculativelyConnectAllTransportChannels();
+ // Helper method to provide remote candidates to the transport.
+ bool OnRemoteCandidates(const std::string& content_name,
+ const Candidates& candidates,
+ std::string* error);
+
+ // This method will mux transport channels by content_name.
+ // First content is used for muxing.
+ bool MaybeEnableMuxingSupport();
+
+ // Called when a transport requests signaling.
+ virtual void OnTransportRequestSignaling(Transport* transport) {
+ }
+
+ // Called when the first channel of a transport begins connecting. We use
+ // this to start a timer, to make sure that the connection completes in a
+ // reasonable amount of time.
+ virtual void OnTransportConnecting(Transport* transport) {
+ }
+
+ // Called when a transport changes its writable state. We track this to make
+ // sure that the transport becomes writable within a reasonable amount of
+ // time. If this does not occur, we signal an error.
+ virtual void OnTransportWritable(Transport* transport) {
+ }
+ virtual void OnTransportReadable(Transport* transport) {
+ }
+
+ // Called when a transport has found its steady-state connections.
+ virtual void OnTransportCompleted(Transport* transport) {
+ }
+
+ // Called when a transport has failed permanently.
+ virtual void OnTransportFailed(Transport* transport) {
+ }
+
+ // Called when a transport signals that it has new candidates.
+ virtual void OnTransportProxyCandidatesReady(TransportProxy* proxy,
+ const Candidates& candidates) {
+ }
+
+ // Called when a transport signals that it found an error in an incoming
+ // message.
+ virtual void OnTransportSendError(Transport* transport,
+ const buzz::XmlElement* stanza,
+ const buzz::QName& name,
+ const std::string& type,
+ const std::string& text,
+ const buzz::XmlElement* extra_info) {
+ }
+
+ virtual void OnTransportRouteChange(
+ Transport* transport,
+ int component,
+ const cricket::Candidate& remote_candidate) {
+ }
+
+ virtual void OnTransportCandidatesAllocationDone(Transport* transport);
+
+ // Called when all transport channels allocated required candidates.
+ // This method should be used as an indication of candidates gathering process
+ // is completed and application can now send local candidates list to remote.
+ virtual void OnCandidatesAllocationDone() {
+ }
+
+ // Handles the ice role change callback from Transport. This must be
+ // propagated to all the transports.
+ virtual void OnRoleConflict();
+
+ // Handles messages posted to us.
+ virtual void OnMessage(rtc::Message *pmsg);
+
+ protected:
+ State state_;
+ Error error_;
+ std::string error_desc_;
+
+ private:
+ // Helper methods to push local and remote transport descriptions.
+ bool PushdownLocalTransportDescription(
+ const SessionDescription* sdesc, ContentAction action,
+ std::string* error_desc);
+ bool PushdownRemoteTransportDescription(
+ const SessionDescription* sdesc, ContentAction action,
+ std::string* error_desc);
+
+ bool IsCandidateAllocationDone() const;
+ void MaybeCandidateAllocationDone();
+
+ // This method will delete the Transport and TransportChannelImpls and
+ // replace those with the selected Transport objects. Selection is done
+ // based on the content_name and in this case first MediaContent information
+ // is used for mux.
+ bool SetSelectedProxy(const std::string& content_name,
+ const ContentGroup* muxed_group);
+ // Log session state.
+ void LogState(State old_state, State new_state);
+
+ // Returns true and the TransportInfo of the given |content_name|
+ // from |description|. Returns false if it's not available.
+ static bool GetTransportDescription(const SessionDescription* description,
+ const std::string& content_name,
+ TransportDescription* info);
+
+ // Fires the new description signal according to the current state.
+ void SignalNewDescription();
+
+ // Gets the ContentAction and ContentSource according to the session state.
+ bool GetContentAction(ContentAction* action, ContentSource* source);
+
+ rtc::Thread* const signaling_thread_;
+ rtc::Thread* const worker_thread_;
+ PortAllocator* const port_allocator_;
+ const std::string sid_;
+ const std::string content_type_;
+ const std::string transport_type_;
+ bool initiator_;
+ rtc::SSLIdentity* identity_;
+ rtc::scoped_ptr<const SessionDescription> local_description_;
+ rtc::scoped_ptr<SessionDescription> remote_description_;
+ uint64 ice_tiebreaker_;
+ // This flag will be set to true after the first role switch. This flag
+ // will enable us to stop any role switch during the call.
+ bool role_switch_;
+ TransportMap transports_;
+};
+
+// A specific Session created by the SessionManager, using XMPP for protocol.
+class Session : public BaseSession {
+ public:
+ // Returns the manager that created and owns this session.
+ SessionManager* session_manager() const { return session_manager_; }
+
+ // Returns the client that is handling the application data of this session.
+ SessionClient* client() const { return client_; }
+
+ // Returns the JID of this client.
+ const std::string& local_name() const { return local_name_; }
+
+ // Returns the JID of the other peer in this session.
+ const std::string& remote_name() const { return remote_name_; }
+
+ // Set the JID of the other peer in this session.
+ // Typically the remote_name_ is set when the session is initiated.
+ // However, sometimes (e.g when a proxy is used) the peer name is
+ // known after the BaseSession has been initiated and it must be updated
+ // explicitly.
+ void set_remote_name(const std::string& name) { remote_name_ = name; }
+
+ // Set the JID of the initiator of this session. Allows for the overriding
+ // of the initiator to be a third-party, eg. the MUC JID when creating p2p
+ // sessions.
+ void set_initiator_name(const std::string& name) { initiator_name_ = name; }
+
+ // Indicates the JID of the entity who initiated this session.
+ // In special cases, may be different than both local_name and remote_name.
+ const std::string& initiator_name() const { return initiator_name_; }
+
+ SignalingProtocol current_protocol() const { return current_protocol_; }
+
+ void set_current_protocol(SignalingProtocol protocol) {
+ current_protocol_ = protocol;
+ }
+
+ // Updates the error state, signaling if necessary.
+ virtual void SetError(Error error, const std::string& error_desc);
+
+ // When the session needs to send signaling messages, it beings by requesting
+ // signaling. The client should handle this by calling OnSignalingReady once
+ // it is ready to send the messages.
+ // (These are called only by SessionManager.)
+ sigslot::signal1<Session*> SignalRequestSignaling;
+ void OnSignalingReady() { BaseSession::OnSignalingReady(); }
+
+ // Takes ownership of session description.
+ // TODO: Add an error argument to pass back to the caller.
+ bool Initiate(const std::string& to,
+ const SessionDescription* sdesc);
+
+ // When we receive an initiate, we create a session in the
+ // RECEIVEDINITIATE state and respond by accepting or rejecting.
+ // Takes ownership of session description.
+ // TODO: Add an error argument to pass back to the caller.
+ bool Accept(const SessionDescription* sdesc);
+ bool Reject(const std::string& reason);
+ bool Terminate() {
+ return TerminateWithReason(STR_TERMINATE_SUCCESS);
+ }
+ bool TerminateWithReason(const std::string& reason);
+ // Fired whenever we receive a terminate message along with a reason
+ sigslot::signal2<Session*, const std::string&> SignalReceivedTerminateReason;
+
+ // The two clients in the session may also send one another
+ // arbitrary XML messages, which are called "info" messages. Sending
+ // takes ownership of the given elements. The signal does not; the
+ // parent element will be deleted after the signal.
+ bool SendInfoMessage(const XmlElements& elems,
+ const std::string& remote_name);
+ bool SendDescriptionInfoMessage(const ContentInfos& contents);
+ sigslot::signal2<Session*, const buzz::XmlElement*> SignalInfoMessage;
+
+ private:
+ // Creates or destroys a session. (These are called only SessionManager.)
+ Session(SessionManager *session_manager,
+ const std::string& local_name, const std::string& initiator_name,
+ const std::string& sid, const std::string& content_type,
+ SessionClient* client);
+ ~Session();
+ // For each transport info, create a transport proxy. Can fail for
+ // incompatible transport types.
+ bool CreateTransportProxies(const TransportInfos& tinfos,
+ SessionError* error);
+ bool OnRemoteCandidates(const TransportInfos& tinfos,
+ ParseError* error);
+ // Returns a TransportInfo without candidates for each content name.
+ // Uses the transport_type_ of the session.
+ TransportInfos GetEmptyTransportInfos(const ContentInfos& contents) const;
+
+ // Maps passed to serialization functions.
+ TransportParserMap GetTransportParsers();
+ ContentParserMap GetContentParsers();
+ CandidateTranslatorMap GetCandidateTranslators();
+
+ virtual void OnTransportRequestSignaling(Transport* transport);
+ virtual void OnTransportConnecting(Transport* transport);
+ virtual void OnTransportWritable(Transport* transport);
+ virtual void OnTransportProxyCandidatesReady(TransportProxy* proxy,
+ const Candidates& candidates);
+ virtual void OnTransportSendError(Transport* transport,
+ const buzz::XmlElement* stanza,
+ const buzz::QName& name,
+ const std::string& type,
+ const std::string& text,
+ const buzz::XmlElement* extra_info);
+ virtual void OnMessage(rtc::Message *pmsg);
+
+ // Send various kinds of session messages.
+ bool SendInitiateMessage(const SessionDescription* sdesc,
+ SessionError* error);
+ bool SendAcceptMessage(const SessionDescription* sdesc, SessionError* error);
+ bool SendRejectMessage(const std::string& reason, SessionError* error);
+ bool SendTerminateMessage(const std::string& reason, SessionError* error);
+ bool SendTransportInfoMessage(const TransportInfo& tinfo,
+ SessionError* error);
+ bool SendTransportInfoMessage(const TransportProxy* transproxy,
+ const Candidates& candidates,
+ SessionError* error);
+
+ bool ResendAllTransportInfoMessages(SessionError* error);
+ bool SendAllUnsentTransportInfoMessages(SessionError* error);
+
+ // All versions of SendMessage send a message of the given type to
+ // the other client. Can pass either a set of elements or an
+ // "action", which must have a WriteSessionAction method to go along
+ // with it. Sending with an action supports sending a "hybrid"
+ // message. Sending with elements must be sent as Jingle or Gingle.
+
+ // When passing elems, must be either Jingle or Gingle protocol.
+ // Takes ownership of action_elems.
+ bool SendMessage(ActionType type, const XmlElements& action_elems,
+ SessionError* error);
+ // Sends a messge, but overrides the remote name.
+ bool SendMessage(ActionType type, const XmlElements& action_elems,
+ const std::string& remote_name,
+ SessionError* error);
+ // When passing an action, may be Hybrid protocol.
+ template <typename Action>
+ bool SendMessage(ActionType type, const Action& action,
+ SessionError* error);
+
+ // Helper methods to write the session message stanza.
+ template <typename Action>
+ bool WriteActionMessage(ActionType type, const Action& action,
+ buzz::XmlElement* stanza, WriteError* error);
+ template <typename Action>
+ bool WriteActionMessage(SignalingProtocol protocol,
+ ActionType type, const Action& action,
+ buzz::XmlElement* stanza, WriteError* error);
+
+ // Sending messages in hybrid form requires being able to write them
+ // on a per-protocol basis with a common method signature, which all
+ // of these have.
+ bool WriteSessionAction(SignalingProtocol protocol,
+ const SessionInitiate& init,
+ XmlElements* elems, WriteError* error);
+ bool WriteSessionAction(SignalingProtocol protocol,
+ const TransportInfo& tinfo,
+ XmlElements* elems, WriteError* error);
+ bool WriteSessionAction(SignalingProtocol protocol,
+ const SessionTerminate& term,
+ XmlElements* elems, WriteError* error);
+
+ // Sends a message back to the other client indicating that we have received
+ // and accepted their message.
+ void SendAcknowledgementMessage(const buzz::XmlElement* stanza);
+
+ // Once signaling is ready, the session will use this signal to request the
+ // sending of each message. When messages are received by the other client,
+ // they should be handed to OnIncomingMessage.
+ // (These are called only by SessionManager.)
+ sigslot::signal2<Session* , const buzz::XmlElement*> SignalOutgoingMessage;
+ void OnIncomingMessage(const SessionMessage& msg);
+
+ void OnIncomingResponse(const buzz::XmlElement* orig_stanza,
+ const buzz::XmlElement* response_stanza,
+ const SessionMessage& msg);
+ void OnInitiateAcked();
+ void OnFailedSend(const buzz::XmlElement* orig_stanza,
+ const buzz::XmlElement* error_stanza);
+
+ // Invoked when an error is found in an incoming message. This is translated
+ // into the appropriate XMPP response by SessionManager.
+ sigslot::signal6<BaseSession*,
+ const buzz::XmlElement*,
+ const buzz::QName&,
+ const std::string&,
+ const std::string&,
+ const buzz::XmlElement*> SignalErrorMessage;
+
+ // Handlers for the various types of messages. These functions may take
+ // pointers to the whole stanza or to just the session element.
+ bool OnInitiateMessage(const SessionMessage& msg, MessageError* error);
+ bool OnAcceptMessage(const SessionMessage& msg, MessageError* error);
+ bool OnRejectMessage(const SessionMessage& msg, MessageError* error);
+ bool OnInfoMessage(const SessionMessage& msg);
+ bool OnTerminateMessage(const SessionMessage& msg, MessageError* error);
+ bool OnTransportInfoMessage(const SessionMessage& msg, MessageError* error);
+ bool OnTransportAcceptMessage(const SessionMessage& msg, MessageError* error);
+ bool OnDescriptionInfoMessage(const SessionMessage& msg, MessageError* error);
+ bool OnRedirectError(const SessionRedirect& redirect, SessionError* error);
+
+ // Verifies that we are in the appropriate state to receive this message.
+ bool CheckState(State state, MessageError* error);
+
+ SessionManager* session_manager_;
+ bool initiate_acked_;
+ std::string local_name_;
+ std::string initiator_name_;
+ std::string remote_name_;
+ SessionClient* client_;
+ TransportParser* transport_parser_;
+ // Keeps track of what protocol we are speaking.
+ SignalingProtocol current_protocol_;
+
+ friend class SessionManager; // For access to constructor, destructor,
+ // and signaling related methods.
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_SESSION_H_
diff --git a/p2p/base/session_unittest.cc b/p2p/base/session_unittest.cc
new file mode 100644
index 00000000..d6f94b29
--- /dev/null
+++ b/p2p/base/session_unittest.cc
@@ -0,0 +1,2430 @@
+/*
+ * 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 <string.h>
+
+#include <deque>
+#include <map>
+#include <sstream>
+
+#include "webrtc/p2p/base/basicpacketsocketfactory.h"
+#include "webrtc/p2p/base/constants.h"
+#include "webrtc/p2p/base/p2ptransport.h"
+#include "webrtc/p2p/base/parsing.h"
+#include "webrtc/p2p/base/portallocator.h"
+#include "webrtc/p2p/base/relayport.h"
+#include "webrtc/p2p/base/relayserver.h"
+#include "webrtc/p2p/base/session.h"
+#include "webrtc/p2p/base/sessionclient.h"
+#include "webrtc/p2p/base/sessionmanager.h"
+#include "webrtc/p2p/base/stunport.h"
+#include "webrtc/p2p/base/stunserver.h"
+#include "webrtc/p2p/base/transportchannel.h"
+#include "webrtc/p2p/base/transportchannelproxy.h"
+#include "webrtc/p2p/base/udpport.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/base/base64.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/natserver.h"
+#include "webrtc/base/natsocketfactory.h"
+#include "webrtc/base/stringencode.h"
+
+using cricket::SignalingProtocol;
+using cricket::PROTOCOL_HYBRID;
+using cricket::PROTOCOL_JINGLE;
+using cricket::PROTOCOL_GINGLE;
+
+static const std::string kInitiator = "init@init.com";
+static const std::string kResponder = "resp@resp.com";
+// Expected from test random number generator.
+static const std::string kSessionId = "9254631414740579489";
+// TODO: When we need to test more than one transport type,
+// allow this to be injected like the content types are.
+static const std::string kTransportType = "http://www.google.com/transport/p2p";
+
+// Controls how long we wait for a session to send messages that we
+// expect, in milliseconds. We put it high to avoid flaky tests.
+static const int kEventTimeout = 5000;
+
+static const int kNumPorts = 2;
+static const int kPort0 = 28653;
+static const int kPortStep = 5;
+
+int GetPort(int port_index) {
+ return kPort0 + (port_index * kPortStep);
+}
+
+std::string GetPortString(int port_index) {
+ return rtc::ToString(GetPort(port_index));
+}
+
+// Only works for port_index < 10, which is fine for our purposes.
+std::string GetUsername(int port_index) {
+ return "username" + std::string(8, rtc::ToString(port_index)[0]);
+}
+
+// Only works for port_index < 10, which is fine for our purposes.
+std::string GetPassword(int port_index) {
+ return "password" + std::string(8, rtc::ToString(port_index)[0]);
+}
+
+std::string IqAck(const std::string& id,
+ const std::string& from,
+ const std::string& to) {
+ return "<cli:iq"
+ " to=\"" + to + "\""
+ " id=\"" + id + "\""
+ " type=\"result\""
+ " from=\"" + from + "\""
+ " xmlns:cli=\"jabber:client\""
+ "/>";
+}
+
+std::string IqSet(const std::string& id,
+ const std::string& from,
+ const std::string& to,
+ const std::string& content) {
+ return "<cli:iq"
+ " to=\"" + to + "\""
+ " type=\"set\""
+ " from=\"" + from + "\""
+ " id=\"" + id + "\""
+ " xmlns:cli=\"jabber:client\""
+ ">"
+ + content +
+ "</cli:iq>";
+}
+
+std::string IqError(const std::string& id,
+ const std::string& from,
+ const std::string& to,
+ const std::string& content) {
+ return "<cli:error"
+ " to=\"" + to + "\""
+ " type=\"error\""
+ " from=\"" + from + "\""
+ " id=\"" + id + "\""
+ " xmlns:cli=\"jabber:client\""
+ ">"
+ + content +
+ "</cli:error>";
+}
+
+std::string GingleSessionXml(const std::string& type,
+ const std::string& content) {
+ return "<session"
+ " xmlns=\"http://www.google.com/session\""
+ " type=\"" + type + "\""
+ " id=\"" + kSessionId + "\""
+ " initiator=\"" + kInitiator + "\""
+ ">"
+ + content +
+ "</session>";
+}
+
+std::string GingleDescriptionXml(const std::string& content_type) {
+ return "<description"
+ " xmlns=\"" + content_type + "\""
+ "/>";
+}
+
+std::string P2pCandidateXml(const std::string& name, int port_index) {
+ // Port will update the rtcp username by +1 on the last character. So we need
+ // to compensate here. See Port::username_fragment() for detail.
+ std::string username = GetUsername(port_index);
+ // TODO: Use the component id instead of the channel name to
+ // determinte if we need to covert the username here.
+ if (name == "rtcp" || name == "video_rtcp" || name == "chanb") {
+ char next_ch = username[username.size() - 1];
+ ASSERT(username.size() > 0);
+ rtc::Base64::GetNextBase64Char(next_ch, &next_ch);
+ username[username.size() - 1] = next_ch;
+ }
+ return "<candidate"
+ " name=\"" + name + "\""
+ " address=\"127.0.0.1\""
+ " port=\"" + GetPortString(port_index) + "\""
+ " preference=\"0.99\""
+ " username=\"" + username + "\""
+ " protocol=\"udp\""
+ " generation=\"0\""
+ " password=\"" + GetPassword(port_index) + "\""
+ " type=\"local\""
+ " network=\"network\""
+ "/>";
+}
+
+std::string JingleActionXml(const std::string& action,
+ const std::string& content) {
+ return "<jingle"
+ " xmlns=\"urn:xmpp:jingle:1\""
+ " action=\"" + action + "\""
+ " sid=\"" + kSessionId + "\""
+ ">"
+ + content +
+ "</jingle>";
+}
+
+std::string JingleInitiateActionXml(const std::string& content) {
+ return "<jingle"
+ " xmlns=\"urn:xmpp:jingle:1\""
+ " action=\"session-initiate\""
+ " sid=\"" + kSessionId + "\""
+ " initiator=\"" + kInitiator + "\""
+ ">"
+ + content +
+ "</jingle>";
+}
+
+std::string JingleGroupInfoXml(const std::string& content_name_a,
+ const std::string& content_name_b) {
+ std::string group_info = "<jin:group"
+ " type=\"BUNDLE\""
+ " xmlns:jin=\"google:jingle\""
+ ">";
+ if (!content_name_a.empty())
+ group_info += "<content name=\"" + content_name_a + "\""
+ "/>";
+ if (!content_name_b.empty())
+ group_info += "<content name=\"" + content_name_b + "\""
+ "/>";
+ group_info += "</jin:group>";
+ return group_info;
+}
+
+
+std::string JingleEmptyContentXml(const std::string& content_name,
+ const std::string& content_type,
+ const std::string& transport_type) {
+ return "<content"
+ " name=\"" + content_name + "\""
+ " creator=\"initiator\""
+ ">"
+ "<description"
+ " xmlns=\"" + content_type + "\""
+ "/>"
+ "<transport"
+ " xmlns=\"" + transport_type + "\""
+ "/>"
+ "</content>";
+}
+
+std::string JingleContentXml(const std::string& content_name,
+ const std::string& content_type,
+ const std::string& transport_type,
+ const std::string& transport_main) {
+ std::string transport = transport_type.empty() ? "" :
+ "<transport"
+ " xmlns=\"" + transport_type + "\""
+ ">"
+ + transport_main +
+ "</transport>";
+
+ return"<content"
+ " name=\"" + content_name + "\""
+ " creator=\"initiator\""
+ ">"
+ "<description"
+ " xmlns=\"" + content_type + "\""
+ "/>"
+ + transport +
+ "</content>";
+}
+
+std::string JingleTransportContentXml(const std::string& content_name,
+ const std::string& transport_type,
+ const std::string& content) {
+ return "<content"
+ " name=\"" + content_name + "\""
+ " creator=\"initiator\""
+ ">"
+ "<transport"
+ " xmlns=\"" + transport_type + "\""
+ ">"
+ + content +
+ "</transport>"
+ "</content>";
+}
+
+std::string GingleInitiateXml(const std::string& content_type) {
+ return GingleSessionXml(
+ "initiate",
+ GingleDescriptionXml(content_type));
+}
+
+std::string JingleInitiateXml(const std::string& content_name_a,
+ const std::string& content_type_a,
+ const std::string& content_name_b,
+ const std::string& content_type_b,
+ bool bundle = false) {
+ std::string content_xml;
+ if (content_name_b.empty()) {
+ content_xml = JingleEmptyContentXml(
+ content_name_a, content_type_a, kTransportType);
+ } else {
+ content_xml = JingleEmptyContentXml(
+ content_name_a, content_type_a, kTransportType) +
+ JingleEmptyContentXml(
+ content_name_b, content_type_b, kTransportType);
+ if (bundle) {
+ content_xml += JingleGroupInfoXml(content_name_a, content_name_b);
+ }
+ }
+ return JingleInitiateActionXml(content_xml);
+}
+
+std::string GingleAcceptXml(const std::string& content_type) {
+ return GingleSessionXml(
+ "accept",
+ GingleDescriptionXml(content_type));
+}
+
+std::string JingleAcceptXml(const std::string& content_name_a,
+ const std::string& content_type_a,
+ const std::string& content_name_b,
+ const std::string& content_type_b,
+ bool bundle = false) {
+ std::string content_xml;
+ if (content_name_b.empty()) {
+ content_xml = JingleEmptyContentXml(
+ content_name_a, content_type_a, kTransportType);
+ } else {
+ content_xml = JingleEmptyContentXml(
+ content_name_a, content_type_a, kTransportType) +
+ JingleEmptyContentXml(
+ content_name_b, content_type_b, kTransportType);
+ }
+ if (bundle) {
+ content_xml += JingleGroupInfoXml(content_name_a, content_name_b);
+ }
+
+ return JingleActionXml("session-accept", content_xml);
+}
+
+std::string Gingle2CandidatesXml(const std::string& channel_name,
+ int port_index0,
+ int port_index1) {
+ return GingleSessionXml(
+ "candidates",
+ P2pCandidateXml(channel_name, port_index0) +
+ P2pCandidateXml(channel_name, port_index1));
+}
+
+std::string Gingle4CandidatesXml(const std::string& channel_name_a,
+ int port_index0,
+ int port_index1,
+ const std::string& channel_name_b,
+ int port_index2,
+ int port_index3) {
+ return GingleSessionXml(
+ "candidates",
+ P2pCandidateXml(channel_name_a, port_index0) +
+ P2pCandidateXml(channel_name_a, port_index1) +
+ P2pCandidateXml(channel_name_b, port_index2) +
+ P2pCandidateXml(channel_name_b, port_index3));
+}
+
+std::string Jingle2TransportInfoXml(const std::string& content_name,
+ const std::string& channel_name,
+ int port_index0,
+ int port_index1) {
+ return JingleActionXml(
+ "transport-info",
+ JingleTransportContentXml(
+ content_name, kTransportType,
+ P2pCandidateXml(channel_name, port_index0) +
+ P2pCandidateXml(channel_name, port_index1)));
+}
+
+std::string Jingle4TransportInfoXml(const std::string& content_name,
+ const std::string& channel_name_a,
+ int port_index0,
+ int port_index1,
+ const std::string& channel_name_b,
+ int port_index2,
+ int port_index3) {
+ return JingleActionXml(
+ "transport-info",
+ JingleTransportContentXml(
+ content_name, kTransportType,
+ P2pCandidateXml(channel_name_a, port_index0) +
+ P2pCandidateXml(channel_name_a, port_index1) +
+ P2pCandidateXml(channel_name_b, port_index2) +
+ P2pCandidateXml(channel_name_b, port_index3)));
+}
+
+std::string JingleDescriptionInfoXml(const std::string& content_name,
+ const std::string& content_type) {
+ return JingleActionXml(
+ "description-info",
+ JingleContentXml(content_name, content_type, "", ""));
+}
+
+std::string GingleRejectXml(const std::string& reason) {
+ return GingleSessionXml(
+ "reject",
+ "<" + reason + "/>");
+}
+
+std::string JingleTerminateXml(const std::string& reason) {
+ return JingleActionXml(
+ "session-terminate",
+ "<reason><" + reason + "/></reason>");
+}
+
+std::string GingleTerminateXml(const std::string& reason) {
+ return GingleSessionXml(
+ "terminate",
+ "<" + reason + "/>");
+}
+
+std::string GingleRedirectXml(const std::string& intitiate,
+ const std::string& target) {
+ return intitiate +
+ "<error code=\"302\" type=\"modify\">"
+ "<redirect xmlns=\"http://www.google.com/session\">"
+ "xmpp:" + target +
+ "</redirect>"
+ "</error>";
+}
+
+std::string JingleRedirectXml(const std::string& intitiate,
+ const std::string& target) {
+ return intitiate +
+ "<error code=\"302\" type=\"modify\">"
+ "<redirect xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\">"
+ "xmpp:" + target +
+ "</redirect>"
+ "</error>";
+}
+
+std::string InitiateXml(SignalingProtocol protocol,
+ const std::string& gingle_content_type,
+ const std::string& content_name_a,
+ const std::string& content_type_a,
+ const std::string& content_name_b,
+ const std::string& content_type_b,
+ bool bundle = false) {
+ switch (protocol) {
+ case PROTOCOL_JINGLE:
+ return JingleInitiateXml(content_name_a, content_type_a,
+ content_name_b, content_type_b,
+ bundle);
+ case PROTOCOL_GINGLE:
+ return GingleInitiateXml(gingle_content_type);
+ case PROTOCOL_HYBRID:
+ return JingleInitiateXml(content_name_a, content_type_a,
+ content_name_b, content_type_b) +
+ GingleInitiateXml(gingle_content_type);
+ }
+ return "";
+}
+
+std::string InitiateXml(SignalingProtocol protocol,
+ const std::string& content_name,
+ const std::string& content_type) {
+ return InitiateXml(protocol,
+ content_type,
+ content_name, content_type,
+ "", "");
+}
+
+std::string AcceptXml(SignalingProtocol protocol,
+ const std::string& gingle_content_type,
+ const std::string& content_name_a,
+ const std::string& content_type_a,
+ const std::string& content_name_b,
+ const std::string& content_type_b,
+ bool bundle = false) {
+ switch (protocol) {
+ case PROTOCOL_JINGLE:
+ return JingleAcceptXml(content_name_a, content_type_a,
+ content_name_b, content_type_b, bundle);
+ case PROTOCOL_GINGLE:
+ return GingleAcceptXml(gingle_content_type);
+ case PROTOCOL_HYBRID:
+ return
+ JingleAcceptXml(content_name_a, content_type_a,
+ content_name_b, content_type_b) +
+ GingleAcceptXml(gingle_content_type);
+ }
+ return "";
+}
+
+
+std::string AcceptXml(SignalingProtocol protocol,
+ const std::string& content_name,
+ const std::string& content_type,
+ bool bundle = false) {
+ return AcceptXml(protocol,
+ content_type,
+ content_name, content_type,
+ "", "");
+}
+
+std::string TransportInfo2Xml(SignalingProtocol protocol,
+ const std::string& content_name,
+ const std::string& channel_name,
+ int port_index0,
+ int port_index1) {
+ switch (protocol) {
+ case PROTOCOL_JINGLE:
+ return Jingle2TransportInfoXml(
+ content_name,
+ channel_name, port_index0, port_index1);
+ case PROTOCOL_GINGLE:
+ return Gingle2CandidatesXml(
+ channel_name, port_index0, port_index1);
+ case PROTOCOL_HYBRID:
+ return
+ Jingle2TransportInfoXml(
+ content_name,
+ channel_name, port_index0, port_index1) +
+ Gingle2CandidatesXml(
+ channel_name, port_index0, port_index1);
+ }
+ return "";
+}
+
+std::string TransportInfo4Xml(SignalingProtocol protocol,
+ const std::string& content_name,
+ const std::string& channel_name_a,
+ int port_index0,
+ int port_index1,
+ const std::string& channel_name_b,
+ int port_index2,
+ int port_index3) {
+ switch (protocol) {
+ case PROTOCOL_JINGLE:
+ return Jingle4TransportInfoXml(
+ content_name,
+ channel_name_a, port_index0, port_index1,
+ channel_name_b, port_index2, port_index3);
+ case PROTOCOL_GINGLE:
+ return Gingle4CandidatesXml(
+ channel_name_a, port_index0, port_index1,
+ channel_name_b, port_index2, port_index3);
+ case PROTOCOL_HYBRID:
+ return
+ Jingle4TransportInfoXml(
+ content_name,
+ channel_name_a, port_index0, port_index1,
+ channel_name_b, port_index2, port_index3) +
+ Gingle4CandidatesXml(
+ channel_name_a, port_index0, port_index1,
+ channel_name_b, port_index2, port_index3);
+ }
+ return "";
+}
+
+std::string RejectXml(SignalingProtocol protocol,
+ const std::string& reason) {
+ switch (protocol) {
+ case PROTOCOL_JINGLE:
+ return JingleTerminateXml(reason);
+ case PROTOCOL_GINGLE:
+ return GingleRejectXml(reason);
+ case PROTOCOL_HYBRID:
+ return JingleTerminateXml(reason) +
+ GingleRejectXml(reason);
+ }
+ return "";
+}
+
+std::string TerminateXml(SignalingProtocol protocol,
+ const std::string& reason) {
+ switch (protocol) {
+ case PROTOCOL_JINGLE:
+ return JingleTerminateXml(reason);
+ case PROTOCOL_GINGLE:
+ return GingleTerminateXml(reason);
+ case PROTOCOL_HYBRID:
+ return JingleTerminateXml(reason) +
+ GingleTerminateXml(reason);
+ }
+ return "";
+}
+
+std::string RedirectXml(SignalingProtocol protocol,
+ const std::string& initiate,
+ const std::string& target) {
+ switch (protocol) {
+ case PROTOCOL_JINGLE:
+ return JingleRedirectXml(initiate, target);
+ case PROTOCOL_GINGLE:
+ return GingleRedirectXml(initiate, target);
+ default:
+ break;
+ }
+ return "";
+}
+
+// TODO: Break out and join with fakeportallocator.h
+class TestPortAllocatorSession : public cricket::PortAllocatorSession {
+ public:
+ TestPortAllocatorSession(const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd,
+ const int port_offset)
+ : PortAllocatorSession(content_name, component, ice_ufrag, ice_pwd, 0),
+ port_offset_(port_offset),
+ ports_(kNumPorts),
+ address_("127.0.0.1", 0),
+ network_("network", "unittest",
+ rtc::IPAddress(INADDR_LOOPBACK), 8),
+ socket_factory_(rtc::Thread::Current()),
+ running_(false) {
+ network_.AddIP(address_.ipaddr());
+ }
+
+ ~TestPortAllocatorSession() {
+ for (size_t i = 0; i < ports_.size(); i++)
+ delete ports_[i];
+ }
+
+ virtual void StartGettingPorts() {
+ for (int i = 0; i < kNumPorts; i++) {
+ int index = port_offset_ + i;
+ ports_[i] = cricket::UDPPort::Create(
+ rtc::Thread::Current(), &socket_factory_,
+ &network_, address_.ipaddr(), GetPort(index), GetPort(index),
+ GetUsername(index), GetPassword(index));
+ AddPort(ports_[i]);
+ }
+ running_ = true;
+ }
+
+ virtual void StopGettingPorts() { running_ = false; }
+ virtual bool IsGettingPorts() { return running_; }
+
+ void AddPort(cricket::Port* port) {
+ port->set_component(component_);
+ port->set_generation(0);
+ port->SignalDestroyed.connect(
+ this, &TestPortAllocatorSession::OnPortDestroyed);
+ port->SignalPortComplete.connect(
+ this, &TestPortAllocatorSession::OnPortComplete);
+ port->PrepareAddress();
+ SignalPortReady(this, port);
+ }
+
+ void OnPortDestroyed(cricket::PortInterface* port) {
+ for (size_t i = 0; i < ports_.size(); i++) {
+ if (ports_[i] == port)
+ ports_[i] = NULL;
+ }
+ }
+
+ void OnPortComplete(cricket::Port* port) {
+ SignalCandidatesReady(this, port->Candidates());
+ }
+
+ private:
+ int port_offset_;
+ std::vector<cricket::Port*> ports_;
+ rtc::SocketAddress address_;
+ rtc::Network network_;
+ rtc::BasicPacketSocketFactory socket_factory_;
+ bool running_;
+};
+
+class TestPortAllocator : public cricket::PortAllocator {
+ public:
+ TestPortAllocator() : port_offset_(0) {}
+
+ virtual cricket::PortAllocatorSession*
+ CreateSessionInternal(
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd) {
+ port_offset_ += 2;
+ return new TestPortAllocatorSession(content_name, component,
+ ice_ufrag, ice_pwd, port_offset_ - 2);
+ }
+
+ int port_offset_;
+};
+
+class TestContentDescription : public cricket::ContentDescription {
+ public:
+ explicit TestContentDescription(const std::string& gingle_content_type,
+ const std::string& content_type)
+ : gingle_content_type(gingle_content_type),
+ content_type(content_type) {
+ }
+ virtual ContentDescription* Copy() const {
+ return new TestContentDescription(*this);
+ }
+
+ std::string gingle_content_type;
+ std::string content_type;
+};
+
+cricket::SessionDescription* NewTestSessionDescription(
+ const std::string gingle_content_type,
+ const std::string& content_name_a, const std::string& content_type_a,
+ const std::string& content_name_b, const std::string& content_type_b) {
+
+ cricket::SessionDescription* offer = new cricket::SessionDescription();
+ offer->AddContent(content_name_a, content_type_a,
+ new TestContentDescription(gingle_content_type,
+ content_type_a));
+ cricket::TransportDescription desc(cricket::NS_GINGLE_P2P,
+ std::string(), std::string());
+ offer->AddTransportInfo(cricket::TransportInfo(content_name_a, desc));
+
+ if (content_name_a != content_name_b) {
+ offer->AddContent(content_name_b, content_type_b,
+ new TestContentDescription(gingle_content_type,
+ content_type_b));
+ offer->AddTransportInfo(cricket::TransportInfo(content_name_b, desc));
+ }
+ return offer;
+}
+
+cricket::SessionDescription* NewTestSessionDescription(
+ const std::string& content_name, const std::string& content_type) {
+
+ cricket::SessionDescription* offer = new cricket::SessionDescription();
+ offer->AddContent(content_name, content_type,
+ new TestContentDescription(content_type,
+ content_type));
+ offer->AddTransportInfo(cricket::TransportInfo
+ (content_name, cricket::TransportDescription(
+ cricket::NS_GINGLE_P2P,
+ std::string(), std::string())));
+ return offer;
+}
+
+struct TestSessionClient: public cricket::SessionClient,
+ public sigslot::has_slots<> {
+ public:
+ TestSessionClient() {
+ }
+
+ ~TestSessionClient() {
+ }
+
+ virtual bool ParseContent(SignalingProtocol protocol,
+ const buzz::XmlElement* elem,
+ cricket::ContentDescription** content,
+ cricket::ParseError* error) {
+ std::string content_type;
+ std::string gingle_content_type;
+ if (protocol == PROTOCOL_GINGLE) {
+ gingle_content_type = elem->Name().Namespace();
+ } else {
+ content_type = elem->Name().Namespace();
+ }
+
+ *content = new TestContentDescription(gingle_content_type, content_type);
+ return true;
+ }
+
+ virtual bool WriteContent(SignalingProtocol protocol,
+ const cricket::ContentDescription* untyped_content,
+ buzz::XmlElement** elem,
+ cricket::WriteError* error) {
+ const TestContentDescription* content =
+ static_cast<const TestContentDescription*>(untyped_content);
+ std::string content_type = (protocol == PROTOCOL_GINGLE ?
+ content->gingle_content_type :
+ content->content_type);
+ *elem = new buzz::XmlElement(
+ buzz::QName(content_type, "description"), true);
+ return true;
+ }
+
+ void OnSessionCreate(cricket::Session* session, bool initiate) {
+ }
+
+ void OnSessionDestroy(cricket::Session* session) {
+ }
+};
+
+struct ChannelHandler : sigslot::has_slots<> {
+ explicit ChannelHandler(cricket::TransportChannel* p, const std::string& name)
+ : channel(p), last_readable(false), last_writable(false), data_count(0),
+ last_size(0), name(name) {
+ p->SignalReadableState.connect(this, &ChannelHandler::OnReadableState);
+ p->SignalWritableState.connect(this, &ChannelHandler::OnWritableState);
+ p->SignalReadPacket.connect(this, &ChannelHandler::OnReadPacket);
+ }
+
+ bool writable() const {
+ return last_writable && channel->writable();
+ }
+
+ bool readable() const {
+ return last_readable && channel->readable();
+ }
+
+ void OnReadableState(cricket::TransportChannel* p) {
+ EXPECT_EQ(channel, p);
+ last_readable = channel->readable();
+ }
+
+ void OnWritableState(cricket::TransportChannel* p) {
+ EXPECT_EQ(channel, p);
+ last_writable = channel->writable();
+ }
+
+ void OnReadPacket(cricket::TransportChannel* p, const char* buf,
+ size_t size, const rtc::PacketTime& time, int flags) {
+ if (memcmp(buf, name.c_str(), name.size()) != 0)
+ return; // drop packet if packet doesn't belong to this channel. This
+ // can happen when transport channels are muxed together.
+ buf += name.size(); // Remove channel name from the message.
+ size -= name.size(); // Decrement size by channel name string size.
+ EXPECT_EQ(channel, p);
+ EXPECT_LE(size, sizeof(last_data));
+ data_count += 1;
+ last_size = size;
+ memcpy(last_data, buf, size);
+ }
+
+ void Send(const char* data, size_t size) {
+ rtc::PacketOptions options;
+ std::string data_with_id(name);
+ data_with_id += data;
+ int result = channel->SendPacket(data_with_id.c_str(), data_with_id.size(),
+ options, 0);
+ EXPECT_EQ(static_cast<int>(data_with_id.size()), result);
+ }
+
+ cricket::TransportChannel* channel;
+ bool last_readable, last_writable;
+ int data_count;
+ char last_data[4096];
+ size_t last_size;
+ std::string name;
+};
+
+void PrintStanza(const std::string& message,
+ const buzz::XmlElement* stanza) {
+ printf("%s: %s\n", message.c_str(), stanza->Str().c_str());
+}
+
+class TestClient : public sigslot::has_slots<> {
+ public:
+ // TODO: Add channel_component_a/b as inputs to the ctor.
+ TestClient(cricket::PortAllocator* port_allocator,
+ int* next_message_id,
+ const std::string& local_name,
+ SignalingProtocol start_protocol,
+ const std::string& content_type,
+ const std::string& content_name_a,
+ const std::string& channel_name_a,
+ const std::string& content_name_b,
+ const std::string& channel_name_b) {
+ Construct(port_allocator, next_message_id, local_name, start_protocol,
+ content_type, content_name_a, channel_name_a,
+ content_name_b, channel_name_b);
+ }
+
+ ~TestClient() {
+ if (session) {
+ session_manager->DestroySession(session);
+ EXPECT_EQ(1U, session_destroyed_count);
+ }
+ delete session_manager;
+ delete client;
+ for (std::deque<buzz::XmlElement*>::iterator it = sent_stanzas.begin();
+ it != sent_stanzas.end(); ++it) {
+ delete *it;
+ }
+ }
+
+ void Construct(cricket::PortAllocator* pa,
+ int* message_id,
+ const std::string& lname,
+ SignalingProtocol protocol,
+ const std::string& cont_type,
+ const std::string& cont_name_a,
+ const std::string& chan_name_a,
+ const std::string& cont_name_b,
+ const std::string& chan_name_b) {
+ port_allocator_ = pa;
+ next_message_id = message_id;
+ local_name = lname;
+ start_protocol = protocol;
+ content_type = cont_type;
+ content_name_a = cont_name_a;
+ channel_name_a = chan_name_a;
+ content_name_b = cont_name_b;
+ channel_name_b = chan_name_b;
+ session_created_count = 0;
+ session_destroyed_count = 0;
+ session_remote_description_update_count = 0;
+ new_local_description = false;
+ new_remote_description = false;
+ last_content_action = cricket::CA_OFFER;
+ last_content_source = cricket::CS_LOCAL;
+ session = NULL;
+ last_session_state = cricket::BaseSession::STATE_INIT;
+ blow_up_on_error = true;
+ error_count = 0;
+
+ session_manager = new cricket::SessionManager(port_allocator_);
+ session_manager->SignalSessionCreate.connect(
+ this, &TestClient::OnSessionCreate);
+ session_manager->SignalSessionDestroy.connect(
+ this, &TestClient::OnSessionDestroy);
+ session_manager->SignalOutgoingMessage.connect(
+ this, &TestClient::OnOutgoingMessage);
+
+ client = new TestSessionClient();
+ session_manager->AddClient(content_type, client);
+ EXPECT_EQ(client, session_manager->GetClient(content_type));
+ }
+
+ uint32 sent_stanza_count() const {
+ return static_cast<uint32>(sent_stanzas.size());
+ }
+
+ const buzz::XmlElement* stanza() const {
+ return last_expected_sent_stanza.get();
+ }
+
+ cricket::BaseSession::State session_state() const {
+ EXPECT_EQ(last_session_state, session->state());
+ return session->state();
+ }
+
+ void SetSessionState(cricket::BaseSession::State state) {
+ session->SetState(state);
+ EXPECT_EQ_WAIT(last_session_state, session->state(), kEventTimeout);
+ }
+
+ void CreateSession() {
+ session_manager->CreateSession(local_name, content_type);
+ }
+
+ void DeliverStanza(const buzz::XmlElement* stanza) {
+ session_manager->OnIncomingMessage(stanza);
+ }
+
+ void DeliverStanza(const std::string& str) {
+ buzz::XmlElement* stanza = buzz::XmlElement::ForStr(str);
+ session_manager->OnIncomingMessage(stanza);
+ delete stanza;
+ }
+
+ void DeliverAckToLastStanza() {
+ const buzz::XmlElement* orig_stanza = stanza();
+ const buzz::XmlElement* response_stanza =
+ buzz::XmlElement::ForStr(IqAck(orig_stanza->Attr(buzz::QN_IQ), "", ""));
+ session_manager->OnIncomingResponse(orig_stanza, response_stanza);
+ delete response_stanza;
+ }
+
+ void ExpectSentStanza(const std::string& expected) {
+ EXPECT_TRUE(!sent_stanzas.empty()) <<
+ "Found no stanza when expected " << expected;
+
+ last_expected_sent_stanza.reset(sent_stanzas.front());
+ sent_stanzas.pop_front();
+
+ std::string actual = last_expected_sent_stanza->Str();
+ EXPECT_EQ(expected, actual);
+ }
+
+ void SkipUnsentStanza() {
+ GetNextOutgoingMessageID();
+ }
+
+ bool HasTransport(const std::string& content_name) const {
+ ASSERT(session != NULL);
+ const cricket::Transport* transport = session->GetTransport(content_name);
+ return transport != NULL && (kTransportType == transport->type());
+ }
+
+ bool HasChannel(const std::string& content_name,
+ int component) const {
+ ASSERT(session != NULL);
+ const cricket::TransportChannel* channel =
+ session->GetChannel(content_name, component);
+ return channel != NULL && (component == channel->component());
+ }
+
+ cricket::TransportChannel* GetChannel(const std::string& content_name,
+ int component) const {
+ ASSERT(session != NULL);
+ return session->GetChannel(content_name, component);
+ }
+
+ void OnSessionCreate(cricket::Session* created_session, bool initiate) {
+ session_created_count += 1;
+
+ session = created_session;
+ session->set_current_protocol(start_protocol);
+ session->SignalState.connect(this, &TestClient::OnSessionState);
+ session->SignalError.connect(this, &TestClient::OnSessionError);
+ session->SignalRemoteDescriptionUpdate.connect(
+ this, &TestClient::OnSessionRemoteDescriptionUpdate);
+ session->SignalNewLocalDescription.connect(
+ this, &TestClient::OnNewLocalDescription);
+ session->SignalNewRemoteDescription.connect(
+ this, &TestClient::OnNewRemoteDescription);
+
+ CreateChannels();
+ }
+
+ void OnSessionDestroy(cricket::Session *session) {
+ session_destroyed_count += 1;
+ }
+
+ void OnSessionState(cricket::BaseSession* session,
+ cricket::BaseSession::State state) {
+ // EXPECT_EQ does not allow use of this, hence the tmp variable.
+ cricket::BaseSession* tmp = this->session;
+ EXPECT_EQ(tmp, session);
+ last_session_state = state;
+ }
+
+ void OnSessionError(cricket::BaseSession* session,
+ cricket::BaseSession::Error error) {
+ // EXPECT_EQ does not allow use of this, hence the tmp variable.
+ cricket::BaseSession* tmp = this->session;
+ EXPECT_EQ(tmp, session);
+ if (blow_up_on_error) {
+ EXPECT_TRUE(false);
+ } else {
+ error_count++;
+ }
+ }
+
+ void OnSessionRemoteDescriptionUpdate(cricket::BaseSession* session,
+ const cricket::ContentInfos& contents) {
+ session_remote_description_update_count++;
+ }
+
+ void OnNewLocalDescription(cricket::BaseSession* session,
+ cricket::ContentAction action) {
+ new_local_description = true;
+ last_content_action = action;
+ last_content_source = cricket::CS_LOCAL;
+ }
+
+ void OnNewRemoteDescription(cricket::BaseSession* session,
+ cricket::ContentAction action) {
+ new_remote_description = true;
+ last_content_action = action;
+ last_content_source = cricket::CS_REMOTE;
+ }
+
+ void PrepareCandidates() {
+ session_manager->OnSignalingReady();
+ }
+
+ void OnOutgoingMessage(cricket::SessionManager* manager,
+ const buzz::XmlElement* stanza) {
+ buzz::XmlElement* elem = new buzz::XmlElement(*stanza);
+ EXPECT_TRUE(elem->Name() == buzz::QN_IQ);
+ EXPECT_TRUE(elem->HasAttr(buzz::QN_TO));
+ EXPECT_FALSE(elem->HasAttr(buzz::QN_FROM));
+ EXPECT_TRUE(elem->HasAttr(buzz::QN_TYPE));
+ EXPECT_TRUE((elem->Attr(buzz::QN_TYPE) == "set") ||
+ (elem->Attr(buzz::QN_TYPE) == "result") ||
+ (elem->Attr(buzz::QN_TYPE) == "error"));
+
+ elem->SetAttr(buzz::QN_FROM, local_name);
+ if (elem->Attr(buzz::QN_TYPE) == "set") {
+ EXPECT_FALSE(elem->HasAttr(buzz::QN_ID));
+ elem->SetAttr(buzz::QN_ID, GetNextOutgoingMessageID());
+ }
+
+ // Uncommenting this is useful for debugging.
+ // PrintStanza("OutgoingMessage", elem);
+ sent_stanzas.push_back(elem);
+ }
+
+ std::string GetNextOutgoingMessageID() {
+ int message_id = (*next_message_id)++;
+ std::ostringstream ost;
+ ost << message_id;
+ return ost.str();
+ }
+
+ void CreateChannels() {
+ ASSERT(session != NULL);
+ // We either have a single content with multiple components (RTP/RTCP), or
+ // multiple contents with single components, but not both.
+ int component_a = 1;
+ int component_b = (content_name_a == content_name_b) ? 2 : 1;
+ chan_a.reset(new ChannelHandler(
+ session->CreateChannel(content_name_a, channel_name_a, component_a),
+ channel_name_a));
+ chan_b.reset(new ChannelHandler(
+ session->CreateChannel(content_name_b, channel_name_b, component_b),
+ channel_name_b));
+ }
+
+ int* next_message_id;
+ std::string local_name;
+ SignalingProtocol start_protocol;
+ std::string content_type;
+ std::string content_name_a;
+ std::string channel_name_a;
+ std::string content_name_b;
+ std::string channel_name_b;
+
+ uint32 session_created_count;
+ uint32 session_destroyed_count;
+ uint32 session_remote_description_update_count;
+ bool new_local_description;
+ bool new_remote_description;
+ cricket::ContentAction last_content_action;
+ cricket::ContentSource last_content_source;
+ std::deque<buzz::XmlElement*> sent_stanzas;
+ rtc::scoped_ptr<buzz::XmlElement> last_expected_sent_stanza;
+
+ cricket::SessionManager* session_manager;
+ TestSessionClient* client;
+ cricket::PortAllocator* port_allocator_;
+ cricket::Session* session;
+ cricket::BaseSession::State last_session_state;
+ rtc::scoped_ptr<ChannelHandler> chan_a;
+ rtc::scoped_ptr<ChannelHandler> chan_b;
+ bool blow_up_on_error;
+ int error_count;
+};
+
+class SessionTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ // Seed needed for each test to satisfy expectations.
+ rtc::SetRandomTestMode(true);
+ }
+
+ virtual void TearDown() {
+ rtc::SetRandomTestMode(false);
+ }
+
+ // Tests sending data between two clients, over two channels.
+ void TestSendRecv(ChannelHandler* chan1a,
+ ChannelHandler* chan1b,
+ ChannelHandler* chan2a,
+ ChannelHandler* chan2b) {
+ const char* dat1a = "spamspamspamspamspamspamspambakedbeansspam";
+ const char* dat2a = "mapssnaebdekabmapsmapsmapsmapsmapsmapsmaps";
+ const char* dat1b = "Lobster Thermidor a Crevette with a mornay sauce...";
+ const char* dat2b = "...ecuas yanrom a htiw etteverC a rodimrehT retsboL";
+
+ for (int i = 0; i < 20; i++) {
+ chan1a->Send(dat1a, strlen(dat1a));
+ chan1b->Send(dat1b, strlen(dat1b));
+ chan2a->Send(dat2a, strlen(dat2a));
+ chan2b->Send(dat2b, strlen(dat2b));
+
+ EXPECT_EQ_WAIT(i + 1, chan1a->data_count, kEventTimeout);
+ EXPECT_EQ_WAIT(i + 1, chan1b->data_count, kEventTimeout);
+ EXPECT_EQ_WAIT(i + 1, chan2a->data_count, kEventTimeout);
+ EXPECT_EQ_WAIT(i + 1, chan2b->data_count, kEventTimeout);
+
+ EXPECT_EQ(strlen(dat2a), chan1a->last_size);
+ EXPECT_EQ(strlen(dat2b), chan1b->last_size);
+ EXPECT_EQ(strlen(dat1a), chan2a->last_size);
+ EXPECT_EQ(strlen(dat1b), chan2b->last_size);
+
+ EXPECT_EQ(0, memcmp(chan1a->last_data, dat2a, strlen(dat2a)));
+ EXPECT_EQ(0, memcmp(chan1b->last_data, dat2b, strlen(dat2b)));
+ EXPECT_EQ(0, memcmp(chan2a->last_data, dat1a, strlen(dat1a)));
+ EXPECT_EQ(0, memcmp(chan2b->last_data, dat1b, strlen(dat1b)));
+ }
+ }
+
+ // Test an initiate from one client to another, each with
+ // independent initial protocols. Checks for the correct initiates,
+ // candidates, and accept messages, and tests that working network
+ // channels are established.
+ void TestSession(SignalingProtocol initiator_protocol,
+ SignalingProtocol responder_protocol,
+ SignalingProtocol resulting_protocol,
+ const std::string& gingle_content_type,
+ const std::string& content_type,
+ const std::string& content_name_a,
+ const std::string& channel_name_a,
+ const std::string& content_name_b,
+ const std::string& channel_name_b,
+ const std::string& initiate_xml,
+ const std::string& transport_info_a_xml,
+ const std::string& transport_info_b_xml,
+ const std::string& transport_info_reply_a_xml,
+ const std::string& transport_info_reply_b_xml,
+ const std::string& accept_xml,
+ bool bundle = false) {
+ rtc::scoped_ptr<cricket::PortAllocator> allocator(
+ new TestPortAllocator());
+ int next_message_id = 0;
+
+ rtc::scoped_ptr<TestClient> initiator(
+ new TestClient(allocator.get(), &next_message_id,
+ kInitiator, initiator_protocol,
+ content_type,
+ content_name_a, channel_name_a,
+ content_name_b, channel_name_b));
+ rtc::scoped_ptr<TestClient> responder(
+ new TestClient(allocator.get(), &next_message_id,
+ kResponder, responder_protocol,
+ content_type,
+ content_name_a, channel_name_a,
+ content_name_b, channel_name_b));
+
+ // Create Session and check channels and state.
+ initiator->CreateSession();
+ EXPECT_EQ(1U, initiator->session_created_count);
+ EXPECT_EQ(kSessionId, initiator->session->id());
+ EXPECT_EQ(initiator->session->local_name(), kInitiator);
+ EXPECT_EQ(cricket::BaseSession::STATE_INIT,
+ initiator->session_state());
+
+ // See comment in CreateChannels about how we choose component IDs.
+ int component_a = 1;
+ int component_b = (content_name_a == content_name_b) ? 2 : 1;
+ EXPECT_TRUE(initiator->HasTransport(content_name_a));
+ EXPECT_TRUE(initiator->HasChannel(content_name_a, component_a));
+ EXPECT_TRUE(initiator->HasTransport(content_name_b));
+ EXPECT_TRUE(initiator->HasChannel(content_name_b, component_b));
+
+ // Initiate and expect initiate message sent.
+ cricket::SessionDescription* offer = NewTestSessionDescription(
+ gingle_content_type,
+ content_name_a, content_type,
+ content_name_b, content_type);
+ if (bundle) {
+ cricket::ContentGroup group(cricket::GROUP_TYPE_BUNDLE);
+ group.AddContentName(content_name_a);
+ group.AddContentName(content_name_b);
+ EXPECT_TRUE(group.HasContentName(content_name_a));
+ EXPECT_TRUE(group.HasContentName(content_name_b));
+ offer->AddGroup(group);
+ }
+ EXPECT_TRUE(initiator->session->Initiate(kResponder, offer));
+ EXPECT_EQ(initiator->session->remote_name(), kResponder);
+ EXPECT_EQ(initiator->session->local_description(), offer);
+
+ EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
+ EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE,
+ initiator->session_state());
+
+ initiator->ExpectSentStanza(
+ IqSet("0", kInitiator, kResponder, initiate_xml));
+
+ // Deliver the initiate. Expect ack and session created with
+ // transports.
+ responder->DeliverStanza(initiator->stanza());
+ responder->ExpectSentStanza(
+ IqAck("0", kResponder, kInitiator));
+ EXPECT_EQ(0U, responder->sent_stanza_count());
+
+ EXPECT_EQ(1U, responder->session_created_count);
+ EXPECT_EQ(kSessionId, responder->session->id());
+ EXPECT_EQ(responder->session->local_name(), kResponder);
+ EXPECT_EQ(responder->session->remote_name(), kInitiator);
+ EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDINITIATE,
+ responder->session_state());
+
+ EXPECT_TRUE(responder->HasTransport(content_name_a));
+ EXPECT_TRUE(responder->HasChannel(content_name_a, component_a));
+ EXPECT_TRUE(responder->HasTransport(content_name_b));
+ EXPECT_TRUE(responder->HasChannel(content_name_b, component_b));
+
+ // Expect transport-info message from initiator.
+ // But don't send candidates until initiate ack is received.
+ initiator->PrepareCandidates();
+ WAIT(initiator->sent_stanza_count() > 0, 100);
+ EXPECT_EQ(0U, initiator->sent_stanza_count());
+ initiator->DeliverAckToLastStanza();
+ EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
+ initiator->ExpectSentStanza(
+ IqSet("1", kInitiator, kResponder, transport_info_a_xml));
+
+ // Deliver transport-info and expect ack.
+ responder->DeliverStanza(initiator->stanza());
+ responder->ExpectSentStanza(
+ IqAck("1", kResponder, kInitiator));
+
+ if (!transport_info_b_xml.empty()) {
+ // Expect second transport-info message from initiator.
+ EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
+ initiator->ExpectSentStanza(
+ IqSet("2", kInitiator, kResponder, transport_info_b_xml));
+ EXPECT_EQ(0U, initiator->sent_stanza_count());
+
+ // Deliver second transport-info message and expect ack.
+ responder->DeliverStanza(initiator->stanza());
+ responder->ExpectSentStanza(
+ IqAck("2", kResponder, kInitiator));
+ } else {
+ EXPECT_EQ(0U, initiator->sent_stanza_count());
+ EXPECT_EQ(0U, responder->sent_stanza_count());
+ initiator->SkipUnsentStanza();
+ }
+
+ // Expect reply transport-info message from responder.
+ responder->PrepareCandidates();
+ EXPECT_TRUE_WAIT(responder->sent_stanza_count() > 0, kEventTimeout);
+ responder->ExpectSentStanza(
+ IqSet("3", kResponder, kInitiator, transport_info_reply_a_xml));
+
+ // Deliver reply transport-info and expect ack.
+ initiator->DeliverStanza(responder->stanza());
+ initiator->ExpectSentStanza(
+ IqAck("3", kInitiator, kResponder));
+
+ if (!transport_info_reply_b_xml.empty()) {
+ // Expect second reply transport-info message from responder.
+ EXPECT_TRUE_WAIT(responder->sent_stanza_count() > 0, kEventTimeout);
+ responder->ExpectSentStanza(
+ IqSet("4", kResponder, kInitiator, transport_info_reply_b_xml));
+ EXPECT_EQ(0U, responder->sent_stanza_count());
+
+ // Deliver second reply transport-info message and expect ack.
+ initiator->DeliverStanza(responder->stanza());
+ initiator->ExpectSentStanza(
+ IqAck("4", kInitiator, kResponder));
+ EXPECT_EQ(0U, initiator->sent_stanza_count());
+ } else {
+ EXPECT_EQ(0U, initiator->sent_stanza_count());
+ EXPECT_EQ(0U, responder->sent_stanza_count());
+ responder->SkipUnsentStanza();
+ }
+
+ // The channels should be able to become writable at this point. This
+ // requires pinging, so it may take a little while.
+ EXPECT_TRUE_WAIT(initiator->chan_a->writable() &&
+ initiator->chan_a->readable(), kEventTimeout);
+ EXPECT_TRUE_WAIT(initiator->chan_b->writable() &&
+ initiator->chan_b->readable(), kEventTimeout);
+ EXPECT_TRUE_WAIT(responder->chan_a->writable() &&
+ responder->chan_a->readable(), kEventTimeout);
+ EXPECT_TRUE_WAIT(responder->chan_b->writable() &&
+ responder->chan_b->readable(), kEventTimeout);
+
+ // Accept the session and expect accept stanza.
+ cricket::SessionDescription* answer = NewTestSessionDescription(
+ gingle_content_type,
+ content_name_a, content_type,
+ content_name_b, content_type);
+ if (bundle) {
+ cricket::ContentGroup group(cricket::GROUP_TYPE_BUNDLE);
+ group.AddContentName(content_name_a);
+ group.AddContentName(content_name_b);
+ EXPECT_TRUE(group.HasContentName(content_name_a));
+ EXPECT_TRUE(group.HasContentName(content_name_b));
+ answer->AddGroup(group);
+ }
+ EXPECT_TRUE(responder->session->Accept(answer));
+ EXPECT_EQ(responder->session->local_description(), answer);
+
+ responder->ExpectSentStanza(
+ IqSet("5", kResponder, kInitiator, accept_xml));
+
+ EXPECT_EQ(0U, responder->sent_stanza_count());
+
+ // Deliver the accept message and expect an ack.
+ initiator->DeliverStanza(responder->stanza());
+ EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
+ initiator->ExpectSentStanza(
+ IqAck("5", kInitiator, kResponder));
+ EXPECT_EQ(0U, initiator->sent_stanza_count());
+
+ // Both sessions should be in progress and have functioning
+ // channels.
+ EXPECT_EQ(resulting_protocol, initiator->session->current_protocol());
+ EXPECT_EQ(resulting_protocol, responder->session->current_protocol());
+ EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS,
+ initiator->session_state(), kEventTimeout);
+ EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS,
+ responder->session_state(), kEventTimeout);
+ if (bundle) {
+ cricket::TransportChannel* initiator_chan_a = initiator->chan_a->channel;
+ cricket::TransportChannel* initiator_chan_b = initiator->chan_b->channel;
+
+ // Since we know these are TransportChannelProxy, type cast it.
+ cricket::TransportChannelProxy* initiator_proxy_chan_a =
+ static_cast<cricket::TransportChannelProxy*>(initiator_chan_a);
+ cricket::TransportChannelProxy* initiator_proxy_chan_b =
+ static_cast<cricket::TransportChannelProxy*>(initiator_chan_b);
+ EXPECT_TRUE(initiator_proxy_chan_a->impl() != NULL);
+ EXPECT_TRUE(initiator_proxy_chan_b->impl() != NULL);
+ EXPECT_EQ(initiator_proxy_chan_a->impl(), initiator_proxy_chan_b->impl());
+
+ cricket::TransportChannel* responder_chan_a = responder->chan_a->channel;
+ cricket::TransportChannel* responder_chan_b = responder->chan_b->channel;
+
+ // Since we know these are TransportChannelProxy, type cast it.
+ cricket::TransportChannelProxy* responder_proxy_chan_a =
+ static_cast<cricket::TransportChannelProxy*>(responder_chan_a);
+ cricket::TransportChannelProxy* responder_proxy_chan_b =
+ static_cast<cricket::TransportChannelProxy*>(responder_chan_b);
+ EXPECT_TRUE(responder_proxy_chan_a->impl() != NULL);
+ EXPECT_TRUE(responder_proxy_chan_b->impl() != NULL);
+ EXPECT_EQ(responder_proxy_chan_a->impl(), responder_proxy_chan_b->impl());
+ }
+ TestSendRecv(initiator->chan_a.get(), initiator->chan_b.get(),
+ responder->chan_a.get(), responder->chan_b.get());
+
+ if (resulting_protocol == PROTOCOL_JINGLE) {
+ // Deliver a description-info message to the initiator and check if the
+ // content description changes.
+ EXPECT_EQ(0U, initiator->session_remote_description_update_count);
+
+ const cricket::SessionDescription* old_session_desc =
+ initiator->session->remote_description();
+ const cricket::ContentInfo* old_content_a =
+ old_session_desc->GetContentByName(content_name_a);
+ const cricket::ContentDescription* old_content_desc_a =
+ old_content_a->description;
+ const cricket::ContentInfo* old_content_b =
+ old_session_desc->GetContentByName(content_name_b);
+ const cricket::ContentDescription* old_content_desc_b =
+ old_content_b->description;
+ EXPECT_TRUE(old_content_desc_a != NULL);
+ EXPECT_TRUE(old_content_desc_b != NULL);
+
+ LOG(LS_INFO) << "A " << old_content_a->name;
+ LOG(LS_INFO) << "B " << old_content_b->name;
+
+ std::string description_info_xml =
+ JingleDescriptionInfoXml(content_name_a, content_type);
+ initiator->DeliverStanza(
+ IqSet("6", kResponder, kInitiator, description_info_xml));
+ responder->SkipUnsentStanza();
+ EXPECT_EQ(1U, initiator->session_remote_description_update_count);
+
+ const cricket::SessionDescription* new_session_desc =
+ initiator->session->remote_description();
+ const cricket::ContentInfo* new_content_a =
+ new_session_desc->GetContentByName(content_name_a);
+ const cricket::ContentDescription* new_content_desc_a =
+ new_content_a->description;
+ const cricket::ContentInfo* new_content_b =
+ new_session_desc->GetContentByName(content_name_b);
+ const cricket::ContentDescription* new_content_desc_b =
+ new_content_b->description;
+ EXPECT_TRUE(new_content_desc_a != NULL);
+ EXPECT_TRUE(new_content_desc_b != NULL);
+
+ // TODO: We used to replace contents from an update, but
+ // that no longer works with partial updates. We need to figure out
+ // a way to merge patial updates into contents. For now, users of
+ // Session should listen to SignalRemoteDescriptionUpdate and handle
+ // updates. They should not expect remote_description to be the
+ // latest value.
+ // See session.cc OnDescriptionInfoMessage.
+
+ // EXPECT_NE(old_content_desc_a, new_content_desc_a);
+
+ // if (content_name_a != content_name_b) {
+ // // If content_name_a != content_name_b, then b's content description
+ // // should not have changed since the description-info message only
+ // // contained an update for content_name_a.
+ // EXPECT_EQ(old_content_desc_b, new_content_desc_b);
+ // }
+
+ EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
+ initiator->ExpectSentStanza(
+ IqAck("6", kInitiator, kResponder));
+ EXPECT_EQ(0U, initiator->sent_stanza_count());
+ } else {
+ responder->SkipUnsentStanza();
+ }
+
+ initiator->session->Terminate();
+ initiator->ExpectSentStanza(
+ IqSet("7", kInitiator, kResponder,
+ TerminateXml(resulting_protocol,
+ cricket::STR_TERMINATE_SUCCESS)));
+
+ responder->DeliverStanza(initiator->stanza());
+ responder->ExpectSentStanza(
+ IqAck("7", kResponder, kInitiator));
+ EXPECT_EQ(cricket::BaseSession::STATE_SENTTERMINATE,
+ initiator->session_state());
+ EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDTERMINATE,
+ responder->session_state());
+ }
+
+ // Test an initiate with other content, called "main".
+ void TestOtherContent(SignalingProtocol initiator_protocol,
+ SignalingProtocol responder_protocol,
+ SignalingProtocol resulting_protocol) {
+ std::string content_name = "main";
+ std::string content_type = "http://oink.splat/session";
+ std::string content_name_a = content_name;
+ std::string channel_name_a = "rtp";
+ std::string content_name_b = content_name;
+ std::string channel_name_b = "rtcp";
+ std::string initiate_xml = InitiateXml(
+ initiator_protocol,
+ content_name_a, content_type);
+ std::string transport_info_a_xml = TransportInfo4Xml(
+ initiator_protocol, content_name,
+ channel_name_a, 0, 1,
+ channel_name_b, 2, 3);
+ std::string transport_info_b_xml = "";
+ std::string transport_info_reply_a_xml = TransportInfo4Xml(
+ resulting_protocol, content_name,
+ channel_name_a, 4, 5,
+ channel_name_b, 6, 7);
+ std::string transport_info_reply_b_xml = "";
+ std::string accept_xml = AcceptXml(
+ resulting_protocol,
+ content_name_a, content_type);
+
+
+ TestSession(initiator_protocol, responder_protocol, resulting_protocol,
+ content_type,
+ content_type,
+ content_name_a, channel_name_a,
+ content_name_b, channel_name_b,
+ initiate_xml,
+ transport_info_a_xml, transport_info_b_xml,
+ transport_info_reply_a_xml, transport_info_reply_b_xml,
+ accept_xml);
+ }
+
+ // Test an initiate with audio content.
+ void TestAudioContent(SignalingProtocol initiator_protocol,
+ SignalingProtocol responder_protocol,
+ SignalingProtocol resulting_protocol) {
+ std::string gingle_content_type = cricket::NS_GINGLE_AUDIO;
+ std::string content_name = cricket::CN_AUDIO;
+ std::string content_type = cricket::NS_JINGLE_RTP;
+ std::string channel_name_a = "rtp";
+ std::string channel_name_b = "rtcp";
+ std::string initiate_xml = InitiateXml(
+ initiator_protocol,
+ gingle_content_type,
+ content_name, content_type,
+ "", "");
+ std::string transport_info_a_xml = TransportInfo4Xml(
+ initiator_protocol, content_name,
+ channel_name_a, 0, 1,
+ channel_name_b, 2, 3);
+ std::string transport_info_b_xml = "";
+ std::string transport_info_reply_a_xml = TransportInfo4Xml(
+ resulting_protocol, content_name,
+ channel_name_a, 4, 5,
+ channel_name_b, 6, 7);
+ std::string transport_info_reply_b_xml = "";
+ std::string accept_xml = AcceptXml(
+ resulting_protocol,
+ gingle_content_type,
+ content_name, content_type,
+ "", "");
+
+
+ TestSession(initiator_protocol, responder_protocol, resulting_protocol,
+ gingle_content_type,
+ content_type,
+ content_name, channel_name_a,
+ content_name, channel_name_b,
+ initiate_xml,
+ transport_info_a_xml, transport_info_b_xml,
+ transport_info_reply_a_xml, transport_info_reply_b_xml,
+ accept_xml);
+ }
+
+ // Since media content is "split" into two contents (audio and
+ // video), we need to treat it special.
+ void TestVideoContents(SignalingProtocol initiator_protocol,
+ SignalingProtocol responder_protocol,
+ SignalingProtocol resulting_protocol) {
+ std::string content_type = cricket::NS_JINGLE_RTP;
+ std::string gingle_content_type = cricket::NS_GINGLE_VIDEO;
+ std::string content_name_a = cricket::CN_AUDIO;
+ std::string channel_name_a = "rtp";
+ std::string content_name_b = cricket::CN_VIDEO;
+ std::string channel_name_b = "video_rtp";
+
+ std::string initiate_xml = InitiateXml(
+ initiator_protocol,
+ gingle_content_type,
+ content_name_a, content_type,
+ content_name_b, content_type);
+ std::string transport_info_a_xml = TransportInfo2Xml(
+ initiator_protocol, content_name_a,
+ channel_name_a, 0, 1);
+ std::string transport_info_b_xml = TransportInfo2Xml(
+ initiator_protocol, content_name_b,
+ channel_name_b, 2, 3);
+ std::string transport_info_reply_a_xml = TransportInfo2Xml(
+ resulting_protocol, content_name_a,
+ channel_name_a, 4, 5);
+ std::string transport_info_reply_b_xml = TransportInfo2Xml(
+ resulting_protocol, content_name_b,
+ channel_name_b, 6, 7);
+ std::string accept_xml = AcceptXml(
+ resulting_protocol,
+ gingle_content_type,
+ content_name_a, content_type,
+ content_name_b, content_type);
+
+ TestSession(initiator_protocol, responder_protocol, resulting_protocol,
+ gingle_content_type,
+ content_type,
+ content_name_a, channel_name_a,
+ content_name_b, channel_name_b,
+ initiate_xml,
+ transport_info_a_xml, transport_info_b_xml,
+ transport_info_reply_a_xml, transport_info_reply_b_xml,
+ accept_xml);
+ }
+
+ void TestBadRedirect(SignalingProtocol protocol) {
+ std::string content_name = "main";
+ std::string content_type = "http://oink.splat/session";
+ std::string channel_name_a = "chana";
+ std::string channel_name_b = "chanb";
+ std::string initiate_xml = InitiateXml(
+ protocol, content_name, content_type);
+ std::string transport_info_xml = TransportInfo4Xml(
+ protocol, content_name,
+ channel_name_a, 0, 1,
+ channel_name_b, 2, 3);
+ std::string transport_info_reply_xml = TransportInfo4Xml(
+ protocol, content_name,
+ channel_name_a, 4, 5,
+ channel_name_b, 6, 7);
+ std::string accept_xml = AcceptXml(
+ protocol, content_name, content_type);
+ std::string responder_full = kResponder + "/full";
+
+ rtc::scoped_ptr<cricket::PortAllocator> allocator(
+ new TestPortAllocator());
+ int next_message_id = 0;
+
+ rtc::scoped_ptr<TestClient> initiator(
+ new TestClient(allocator.get(), &next_message_id,
+ kInitiator, protocol,
+ content_type,
+ content_name, channel_name_a,
+ content_name, channel_name_b));
+
+ rtc::scoped_ptr<TestClient> responder(
+ new TestClient(allocator.get(), &next_message_id,
+ responder_full, protocol,
+ content_type,
+ content_name, channel_name_a,
+ content_name, channel_name_b));
+
+ // Create Session and check channels and state.
+ initiator->CreateSession();
+ EXPECT_EQ(1U, initiator->session_created_count);
+ EXPECT_EQ(kSessionId, initiator->session->id());
+ EXPECT_EQ(initiator->session->local_name(), kInitiator);
+ EXPECT_EQ(cricket::BaseSession::STATE_INIT,
+ initiator->session_state());
+
+ EXPECT_TRUE(initiator->HasChannel(content_name, 1));
+ EXPECT_TRUE(initiator->HasChannel(content_name, 2));
+
+ // Initiate and expect initiate message sent.
+ cricket::SessionDescription* offer = NewTestSessionDescription(
+ content_name, content_type);
+ EXPECT_TRUE(initiator->session->Initiate(kResponder, offer));
+ EXPECT_EQ(initiator->session->remote_name(), kResponder);
+ EXPECT_EQ(initiator->session->local_description(), offer);
+
+ EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
+ EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE,
+ initiator->session_state());
+ initiator->ExpectSentStanza(
+ IqSet("0", kInitiator, kResponder, initiate_xml));
+
+ // Expect transport-info message from initiator.
+ initiator->DeliverAckToLastStanza();
+ initiator->PrepareCandidates();
+ EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
+ initiator->ExpectSentStanza(
+ IqSet("1", kInitiator, kResponder, transport_info_xml));
+
+ // Send an unauthorized redirect to the initiator and expect it be ignored.
+ initiator->blow_up_on_error = false;
+ const buzz::XmlElement* initiate_stanza = initiator->stanza();
+ rtc::scoped_ptr<buzz::XmlElement> redirect_stanza(
+ buzz::XmlElement::ForStr(
+ IqError("ER", kResponder, kInitiator,
+ RedirectXml(protocol, initiate_xml, "not@allowed.com"))));
+ initiator->session_manager->OnFailedSend(
+ initiate_stanza, redirect_stanza.get());
+ EXPECT_EQ(initiator->session->remote_name(), kResponder);
+ initiator->blow_up_on_error = true;
+ EXPECT_EQ(initiator->error_count, 1);
+ }
+
+ void TestGoodRedirect(SignalingProtocol protocol) {
+ std::string content_name = "main";
+ std::string content_type = "http://oink.splat/session";
+ std::string channel_name_a = "chana";
+ std::string channel_name_b = "chanb";
+ std::string initiate_xml = InitiateXml(
+ protocol, content_name, content_type);
+ std::string transport_info_xml = TransportInfo4Xml(
+ protocol, content_name,
+ channel_name_a, 0, 1,
+ channel_name_b, 2, 3);
+ std::string transport_info_reply_xml = TransportInfo4Xml(
+ protocol, content_name,
+ channel_name_a, 4, 5,
+ channel_name_b, 6, 7);
+ std::string accept_xml = AcceptXml(
+ protocol, content_name, content_type);
+ std::string responder_full = kResponder + "/full";
+
+ rtc::scoped_ptr<cricket::PortAllocator> allocator(
+ new TestPortAllocator());
+ int next_message_id = 0;
+
+ rtc::scoped_ptr<TestClient> initiator(
+ new TestClient(allocator.get(), &next_message_id,
+ kInitiator, protocol,
+ content_type,
+ content_name, channel_name_a,
+ content_name, channel_name_b));
+
+ rtc::scoped_ptr<TestClient> responder(
+ new TestClient(allocator.get(), &next_message_id,
+ responder_full, protocol,
+ content_type,
+ content_name, channel_name_a,
+ content_name, channel_name_b));
+
+ // Create Session and check channels and state.
+ initiator->CreateSession();
+ EXPECT_EQ(1U, initiator->session_created_count);
+ EXPECT_EQ(kSessionId, initiator->session->id());
+ EXPECT_EQ(initiator->session->local_name(), kInitiator);
+ EXPECT_EQ(cricket::BaseSession::STATE_INIT,
+ initiator->session_state());
+
+ EXPECT_TRUE(initiator->HasChannel(content_name, 1));
+ EXPECT_TRUE(initiator->HasChannel(content_name, 2));
+
+ // Initiate and expect initiate message sent.
+ cricket::SessionDescription* offer = NewTestSessionDescription(
+ content_name, content_type);
+ EXPECT_TRUE(initiator->session->Initiate(kResponder, offer));
+ EXPECT_EQ(initiator->session->remote_name(), kResponder);
+ EXPECT_EQ(initiator->session->local_description(), offer);
+
+ EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
+ EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE,
+ initiator->session_state());
+ initiator->ExpectSentStanza(
+ IqSet("0", kInitiator, kResponder, initiate_xml));
+
+ // Expect transport-info message from initiator.
+ initiator->DeliverAckToLastStanza();
+ initiator->PrepareCandidates();
+ EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
+ initiator->ExpectSentStanza(
+ IqSet("1", kInitiator, kResponder, transport_info_xml));
+
+ // Send a redirect to the initiator and expect all of the message
+ // to be resent.
+ const buzz::XmlElement* initiate_stanza = initiator->stanza();
+ rtc::scoped_ptr<buzz::XmlElement> redirect_stanza(
+ buzz::XmlElement::ForStr(
+ IqError("ER2", kResponder, kInitiator,
+ RedirectXml(protocol, initiate_xml, responder_full))));
+ initiator->session_manager->OnFailedSend(
+ initiate_stanza, redirect_stanza.get());
+ EXPECT_EQ(initiator->session->remote_name(), responder_full);
+
+ EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
+ initiator->ExpectSentStanza(
+ IqSet("2", kInitiator, responder_full, initiate_xml));
+ initiator->ExpectSentStanza(
+ IqSet("3", kInitiator, responder_full, transport_info_xml));
+
+ // Deliver the initiate. Expect ack and session created with
+ // transports.
+ responder->DeliverStanza(
+ IqSet("2", kInitiator, responder_full, initiate_xml));
+ responder->ExpectSentStanza(
+ IqAck("2", responder_full, kInitiator));
+ EXPECT_EQ(0U, responder->sent_stanza_count());
+
+ EXPECT_EQ(1U, responder->session_created_count);
+ EXPECT_EQ(kSessionId, responder->session->id());
+ EXPECT_EQ(responder->session->local_name(), responder_full);
+ EXPECT_EQ(responder->session->remote_name(), kInitiator);
+ EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDINITIATE,
+ responder->session_state());
+
+ EXPECT_TRUE(responder->HasChannel(content_name, 1));
+ EXPECT_TRUE(responder->HasChannel(content_name, 2));
+
+ // Deliver transport-info and expect ack.
+ responder->DeliverStanza(
+ IqSet("3", kInitiator, responder_full, transport_info_xml));
+ responder->ExpectSentStanza(
+ IqAck("3", responder_full, kInitiator));
+
+ // Expect reply transport-infos sent to new remote JID
+ responder->PrepareCandidates();
+ EXPECT_TRUE_WAIT(responder->sent_stanza_count() > 0, kEventTimeout);
+ responder->ExpectSentStanza(
+ IqSet("4", responder_full, kInitiator, transport_info_reply_xml));
+
+ initiator->DeliverStanza(responder->stanza());
+ initiator->ExpectSentStanza(
+ IqAck("4", kInitiator, responder_full));
+
+ // The channels should be able to become writable at this point. This
+ // requires pinging, so it may take a little while.
+ EXPECT_TRUE_WAIT(initiator->chan_a->writable() &&
+ initiator->chan_a->readable(), kEventTimeout);
+ EXPECT_TRUE_WAIT(initiator->chan_b->writable() &&
+ initiator->chan_b->readable(), kEventTimeout);
+ EXPECT_TRUE_WAIT(responder->chan_a->writable() &&
+ responder->chan_a->readable(), kEventTimeout);
+ EXPECT_TRUE_WAIT(responder->chan_b->writable() &&
+ responder->chan_b->readable(), kEventTimeout);
+
+ // Accept the session and expect accept stanza.
+ cricket::SessionDescription* answer = NewTestSessionDescription(
+ content_name, content_type);
+ EXPECT_TRUE(responder->session->Accept(answer));
+ EXPECT_EQ(responder->session->local_description(), answer);
+
+ responder->ExpectSentStanza(
+ IqSet("5", responder_full, kInitiator, accept_xml));
+ EXPECT_EQ(0U, responder->sent_stanza_count());
+
+ // Deliver the accept message and expect an ack.
+ initiator->DeliverStanza(responder->stanza());
+ EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
+ initiator->ExpectSentStanza(
+ IqAck("5", kInitiator, responder_full));
+ EXPECT_EQ(0U, initiator->sent_stanza_count());
+
+ // Both sessions should be in progress and have functioning
+ // channels.
+ EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS,
+ initiator->session_state(), kEventTimeout);
+ EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS,
+ responder->session_state(), kEventTimeout);
+ TestSendRecv(initiator->chan_a.get(), initiator->chan_b.get(),
+ responder->chan_a.get(), responder->chan_b.get());
+ }
+
+ void TestCandidatesInInitiateAndAccept(const std::string& test_name) {
+ std::string content_name = "main";
+ std::string content_type = "http://oink.splat/session";
+ std::string channel_name_a = "rtp";
+ std::string channel_name_b = "rtcp";
+ cricket::SignalingProtocol protocol = PROTOCOL_JINGLE;
+
+ rtc::scoped_ptr<cricket::PortAllocator> allocator(
+ new TestPortAllocator());
+ int next_message_id = 0;
+
+ rtc::scoped_ptr<TestClient> initiator(
+ new TestClient(allocator.get(), &next_message_id,
+ kInitiator, protocol,
+ content_type,
+ content_name, channel_name_a,
+ content_name, channel_name_b));
+
+ rtc::scoped_ptr<TestClient> responder(
+ new TestClient(allocator.get(), &next_message_id,
+ kResponder, protocol,
+ content_type,
+ content_name, channel_name_a,
+ content_name, channel_name_b));
+
+ // Create Session and check channels and state.
+ initiator->CreateSession();
+ EXPECT_TRUE(initiator->HasTransport(content_name));
+ EXPECT_TRUE(initiator->HasChannel(content_name, 1));
+ EXPECT_TRUE(initiator->HasTransport(content_name));
+ EXPECT_TRUE(initiator->HasChannel(content_name, 2));
+
+ // Initiate and expect initiate message sent.
+ cricket::SessionDescription* offer = NewTestSessionDescription(
+ content_name, content_type);
+ EXPECT_TRUE(initiator->session->Initiate(kResponder, offer));
+
+ EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
+ EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE,
+ initiator->session_state());
+ initiator->ExpectSentStanza(
+ IqSet("0", kInitiator, kResponder,
+ InitiateXml(protocol, content_name, content_type)));
+
+ // Fake the delivery the initiate and candidates together.
+ responder->DeliverStanza(
+ IqSet("A", kInitiator, kResponder,
+ JingleInitiateActionXml(
+ JingleContentXml(
+ content_name, content_type, kTransportType,
+ P2pCandidateXml(channel_name_a, 0) +
+ P2pCandidateXml(channel_name_a, 1) +
+ P2pCandidateXml(channel_name_b, 2) +
+ P2pCandidateXml(channel_name_b, 3)))));
+ responder->ExpectSentStanza(
+ IqAck("A", kResponder, kInitiator));
+ EXPECT_EQ(0U, responder->sent_stanza_count());
+
+ EXPECT_EQ(1U, responder->session_created_count);
+ EXPECT_EQ(kSessionId, responder->session->id());
+ EXPECT_EQ(responder->session->local_name(), kResponder);
+ EXPECT_EQ(responder->session->remote_name(), kInitiator);
+ EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDINITIATE,
+ responder->session_state());
+
+ EXPECT_TRUE(responder->HasTransport(content_name));
+ EXPECT_TRUE(responder->HasChannel(content_name, 1));
+ EXPECT_TRUE(responder->HasTransport(content_name));
+ EXPECT_TRUE(responder->HasChannel(content_name, 2));
+
+ // Expect transport-info message from initiator.
+ // But don't send candidates until initiate ack is received.
+ initiator->DeliverAckToLastStanza();
+ initiator->PrepareCandidates();
+ EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
+ initiator->ExpectSentStanza(
+ IqSet("1", kInitiator, kResponder,
+ TransportInfo4Xml(protocol, content_name,
+ channel_name_a, 0, 1,
+ channel_name_b, 2, 3)));
+
+ responder->PrepareCandidates();
+ EXPECT_TRUE_WAIT(responder->sent_stanza_count() > 0, kEventTimeout);
+ responder->ExpectSentStanza(
+ IqSet("2", kResponder, kInitiator,
+ TransportInfo4Xml(protocol, content_name,
+ channel_name_a, 4, 5,
+ channel_name_b, 6, 7)));
+
+ // Accept the session and expect accept stanza.
+ cricket::SessionDescription* answer = NewTestSessionDescription(
+ content_name, content_type);
+ EXPECT_TRUE(responder->session->Accept(answer));
+
+ responder->ExpectSentStanza(
+ IqSet("3", kResponder, kInitiator,
+ AcceptXml(protocol, content_name, content_type)));
+ EXPECT_EQ(0U, responder->sent_stanza_count());
+
+ // Fake the delivery the accept and candidates together.
+ initiator->DeliverStanza(
+ IqSet("B", kResponder, kInitiator,
+ JingleActionXml("session-accept",
+ JingleContentXml(
+ content_name, content_type, kTransportType,
+ P2pCandidateXml(channel_name_a, 4) +
+ P2pCandidateXml(channel_name_a, 5) +
+ P2pCandidateXml(channel_name_b, 6) +
+ P2pCandidateXml(channel_name_b, 7)))));
+ EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
+ initiator->ExpectSentStanza(
+ IqAck("B", kInitiator, kResponder));
+ EXPECT_EQ(0U, initiator->sent_stanza_count());
+
+ // The channels should be able to become writable at this point. This
+ // requires pinging, so it may take a little while.
+ EXPECT_TRUE_WAIT(initiator->chan_a->writable() &&
+ initiator->chan_a->readable(), kEventTimeout);
+ EXPECT_TRUE_WAIT(initiator->chan_b->writable() &&
+ initiator->chan_b->readable(), kEventTimeout);
+ EXPECT_TRUE_WAIT(responder->chan_a->writable() &&
+ responder->chan_a->readable(), kEventTimeout);
+ EXPECT_TRUE_WAIT(responder->chan_b->writable() &&
+ responder->chan_b->readable(), kEventTimeout);
+
+
+ // Both sessions should be in progress and have functioning
+ // channels.
+ EXPECT_EQ(protocol, initiator->session->current_protocol());
+ EXPECT_EQ(protocol, responder->session->current_protocol());
+ EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS,
+ initiator->session_state(), kEventTimeout);
+ EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS,
+ responder->session_state(), kEventTimeout);
+ TestSendRecv(initiator->chan_a.get(), initiator->chan_b.get(),
+ responder->chan_a.get(), responder->chan_b.get());
+ }
+
+ // Tests that when an initiator terminates right after initiate,
+ // everything behaves correctly.
+ void TestEarlyTerminationFromInitiator(SignalingProtocol protocol) {
+ std::string content_name = "main";
+ std::string content_type = "http://oink.splat/session";
+
+ rtc::scoped_ptr<cricket::PortAllocator> allocator(
+ new TestPortAllocator());
+ int next_message_id = 0;
+
+ rtc::scoped_ptr<TestClient> initiator(
+ new TestClient(allocator.get(), &next_message_id,
+ kInitiator, protocol,
+ content_type,
+ content_name, "a",
+ content_name, "b"));
+
+ rtc::scoped_ptr<TestClient> responder(
+ new TestClient(allocator.get(), &next_message_id,
+ kResponder, protocol,
+ content_type,
+ content_name, "a",
+ content_name, "b"));
+
+ // Send initiate
+ initiator->CreateSession();
+ EXPECT_TRUE(initiator->session->Initiate(
+ kResponder, NewTestSessionDescription(content_name, content_type)));
+ initiator->ExpectSentStanza(
+ IqSet("0", kInitiator, kResponder,
+ InitiateXml(protocol, content_name, content_type)));
+ EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE,
+ initiator->session_state());
+
+ responder->DeliverStanza(initiator->stanza());
+ responder->ExpectSentStanza(
+ IqAck("0", kResponder, kInitiator));
+ EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDINITIATE,
+ responder->session_state());
+
+ initiator->session->TerminateWithReason(cricket::STR_TERMINATE_ERROR);
+ initiator->ExpectSentStanza(
+ IqSet("1", kInitiator, kResponder,
+ TerminateXml(protocol, cricket::STR_TERMINATE_ERROR)));
+ EXPECT_EQ(cricket::BaseSession::STATE_SENTTERMINATE,
+ initiator->session_state());
+
+ responder->DeliverStanza(initiator->stanza());
+ responder->ExpectSentStanza(
+ IqAck("1", kResponder, kInitiator));
+ EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDTERMINATE,
+ responder->session_state());
+ }
+
+ // Tests that when the responder rejects, everything behaves
+ // correctly.
+ void TestRejection(SignalingProtocol protocol) {
+ std::string content_name = "main";
+ std::string content_type = "http://oink.splat/session";
+
+ rtc::scoped_ptr<cricket::PortAllocator> allocator(
+ new TestPortAllocator());
+ int next_message_id = 0;
+
+ rtc::scoped_ptr<TestClient> initiator(
+ new TestClient(allocator.get(), &next_message_id,
+ kInitiator, protocol,
+ content_type,
+ content_name, "a",
+ content_name, "b"));
+
+ // Send initiate
+ initiator->CreateSession();
+ EXPECT_TRUE(initiator->session->Initiate(
+ kResponder, NewTestSessionDescription(content_name, content_type)));
+ initiator->ExpectSentStanza(
+ IqSet("0", kInitiator, kResponder,
+ InitiateXml(protocol, content_name, content_type)));
+ EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE,
+ initiator->session_state());
+
+ initiator->DeliverStanza(
+ IqSet("1", kResponder, kInitiator,
+ RejectXml(protocol, cricket::STR_TERMINATE_ERROR)));
+ initiator->ExpectSentStanza(
+ IqAck("1", kInitiator, kResponder));
+ if (protocol == PROTOCOL_JINGLE) {
+ EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDTERMINATE,
+ initiator->session_state());
+ } else {
+ EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDREJECT,
+ initiator->session_state());
+ }
+ }
+
+ void TestTransportMux() {
+ SignalingProtocol initiator_protocol = PROTOCOL_JINGLE;
+ SignalingProtocol responder_protocol = PROTOCOL_JINGLE;
+ SignalingProtocol resulting_protocol = PROTOCOL_JINGLE;
+ std::string content_type = cricket::NS_JINGLE_RTP;
+ std::string gingle_content_type = cricket::NS_GINGLE_VIDEO;
+ std::string content_name_a = cricket::CN_AUDIO;
+ std::string channel_name_a = "rtp";
+ std::string content_name_b = cricket::CN_VIDEO;
+ std::string channel_name_b = "video_rtp";
+
+ std::string initiate_xml = InitiateXml(
+ initiator_protocol,
+ gingle_content_type,
+ content_name_a, content_type,
+ content_name_b, content_type, true);
+ std::string transport_info_a_xml = TransportInfo2Xml(
+ initiator_protocol, content_name_a,
+ channel_name_a, 0, 1);
+ std::string transport_info_b_xml = TransportInfo2Xml(
+ initiator_protocol, content_name_b,
+ channel_name_b, 2, 3);
+ std::string transport_info_reply_a_xml = TransportInfo2Xml(
+ resulting_protocol, content_name_a,
+ channel_name_a, 4, 5);
+ std::string transport_info_reply_b_xml = TransportInfo2Xml(
+ resulting_protocol, content_name_b,
+ channel_name_b, 6, 7);
+ std::string accept_xml = AcceptXml(
+ resulting_protocol,
+ gingle_content_type,
+ content_name_a, content_type,
+ content_name_b, content_type, true);
+
+ TestSession(initiator_protocol, responder_protocol, resulting_protocol,
+ gingle_content_type,
+ content_type,
+ content_name_a, channel_name_a,
+ content_name_b, channel_name_b,
+ initiate_xml,
+ transport_info_a_xml, transport_info_b_xml,
+ transport_info_reply_a_xml, transport_info_reply_b_xml,
+ accept_xml,
+ true);
+ }
+
+ void TestSendDescriptionInfo() {
+ rtc::scoped_ptr<cricket::PortAllocator> allocator(
+ new TestPortAllocator());
+ int next_message_id = 0;
+
+ std::string content_name = "content-name";
+ std::string content_type = "content-type";
+ rtc::scoped_ptr<TestClient> initiator(
+ new TestClient(allocator.get(), &next_message_id,
+ kInitiator, PROTOCOL_JINGLE,
+ content_type,
+ content_name, "",
+ "", ""));
+
+ initiator->CreateSession();
+ cricket::SessionDescription* offer = NewTestSessionDescription(
+ content_name, content_type);
+ std::string initiate_xml = InitiateXml(
+ PROTOCOL_JINGLE, content_name, content_type);
+
+ cricket::ContentInfos contents;
+ TestContentDescription content(content_type, content_type);
+ contents.push_back(
+ cricket::ContentInfo(content_name, content_type, &content));
+ std::string description_info_xml = JingleDescriptionInfoXml(
+ content_name, content_type);
+
+ EXPECT_TRUE(initiator->session->Initiate(kResponder, offer));
+ initiator->ExpectSentStanza(
+ IqSet("0", kInitiator, kResponder, initiate_xml));
+
+ EXPECT_TRUE(initiator->session->SendDescriptionInfoMessage(contents));
+ initiator->ExpectSentStanza(
+ IqSet("1", kInitiator, kResponder, description_info_xml));
+ }
+
+ void DoTestSignalNewDescription(
+ TestClient* client,
+ cricket::BaseSession::State state,
+ cricket::ContentAction expected_content_action,
+ cricket::ContentSource expected_content_source) {
+ // Clean up before the new test.
+ client->new_local_description = false;
+ client->new_remote_description = false;
+
+ client->SetSessionState(state);
+ EXPECT_EQ((expected_content_source == cricket::CS_LOCAL),
+ client->new_local_description);
+ EXPECT_EQ((expected_content_source == cricket::CS_REMOTE),
+ client->new_remote_description);
+ EXPECT_EQ(expected_content_action, client->last_content_action);
+ EXPECT_EQ(expected_content_source, client->last_content_source);
+ }
+
+ void TestCallerSignalNewDescription() {
+ rtc::scoped_ptr<cricket::PortAllocator> allocator(
+ new TestPortAllocator());
+ int next_message_id = 0;
+
+ std::string content_name = "content-name";
+ std::string content_type = "content-type";
+ rtc::scoped_ptr<TestClient> initiator(
+ new TestClient(allocator.get(), &next_message_id,
+ kInitiator, PROTOCOL_JINGLE,
+ content_type,
+ content_name, "",
+ "", ""));
+
+ initiator->CreateSession();
+
+ // send offer -> send update offer ->
+ // receive pr answer -> receive update pr answer ->
+ // receive answer
+ DoTestSignalNewDescription(
+ initiator.get(), cricket::BaseSession::STATE_SENTINITIATE,
+ cricket::CA_OFFER, cricket::CS_LOCAL);
+
+ DoTestSignalNewDescription(
+ initiator.get(), cricket::BaseSession::STATE_SENTINITIATE,
+ cricket::CA_OFFER, cricket::CS_LOCAL);
+
+ DoTestSignalNewDescription(
+ initiator.get(), cricket::BaseSession::STATE_RECEIVEDPRACCEPT,
+ cricket::CA_PRANSWER, cricket::CS_REMOTE);
+
+ DoTestSignalNewDescription(
+ initiator.get(), cricket::BaseSession::STATE_RECEIVEDPRACCEPT,
+ cricket::CA_PRANSWER, cricket::CS_REMOTE);
+
+ DoTestSignalNewDescription(
+ initiator.get(), cricket::BaseSession::STATE_RECEIVEDACCEPT,
+ cricket::CA_ANSWER, cricket::CS_REMOTE);
+ }
+
+ void TestCalleeSignalNewDescription() {
+ rtc::scoped_ptr<cricket::PortAllocator> allocator(
+ new TestPortAllocator());
+ int next_message_id = 0;
+
+ std::string content_name = "content-name";
+ std::string content_type = "content-type";
+ rtc::scoped_ptr<TestClient> initiator(
+ new TestClient(allocator.get(), &next_message_id,
+ kInitiator, PROTOCOL_JINGLE,
+ content_type,
+ content_name, "",
+ "", ""));
+
+ initiator->CreateSession();
+
+ // receive offer -> receive update offer ->
+ // send pr answer -> send update pr answer ->
+ // send answer
+ DoTestSignalNewDescription(
+ initiator.get(), cricket::BaseSession::STATE_RECEIVEDINITIATE,
+ cricket::CA_OFFER, cricket::CS_REMOTE);
+
+ DoTestSignalNewDescription(
+ initiator.get(), cricket::BaseSession::STATE_RECEIVEDINITIATE,
+ cricket::CA_OFFER, cricket::CS_REMOTE);
+
+ DoTestSignalNewDescription(
+ initiator.get(), cricket::BaseSession::STATE_SENTPRACCEPT,
+ cricket::CA_PRANSWER, cricket::CS_LOCAL);
+
+ DoTestSignalNewDescription(
+ initiator.get(), cricket::BaseSession::STATE_SENTPRACCEPT,
+ cricket::CA_PRANSWER, cricket::CS_LOCAL);
+
+ DoTestSignalNewDescription(
+ initiator.get(), cricket::BaseSession::STATE_SENTACCEPT,
+ cricket::CA_ANSWER, cricket::CS_LOCAL);
+ }
+
+ void TestGetTransportStats() {
+ rtc::scoped_ptr<cricket::PortAllocator> allocator(
+ new TestPortAllocator());
+ int next_message_id = 0;
+
+ std::string content_name = "content-name";
+ std::string content_type = "content-type";
+ rtc::scoped_ptr<TestClient> initiator(
+ new TestClient(allocator.get(), &next_message_id,
+ kInitiator, PROTOCOL_JINGLE,
+ content_type,
+ content_name, "",
+ "", ""));
+ initiator->CreateSession();
+
+ cricket::SessionStats stats;
+ EXPECT_TRUE(initiator->session->GetStats(&stats));
+ // At initiation, there are 2 transports.
+ EXPECT_EQ(2ul, stats.proxy_to_transport.size());
+ EXPECT_EQ(2ul, stats.transport_stats.size());
+ }
+};
+
+// For each of these, "X => Y = Z" means "if a client with protocol X
+// initiates to a client with protocol Y, they end up speaking protocol Z.
+
+// Gingle => Gingle = Gingle (with other content)
+TEST_F(SessionTest, GingleToGingleOtherContent) {
+ TestOtherContent(PROTOCOL_GINGLE, PROTOCOL_GINGLE, PROTOCOL_GINGLE);
+}
+
+// Gingle => Gingle = Gingle (with audio content)
+TEST_F(SessionTest, GingleToGingleAudioContent) {
+ TestAudioContent(PROTOCOL_GINGLE, PROTOCOL_GINGLE, PROTOCOL_GINGLE);
+}
+
+// Gingle => Gingle = Gingle (with video contents)
+TEST_F(SessionTest, GingleToGingleVideoContents) {
+ TestVideoContents(PROTOCOL_GINGLE, PROTOCOL_GINGLE, PROTOCOL_GINGLE);
+}
+
+// Jingle => Jingle = Jingle (with other content)
+TEST_F(SessionTest, JingleToJingleOtherContent) {
+ TestOtherContent(PROTOCOL_JINGLE, PROTOCOL_JINGLE, PROTOCOL_JINGLE);
+}
+
+// Jingle => Jingle = Jingle (with audio content)
+TEST_F(SessionTest, JingleToJingleAudioContent) {
+ TestAudioContent(PROTOCOL_JINGLE, PROTOCOL_JINGLE, PROTOCOL_JINGLE);
+}
+
+// Jingle => Jingle = Jingle (with video contents)
+TEST_F(SessionTest, JingleToJingleVideoContents) {
+ TestVideoContents(PROTOCOL_JINGLE, PROTOCOL_JINGLE, PROTOCOL_JINGLE);
+}
+
+// Hybrid => Hybrid = Jingle (with other content)
+TEST_F(SessionTest, HybridToHybridOtherContent) {
+ TestOtherContent(PROTOCOL_HYBRID, PROTOCOL_HYBRID, PROTOCOL_JINGLE);
+}
+
+// Hybrid => Hybrid = Jingle (with audio content)
+TEST_F(SessionTest, HybridToHybridAudioContent) {
+ TestAudioContent(PROTOCOL_HYBRID, PROTOCOL_HYBRID, PROTOCOL_JINGLE);
+}
+
+// Hybrid => Hybrid = Jingle (with video contents)
+TEST_F(SessionTest, HybridToHybridVideoContents) {
+ TestVideoContents(PROTOCOL_HYBRID, PROTOCOL_HYBRID, PROTOCOL_JINGLE);
+}
+
+// Gingle => Hybrid = Gingle (with other content)
+TEST_F(SessionTest, GingleToHybridOtherContent) {
+ TestOtherContent(PROTOCOL_GINGLE, PROTOCOL_HYBRID, PROTOCOL_GINGLE);
+}
+
+// Gingle => Hybrid = Gingle (with audio content)
+TEST_F(SessionTest, GingleToHybridAudioContent) {
+ TestAudioContent(PROTOCOL_GINGLE, PROTOCOL_HYBRID, PROTOCOL_GINGLE);
+}
+
+// Gingle => Hybrid = Gingle (with video contents)
+TEST_F(SessionTest, GingleToHybridVideoContents) {
+ TestVideoContents(PROTOCOL_GINGLE, PROTOCOL_HYBRID, PROTOCOL_GINGLE);
+}
+
+// Jingle => Hybrid = Jingle (with other content)
+TEST_F(SessionTest, JingleToHybridOtherContent) {
+ TestOtherContent(PROTOCOL_JINGLE, PROTOCOL_HYBRID, PROTOCOL_JINGLE);
+}
+
+// Jingle => Hybrid = Jingle (with audio content)
+TEST_F(SessionTest, JingleToHybridAudioContent) {
+ TestAudioContent(PROTOCOL_JINGLE, PROTOCOL_HYBRID, PROTOCOL_JINGLE);
+}
+
+// Jingle => Hybrid = Jingle (with video contents)
+TEST_F(SessionTest, JingleToHybridVideoContents) {
+ TestVideoContents(PROTOCOL_JINGLE, PROTOCOL_HYBRID, PROTOCOL_JINGLE);
+}
+
+// Hybrid => Gingle = Gingle (with other content)
+TEST_F(SessionTest, HybridToGingleOtherContent) {
+ TestOtherContent(PROTOCOL_HYBRID, PROTOCOL_GINGLE, PROTOCOL_GINGLE);
+}
+
+// Hybrid => Gingle = Gingle (with audio content)
+TEST_F(SessionTest, HybridToGingleAudioContent) {
+ TestAudioContent(PROTOCOL_HYBRID, PROTOCOL_GINGLE, PROTOCOL_GINGLE);
+}
+
+// Hybrid => Gingle = Gingle (with video contents)
+TEST_F(SessionTest, HybridToGingleVideoContents) {
+ TestVideoContents(PROTOCOL_HYBRID, PROTOCOL_GINGLE, PROTOCOL_GINGLE);
+}
+
+// Hybrid => Jingle = Jingle (with other content)
+TEST_F(SessionTest, HybridToJingleOtherContent) {
+ TestOtherContent(PROTOCOL_HYBRID, PROTOCOL_JINGLE, PROTOCOL_JINGLE);
+}
+
+// Hybrid => Jingle = Jingle (with audio content)
+TEST_F(SessionTest, HybridToJingleAudioContent) {
+ TestAudioContent(PROTOCOL_HYBRID, PROTOCOL_JINGLE, PROTOCOL_JINGLE);
+}
+
+// Hybrid => Jingle = Jingle (with video contents)
+TEST_F(SessionTest, HybridToJingleVideoContents) {
+ TestVideoContents(PROTOCOL_HYBRID, PROTOCOL_JINGLE, PROTOCOL_JINGLE);
+}
+
+TEST_F(SessionTest, GingleEarlyTerminationFromInitiator) {
+ TestEarlyTerminationFromInitiator(PROTOCOL_GINGLE);
+}
+
+TEST_F(SessionTest, JingleEarlyTerminationFromInitiator) {
+ TestEarlyTerminationFromInitiator(PROTOCOL_JINGLE);
+}
+
+TEST_F(SessionTest, HybridEarlyTerminationFromInitiator) {
+ TestEarlyTerminationFromInitiator(PROTOCOL_HYBRID);
+}
+
+TEST_F(SessionTest, GingleRejection) {
+ TestRejection(PROTOCOL_GINGLE);
+}
+
+TEST_F(SessionTest, JingleRejection) {
+ TestRejection(PROTOCOL_JINGLE);
+}
+
+TEST_F(SessionTest, GingleGoodRedirect) {
+ TestGoodRedirect(PROTOCOL_GINGLE);
+}
+
+TEST_F(SessionTest, JingleGoodRedirect) {
+ TestGoodRedirect(PROTOCOL_JINGLE);
+}
+
+TEST_F(SessionTest, GingleBadRedirect) {
+ TestBadRedirect(PROTOCOL_GINGLE);
+}
+
+TEST_F(SessionTest, JingleBadRedirect) {
+ TestBadRedirect(PROTOCOL_JINGLE);
+}
+
+TEST_F(SessionTest, TestCandidatesInInitiateAndAccept) {
+ TestCandidatesInInitiateAndAccept("Candidates in initiate/accept");
+}
+
+TEST_F(SessionTest, TestTransportMux) {
+ TestTransportMux();
+}
+
+TEST_F(SessionTest, TestSendDescriptionInfo) {
+ TestSendDescriptionInfo();
+}
+
+TEST_F(SessionTest, TestCallerSignalNewDescription) {
+ TestCallerSignalNewDescription();
+}
+
+TEST_F(SessionTest, TestCalleeSignalNewDescription) {
+ TestCalleeSignalNewDescription();
+}
+
+TEST_F(SessionTest, TestGetTransportStats) {
+ TestGetTransportStats();
+}
diff --git a/p2p/base/sessionclient.h b/p2p/base/sessionclient.h
new file mode 100644
index 00000000..89687885
--- /dev/null
+++ b/p2p/base/sessionclient.h
@@ -0,0 +1,78 @@
+/*
+ * 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 WEBRTC_P2P_BASE_SESSIONCLIENT_H_
+#define WEBRTC_P2P_BASE_SESSIONCLIENT_H_
+
+#include "webrtc/p2p/base/constants.h"
+
+namespace buzz {
+class XmlElement;
+}
+
+namespace cricket {
+
+struct ParseError;
+class Session;
+class ContentDescription;
+
+class ContentParser {
+ public:
+ virtual bool ParseContent(SignalingProtocol protocol,
+ const buzz::XmlElement* elem,
+ ContentDescription** content,
+ ParseError* error) = 0;
+ // If not IsWriteable, then a given content should be "skipped" when
+ // writing in the given protocol, as if it didn't exist. We assume
+ // most things are writeable. We do this to avoid strange cases
+ // like data contents in Gingle, which aren't writable.
+ virtual bool IsWritable(SignalingProtocol protocol,
+ const ContentDescription* content) {
+ return true;
+ }
+ virtual bool WriteContent(SignalingProtocol protocol,
+ const ContentDescription* content,
+ buzz::XmlElement** elem,
+ WriteError* error) = 0;
+ virtual ~ContentParser() {}
+};
+
+// A SessionClient exists in 1-1 relation with each session. The implementor
+// of this interface is the one that understands *what* the two sides are
+// trying to send to one another. The lower-level layers only know how to send
+// data; they do not know what is being sent.
+class SessionClient : public ContentParser {
+ public:
+ // Notifies the client of the creation / destruction of sessions of this type.
+ //
+ // IMPORTANT: The SessionClient, in its handling of OnSessionCreate, must
+ // create whatever channels are indicate in the description. This is because
+ // the remote client may already be attempting to connect those channels. If
+ // we do not create our channel right away, then connection may fail or be
+ // delayed.
+ virtual void OnSessionCreate(Session* session, bool received_initiate) = 0;
+ virtual void OnSessionDestroy(Session* session) = 0;
+
+ virtual bool ParseContent(SignalingProtocol protocol,
+ const buzz::XmlElement* elem,
+ ContentDescription** content,
+ ParseError* error) = 0;
+ virtual bool WriteContent(SignalingProtocol protocol,
+ const ContentDescription* content,
+ buzz::XmlElement** elem,
+ WriteError* error) = 0;
+ protected:
+ // The SessionClient interface explicitly does not include destructor
+ virtual ~SessionClient() { }
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_SESSIONCLIENT_H_
diff --git a/p2p/base/sessiondescription.cc b/p2p/base/sessiondescription.cc
new file mode 100644
index 00000000..b05dc510
--- /dev/null
+++ b/p2p/base/sessiondescription.cc
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2010 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can 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 "webrtc/p2p/base/sessiondescription.h"
+
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+
+namespace cricket {
+
+ContentInfo* FindContentInfoByName(
+ ContentInfos& contents, const std::string& name) {
+ for (ContentInfos::iterator content = contents.begin();
+ content != contents.end(); ++content) {
+ if (content->name == name) {
+ return &(*content);
+ }
+ }
+ return NULL;
+}
+
+const ContentInfo* FindContentInfoByName(
+ const ContentInfos& contents, const std::string& name) {
+ for (ContentInfos::const_iterator content = contents.begin();
+ content != contents.end(); ++content) {
+ if (content->name == name) {
+ return &(*content);
+ }
+ }
+ return NULL;
+}
+
+const ContentInfo* FindContentInfoByType(
+ const ContentInfos& contents, const std::string& type) {
+ for (ContentInfos::const_iterator content = contents.begin();
+ content != contents.end(); ++content) {
+ if (content->type == type) {
+ return &(*content);
+ }
+ }
+ return NULL;
+}
+
+const std::string* ContentGroup::FirstContentName() const {
+ return (!content_names_.empty()) ? &(*content_names_.begin()) : NULL;
+}
+
+bool ContentGroup::HasContentName(const std::string& content_name) const {
+ return (std::find(content_names_.begin(), content_names_.end(),
+ content_name) != content_names_.end());
+}
+
+void ContentGroup::AddContentName(const std::string& content_name) {
+ if (!HasContentName(content_name)) {
+ content_names_.push_back(content_name);
+ }
+}
+
+bool ContentGroup::RemoveContentName(const std::string& content_name) {
+ ContentNames::iterator iter = std::find(
+ content_names_.begin(), content_names_.end(), content_name);
+ if (iter == content_names_.end()) {
+ return false;
+ }
+ content_names_.erase(iter);
+ return true;
+}
+
+SessionDescription* SessionDescription::Copy() const {
+ SessionDescription* copy = new SessionDescription(*this);
+ // Copy all ContentDescriptions.
+ for (ContentInfos::iterator content = copy->contents_.begin();
+ content != copy->contents().end(); ++content) {
+ content->description = content->description->Copy();
+ }
+ return copy;
+}
+
+const ContentInfo* SessionDescription::GetContentByName(
+ const std::string& name) const {
+ return FindContentInfoByName(contents_, name);
+}
+
+ContentInfo* SessionDescription::GetContentByName(
+ const std::string& name) {
+ return FindContentInfoByName(contents_, name);
+}
+
+const ContentDescription* SessionDescription::GetContentDescriptionByName(
+ const std::string& name) const {
+ const ContentInfo* cinfo = FindContentInfoByName(contents_, name);
+ if (cinfo == NULL) {
+ return NULL;
+ }
+
+ return cinfo->description;
+}
+
+ContentDescription* SessionDescription::GetContentDescriptionByName(
+ const std::string& name) {
+ ContentInfo* cinfo = FindContentInfoByName(contents_, name);
+ if (cinfo == NULL) {
+ return NULL;
+ }
+
+ return cinfo->description;
+}
+
+const ContentInfo* SessionDescription::FirstContentByType(
+ const std::string& type) const {
+ return FindContentInfoByType(contents_, type);
+}
+
+const ContentInfo* SessionDescription::FirstContent() const {
+ return (contents_.empty()) ? NULL : &(*contents_.begin());
+}
+
+void SessionDescription::AddContent(const std::string& name,
+ const std::string& type,
+ ContentDescription* description) {
+ contents_.push_back(ContentInfo(name, type, description));
+}
+
+void SessionDescription::AddContent(const std::string& name,
+ const std::string& type,
+ bool rejected,
+ ContentDescription* description) {
+ contents_.push_back(ContentInfo(name, type, rejected, description));
+}
+
+bool SessionDescription::RemoveContentByName(const std::string& name) {
+ for (ContentInfos::iterator content = contents_.begin();
+ content != contents_.end(); ++content) {
+ if (content->name == name) {
+ delete content->description;
+ contents_.erase(content);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool SessionDescription::AddTransportInfo(const TransportInfo& transport_info) {
+ if (GetTransportInfoByName(transport_info.content_name) != NULL) {
+ return false;
+ }
+ transport_infos_.push_back(transport_info);
+ return true;
+}
+
+bool SessionDescription::RemoveTransportInfoByName(const std::string& name) {
+ for (TransportInfos::iterator transport_info = transport_infos_.begin();
+ transport_info != transport_infos_.end(); ++transport_info) {
+ if (transport_info->content_name == name) {
+ transport_infos_.erase(transport_info);
+ return true;
+ }
+ }
+ return false;
+}
+
+const TransportInfo* SessionDescription::GetTransportInfoByName(
+ const std::string& name) const {
+ for (TransportInfos::const_iterator iter = transport_infos_.begin();
+ iter != transport_infos_.end(); ++iter) {
+ if (iter->content_name == name) {
+ return &(*iter);
+ }
+ }
+ return NULL;
+}
+
+TransportInfo* SessionDescription::GetTransportInfoByName(
+ const std::string& name) {
+ for (TransportInfos::iterator iter = transport_infos_.begin();
+ iter != transport_infos_.end(); ++iter) {
+ if (iter->content_name == name) {
+ return &(*iter);
+ }
+ }
+ return NULL;
+}
+
+void SessionDescription::RemoveGroupByName(const std::string& name) {
+ for (ContentGroups::iterator iter = content_groups_.begin();
+ iter != content_groups_.end(); ++iter) {
+ if (iter->semantics() == name) {
+ content_groups_.erase(iter);
+ break;
+ }
+ }
+}
+
+bool SessionDescription::HasGroup(const std::string& name) const {
+ for (ContentGroups::const_iterator iter = content_groups_.begin();
+ iter != content_groups_.end(); ++iter) {
+ if (iter->semantics() == name) {
+ return true;
+ }
+ }
+ return false;
+}
+
+const ContentGroup* SessionDescription::GetGroupByName(
+ const std::string& name) const {
+ for (ContentGroups::const_iterator iter = content_groups_.begin();
+ iter != content_groups_.end(); ++iter) {
+ if (iter->semantics() == name) {
+ return &(*iter);
+ }
+ }
+ return NULL;
+}
+
+} // namespace cricket
diff --git a/p2p/base/sessiondescription.h b/p2p/base/sessiondescription.h
new file mode 100644
index 00000000..1182a677
--- /dev/null
+++ b/p2p/base/sessiondescription.h
@@ -0,0 +1,185 @@
+/*
+ * 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 WEBRTC_P2P_BASE_SESSIONDESCRIPTION_H_
+#define WEBRTC_P2P_BASE_SESSIONDESCRIPTION_H_
+
+#include <string>
+#include <vector>
+
+#include "webrtc/p2p/base/transportinfo.h"
+#include "webrtc/base/constructormagic.h"
+
+namespace cricket {
+
+// Describes a session content. Individual content types inherit from
+// this class. Analagous to a <jingle><content><description> or
+// <session><description>.
+class ContentDescription {
+ public:
+ virtual ~ContentDescription() {}
+ virtual ContentDescription* Copy() const = 0;
+};
+
+// Analagous to a <jingle><content> or <session><description>.
+// name = name of <content name="...">
+// type = xmlns of <content>
+struct ContentInfo {
+ ContentInfo() : description(NULL) {}
+ ContentInfo(const std::string& name,
+ const std::string& type,
+ ContentDescription* description) :
+ name(name), type(type), rejected(false), description(description) {}
+ ContentInfo(const std::string& name,
+ const std::string& type,
+ bool rejected,
+ ContentDescription* description) :
+ name(name), type(type), rejected(rejected), description(description) {}
+ std::string name;
+ std::string type;
+ bool rejected;
+ ContentDescription* description;
+};
+
+typedef std::vector<std::string> ContentNames;
+
+// This class provides a mechanism to aggregate different media contents into a
+// group. This group can also be shared with the peers in a pre-defined format.
+// GroupInfo should be populated only with the |content_name| of the
+// MediaDescription.
+class ContentGroup {
+ public:
+ explicit ContentGroup(const std::string& semantics) :
+ semantics_(semantics) {}
+
+ const std::string& semantics() const { return semantics_; }
+ const ContentNames& content_names() const { return content_names_; }
+
+ const std::string* FirstContentName() const;
+ bool HasContentName(const std::string& content_name) const;
+ void AddContentName(const std::string& content_name);
+ bool RemoveContentName(const std::string& content_name);
+
+ private:
+ std::string semantics_;
+ ContentNames content_names_;
+};
+
+typedef std::vector<ContentInfo> ContentInfos;
+typedef std::vector<ContentGroup> ContentGroups;
+
+const ContentInfo* FindContentInfoByName(
+ const ContentInfos& contents, const std::string& name);
+const ContentInfo* FindContentInfoByType(
+ const ContentInfos& contents, const std::string& type);
+
+// Describes a collection of contents, each with its own name and
+// type. Analogous to a <jingle> or <session> stanza. Assumes that
+// contents are unique be name, but doesn't enforce that.
+class SessionDescription {
+ public:
+ SessionDescription() {}
+ explicit SessionDescription(const ContentInfos& contents) :
+ contents_(contents) {}
+ SessionDescription(const ContentInfos& contents,
+ const ContentGroups& groups) :
+ contents_(contents),
+ content_groups_(groups) {}
+ SessionDescription(const ContentInfos& contents,
+ const TransportInfos& transports,
+ const ContentGroups& groups) :
+ contents_(contents),
+ transport_infos_(transports),
+ content_groups_(groups) {}
+ ~SessionDescription() {
+ for (ContentInfos::iterator content = contents_.begin();
+ content != contents_.end(); ++content) {
+ delete content->description;
+ }
+ }
+
+ SessionDescription* Copy() const;
+
+ // Content accessors.
+ const ContentInfos& contents() const { return contents_; }
+ ContentInfos& contents() { return contents_; }
+ const ContentInfo* GetContentByName(const std::string& name) const;
+ ContentInfo* GetContentByName(const std::string& name);
+ const ContentDescription* GetContentDescriptionByName(
+ const std::string& name) const;
+ ContentDescription* GetContentDescriptionByName(const std::string& name);
+ const ContentInfo* FirstContentByType(const std::string& type) const;
+ const ContentInfo* FirstContent() const;
+
+ // Content mutators.
+ // Adds a content to this description. Takes ownership of ContentDescription*.
+ void AddContent(const std::string& name,
+ const std::string& type,
+ ContentDescription* description);
+ void AddContent(const std::string& name,
+ const std::string& type,
+ bool rejected,
+ ContentDescription* description);
+ bool RemoveContentByName(const std::string& name);
+
+ // Transport accessors.
+ const TransportInfos& transport_infos() const { return transport_infos_; }
+ TransportInfos& transport_infos() { return transport_infos_; }
+ const TransportInfo* GetTransportInfoByName(
+ const std::string& name) const;
+ TransportInfo* GetTransportInfoByName(const std::string& name);
+ const TransportDescription* GetTransportDescriptionByName(
+ const std::string& name) const {
+ const TransportInfo* tinfo = GetTransportInfoByName(name);
+ return tinfo ? &tinfo->description : NULL;
+ }
+
+ // Transport mutators.
+ void set_transport_infos(const TransportInfos& transport_infos) {
+ transport_infos_ = transport_infos;
+ }
+ // Adds a TransportInfo to this description.
+ // Returns false if a TransportInfo with the same name already exists.
+ bool AddTransportInfo(const TransportInfo& transport_info);
+ bool RemoveTransportInfoByName(const std::string& name);
+
+ // Group accessors.
+ const ContentGroups& groups() const { return content_groups_; }
+ const ContentGroup* GetGroupByName(const std::string& name) const;
+ bool HasGroup(const std::string& name) const;
+
+ // Group mutators.
+ void AddGroup(const ContentGroup& group) { content_groups_.push_back(group); }
+ // Remove the first group with the same semantics specified by |name|.
+ void RemoveGroupByName(const std::string& name);
+
+ private:
+ ContentInfos contents_;
+ TransportInfos transport_infos_;
+ ContentGroups content_groups_;
+};
+
+// Indicates whether a ContentDescription was an offer or an answer, as
+// described in http://www.ietf.org/rfc/rfc3264.txt. CA_UPDATE
+// indicates a jingle update message which contains a subset of a full
+// session description
+enum ContentAction {
+ CA_OFFER, CA_PRANSWER, CA_ANSWER, CA_UPDATE
+};
+
+// Indicates whether a ContentDescription was sent by the local client
+// or received from the remote client.
+enum ContentSource {
+ CS_LOCAL, CS_REMOTE
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_SESSIONDESCRIPTION_H_
diff --git a/p2p/base/sessionid.h b/p2p/base/sessionid.h
new file mode 100644
index 00000000..f6957003
--- /dev/null
+++ b/p2p/base/sessionid.h
@@ -0,0 +1,20 @@
+/*
+ * 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 WEBRTC_P2P_BASE_SESSIONID_H_
+#define WEBRTC_P2P_BASE_SESSIONID_H_
+
+// TODO: Remove this file.
+
+namespace cricket {
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_SESSIONID_H_
diff --git a/p2p/base/sessionmanager.cc b/p2p/base/sessionmanager.cc
new file mode 100644
index 00000000..f375dea5
--- /dev/null
+++ b/p2p/base/sessionmanager.cc
@@ -0,0 +1,309 @@
+/*
+ * 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 "webrtc/p2p/base/sessionmanager.h"
+
+#include "webrtc/p2p/base/constants.h"
+#include "webrtc/p2p/base/session.h"
+#include "webrtc/p2p/base/sessionmessages.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/jid.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/stringencode.h"
+
+namespace cricket {
+
+SessionManager::SessionManager(PortAllocator *allocator,
+ rtc::Thread *worker) {
+ allocator_ = allocator;
+ signaling_thread_ = rtc::Thread::Current();
+ if (worker == NULL) {
+ worker_thread_ = rtc::Thread::Current();
+ } else {
+ worker_thread_ = worker;
+ }
+ timeout_ = 50;
+}
+
+SessionManager::~SessionManager() {
+ // Note: Session::Terminate occurs asynchronously, so it's too late to
+ // delete them now. They better be all gone.
+ ASSERT(session_map_.empty());
+ // TerminateAll();
+ SignalDestroyed();
+}
+
+void SessionManager::AddClient(const std::string& content_type,
+ SessionClient* client) {
+ ASSERT(client_map_.find(content_type) == client_map_.end());
+ client_map_[content_type] = client;
+}
+
+void SessionManager::RemoveClient(const std::string& content_type) {
+ ClientMap::iterator iter = client_map_.find(content_type);
+ ASSERT(iter != client_map_.end());
+ client_map_.erase(iter);
+}
+
+SessionClient* SessionManager::GetClient(const std::string& content_type) {
+ ClientMap::iterator iter = client_map_.find(content_type);
+ return (iter != client_map_.end()) ? iter->second : NULL;
+}
+
+Session* SessionManager::CreateSession(const std::string& local_name,
+ const std::string& content_type) {
+ std::string id;
+ return CreateSession(id, local_name, content_type);
+}
+
+Session* SessionManager::CreateSession(const std::string& id,
+ const std::string& local_name,
+ const std::string& content_type) {
+ std::string sid =
+ id.empty() ? rtc::ToString(rtc::CreateRandomId64()) : id;
+ return CreateSession(local_name, local_name, sid, content_type, false);
+}
+
+Session* SessionManager::CreateSession(
+ const std::string& local_name, const std::string& initiator_name,
+ const std::string& sid, const std::string& content_type,
+ bool received_initiate) {
+ SessionClient* client = GetClient(content_type);
+ ASSERT(client != NULL);
+
+ Session* session = new Session(this, local_name, initiator_name,
+ sid, content_type, client);
+ session->SetIdentity(transport_desc_factory_.identity());
+ session_map_[session->id()] = session;
+ session->SignalRequestSignaling.connect(
+ this, &SessionManager::OnRequestSignaling);
+ session->SignalOutgoingMessage.connect(
+ this, &SessionManager::OnOutgoingMessage);
+ session->SignalErrorMessage.connect(this, &SessionManager::OnErrorMessage);
+ SignalSessionCreate(session, received_initiate);
+ session->client()->OnSessionCreate(session, received_initiate);
+ return session;
+}
+
+void SessionManager::DestroySession(Session* session) {
+ if (session != NULL) {
+ SessionMap::iterator it = session_map_.find(session->id());
+ if (it != session_map_.end()) {
+ SignalSessionDestroy(session);
+ session->client()->OnSessionDestroy(session);
+ session_map_.erase(it);
+ delete session;
+ }
+ }
+}
+
+Session* SessionManager::GetSession(const std::string& sid) {
+ SessionMap::iterator it = session_map_.find(sid);
+ if (it != session_map_.end())
+ return it->second;
+ return NULL;
+}
+
+void SessionManager::TerminateAll() {
+ while (session_map_.begin() != session_map_.end()) {
+ Session* session = session_map_.begin()->second;
+ session->Terminate();
+ }
+}
+
+bool SessionManager::IsSessionMessage(const buzz::XmlElement* stanza) {
+ return cricket::IsSessionMessage(stanza);
+}
+
+Session* SessionManager::FindSession(const std::string& sid,
+ const std::string& remote_name) {
+ SessionMap::iterator iter = session_map_.find(sid);
+ if (iter == session_map_.end())
+ return NULL;
+
+ Session* session = iter->second;
+ if (buzz::Jid(remote_name) != buzz::Jid(session->remote_name()))
+ return NULL;
+
+ return session;
+}
+
+void SessionManager::OnIncomingMessage(const buzz::XmlElement* stanza) {
+ SessionMessage msg;
+ ParseError error;
+
+ if (!ParseSessionMessage(stanza, &msg, &error)) {
+ SendErrorMessage(stanza, buzz::QN_STANZA_BAD_REQUEST, "modify",
+ error.text, NULL);
+ return;
+ }
+
+ Session* session = FindSession(msg.sid, msg.from);
+ if (session) {
+ session->OnIncomingMessage(msg);
+ return;
+ }
+ if (msg.type != ACTION_SESSION_INITIATE) {
+ SendErrorMessage(stanza, buzz::QN_STANZA_BAD_REQUEST, "modify",
+ "unknown session", NULL);
+ return;
+ }
+
+ std::string content_type;
+ if (!ParseContentType(msg.protocol, msg.action_elem,
+ &content_type, &error)) {
+ SendErrorMessage(stanza, buzz::QN_STANZA_BAD_REQUEST, "modify",
+ error.text, NULL);
+ return;
+ }
+
+ if (!GetClient(content_type)) {
+ SendErrorMessage(stanza, buzz::QN_STANZA_BAD_REQUEST, "modify",
+ "unknown content type: " + content_type, NULL);
+ return;
+ }
+
+ session = CreateSession(msg.to, msg.initiator, msg.sid,
+ content_type, true);
+ session->OnIncomingMessage(msg);
+}
+
+void SessionManager::OnIncomingResponse(const buzz::XmlElement* orig_stanza,
+ const buzz::XmlElement* response_stanza) {
+ if (orig_stanza == NULL || response_stanza == NULL) {
+ return;
+ }
+
+ SessionMessage msg;
+ ParseError error;
+ if (!ParseSessionMessage(orig_stanza, &msg, &error)) {
+ LOG(LS_WARNING) << "Error parsing incoming response: " << error.text
+ << ":" << orig_stanza;
+ return;
+ }
+
+ Session* session = FindSession(msg.sid, msg.to);
+ if (!session) {
+ // Also try the QN_FROM in the response stanza, in case we sent the request
+ // to a bare JID but got the response from a full JID.
+ std::string ack_from = response_stanza->Attr(buzz::QN_FROM);
+ session = FindSession(msg.sid, ack_from);
+ }
+ if (session) {
+ session->OnIncomingResponse(orig_stanza, response_stanza, msg);
+ }
+}
+
+void SessionManager::OnFailedSend(const buzz::XmlElement* orig_stanza,
+ const buzz::XmlElement* error_stanza) {
+ SessionMessage msg;
+ ParseError error;
+ if (!ParseSessionMessage(orig_stanza, &msg, &error)) {
+ return; // TODO: log somewhere?
+ }
+
+ Session* session = FindSession(msg.sid, msg.to);
+ if (session) {
+ rtc::scoped_ptr<buzz::XmlElement> synthetic_error;
+ if (!error_stanza) {
+ // A failed send is semantically equivalent to an error response, so we
+ // can just turn the former into the latter.
+ synthetic_error.reset(
+ CreateErrorMessage(orig_stanza, buzz::QN_STANZA_ITEM_NOT_FOUND,
+ "cancel", "Recipient did not respond", NULL));
+ error_stanza = synthetic_error.get();
+ }
+
+ session->OnFailedSend(orig_stanza, error_stanza);
+ }
+}
+
+void SessionManager::SendErrorMessage(const buzz::XmlElement* stanza,
+ const buzz::QName& name,
+ const std::string& type,
+ const std::string& text,
+ const buzz::XmlElement* extra_info) {
+ rtc::scoped_ptr<buzz::XmlElement> msg(
+ CreateErrorMessage(stanza, name, type, text, extra_info));
+ SignalOutgoingMessage(this, msg.get());
+}
+
+buzz::XmlElement* SessionManager::CreateErrorMessage(
+ const buzz::XmlElement* stanza,
+ const buzz::QName& name,
+ const std::string& type,
+ const std::string& text,
+ const buzz::XmlElement* extra_info) {
+ buzz::XmlElement* iq = new buzz::XmlElement(buzz::QN_IQ);
+ iq->SetAttr(buzz::QN_TO, stanza->Attr(buzz::QN_FROM));
+ iq->SetAttr(buzz::QN_ID, stanza->Attr(buzz::QN_ID));
+ iq->SetAttr(buzz::QN_TYPE, "error");
+
+ CopyXmlChildren(stanza, iq);
+
+ buzz::XmlElement* error = new buzz::XmlElement(buzz::QN_ERROR);
+ error->SetAttr(buzz::QN_TYPE, type);
+ iq->AddElement(error);
+
+ // If the error name is not in the standard namespace, we have to first add
+ // some error from that namespace.
+ if (name.Namespace() != buzz::NS_STANZA) {
+ error->AddElement(
+ new buzz::XmlElement(buzz::QN_STANZA_UNDEFINED_CONDITION));
+ }
+ error->AddElement(new buzz::XmlElement(name));
+
+ if (extra_info)
+ error->AddElement(new buzz::XmlElement(*extra_info));
+
+ if (text.size() > 0) {
+ // It's okay to always use English here. This text is for debugging
+ // purposes only.
+ buzz::XmlElement* text_elem = new buzz::XmlElement(buzz::QN_STANZA_TEXT);
+ text_elem->SetAttr(buzz::QN_XML_LANG, "en");
+ text_elem->SetBodyText(text);
+ error->AddElement(text_elem);
+ }
+
+ // TODO: Should we include error codes as well for SIP compatibility?
+
+ return iq;
+}
+
+void SessionManager::OnOutgoingMessage(Session* session,
+ const buzz::XmlElement* stanza) {
+ SignalOutgoingMessage(this, stanza);
+}
+
+void SessionManager::OnErrorMessage(BaseSession* session,
+ const buzz::XmlElement* stanza,
+ const buzz::QName& name,
+ const std::string& type,
+ const std::string& text,
+ const buzz::XmlElement* extra_info) {
+ SendErrorMessage(stanza, name, type, text, extra_info);
+}
+
+void SessionManager::OnSignalingReady() {
+ for (SessionMap::iterator it = session_map_.begin();
+ it != session_map_.end();
+ ++it) {
+ it->second->OnSignalingReady();
+ }
+}
+
+void SessionManager::OnRequestSignaling(Session* session) {
+ SignalRequestSignaling();
+}
+
+} // namespace cricket
diff --git a/p2p/base/sessionmanager.h b/p2p/base/sessionmanager.h
new file mode 100644
index 00000000..74ee5c07
--- /dev/null
+++ b/p2p/base/sessionmanager.h
@@ -0,0 +1,194 @@
+/*
+ * 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 WEBRTC_P2P_BASE_SESSIONMANAGER_H_
+#define WEBRTC_P2P_BASE_SESSIONMANAGER_H_
+
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "webrtc/p2p/base/portallocator.h"
+#include "webrtc/p2p/base/transportdescriptionfactory.h"
+#include "webrtc/base/sigslot.h"
+#include "webrtc/base/thread.h"
+
+namespace buzz {
+class QName;
+class XmlElement;
+}
+
+namespace cricket {
+
+class Session;
+class BaseSession;
+class SessionClient;
+
+// SessionManager manages session instances.
+class SessionManager : public sigslot::has_slots<> {
+ public:
+ SessionManager(PortAllocator *allocator,
+ rtc::Thread *worker_thread = NULL);
+ virtual ~SessionManager();
+
+ PortAllocator *port_allocator() const { return allocator_; }
+ rtc::Thread *worker_thread() const { return worker_thread_; }
+ rtc::Thread *signaling_thread() const { return signaling_thread_; }
+
+ int session_timeout() const { return timeout_; }
+ void set_session_timeout(int timeout) { timeout_ = timeout; }
+
+ // Set what transport protocol we want to default to.
+ void set_transport_protocol(TransportProtocol proto) {
+ transport_desc_factory_.set_protocol(proto);
+ }
+
+ // Control use of DTLS. An identity must be supplied if DTLS is enabled.
+ void set_secure(SecurePolicy policy) {
+ transport_desc_factory_.set_secure(policy);
+ }
+ void set_identity(rtc::SSLIdentity* identity) {
+ transport_desc_factory_.set_identity(identity);
+ }
+ const TransportDescriptionFactory* transport_desc_factory() const {
+ return &transport_desc_factory_;
+ }
+
+ // Registers support for the given client. If we receive an initiate
+ // describing a session of the given type, we will automatically create a
+ // Session object and notify this client. The client may then accept or
+ // reject the session.
+ void AddClient(const std::string& content_type, SessionClient* client);
+ void RemoveClient(const std::string& content_type);
+ SessionClient* GetClient(const std::string& content_type);
+
+ // Creates a new session. The given name is the JID of the client on whose
+ // behalf we initiate the session.
+ Session *CreateSession(const std::string& local_name,
+ const std::string& content_type);
+
+ Session *CreateSession(const std::string& id,
+ const std::string& local_name,
+ const std::string& content_type);
+
+ // Destroys the given session.
+ void DestroySession(Session *session);
+
+ // Returns the session with the given ID or NULL if none exists.
+ Session *GetSession(const std::string& sid);
+
+ // Terminates all of the sessions created by this manager.
+ void TerminateAll();
+
+ // These are signaled whenever the set of existing sessions changes.
+ sigslot::signal2<Session *, bool> SignalSessionCreate;
+ sigslot::signal1<Session *> SignalSessionDestroy;
+
+ // Determines whether the given stanza is intended for some session.
+ bool IsSessionMessage(const buzz::XmlElement* stanza);
+
+ // Given a sid, initiator, and remote_name, this finds the matching Session
+ Session* FindSession(const std::string& sid,
+ const std::string& remote_name);
+
+ // Called when we receive a stanza for which IsSessionMessage is true.
+ void OnIncomingMessage(const buzz::XmlElement* stanza);
+
+ // Called when we get a response to a message that we sent.
+ void OnIncomingResponse(const buzz::XmlElement* orig_stanza,
+ const buzz::XmlElement* response_stanza);
+
+ // Called if an attempted to send times out or an error is returned. In the
+ // timeout case error_stanza will be NULL
+ void OnFailedSend(const buzz::XmlElement* orig_stanza,
+ const buzz::XmlElement* error_stanza);
+
+ // Signalled each time a session generates a signaling message to send.
+ // Also signalled on errors, but with a NULL session.
+ sigslot::signal2<SessionManager*,
+ const buzz::XmlElement*> SignalOutgoingMessage;
+
+ // Signaled before sessions try to send certain signaling messages. The
+ // client should call OnSignalingReady once it is safe to send them. These
+ // steps are taken so that we don't send signaling messages trying to
+ // re-establish the connectivity of a session when the client cannot send
+ // the messages (and would probably just drop them on the floor).
+ //
+ // Note: you can connect this directly to OnSignalingReady(), if a signalling
+ // check is not supported.
+ sigslot::signal0<> SignalRequestSignaling;
+ void OnSignalingReady();
+
+ // Signaled when this SessionManager is deleted.
+ sigslot::signal0<> SignalDestroyed;
+
+ private:
+ typedef std::map<std::string, Session*> SessionMap;
+ typedef std::map<std::string, SessionClient*> ClientMap;
+
+ // Helper function for CreateSession. This is also invoked when we receive
+ // a message attempting to initiate a session with this client.
+ Session *CreateSession(const std::string& local_name,
+ const std::string& initiator,
+ const std::string& sid,
+ const std::string& content_type,
+ bool received_initiate);
+
+ // Attempts to find a registered session type whose description appears as
+ // a child of the session element. Such a child should be present indicating
+ // the application they hope to initiate.
+ std::string FindClient(const buzz::XmlElement* session);
+
+ // Sends a message back to the other client indicating that we found an error
+ // in the stanza they sent. name identifies the error, type is one of the
+ // standard XMPP types (cancel, continue, modify, auth, wait), and text is a
+ // description for debugging purposes.
+ void SendErrorMessage(const buzz::XmlElement* stanza,
+ const buzz::QName& name,
+ const std::string& type,
+ const std::string& text,
+ const buzz::XmlElement* extra_info);
+
+ // Creates and returns an error message from the given components. The
+ // caller is responsible for deleting this.
+ buzz::XmlElement* CreateErrorMessage(
+ const buzz::XmlElement* stanza,
+ const buzz::QName& name,
+ const std::string& type,
+ const std::string& text,
+ const buzz::XmlElement* extra_info);
+
+ // Called each time a session requests signaling.
+ void OnRequestSignaling(Session* session);
+
+ // Called each time a session has an outgoing message.
+ void OnOutgoingMessage(Session* session, const buzz::XmlElement* stanza);
+
+ // Called each time a session has an error to send.
+ void OnErrorMessage(BaseSession* session,
+ const buzz::XmlElement* stanza,
+ const buzz::QName& name,
+ const std::string& type,
+ const std::string& text,
+ const buzz::XmlElement* extra_info);
+
+ PortAllocator *allocator_;
+ rtc::Thread *signaling_thread_;
+ rtc::Thread *worker_thread_;
+ int timeout_;
+ TransportDescriptionFactory transport_desc_factory_;
+ SessionMap session_map_;
+ ClientMap client_map_;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_SESSIONMANAGER_H_
diff --git a/p2p/base/sessionmessages.cc b/p2p/base/sessionmessages.cc
new file mode 100644
index 00000000..cc63673f
--- /dev/null
+++ b/p2p/base/sessionmessages.cc
@@ -0,0 +1,1132 @@
+/*
+ * Copyright 2010 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can 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 "webrtc/p2p/base/sessionmessages.h"
+
+#include <stdio.h>
+#include <string>
+
+#include "webrtc/p2p/base/constants.h"
+#include "webrtc/p2p/base/p2ptransport.h"
+#include "webrtc/p2p/base/parsing.h"
+#include "webrtc/p2p/base/sessionclient.h"
+#include "webrtc/p2p/base/sessiondescription.h"
+#include "webrtc/p2p/base/transport.h"
+#include "webrtc/libjingle/xmllite/xmlconstants.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/stringutils.h"
+
+namespace cricket {
+
+ActionType ToActionType(const std::string& type) {
+ if (type == GINGLE_ACTION_INITIATE)
+ return ACTION_SESSION_INITIATE;
+ if (type == GINGLE_ACTION_INFO)
+ return ACTION_SESSION_INFO;
+ if (type == GINGLE_ACTION_ACCEPT)
+ return ACTION_SESSION_ACCEPT;
+ if (type == GINGLE_ACTION_REJECT)
+ return ACTION_SESSION_REJECT;
+ if (type == GINGLE_ACTION_TERMINATE)
+ return ACTION_SESSION_TERMINATE;
+ if (type == GINGLE_ACTION_CANDIDATES)
+ return ACTION_TRANSPORT_INFO;
+ if (type == JINGLE_ACTION_SESSION_INITIATE)
+ return ACTION_SESSION_INITIATE;
+ if (type == JINGLE_ACTION_TRANSPORT_INFO)
+ return ACTION_TRANSPORT_INFO;
+ if (type == JINGLE_ACTION_TRANSPORT_ACCEPT)
+ return ACTION_TRANSPORT_ACCEPT;
+ if (type == JINGLE_ACTION_SESSION_INFO)
+ return ACTION_SESSION_INFO;
+ if (type == JINGLE_ACTION_SESSION_ACCEPT)
+ return ACTION_SESSION_ACCEPT;
+ if (type == JINGLE_ACTION_SESSION_TERMINATE)
+ return ACTION_SESSION_TERMINATE;
+ if (type == JINGLE_ACTION_TRANSPORT_INFO)
+ return ACTION_TRANSPORT_INFO;
+ if (type == JINGLE_ACTION_TRANSPORT_ACCEPT)
+ return ACTION_TRANSPORT_ACCEPT;
+ if (type == JINGLE_ACTION_DESCRIPTION_INFO)
+ return ACTION_DESCRIPTION_INFO;
+ if (type == GINGLE_ACTION_UPDATE)
+ return ACTION_DESCRIPTION_INFO;
+
+ return ACTION_UNKNOWN;
+}
+
+std::string ToJingleString(ActionType type) {
+ switch (type) {
+ case ACTION_SESSION_INITIATE:
+ return JINGLE_ACTION_SESSION_INITIATE;
+ case ACTION_SESSION_INFO:
+ return JINGLE_ACTION_SESSION_INFO;
+ case ACTION_DESCRIPTION_INFO:
+ return JINGLE_ACTION_DESCRIPTION_INFO;
+ case ACTION_SESSION_ACCEPT:
+ return JINGLE_ACTION_SESSION_ACCEPT;
+ // Notice that reject and terminate both go to
+ // "session-terminate", but there is no "session-reject".
+ case ACTION_SESSION_REJECT:
+ case ACTION_SESSION_TERMINATE:
+ return JINGLE_ACTION_SESSION_TERMINATE;
+ case ACTION_TRANSPORT_INFO:
+ return JINGLE_ACTION_TRANSPORT_INFO;
+ case ACTION_TRANSPORT_ACCEPT:
+ return JINGLE_ACTION_TRANSPORT_ACCEPT;
+ default:
+ return "";
+ }
+}
+
+std::string ToGingleString(ActionType type) {
+ switch (type) {
+ case ACTION_SESSION_INITIATE:
+ return GINGLE_ACTION_INITIATE;
+ case ACTION_SESSION_INFO:
+ return GINGLE_ACTION_INFO;
+ case ACTION_SESSION_ACCEPT:
+ return GINGLE_ACTION_ACCEPT;
+ case ACTION_SESSION_REJECT:
+ return GINGLE_ACTION_REJECT;
+ case ACTION_SESSION_TERMINATE:
+ return GINGLE_ACTION_TERMINATE;
+ case ACTION_TRANSPORT_INFO:
+ return GINGLE_ACTION_CANDIDATES;
+ default:
+ return "";
+ }
+}
+
+
+bool IsJingleMessage(const buzz::XmlElement* stanza) {
+ const buzz::XmlElement* jingle = stanza->FirstNamed(QN_JINGLE);
+ if (jingle == NULL)
+ return false;
+
+ return (jingle->HasAttr(buzz::QN_ACTION) && jingle->HasAttr(QN_SID));
+}
+
+bool IsGingleMessage(const buzz::XmlElement* stanza) {
+ const buzz::XmlElement* session = stanza->FirstNamed(QN_GINGLE_SESSION);
+ if (session == NULL)
+ return false;
+
+ return (session->HasAttr(buzz::QN_TYPE) &&
+ session->HasAttr(buzz::QN_ID) &&
+ session->HasAttr(QN_INITIATOR));
+}
+
+bool IsSessionMessage(const buzz::XmlElement* stanza) {
+ return (stanza->Name() == buzz::QN_IQ &&
+ stanza->Attr(buzz::QN_TYPE) == buzz::STR_SET &&
+ (IsJingleMessage(stanza) ||
+ IsGingleMessage(stanza)));
+}
+
+bool ParseGingleSessionMessage(const buzz::XmlElement* session,
+ SessionMessage* msg,
+ ParseError* error) {
+ msg->protocol = PROTOCOL_GINGLE;
+ std::string type_string = session->Attr(buzz::QN_TYPE);
+ msg->type = ToActionType(type_string);
+ msg->sid = session->Attr(buzz::QN_ID);
+ msg->initiator = session->Attr(QN_INITIATOR);
+ msg->action_elem = session;
+
+ if (msg->type == ACTION_UNKNOWN)
+ return BadParse("unknown action: " + type_string, error);
+
+ return true;
+}
+
+bool ParseJingleSessionMessage(const buzz::XmlElement* jingle,
+ SessionMessage* msg,
+ ParseError* error) {
+ msg->protocol = PROTOCOL_JINGLE;
+ std::string type_string = jingle->Attr(buzz::QN_ACTION);
+ msg->type = ToActionType(type_string);
+ msg->sid = jingle->Attr(QN_SID);
+ msg->initiator = GetXmlAttr(jingle, QN_INITIATOR, buzz::STR_EMPTY);
+ msg->action_elem = jingle;
+
+ if (msg->type == ACTION_UNKNOWN)
+ return BadParse("unknown action: " + type_string, error);
+
+ return true;
+}
+
+bool ParseHybridSessionMessage(const buzz::XmlElement* jingle,
+ SessionMessage* msg,
+ ParseError* error) {
+ if (!ParseJingleSessionMessage(jingle, msg, error))
+ return false;
+ msg->protocol = PROTOCOL_HYBRID;
+
+ return true;
+}
+
+bool ParseSessionMessage(const buzz::XmlElement* stanza,
+ SessionMessage* msg,
+ ParseError* error) {
+ msg->id = stanza->Attr(buzz::QN_ID);
+ msg->from = stanza->Attr(buzz::QN_FROM);
+ msg->to = stanza->Attr(buzz::QN_TO);
+ msg->stanza = stanza;
+
+ const buzz::XmlElement* jingle = stanza->FirstNamed(QN_JINGLE);
+ const buzz::XmlElement* session = stanza->FirstNamed(QN_GINGLE_SESSION);
+ if (jingle && session)
+ return ParseHybridSessionMessage(jingle, msg, error);
+ if (jingle != NULL)
+ return ParseJingleSessionMessage(jingle, msg, error);
+ if (session != NULL)
+ return ParseGingleSessionMessage(session, msg, error);
+ return false;
+}
+
+buzz::XmlElement* WriteGingleAction(const SessionMessage& msg,
+ const XmlElements& action_elems) {
+ buzz::XmlElement* session = new buzz::XmlElement(QN_GINGLE_SESSION, true);
+ session->AddAttr(buzz::QN_TYPE, ToGingleString(msg.type));
+ session->AddAttr(buzz::QN_ID, msg.sid);
+ session->AddAttr(QN_INITIATOR, msg.initiator);
+ AddXmlChildren(session, action_elems);
+ return session;
+}
+
+buzz::XmlElement* WriteJingleAction(const SessionMessage& msg,
+ const XmlElements& action_elems) {
+ buzz::XmlElement* jingle = new buzz::XmlElement(QN_JINGLE, true);
+ jingle->AddAttr(buzz::QN_ACTION, ToJingleString(msg.type));
+ jingle->AddAttr(QN_SID, msg.sid);
+ if (msg.type == ACTION_SESSION_INITIATE) {
+ jingle->AddAttr(QN_INITIATOR, msg.initiator);
+ }
+ AddXmlChildren(jingle, action_elems);
+ return jingle;
+}
+
+void WriteSessionMessage(const SessionMessage& msg,
+ const XmlElements& action_elems,
+ buzz::XmlElement* stanza) {
+ stanza->SetAttr(buzz::QN_TO, msg.to);
+ stanza->SetAttr(buzz::QN_TYPE, buzz::STR_SET);
+
+ if (msg.protocol == PROTOCOL_GINGLE) {
+ stanza->AddElement(WriteGingleAction(msg, action_elems));
+ } else {
+ stanza->AddElement(WriteJingleAction(msg, action_elems));
+ }
+}
+
+
+TransportParser* GetTransportParser(const TransportParserMap& trans_parsers,
+ const std::string& transport_type) {
+ TransportParserMap::const_iterator map = trans_parsers.find(transport_type);
+ if (map == trans_parsers.end()) {
+ return NULL;
+ } else {
+ return map->second;
+ }
+}
+
+CandidateTranslator* GetCandidateTranslator(
+ const CandidateTranslatorMap& translators,
+ const std::string& content_name) {
+ CandidateTranslatorMap::const_iterator map = translators.find(content_name);
+ if (map == translators.end()) {
+ return NULL;
+ } else {
+ return map->second;
+ }
+}
+
+bool GetParserAndTranslator(const TransportParserMap& trans_parsers,
+ const CandidateTranslatorMap& translators,
+ const std::string& transport_type,
+ const std::string& content_name,
+ TransportParser** parser,
+ CandidateTranslator** translator,
+ ParseError* error) {
+ *parser = GetTransportParser(trans_parsers, transport_type);
+ if (*parser == NULL) {
+ return BadParse("unknown transport type: " + transport_type, error);
+ }
+ // Not having a translator isn't fatal when parsing. If this is called for an
+ // initiate message, we won't have our proxies set up to do the translation.
+ // Fortunately, for the cases where translation is needed, candidates are
+ // never sent in initiates.
+ *translator = GetCandidateTranslator(translators, content_name);
+ return true;
+}
+
+bool GetParserAndTranslator(const TransportParserMap& trans_parsers,
+ const CandidateTranslatorMap& translators,
+ const std::string& transport_type,
+ const std::string& content_name,
+ TransportParser** parser,
+ CandidateTranslator** translator,
+ WriteError* error) {
+ *parser = GetTransportParser(trans_parsers, transport_type);
+ if (*parser == NULL) {
+ return BadWrite("unknown transport type: " + transport_type, error);
+ }
+ *translator = GetCandidateTranslator(translators, content_name);
+ if (*translator == NULL) {
+ return BadWrite("unknown content name: " + content_name, error);
+ }
+ return true;
+}
+
+bool ParseGingleCandidate(const buzz::XmlElement* candidate_elem,
+ const TransportParserMap& trans_parsers,
+ const CandidateTranslatorMap& translators,
+ const std::string& content_name,
+ Candidates* candidates,
+ ParseError* error) {
+ TransportParser* trans_parser;
+ CandidateTranslator* translator;
+ if (!GetParserAndTranslator(trans_parsers, translators,
+ NS_GINGLE_P2P, content_name,
+ &trans_parser, &translator, error))
+ return false;
+
+ Candidate candidate;
+ if (!trans_parser->ParseGingleCandidate(
+ candidate_elem, translator, &candidate, error)) {
+ return false;
+ }
+
+ candidates->push_back(candidate);
+ return true;
+}
+
+bool ParseGingleCandidates(const buzz::XmlElement* parent,
+ const TransportParserMap& trans_parsers,
+ const CandidateTranslatorMap& translators,
+ const std::string& content_name,
+ Candidates* candidates,
+ ParseError* error) {
+ for (const buzz::XmlElement* candidate_elem = parent->FirstElement();
+ candidate_elem != NULL;
+ candidate_elem = candidate_elem->NextElement()) {
+ if (candidate_elem->Name().LocalPart() == LN_CANDIDATE) {
+ if (!ParseGingleCandidate(candidate_elem, trans_parsers, translators,
+ content_name, candidates, error)) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool ParseGingleTransportInfos(const buzz::XmlElement* action_elem,
+ const ContentInfos& contents,
+ const TransportParserMap& trans_parsers,
+ const CandidateTranslatorMap& translators,
+ TransportInfos* tinfos,
+ ParseError* error) {
+ bool has_audio = FindContentInfoByName(contents, CN_AUDIO) != NULL;
+ bool has_video = FindContentInfoByName(contents, CN_VIDEO) != NULL;
+
+ // If we don't have media, no need to separate the candidates.
+ if (!has_audio && !has_video) {
+ TransportInfo tinfo(CN_OTHER,
+ TransportDescription(NS_GINGLE_P2P, std::string(), std::string()));
+ if (!ParseGingleCandidates(action_elem, trans_parsers, translators,
+ CN_OTHER, &tinfo.description.candidates,
+ error)) {
+ return false;
+ }
+
+ tinfos->push_back(tinfo);
+ return true;
+ }
+
+ // If we have media, separate the candidates.
+ TransportInfo audio_tinfo(
+ CN_AUDIO,
+ TransportDescription(NS_GINGLE_P2P, std::string(), std::string()));
+ TransportInfo video_tinfo(
+ CN_VIDEO,
+ TransportDescription(NS_GINGLE_P2P, std::string(), std::string()));
+ for (const buzz::XmlElement* candidate_elem = action_elem->FirstElement();
+ candidate_elem != NULL;
+ candidate_elem = candidate_elem->NextElement()) {
+ if (candidate_elem->Name().LocalPart() == LN_CANDIDATE) {
+ const std::string& channel_name = candidate_elem->Attr(buzz::QN_NAME);
+ if (has_audio &&
+ (channel_name == GICE_CHANNEL_NAME_RTP ||
+ channel_name == GICE_CHANNEL_NAME_RTCP)) {
+ if (!ParseGingleCandidate(
+ candidate_elem, trans_parsers,
+ translators, CN_AUDIO,
+ &audio_tinfo.description.candidates, error)) {
+ return false;
+ }
+ } else if (has_video &&
+ (channel_name == GICE_CHANNEL_NAME_VIDEO_RTP ||
+ channel_name == GICE_CHANNEL_NAME_VIDEO_RTCP)) {
+ if (!ParseGingleCandidate(
+ candidate_elem, trans_parsers,
+ translators, CN_VIDEO,
+ &video_tinfo.description.candidates, error)) {
+ return false;
+ }
+ } else {
+ return BadParse("Unknown channel name: " + channel_name, error);
+ }
+ }
+ }
+
+ if (has_audio) {
+ tinfos->push_back(audio_tinfo);
+ }
+ if (has_video) {
+ tinfos->push_back(video_tinfo);
+ }
+ return true;
+}
+
+bool ParseJingleTransportInfo(const buzz::XmlElement* trans_elem,
+ const std::string& content_name,
+ const TransportParserMap& trans_parsers,
+ const CandidateTranslatorMap& translators,
+ TransportInfo* tinfo,
+ ParseError* error) {
+ TransportParser* trans_parser;
+ CandidateTranslator* translator;
+ if (!GetParserAndTranslator(trans_parsers, translators,
+ trans_elem->Name().Namespace(), content_name,
+ &trans_parser, &translator, error))
+ return false;
+
+ TransportDescription tdesc;
+ if (!trans_parser->ParseTransportDescription(trans_elem, translator,
+ &tdesc, error))
+ return false;
+
+ *tinfo = TransportInfo(content_name, tdesc);
+ return true;
+}
+
+bool ParseJingleTransportInfos(const buzz::XmlElement* jingle,
+ const ContentInfos& contents,
+ const TransportParserMap trans_parsers,
+ const CandidateTranslatorMap& translators,
+ TransportInfos* tinfos,
+ ParseError* error) {
+ for (const buzz::XmlElement* pair_elem
+ = jingle->FirstNamed(QN_JINGLE_CONTENT);
+ pair_elem != NULL;
+ pair_elem = pair_elem->NextNamed(QN_JINGLE_CONTENT)) {
+ std::string content_name;
+ if (!RequireXmlAttr(pair_elem, QN_JINGLE_CONTENT_NAME,
+ &content_name, error))
+ return false;
+
+ const ContentInfo* content = FindContentInfoByName(contents, content_name);
+ if (!content)
+ return BadParse("Unknown content name: " + content_name, error);
+
+ const buzz::XmlElement* trans_elem;
+ if (!RequireXmlChild(pair_elem, LN_TRANSPORT, &trans_elem, error))
+ return false;
+
+ TransportInfo tinfo;
+ if (!ParseJingleTransportInfo(trans_elem, content->name,
+ trans_parsers, translators,
+ &tinfo, error))
+ return false;
+
+ tinfos->push_back(tinfo);
+ }
+
+ return true;
+}
+
+buzz::XmlElement* NewTransportElement(const std::string& name) {
+ return new buzz::XmlElement(buzz::QName(name, LN_TRANSPORT), true);
+}
+
+bool WriteGingleCandidates(const Candidates& candidates,
+ const TransportParserMap& trans_parsers,
+ const std::string& transport_type,
+ const CandidateTranslatorMap& translators,
+ const std::string& content_name,
+ XmlElements* elems,
+ WriteError* error) {
+ TransportParser* trans_parser;
+ CandidateTranslator* translator;
+ if (!GetParserAndTranslator(trans_parsers, translators,
+ transport_type, content_name,
+ &trans_parser, &translator, error))
+ return false;
+
+ for (size_t i = 0; i < candidates.size(); ++i) {
+ rtc::scoped_ptr<buzz::XmlElement> element;
+ if (!trans_parser->WriteGingleCandidate(candidates[i], translator,
+ element.accept(), error)) {
+ return false;
+ }
+
+ elems->push_back(element.release());
+ }
+
+ return true;
+}
+
+bool WriteGingleTransportInfos(const TransportInfos& tinfos,
+ const TransportParserMap& trans_parsers,
+ const CandidateTranslatorMap& translators,
+ XmlElements* elems,
+ WriteError* error) {
+ for (TransportInfos::const_iterator tinfo = tinfos.begin();
+ tinfo != tinfos.end(); ++tinfo) {
+ if (!WriteGingleCandidates(tinfo->description.candidates,
+ trans_parsers, tinfo->description.transport_type,
+ translators, tinfo->content_name,
+ elems, error))
+ return false;
+ }
+
+ return true;
+}
+
+bool WriteJingleTransportInfo(const TransportInfo& tinfo,
+ const TransportParserMap& trans_parsers,
+ const CandidateTranslatorMap& translators,
+ XmlElements* elems,
+ WriteError* error) {
+ std::string transport_type = tinfo.description.transport_type;
+ TransportParser* trans_parser;
+ CandidateTranslator* translator;
+ if (!GetParserAndTranslator(trans_parsers, translators,
+ transport_type, tinfo.content_name,
+ &trans_parser, &translator, error))
+ return false;
+
+ buzz::XmlElement* trans_elem;
+ if (!trans_parser->WriteTransportDescription(tinfo.description, translator,
+ &trans_elem, error)) {
+ return false;
+ }
+
+ elems->push_back(trans_elem);
+ return true;
+}
+
+void WriteJingleContent(const std::string name,
+ const XmlElements& child_elems,
+ XmlElements* elems) {
+ buzz::XmlElement* content_elem = new buzz::XmlElement(QN_JINGLE_CONTENT);
+ content_elem->SetAttr(QN_JINGLE_CONTENT_NAME, name);
+ content_elem->SetAttr(QN_CREATOR, LN_INITIATOR);
+ AddXmlChildren(content_elem, child_elems);
+
+ elems->push_back(content_elem);
+}
+
+bool WriteJingleTransportInfos(const TransportInfos& tinfos,
+ const TransportParserMap& trans_parsers,
+ const CandidateTranslatorMap& translators,
+ XmlElements* elems,
+ WriteError* error) {
+ for (TransportInfos::const_iterator tinfo = tinfos.begin();
+ tinfo != tinfos.end(); ++tinfo) {
+ XmlElements content_child_elems;
+ if (!WriteJingleTransportInfo(*tinfo, trans_parsers, translators,
+ &content_child_elems, error))
+
+ return false;
+
+ WriteJingleContent(tinfo->content_name, content_child_elems, elems);
+ }
+
+ return true;
+}
+
+ContentParser* GetContentParser(const ContentParserMap& content_parsers,
+ const std::string& type) {
+ ContentParserMap::const_iterator map = content_parsers.find(type);
+ if (map == content_parsers.end()) {
+ return NULL;
+ } else {
+ return map->second;
+ }
+}
+
+bool ParseContentInfo(SignalingProtocol protocol,
+ const std::string& name,
+ const std::string& type,
+ const buzz::XmlElement* elem,
+ const ContentParserMap& parsers,
+ ContentInfos* contents,
+ ParseError* error) {
+ ContentParser* parser = GetContentParser(parsers, type);
+ if (parser == NULL)
+ return BadParse("unknown application content: " + type, error);
+
+ ContentDescription* desc;
+ if (!parser->ParseContent(protocol, elem, &desc, error))
+ return false;
+
+ contents->push_back(ContentInfo(name, type, desc));
+ return true;
+}
+
+bool ParseContentType(const buzz::XmlElement* parent_elem,
+ std::string* content_type,
+ const buzz::XmlElement** content_elem,
+ ParseError* error) {
+ if (!RequireXmlChild(parent_elem, LN_DESCRIPTION, content_elem, error))
+ return false;
+
+ *content_type = (*content_elem)->Name().Namespace();
+ return true;
+}
+
+bool ParseGingleContentInfos(const buzz::XmlElement* session,
+ const ContentParserMap& content_parsers,
+ ContentInfos* contents,
+ ParseError* error) {
+ std::string content_type;
+ const buzz::XmlElement* content_elem;
+ if (!ParseContentType(session, &content_type, &content_elem, error))
+ return false;
+
+ if (content_type == NS_GINGLE_VIDEO) {
+ // A parser parsing audio or video content should look at the
+ // namespace and only parse the codecs relevant to that namespace.
+ // We use this to control which codecs get parsed: first audio,
+ // then video.
+ rtc::scoped_ptr<buzz::XmlElement> audio_elem(
+ new buzz::XmlElement(QN_GINGLE_AUDIO_CONTENT));
+ CopyXmlChildren(content_elem, audio_elem.get());
+ if (!ParseContentInfo(PROTOCOL_GINGLE, CN_AUDIO, NS_JINGLE_RTP,
+ audio_elem.get(), content_parsers,
+ contents, error))
+ return false;
+
+ if (!ParseContentInfo(PROTOCOL_GINGLE, CN_VIDEO, NS_JINGLE_RTP,
+ content_elem, content_parsers,
+ contents, error))
+ return false;
+ } else if (content_type == NS_GINGLE_AUDIO) {
+ if (!ParseContentInfo(PROTOCOL_GINGLE, CN_AUDIO, NS_JINGLE_RTP,
+ content_elem, content_parsers,
+ contents, error))
+ return false;
+ } else {
+ if (!ParseContentInfo(PROTOCOL_GINGLE, CN_OTHER, content_type,
+ content_elem, content_parsers,
+ contents, error))
+ return false;
+ }
+ return true;
+}
+
+bool ParseJingleContentInfos(const buzz::XmlElement* jingle,
+ const ContentParserMap& content_parsers,
+ ContentInfos* contents,
+ ParseError* error) {
+ for (const buzz::XmlElement* pair_elem
+ = jingle->FirstNamed(QN_JINGLE_CONTENT);
+ pair_elem != NULL;
+ pair_elem = pair_elem->NextNamed(QN_JINGLE_CONTENT)) {
+ std::string content_name;
+ if (!RequireXmlAttr(pair_elem, QN_JINGLE_CONTENT_NAME,
+ &content_name, error))
+ return false;
+
+ std::string content_type;
+ const buzz::XmlElement* content_elem;
+ if (!ParseContentType(pair_elem, &content_type, &content_elem, error))
+ return false;
+
+ if (!ParseContentInfo(PROTOCOL_JINGLE, content_name, content_type,
+ content_elem, content_parsers,
+ contents, error))
+ return false;
+ }
+ return true;
+}
+
+bool ParseJingleGroupInfos(const buzz::XmlElement* jingle,
+ ContentGroups* groups,
+ ParseError* error) {
+ for (const buzz::XmlElement* pair_elem
+ = jingle->FirstNamed(QN_JINGLE_DRAFT_GROUP);
+ pair_elem != NULL;
+ pair_elem = pair_elem->NextNamed(QN_JINGLE_DRAFT_GROUP)) {
+ std::string group_name;
+ if (!RequireXmlAttr(pair_elem, QN_JINGLE_DRAFT_GROUP_TYPE,
+ &group_name, error))
+ return false;
+
+ ContentGroup group(group_name);
+ for (const buzz::XmlElement* child_elem
+ = pair_elem->FirstNamed(QN_JINGLE_CONTENT);
+ child_elem != NULL;
+ child_elem = child_elem->NextNamed(QN_JINGLE_CONTENT)) {
+ std::string content_name;
+ if (!RequireXmlAttr(child_elem, QN_JINGLE_CONTENT_NAME,
+ &content_name, error))
+ return false;
+ group.AddContentName(content_name);
+ }
+ groups->push_back(group);
+ }
+ return true;
+}
+
+buzz::XmlElement* WriteContentInfo(SignalingProtocol protocol,
+ const ContentInfo& content,
+ const ContentParserMap& parsers,
+ WriteError* error) {
+ ContentParser* parser = GetContentParser(parsers, content.type);
+ if (parser == NULL) {
+ BadWrite("unknown content type: " + content.type, error);
+ return NULL;
+ }
+
+ buzz::XmlElement* elem = NULL;
+ if (!parser->WriteContent(protocol, content.description, &elem, error))
+ return NULL;
+
+ return elem;
+}
+
+bool IsWritable(SignalingProtocol protocol,
+ const ContentInfo& content,
+ const ContentParserMap& parsers) {
+ ContentParser* parser = GetContentParser(parsers, content.type);
+ if (parser == NULL) {
+ return false;
+ }
+
+ return parser->IsWritable(protocol, content.description);
+}
+
+bool WriteGingleContentInfos(const ContentInfos& contents,
+ const ContentParserMap& parsers,
+ XmlElements* elems,
+ WriteError* error) {
+ if (contents.size() == 1 ||
+ (contents.size() == 2 &&
+ !IsWritable(PROTOCOL_GINGLE, contents.at(1), parsers))) {
+ if (contents.front().rejected) {
+ return BadWrite("Gingle protocol may not reject individual contents.",
+ error);
+ }
+ buzz::XmlElement* elem = WriteContentInfo(
+ PROTOCOL_GINGLE, contents.front(), parsers, error);
+ if (!elem)
+ return false;
+
+ elems->push_back(elem);
+ } else if (contents.size() >= 2 &&
+ contents.at(0).type == NS_JINGLE_RTP &&
+ contents.at(1).type == NS_JINGLE_RTP) {
+ // Special-case audio + video contents so that they are "merged"
+ // into one "video" content.
+ if (contents.at(0).rejected || contents.at(1).rejected) {
+ return BadWrite("Gingle protocol may not reject individual contents.",
+ error);
+ }
+ buzz::XmlElement* audio = WriteContentInfo(
+ PROTOCOL_GINGLE, contents.at(0), parsers, error);
+ if (!audio)
+ return false;
+
+ buzz::XmlElement* video = WriteContentInfo(
+ PROTOCOL_GINGLE, contents.at(1), parsers, error);
+ if (!video) {
+ delete audio;
+ return false;
+ }
+
+ CopyXmlChildren(audio, video);
+ elems->push_back(video);
+ delete audio;
+ } else {
+ return BadWrite("Gingle protocol may only have one content.", error);
+ }
+
+ return true;
+}
+
+const TransportInfo* GetTransportInfoByContentName(
+ const TransportInfos& tinfos, const std::string& content_name) {
+ for (TransportInfos::const_iterator tinfo = tinfos.begin();
+ tinfo != tinfos.end(); ++tinfo) {
+ if (content_name == tinfo->content_name) {
+ return &*tinfo;
+ }
+ }
+ return NULL;
+}
+
+bool WriteJingleContents(const ContentInfos& contents,
+ const ContentParserMap& content_parsers,
+ const TransportInfos& tinfos,
+ const TransportParserMap& trans_parsers,
+ const CandidateTranslatorMap& translators,
+ XmlElements* elems,
+ WriteError* error) {
+ for (ContentInfos::const_iterator content = contents.begin();
+ content != contents.end(); ++content) {
+ if (content->rejected) {
+ continue;
+ }
+ const TransportInfo* tinfo =
+ GetTransportInfoByContentName(tinfos, content->name);
+ if (!tinfo)
+ return BadWrite("No transport for content: " + content->name, error);
+
+ XmlElements pair_elems;
+ buzz::XmlElement* elem = WriteContentInfo(
+ PROTOCOL_JINGLE, *content, content_parsers, error);
+ if (!elem)
+ return false;
+ pair_elems.push_back(elem);
+
+ if (!WriteJingleTransportInfo(*tinfo, trans_parsers, translators,
+ &pair_elems, error))
+ return false;
+
+ WriteJingleContent(content->name, pair_elems, elems);
+ }
+ return true;
+}
+
+bool WriteJingleContentInfos(const ContentInfos& contents,
+ const ContentParserMap& content_parsers,
+ XmlElements* elems,
+ WriteError* error) {
+ for (ContentInfos::const_iterator content = contents.begin();
+ content != contents.end(); ++content) {
+ if (content->rejected) {
+ continue;
+ }
+ XmlElements content_child_elems;
+ buzz::XmlElement* elem = WriteContentInfo(
+ PROTOCOL_JINGLE, *content, content_parsers, error);
+ if (!elem)
+ return false;
+ content_child_elems.push_back(elem);
+ WriteJingleContent(content->name, content_child_elems, elems);
+ }
+ return true;
+}
+
+bool WriteJingleGroupInfo(const ContentInfos& contents,
+ const ContentGroups& groups,
+ XmlElements* elems,
+ WriteError* error) {
+ if (!groups.empty()) {
+ buzz::XmlElement* pair_elem = new buzz::XmlElement(QN_JINGLE_DRAFT_GROUP);
+ pair_elem->SetAttr(QN_JINGLE_DRAFT_GROUP_TYPE, GROUP_TYPE_BUNDLE);
+
+ XmlElements pair_elems;
+ for (ContentInfos::const_iterator content = contents.begin();
+ content != contents.end(); ++content) {
+ buzz::XmlElement* child_elem =
+ new buzz::XmlElement(QN_JINGLE_CONTENT, false);
+ child_elem->SetAttr(QN_JINGLE_CONTENT_NAME, content->name);
+ pair_elems.push_back(child_elem);
+ }
+ AddXmlChildren(pair_elem, pair_elems);
+ elems->push_back(pair_elem);
+ }
+ return true;
+}
+
+bool ParseContentType(SignalingProtocol protocol,
+ const buzz::XmlElement* action_elem,
+ std::string* content_type,
+ ParseError* error) {
+ const buzz::XmlElement* content_elem;
+ if (protocol == PROTOCOL_GINGLE) {
+ if (!ParseContentType(action_elem, content_type, &content_elem, error))
+ return false;
+
+ // Internally, we only use NS_JINGLE_RTP.
+ if (*content_type == NS_GINGLE_AUDIO ||
+ *content_type == NS_GINGLE_VIDEO)
+ *content_type = NS_JINGLE_RTP;
+ } else {
+ const buzz::XmlElement* pair_elem
+ = action_elem->FirstNamed(QN_JINGLE_CONTENT);
+ if (pair_elem == NULL)
+ return BadParse("No contents found", error);
+
+ if (!ParseContentType(pair_elem, content_type, &content_elem, error))
+ return false;
+ }
+
+ return true;
+}
+
+static bool ParseContentMessage(
+ SignalingProtocol protocol,
+ const buzz::XmlElement* action_elem,
+ bool expect_transports,
+ const ContentParserMap& content_parsers,
+ const TransportParserMap& trans_parsers,
+ const CandidateTranslatorMap& translators,
+ SessionInitiate* init,
+ ParseError* error) {
+ init->owns_contents = true;
+ if (protocol == PROTOCOL_GINGLE) {
+ if (!ParseGingleContentInfos(action_elem, content_parsers,
+ &init->contents, error))
+ return false;
+
+ if (expect_transports &&
+ !ParseGingleTransportInfos(action_elem, init->contents,
+ trans_parsers, translators,
+ &init->transports, error))
+ return false;
+ } else {
+ if (!ParseJingleContentInfos(action_elem, content_parsers,
+ &init->contents, error))
+ return false;
+ if (!ParseJingleGroupInfos(action_elem, &init->groups, error))
+ return false;
+
+ if (expect_transports &&
+ !ParseJingleTransportInfos(action_elem, init->contents,
+ trans_parsers, translators,
+ &init->transports, error))
+ return false;
+ }
+
+ return true;
+}
+
+static bool WriteContentMessage(
+ SignalingProtocol protocol,
+ const ContentInfos& contents,
+ const TransportInfos& tinfos,
+ const ContentParserMap& content_parsers,
+ const TransportParserMap& transport_parsers,
+ const CandidateTranslatorMap& translators,
+ const ContentGroups& groups,
+ XmlElements* elems,
+ WriteError* error) {
+ if (protocol == PROTOCOL_GINGLE) {
+ if (!WriteGingleContentInfos(contents, content_parsers, elems, error))
+ return false;
+
+ if (!WriteGingleTransportInfos(tinfos, transport_parsers, translators,
+ elems, error))
+ return false;
+ } else {
+ if (!WriteJingleContents(contents, content_parsers,
+ tinfos, transport_parsers, translators,
+ elems, error))
+ return false;
+ if (!WriteJingleGroupInfo(contents, groups, elems, error))
+ return false;
+ }
+
+ return true;
+}
+
+bool ParseSessionInitiate(SignalingProtocol protocol,
+ const buzz::XmlElement* action_elem,
+ const ContentParserMap& content_parsers,
+ const TransportParserMap& trans_parsers,
+ const CandidateTranslatorMap& translators,
+ SessionInitiate* init,
+ ParseError* error) {
+ bool expect_transports = true;
+ return ParseContentMessage(protocol, action_elem, expect_transports,
+ content_parsers, trans_parsers, translators,
+ init, error);
+}
+
+
+bool WriteSessionInitiate(SignalingProtocol protocol,
+ const ContentInfos& contents,
+ const TransportInfos& tinfos,
+ const ContentParserMap& content_parsers,
+ const TransportParserMap& transport_parsers,
+ const CandidateTranslatorMap& translators,
+ const ContentGroups& groups,
+ XmlElements* elems,
+ WriteError* error) {
+ return WriteContentMessage(protocol, contents, tinfos,
+ content_parsers, transport_parsers, translators,
+ groups,
+ elems, error);
+}
+
+bool ParseSessionAccept(SignalingProtocol protocol,
+ const buzz::XmlElement* action_elem,
+ const ContentParserMap& content_parsers,
+ const TransportParserMap& transport_parsers,
+ const CandidateTranslatorMap& translators,
+ SessionAccept* accept,
+ ParseError* error) {
+ bool expect_transports = true;
+ return ParseContentMessage(protocol, action_elem, expect_transports,
+ content_parsers, transport_parsers, translators,
+ accept, error);
+}
+
+bool WriteSessionAccept(SignalingProtocol protocol,
+ const ContentInfos& contents,
+ const TransportInfos& tinfos,
+ const ContentParserMap& content_parsers,
+ const TransportParserMap& transport_parsers,
+ const CandidateTranslatorMap& translators,
+ const ContentGroups& groups,
+ XmlElements* elems,
+ WriteError* error) {
+ return WriteContentMessage(protocol, contents, tinfos,
+ content_parsers, transport_parsers, translators,
+ groups,
+ elems, error);
+}
+
+bool ParseSessionTerminate(SignalingProtocol protocol,
+ const buzz::XmlElement* action_elem,
+ SessionTerminate* term,
+ ParseError* error) {
+ if (protocol == PROTOCOL_GINGLE) {
+ const buzz::XmlElement* reason_elem = action_elem->FirstElement();
+ if (reason_elem != NULL) {
+ term->reason = reason_elem->Name().LocalPart();
+ const buzz::XmlElement *debug_elem = reason_elem->FirstElement();
+ if (debug_elem != NULL) {
+ term->debug_reason = debug_elem->Name().LocalPart();
+ }
+ }
+ return true;
+ } else {
+ const buzz::XmlElement* reason_elem =
+ action_elem->FirstNamed(QN_JINGLE_REASON);
+ if (reason_elem) {
+ reason_elem = reason_elem->FirstElement();
+ if (reason_elem) {
+ term->reason = reason_elem->Name().LocalPart();
+ }
+ }
+ return true;
+ }
+}
+
+void WriteSessionTerminate(SignalingProtocol protocol,
+ const SessionTerminate& term,
+ XmlElements* elems) {
+ if (protocol == PROTOCOL_GINGLE) {
+ elems->push_back(new buzz::XmlElement(buzz::QName(NS_GINGLE, term.reason)));
+ } else {
+ if (!term.reason.empty()) {
+ buzz::XmlElement* reason_elem = new buzz::XmlElement(QN_JINGLE_REASON);
+ reason_elem->AddElement(new buzz::XmlElement(
+ buzz::QName(NS_JINGLE, term.reason)));
+ elems->push_back(reason_elem);
+ }
+ }
+}
+
+bool ParseDescriptionInfo(SignalingProtocol protocol,
+ const buzz::XmlElement* action_elem,
+ const ContentParserMap& content_parsers,
+ const TransportParserMap& transport_parsers,
+ const CandidateTranslatorMap& translators,
+ DescriptionInfo* description_info,
+ ParseError* error) {
+ bool expect_transports = false;
+ return ParseContentMessage(protocol, action_elem, expect_transports,
+ content_parsers, transport_parsers, translators,
+ description_info, error);
+}
+
+bool WriteDescriptionInfo(SignalingProtocol protocol,
+ const ContentInfos& contents,
+ const ContentParserMap& content_parsers,
+ XmlElements* elems,
+ WriteError* error) {
+ if (protocol == PROTOCOL_GINGLE) {
+ return WriteGingleContentInfos(contents, content_parsers, elems, error);
+ } else {
+ return WriteJingleContentInfos(contents, content_parsers, elems, error);
+ }
+}
+
+bool ParseTransportInfos(SignalingProtocol protocol,
+ const buzz::XmlElement* action_elem,
+ const ContentInfos& contents,
+ const TransportParserMap& trans_parsers,
+ const CandidateTranslatorMap& translators,
+ TransportInfos* tinfos,
+ ParseError* error) {
+ if (protocol == PROTOCOL_GINGLE) {
+ return ParseGingleTransportInfos(
+ action_elem, contents, trans_parsers, translators, tinfos, error);
+ } else {
+ return ParseJingleTransportInfos(
+ action_elem, contents, trans_parsers, translators, tinfos, error);
+ }
+}
+
+bool WriteTransportInfos(SignalingProtocol protocol,
+ const TransportInfos& tinfos,
+ const TransportParserMap& trans_parsers,
+ const CandidateTranslatorMap& translators,
+ XmlElements* elems,
+ WriteError* error) {
+ if (protocol == PROTOCOL_GINGLE) {
+ return WriteGingleTransportInfos(tinfos, trans_parsers, translators,
+ elems, error);
+ } else {
+ return WriteJingleTransportInfos(tinfos, trans_parsers, translators,
+ elems, error);
+ }
+}
+
+bool GetUriTarget(const std::string& prefix, const std::string& str,
+ std::string* after) {
+ size_t pos = str.find(prefix);
+ if (pos == std::string::npos)
+ return false;
+
+ *after = str.substr(pos + prefix.size(), std::string::npos);
+ return true;
+}
+
+bool FindSessionRedirect(const buzz::XmlElement* stanza,
+ SessionRedirect* redirect) {
+ const buzz::XmlElement* error_elem = GetXmlChild(stanza, LN_ERROR);
+ if (error_elem == NULL)
+ return false;
+
+ const buzz::XmlElement* redirect_elem =
+ error_elem->FirstNamed(QN_GINGLE_REDIRECT);
+ if (redirect_elem == NULL)
+ redirect_elem = error_elem->FirstNamed(buzz::QN_STANZA_REDIRECT);
+ if (redirect_elem == NULL)
+ return false;
+
+ if (!GetUriTarget(STR_REDIRECT_PREFIX, redirect_elem->BodyText(),
+ &redirect->target))
+ return false;
+
+ return true;
+}
+
+} // namespace cricket
diff --git a/p2p/base/sessionmessages.h b/p2p/base/sessionmessages.h
new file mode 100644
index 00000000..7b156d49
--- /dev/null
+++ b/p2p/base/sessionmessages.h
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2010 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_P2P_BASE_SESSIONMESSAGES_H_
+#define WEBRTC_P2P_BASE_SESSIONMESSAGES_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "webrtc/p2p/base/constants.h"
+#include "webrtc/p2p/base/parsing.h"
+#include "webrtc/p2p/base/sessiondescription.h" // Needed to delete contents.
+#include "webrtc/p2p/base/transportinfo.h"
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/base/basictypes.h"
+
+namespace cricket {
+
+struct ParseError;
+struct WriteError;
+class Candidate;
+class ContentParser;
+class TransportParser;
+
+typedef std::vector<Candidate> Candidates;
+typedef std::map<std::string, ContentParser*> ContentParserMap;
+typedef std::map<std::string, TransportParser*> TransportParserMap;
+
+enum ActionType {
+ ACTION_UNKNOWN,
+
+ ACTION_SESSION_INITIATE,
+ ACTION_SESSION_INFO,
+ ACTION_SESSION_ACCEPT,
+ ACTION_SESSION_REJECT,
+ ACTION_SESSION_TERMINATE,
+
+ ACTION_TRANSPORT_INFO,
+ ACTION_TRANSPORT_ACCEPT,
+
+ ACTION_DESCRIPTION_INFO,
+};
+
+// Abstraction of a <jingle> element within an <iq> stanza, per XMPP
+// standard XEP-166. Can be serialized into multiple protocols,
+// including the standard (Jingle) and the draft standard (Gingle).
+// In general, used to communicate actions related to a p2p session,
+// such accept, initiate, terminate, etc.
+
+struct SessionMessage {
+ SessionMessage() : action_elem(NULL), stanza(NULL) {}
+
+ SessionMessage(SignalingProtocol protocol, ActionType type,
+ const std::string& sid, const std::string& initiator) :
+ protocol(protocol), type(type), sid(sid), initiator(initiator),
+ action_elem(NULL), stanza(NULL) {}
+
+ std::string id;
+ std::string from;
+ std::string to;
+ SignalingProtocol protocol;
+ ActionType type;
+ std::string sid; // session id
+ std::string initiator;
+
+ // Used for further parsing when necessary.
+ // Represents <session> or <jingle>.
+ const buzz::XmlElement* action_elem;
+ // Mostly used for debugging.
+ const buzz::XmlElement* stanza;
+};
+
+// TODO: Break up this class so we don't have to typedef it into
+// different classes.
+struct ContentMessage {
+ ContentMessage() : owns_contents(false) {}
+
+ ~ContentMessage() {
+ if (owns_contents) {
+ for (ContentInfos::iterator content = contents.begin();
+ content != contents.end(); content++) {
+ delete content->description;
+ }
+ }
+ }
+
+ // Caller takes ownership of contents.
+ ContentInfos ClearContents() {
+ ContentInfos out;
+ contents.swap(out);
+ owns_contents = false;
+ return out;
+ }
+
+ bool owns_contents;
+ ContentInfos contents;
+ TransportInfos transports;
+ ContentGroups groups;
+};
+
+typedef ContentMessage SessionInitiate;
+typedef ContentMessage SessionAccept;
+// Note that a DescriptionInfo does not have TransportInfos.
+typedef ContentMessage DescriptionInfo;
+
+struct SessionTerminate {
+ SessionTerminate() {}
+
+ explicit SessionTerminate(const std::string& reason) :
+ reason(reason) {}
+
+ std::string reason;
+ std::string debug_reason;
+};
+
+struct SessionRedirect {
+ std::string target;
+};
+
+// Used during parsing and writing to map component to channel name
+// and back. This is primarily for converting old G-ICE candidate
+// signalling to new ICE candidate classes.
+class CandidateTranslator {
+ public:
+ virtual bool GetChannelNameFromComponent(
+ int component, std::string* channel_name) const = 0;
+ virtual bool GetComponentFromChannelName(
+ const std::string& channel_name, int* component) const = 0;
+};
+
+// Content name => translator
+typedef std::map<std::string, CandidateTranslator*> CandidateTranslatorMap;
+
+bool IsSessionMessage(const buzz::XmlElement* stanza);
+bool ParseSessionMessage(const buzz::XmlElement* stanza,
+ SessionMessage* msg,
+ ParseError* error);
+// Will return an error if there is more than one content type.
+bool ParseContentType(SignalingProtocol protocol,
+ const buzz::XmlElement* action_elem,
+ std::string* content_type,
+ ParseError* error);
+void WriteSessionMessage(const SessionMessage& msg,
+ const XmlElements& action_elems,
+ buzz::XmlElement* stanza);
+bool ParseSessionInitiate(SignalingProtocol protocol,
+ const buzz::XmlElement* action_elem,
+ const ContentParserMap& content_parsers,
+ const TransportParserMap& transport_parsers,
+ const CandidateTranslatorMap& translators,
+ SessionInitiate* init,
+ ParseError* error);
+bool WriteSessionInitiate(SignalingProtocol protocol,
+ const ContentInfos& contents,
+ const TransportInfos& tinfos,
+ const ContentParserMap& content_parsers,
+ const TransportParserMap& transport_parsers,
+ const CandidateTranslatorMap& translators,
+ const ContentGroups& groups,
+ XmlElements* elems,
+ WriteError* error);
+bool ParseSessionAccept(SignalingProtocol protocol,
+ const buzz::XmlElement* action_elem,
+ const ContentParserMap& content_parsers,
+ const TransportParserMap& transport_parsers,
+ const CandidateTranslatorMap& translators,
+ SessionAccept* accept,
+ ParseError* error);
+bool WriteSessionAccept(SignalingProtocol protocol,
+ const ContentInfos& contents,
+ const TransportInfos& tinfos,
+ const ContentParserMap& content_parsers,
+ const TransportParserMap& transport_parsers,
+ const CandidateTranslatorMap& translators,
+ const ContentGroups& groups,
+ XmlElements* elems,
+ WriteError* error);
+bool ParseSessionTerminate(SignalingProtocol protocol,
+ const buzz::XmlElement* action_elem,
+ SessionTerminate* term,
+ ParseError* error);
+void WriteSessionTerminate(SignalingProtocol protocol,
+ const SessionTerminate& term,
+ XmlElements* elems);
+bool ParseDescriptionInfo(SignalingProtocol protocol,
+ const buzz::XmlElement* action_elem,
+ const ContentParserMap& content_parsers,
+ const TransportParserMap& transport_parsers,
+ const CandidateTranslatorMap& translators,
+ DescriptionInfo* description_info,
+ ParseError* error);
+bool WriteDescriptionInfo(SignalingProtocol protocol,
+ const ContentInfos& contents,
+ const ContentParserMap& content_parsers,
+ XmlElements* elems,
+ WriteError* error);
+// Since a TransportInfo is not a transport-info message, and a
+// transport-info message is just a collection of TransportInfos, we
+// say Parse/Write TransportInfos for transport-info messages.
+bool ParseTransportInfos(SignalingProtocol protocol,
+ const buzz::XmlElement* action_elem,
+ const ContentInfos& contents,
+ const TransportParserMap& trans_parsers,
+ const CandidateTranslatorMap& translators,
+ TransportInfos* tinfos,
+ ParseError* error);
+bool WriteTransportInfos(SignalingProtocol protocol,
+ const TransportInfos& tinfos,
+ const TransportParserMap& trans_parsers,
+ const CandidateTranslatorMap& translators,
+ XmlElements* elems,
+ WriteError* error);
+// Handles both Gingle and Jingle syntax.
+bool FindSessionRedirect(const buzz::XmlElement* stanza,
+ SessionRedirect* redirect);
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_SESSIONMESSAGES_H_
diff --git a/p2p/base/stun.cc b/p2p/base/stun.cc
new file mode 100644
index 00000000..60367fa1
--- /dev/null
+++ b/p2p/base/stun.cc
@@ -0,0 +1,915 @@
+/*
+ * 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 "webrtc/p2p/base/stun.h"
+
+#include <string.h>
+
+#include "webrtc/base/byteorder.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/crc32.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/messagedigest.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/stringencode.h"
+
+using rtc::ByteBuffer;
+
+namespace cricket {
+
+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_FORBIDDEN[] = "Forbidden";
+const char STUN_ERROR_REASON_STALE_CREDENTIALS[] = "Stale Credentials";
+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 STUN_FINGERPRINT_XOR_VALUE = 0x5354554E;
+
+// StunMessage
+
+StunMessage::StunMessage()
+ : type_(0),
+ length_(0),
+ transaction_id_(EMPTY_TRANSACTION_ID) {
+ ASSERT(IsValidTransactionId(transaction_id_));
+ attrs_ = new std::vector<StunAttribute*>();
+}
+
+StunMessage::~StunMessage() {
+ for (size_t i = 0; i < attrs_->size(); i++)
+ delete (*attrs_)[i];
+ delete attrs_;
+}
+
+bool StunMessage::IsLegacy() const {
+ if (transaction_id_.size() == kStunLegacyTransactionIdLength)
+ return true;
+ ASSERT(transaction_id_.size() == kStunTransactionIdLength);
+ return false;
+}
+
+bool StunMessage::SetTransactionID(const std::string& str) {
+ if (!IsValidTransactionId(str)) {
+ return false;
+ }
+ transaction_id_ = str;
+ return true;
+}
+
+bool StunMessage::AddAttribute(StunAttribute* attr) {
+ // Fail any attributes that aren't valid for this type of message.
+ if (attr->value_type() != GetAttributeValueType(attr->type())) {
+ return false;
+ }
+ attrs_->push_back(attr);
+ attr->SetOwner(this);
+ size_t attr_length = attr->length();
+ if (attr_length % 4 != 0) {
+ attr_length += (4 - (attr_length % 4));
+ }
+ length_ += static_cast<uint16>(attr_length + 4);
+ return true;
+}
+
+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 StunErrorCodeAttribute* StunMessage::GetErrorCode() const {
+ return static_cast<const StunErrorCodeAttribute*>(
+ GetAttribute(STUN_ATTR_ERROR_CODE));
+}
+
+const StunUInt16ListAttribute* StunMessage::GetUnknownAttributes() const {
+ return static_cast<const StunUInt16ListAttribute*>(
+ GetAttribute(STUN_ATTR_UNKNOWN_ATTRIBUTES));
+}
+
+// Verifies a STUN message has a valid MESSAGE-INTEGRITY attribute, using the
+// procedure outlined in RFC 5389, section 15.4.
+bool StunMessage::ValidateMessageIntegrity(const char* data, size_t size,
+ const std::string& password) {
+ // Verifying the size of the message.
+ if ((size % 4) != 0) {
+ return false;
+ }
+
+ // Getting the message length from the STUN header.
+ uint16 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 < size) {
+ uint16 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 == STUN_ATTR_MESSAGE_INTEGRITY) {
+ if (attr_length != kStunMessageIntegritySize ||
+ current_pos + 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;
+ rtc::scoped_ptr<char[]> temp_data(new char[current_pos]);
+ memcpy(temp_data.get(), data, current_pos);
+ if (size > mi_pos + kStunAttributeHeaderSize + kStunMessageIntegritySize) {
+ // 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 + kStunMessageIntegritySize);
+ 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>(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));
+ ASSERT(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,
+ sizeof(hmac)) == 0;
+}
+
+bool StunMessage::AddMessageIntegrity(const std::string& password) {
+ return AddMessageIntegrity(password.c_str(), password.size());
+}
+
+bool StunMessage::AddMessageIntegrity(const char* key,
+ size_t keylen) {
+ // Add the attribute with a dummy value. Since this is a known attribute, it
+ // can't fail.
+ StunByteStringAttribute* msg_integrity_attr =
+ new StunByteStringAttribute(STUN_ATTR_MESSAGE_INTEGRITY,
+ std::string(kStunMessageIntegritySize, '0'));
+ VERIFY(AddAttribute(msg_integrity_attr));
+
+ // Calculate the HMAC for the message.
+ rtc::ByteBuffer 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, keylen,
+ buf.Data(), msg_len_for_hmac,
+ hmac, sizeof(hmac));
+ ASSERT(ret == sizeof(hmac));
+ if (ret != sizeof(hmac)) {
+ LOG(LS_ERROR) << "HMAC computation failed. Message-Integrity "
+ << "has dummy value.";
+ return false;
+ }
+
+ // Insert correct HMAC into the attribute.
+ msg_integrity_attr->CopyBytes(hmac, sizeof(hmac));
+ 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)) !=
+ StunUInt32Attribute::SIZE)
+ return false;
+
+ // Check the fingerprint value.
+ uint32 fingerprint =
+ rtc::GetBE32(fingerprint_attr_data + kStunAttributeHeaderSize);
+ return ((fingerprint ^ STUN_FINGERPRINT_XOR_VALUE) ==
+ rtc::ComputeCrc32(data, size - fingerprint_attr_size));
+}
+
+bool StunMessage::AddFingerprint() {
+ // Add the attribute with a dummy value. Since this is a known attribute,
+ // it can't fail.
+ StunUInt32Attribute* fingerprint_attr =
+ new StunUInt32Attribute(STUN_ATTR_FINGERPRINT, 0);
+ VERIFY(AddAttribute(fingerprint_attr));
+
+ // Calculate the CRC-32 for the message and insert it.
+ rtc::ByteBuffer buf;
+ if (!Write(&buf))
+ return false;
+
+ int msg_len_for_crc32 = static_cast<int>(
+ buf.Length() - kStunAttributeHeaderSize - fingerprint_attr->length());
+ uint32 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(ByteBuffer* buf) {
+ 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 magic_cookie_int =
+ *reinterpret_cast<const uint32*>(magic_cookie.data());
+ 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);
+ }
+ ASSERT(IsValidTransactionId(transaction_id));
+ transaction_id_ = transaction_id;
+
+ if (length_ != buf->Length())
+ return false;
+
+ attrs_->resize(0);
+
+ size_t rest = buf->Length() - length_;
+ while (buf->Length() > rest) {
+ uint16 attr_type, attr_length;
+ if (!buf->ReadUInt16(&attr_type))
+ return false;
+ if (!buf->ReadUInt16(&attr_length))
+ return false;
+
+ 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(attr);
+ }
+ }
+
+ ASSERT(buf->Length() == rest);
+ return true;
+}
+
+bool StunMessage::Write(ByteBuffer* buf) const {
+ buf->WriteUInt16(type_);
+ buf->WriteUInt16(length_);
+ if (!IsLegacy())
+ buf->WriteUInt32(kStunMagicCookie);
+ buf->WriteString(transaction_id_);
+
+ for (size_t i = 0; i < attrs_->size(); ++i) {
+ buf->WriteUInt16((*attrs_)[i]->type());
+ buf->WriteUInt16(static_cast<uint16>((*attrs_)[i]->length()));
+ if (!(*attrs_)[i]->Write(buf))
+ return false;
+ }
+
+ return true;
+}
+
+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;
+ default: return STUN_VALUE_UNKNOWN;
+ }
+}
+
+StunAttribute* StunMessage::CreateAttribute(int type, size_t length) /*const*/ {
+ StunAttributeValueType value_type = GetAttributeValueType(type);
+ return StunAttribute::Create(value_type, type,
+ static_cast<uint16>(length), this);
+}
+
+const StunAttribute* StunMessage::GetAttribute(int type) const {
+ for (size_t i = 0; i < attrs_->size(); ++i) {
+ if ((*attrs_)[i]->type() == type)
+ return (*attrs_)[i];
+ }
+ return NULL;
+}
+
+bool StunMessage::IsValidTransactionId(const std::string& transaction_id) {
+ return transaction_id.size() == kStunTransactionIdLength ||
+ transaction_id.size() == kStunLegacyTransactionIdLength;
+}
+
+// StunAttribute
+
+StunAttribute::StunAttribute(uint16 type, uint16 length)
+ : type_(type), length_(length) {
+}
+
+void StunAttribute::ConsumePadding(rtc::ByteBuffer* buf) const {
+ int remainder = length_ % 4;
+ if (remainder > 0) {
+ buf->Consume(4 - remainder);
+ }
+}
+
+void StunAttribute::WritePadding(rtc::ByteBuffer* 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 type, uint16 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;
+ }
+}
+
+StunAddressAttribute* StunAttribute::CreateAddress(uint16 type) {
+ return new StunAddressAttribute(type, 0);
+}
+
+StunXorAddressAttribute* StunAttribute::CreateXorAddress(uint16 type) {
+ return new StunXorAddressAttribute(type, 0, NULL);
+}
+
+StunUInt64Attribute* StunAttribute::CreateUInt64(uint16 type) {
+ return new StunUInt64Attribute(type);
+}
+
+StunUInt32Attribute* StunAttribute::CreateUInt32(uint16 type) {
+ return new StunUInt32Attribute(type);
+}
+
+StunByteStringAttribute* StunAttribute::CreateByteString(uint16 type) {
+ return new StunByteStringAttribute(type, 0);
+}
+
+StunErrorCodeAttribute* StunAttribute::CreateErrorCode() {
+ return new StunErrorCodeAttribute(
+ STUN_ATTR_ERROR_CODE, StunErrorCodeAttribute::MIN_SIZE);
+}
+
+StunUInt16ListAttribute* StunAttribute::CreateUnknownAttributes() {
+ return new StunUInt16ListAttribute(STUN_ATTR_UNKNOWN_ATTRIBUTES, 0);
+}
+
+StunAddressAttribute::StunAddressAttribute(uint16 type,
+ const rtc::SocketAddress& addr)
+ : StunAttribute(type, 0) {
+ SetAddress(addr);
+}
+
+StunAddressAttribute::StunAddressAttribute(uint16 type, uint16 length)
+ : StunAttribute(type, length) {
+}
+
+bool StunAddressAttribute::Read(ByteBuffer* buf) {
+ uint8 dummy;
+ if (!buf->ReadUInt8(&dummy))
+ return false;
+
+ uint8 stun_family;
+ if (!buf->ReadUInt8(&stun_family)) {
+ return false;
+ }
+ uint16 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(ByteBuffer* buf) const {
+ StunAddressFamily address_family = family();
+ if (address_family == STUN_ADDRESS_UNDEF) {
+ 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 type,
+ const rtc::SocketAddress& addr)
+ : StunAddressAttribute(type, addr), owner_(NULL) {
+}
+
+StunXorAddressAttribute::StunXorAddressAttribute(uint16 type,
+ uint16 length,
+ StunMessage* owner)
+ : StunAddressAttribute(type, length), 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 transactionid_as_ints[3];
+ memcpy(&transactionid_as_ints[0], transaction_id.c_str(),
+ transaction_id.length());
+ uint32* ip_as_ints = reinterpret_cast<uint32*>(&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(ByteBuffer* buf) {
+ if (!StunAddressAttribute::Read(buf))
+ return false;
+ uint16 xoredport = port() ^ (kStunMagicCookie >> 16);
+ rtc::IPAddress xored_ip = GetXoredIP();
+ SetAddress(rtc::SocketAddress(xored_ip, xoredport));
+ return true;
+}
+
+bool StunXorAddressAttribute::Write(ByteBuffer* buf) const {
+ StunAddressFamily address_family = family();
+ if (address_family == STUN_ADDRESS_UNDEF) {
+ 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 type, uint32 value)
+ : StunAttribute(type, SIZE), bits_(value) {
+}
+
+StunUInt32Attribute::StunUInt32Attribute(uint16 type)
+ : StunAttribute(type, SIZE), bits_(0) {
+}
+
+bool StunUInt32Attribute::GetBit(size_t index) const {
+ ASSERT(index < 32);
+ return static_cast<bool>((bits_ >> index) & 0x1);
+}
+
+void StunUInt32Attribute::SetBit(size_t index, bool value) {
+ ASSERT(index < 32);
+ bits_ &= ~(1 << index);
+ bits_ |= value ? (1 << index) : 0;
+}
+
+bool StunUInt32Attribute::Read(ByteBuffer* buf) {
+ if (length() != SIZE || !buf->ReadUInt32(&bits_))
+ return false;
+ return true;
+}
+
+bool StunUInt32Attribute::Write(ByteBuffer* buf) const {
+ buf->WriteUInt32(bits_);
+ return true;
+}
+
+StunUInt64Attribute::StunUInt64Attribute(uint16 type, uint64 value)
+ : StunAttribute(type, SIZE), bits_(value) {
+}
+
+StunUInt64Attribute::StunUInt64Attribute(uint16 type)
+ : StunAttribute(type, SIZE), bits_(0) {
+}
+
+bool StunUInt64Attribute::Read(ByteBuffer* buf) {
+ if (length() != SIZE || !buf->ReadUInt64(&bits_))
+ return false;
+ return true;
+}
+
+bool StunUInt64Attribute::Write(ByteBuffer* buf) const {
+ buf->WriteUInt64(bits_);
+ return true;
+}
+
+StunByteStringAttribute::StunByteStringAttribute(uint16 type)
+ : StunAttribute(type, 0), bytes_(NULL) {
+}
+
+StunByteStringAttribute::StunByteStringAttribute(uint16 type,
+ const std::string& str)
+ : StunAttribute(type, 0), bytes_(NULL) {
+ CopyBytes(str.c_str(), str.size());
+}
+
+StunByteStringAttribute::StunByteStringAttribute(uint16 type,
+ const void* bytes,
+ size_t length)
+ : StunAttribute(type, 0), bytes_(NULL) {
+ CopyBytes(bytes, length);
+}
+
+StunByteStringAttribute::StunByteStringAttribute(uint16 type, uint16 length)
+ : StunAttribute(type, length), bytes_(NULL) {
+}
+
+StunByteStringAttribute::~StunByteStringAttribute() {
+ delete [] bytes_;
+}
+
+void StunByteStringAttribute::CopyBytes(const char* bytes) {
+ CopyBytes(bytes, strlen(bytes));
+}
+
+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 StunByteStringAttribute::GetByte(size_t index) const {
+ ASSERT(bytes_ != NULL);
+ ASSERT(index < length());
+ return static_cast<uint8>(bytes_[index]);
+}
+
+void StunByteStringAttribute::SetByte(size_t index, uint8 value) {
+ ASSERT(bytes_ != NULL);
+ ASSERT(index < length());
+ bytes_[index] = value;
+}
+
+bool StunByteStringAttribute::Read(ByteBuffer* buf) {
+ bytes_ = new char[length()];
+ if (!buf->ReadBytes(bytes_, length())) {
+ return false;
+ }
+
+ ConsumePadding(buf);
+ return true;
+}
+
+bool StunByteStringAttribute::Write(ByteBuffer* buf) const {
+ buf->WriteBytes(bytes_, length());
+ WritePadding(buf);
+ return true;
+}
+
+void StunByteStringAttribute::SetBytes(char* bytes, size_t length) {
+ delete [] bytes_;
+ bytes_ = bytes;
+ SetLength(static_cast<uint16>(length));
+}
+
+StunErrorCodeAttribute::StunErrorCodeAttribute(uint16 type, int code,
+ const std::string& reason)
+ : StunAttribute(type, 0) {
+ SetCode(code);
+ SetReason(reason);
+}
+
+StunErrorCodeAttribute::StunErrorCodeAttribute(uint16 type, uint16 length)
+ : StunAttribute(type, length), class_(0), number_(0) {
+}
+
+StunErrorCodeAttribute::~StunErrorCodeAttribute() {
+}
+
+int StunErrorCodeAttribute::code() const {
+ return class_ * 100 + number_;
+}
+
+void StunErrorCodeAttribute::SetCode(int code) {
+ class_ = static_cast<uint8>(code / 100);
+ number_ = static_cast<uint8>(code % 100);
+}
+
+void StunErrorCodeAttribute::SetReason(const std::string& reason) {
+ SetLength(MIN_SIZE + static_cast<uint16>(reason.size()));
+ reason_ = reason;
+}
+
+bool StunErrorCodeAttribute::Read(ByteBuffer* buf) {
+ uint32 val;
+ if (length() < MIN_SIZE || !buf->ReadUInt32(&val))
+ return false;
+
+ if ((val >> 11) != 0)
+ 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(ByteBuffer* buf) const {
+ buf->WriteUInt32(class_ << 8 | number_);
+ buf->WriteString(reason_);
+ WritePadding(buf);
+ return true;
+}
+
+StunUInt16ListAttribute::StunUInt16ListAttribute(uint16 type, uint16 length)
+ : StunAttribute(type, length) {
+ attr_types_ = new std::vector<uint16>();
+}
+
+StunUInt16ListAttribute::~StunUInt16ListAttribute() {
+ delete attr_types_;
+}
+
+size_t StunUInt16ListAttribute::Size() const {
+ return attr_types_->size();
+}
+
+uint16 StunUInt16ListAttribute::GetType(int index) const {
+ return (*attr_types_)[index];
+}
+
+void StunUInt16ListAttribute::SetType(int index, uint16 value) {
+ (*attr_types_)[index] = value;
+}
+
+void StunUInt16ListAttribute::AddType(uint16 value) {
+ attr_types_->push_back(value);
+ SetLength(static_cast<uint16>(attr_types_->size() * 2));
+}
+
+bool StunUInt16ListAttribute::Read(ByteBuffer* buf) {
+ if (length() % 2)
+ return false;
+
+ for (size_t i = 0; i < length() / 2; i++) {
+ uint16 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(ByteBuffer* buf) const {
+ for (size_t i = 0; i < attr_types_->size(); ++i) {
+ buf->WriteUInt16((*attr_types_)[i]);
+ }
+ WritePadding(buf);
+ return true;
+}
+
+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;
+}
+
+} // namespace cricket
diff --git a/p2p/base/stun.h b/p2p/base/stun.h
new file mode 100644
index 00000000..0f600dbf
--- /dev/null
+++ b/p2p/base/stun.h
@@ -0,0 +1,632 @@
+/*
+ * 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 WEBRTC_P2P_BASE_STUN_H_
+#define WEBRTC_P2P_BASE_STUN_H_
+
+// This file contains classes for dealing with the STUN protocol, as specified
+// in RFC 5389, and its descendants.
+
+#include <string>
+#include <vector>
+
+#include "webrtc/base/basictypes.h"
+#include "webrtc/base/bytebuffer.h"
+#include "webrtc/base/socketaddress.h"
+
+namespace cricket {
+
+// These are the types of STUN messages defined in RFC 5389.
+enum StunMessageType {
+ STUN_BINDING_REQUEST = 0x0001,
+ STUN_BINDING_INDICATION = 0x0011,
+ STUN_BINDING_RESPONSE = 0x0101,
+ STUN_BINDING_ERROR_RESPONSE = 0x0111,
+};
+
+// 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_CREDENTIALS = 430, // GICE only
+ 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_CREDENTIALS[];
+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 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 kStunMagicCookie = 0x2112A442;
+const 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;
+
+class StunAttribute;
+class StunAddressAttribute;
+class StunXorAddressAttribute;
+class StunUInt32Attribute;
+class StunUInt64Attribute;
+class StunByteStringAttribute;
+class StunErrorCodeAttribute;
+class StunUInt16ListAttribute;
+
+// 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:
+ StunMessage();
+ virtual ~StunMessage();
+
+ int type() const { return type_; }
+ size_t length() const { return length_; }
+ const std::string& transaction_id() const { return transaction_id_; }
+
+ // Returns true if the message confirms to RFC3489 rather than
+ // RFC5389. The main difference between two version of the STUN
+ // protocol is the presence of the magic cookie and different length
+ // of transaction ID. For outgoing packets version of the protocol
+ // is determined by the lengths of the transaction ID.
+ bool IsLegacy() const;
+
+ void SetType(int type) { type_ = static_cast<uint16>(type); }
+ bool SetTransactionID(const std::string& str);
+
+ // 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;
+
+ // Gets these specific attribute values.
+ const StunErrorCodeAttribute* GetErrorCode() const;
+ const StunUInt16ListAttribute* GetUnknownAttributes() const;
+
+ // Takes ownership of the specified attribute, verifies it is of the correct
+ // type, and adds it to the message. The return value indicates whether this
+ // was successful.
+ bool AddAttribute(StunAttribute* attr);
+
+ // Validates that a raw STUN message has a correct MESSAGE-INTEGRITY value.
+ // This can't currently be done on a StunMessage, since it is affected by
+ // padding data (which we discard when reading a StunMessage).
+ static bool ValidateMessageIntegrity(const char* data, size_t size,
+ const std::string& password);
+ // Adds a MESSAGE-INTEGRITY attribute that is valid for the current message.
+ bool AddMessageIntegrity(const std::string& password);
+ bool AddMessageIntegrity(const char* key, size_t keylen);
+
+ // Verifies that a given buffer is STUN by checking for a correct FINGERPRINT.
+ static bool ValidateFingerprint(const char* data, size_t size);
+
+ // 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::ByteBuffer* buf);
+
+ // Writes this object into a STUN packet. The return value indicates whether
+ // this was successful.
+ bool Write(rtc::ByteBuffer* buf) const;
+
+ // Creates an empty message. Overridable by derived classes.
+ virtual StunMessage* CreateNew() const { return new StunMessage(); }
+
+ protected:
+ // Verifies that the given attribute is allowed for this message.
+ virtual StunAttributeValueType GetAttributeValueType(int type) const;
+
+ private:
+ StunAttribute* CreateAttribute(int type, size_t length) /* const*/;
+ const StunAttribute* GetAttribute(int type) const;
+ static bool IsValidTransactionId(const std::string& transaction_id);
+
+ uint16 type_;
+ uint16 length_;
+ std::string transaction_id_;
+ std::vector<StunAttribute*>* attrs_;
+};
+
+// 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::ByteBuffer* buf) = 0;
+
+ // Writes the body (not the type or length) to the given buffer. Return
+ // value is true if successful.
+ virtual bool Write(rtc::ByteBuffer* buf) const = 0;
+
+ // Creates an attribute object with the given type and smallest length.
+ static StunAttribute* Create(StunAttributeValueType value_type, uint16 type,
+ uint16 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 StunAddressAttribute* CreateAddress(uint16 type);
+ static StunXorAddressAttribute* CreateXorAddress(uint16 type);
+ static StunUInt32Attribute* CreateUInt32(uint16 type);
+ static StunUInt64Attribute* CreateUInt64(uint16 type);
+ static StunByteStringAttribute* CreateByteString(uint16 type);
+ static StunErrorCodeAttribute* CreateErrorCode();
+ static StunUInt16ListAttribute* CreateUnknownAttributes();
+
+ protected:
+ StunAttribute(uint16 type, uint16 length);
+ void SetLength(uint16 length) { length_ = length; }
+ void WritePadding(rtc::ByteBuffer* buf) const;
+ void ConsumePadding(rtc::ByteBuffer* buf) const;
+
+ private:
+ uint16 type_;
+ uint16 length_;
+};
+
+// Implements STUN attributes that record an Internet address.
+class StunAddressAttribute : public StunAttribute {
+ public:
+ static const uint16 SIZE_UNDEF = 0;
+ static const uint16 SIZE_IP4 = 8;
+ static const uint16 SIZE_IP6 = 20;
+ StunAddressAttribute(uint16 type, const rtc::SocketAddress& addr);
+ StunAddressAttribute(uint16 type, uint16 length);
+
+ virtual StunAttributeValueType value_type() const {
+ return STUN_VALUE_ADDRESS;
+ }
+
+ 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 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 port) { address_.SetPort(port); }
+
+ virtual bool Read(rtc::ByteBuffer* buf);
+ virtual bool Write(rtc::ByteBuffer* buf) const;
+
+ 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 type, const rtc::SocketAddress& addr);
+ StunXorAddressAttribute(uint16 type, uint16 length,
+ StunMessage* owner);
+
+ virtual StunAttributeValueType value_type() const {
+ return STUN_VALUE_XOR_ADDRESS;
+ }
+ virtual void SetOwner(StunMessage* owner) {
+ owner_ = owner;
+ }
+ virtual bool Read(rtc::ByteBuffer* buf);
+ virtual bool Write(rtc::ByteBuffer* buf) const;
+
+ private:
+ rtc::IPAddress GetXoredIP() const;
+ StunMessage* owner_;
+};
+
+// Implements STUN attributes that record a 32-bit integer.
+class StunUInt32Attribute : public StunAttribute {
+ public:
+ static const uint16 SIZE = 4;
+ StunUInt32Attribute(uint16 type, uint32 value);
+ explicit StunUInt32Attribute(uint16 type);
+
+ virtual StunAttributeValueType value_type() const {
+ return STUN_VALUE_UINT32;
+ }
+
+ uint32 value() const { return bits_; }
+ void SetValue(uint32 bits) { bits_ = bits; }
+
+ bool GetBit(size_t index) const;
+ void SetBit(size_t index, bool value);
+
+ virtual bool Read(rtc::ByteBuffer* buf);
+ virtual bool Write(rtc::ByteBuffer* buf) const;
+
+ private:
+ uint32 bits_;
+};
+
+class StunUInt64Attribute : public StunAttribute {
+ public:
+ static const uint16 SIZE = 8;
+ StunUInt64Attribute(uint16 type, uint64 value);
+ explicit StunUInt64Attribute(uint16 type);
+
+ virtual StunAttributeValueType value_type() const {
+ return STUN_VALUE_UINT64;
+ }
+
+ uint64 value() const { return bits_; }
+ void SetValue(uint64 bits) { bits_ = bits; }
+
+ virtual bool Read(rtc::ByteBuffer* buf);
+ virtual bool Write(rtc::ByteBuffer* buf) const;
+
+ private:
+ uint64 bits_;
+};
+
+// Implements STUN attributes that record an arbitrary byte string.
+class StunByteStringAttribute : public StunAttribute {
+ public:
+ explicit StunByteStringAttribute(uint16 type);
+ StunByteStringAttribute(uint16 type, const std::string& str);
+ StunByteStringAttribute(uint16 type, const void* bytes, size_t length);
+ StunByteStringAttribute(uint16 type, uint16 length);
+ ~StunByteStringAttribute();
+
+ virtual StunAttributeValueType value_type() const {
+ return STUN_VALUE_BYTE_STRING;
+ }
+
+ const char* bytes() const { return bytes_; }
+ std::string GetString() const { return std::string(bytes_, length()); }
+
+ void CopyBytes(const char* bytes); // uses strlen
+ void CopyBytes(const void* bytes, size_t length);
+
+ uint8 GetByte(size_t index) const;
+ void SetByte(size_t index, uint8 value);
+
+ virtual bool Read(rtc::ByteBuffer* buf);
+ virtual bool Write(rtc::ByteBuffer* buf) const;
+
+ 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 MIN_SIZE = 4;
+ StunErrorCodeAttribute(uint16 type, int code, const std::string& reason);
+ StunErrorCodeAttribute(uint16 type, uint16 length);
+ ~StunErrorCodeAttribute();
+
+ virtual StunAttributeValueType value_type() const {
+ return STUN_VALUE_ERROR_CODE;
+ }
+
+ // 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 eclass) { class_ = eclass; }
+ void SetNumber(uint8 number) { number_ = number; }
+ void SetReason(const std::string& reason);
+
+ bool Read(rtc::ByteBuffer* buf);
+ bool Write(rtc::ByteBuffer* buf) const;
+
+ private:
+ uint8 class_;
+ uint8 number_;
+ std::string reason_;
+};
+
+// Implements STUN attributes that record a list of attribute names.
+class StunUInt16ListAttribute : public StunAttribute {
+ public:
+ StunUInt16ListAttribute(uint16 type, uint16 length);
+ ~StunUInt16ListAttribute();
+
+ virtual StunAttributeValueType value_type() const {
+ return STUN_VALUE_UINT16_LIST;
+ }
+
+ size_t Size() const;
+ uint16 GetType(int index) const;
+ void SetType(int index, uint16 value);
+ void AddType(uint16 value);
+
+ bool Read(rtc::ByteBuffer* buf);
+ bool Write(rtc::ByteBuffer* buf) const;
+
+ private:
+ std::vector<uint16>* attr_types_;
+};
+
+// 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);
+
+// 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 {
+ protected:
+ virtual StunAttributeValueType 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);
+ }
+ }
+ virtual StunMessage* CreateNew() const { return new RelayMessage(); }
+};
+
+// Defined in TURN RFC 5766.
+enum TurnMessageType {
+ 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 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 {
+ protected:
+ virtual StunAttributeValueType 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);
+ }
+ }
+ virtual StunMessage* CreateNew() const { return new TurnMessage(); }
+};
+
+// RFC 5245 ICE STUN attributes.
+enum IceAttributeType {
+ 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
+};
+
+// 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 {
+ protected:
+ virtual StunAttributeValueType GetAttributeValueType(int type) const {
+ switch (type) {
+ case STUN_ATTR_PRIORITY: 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);
+ }
+ }
+ virtual StunMessage* CreateNew() const { return new IceMessage(); }
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_STUN_H_
diff --git a/p2p/base/stun_unittest.cc b/p2p/base/stun_unittest.cc
new file mode 100644
index 00000000..396beb6a
--- /dev/null
+++ b/p2p/base/stun_unittest.cc
@@ -0,0 +1,1402 @@
+/*
+ * 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 <string>
+
+#include "webrtc/p2p/base/stun.h"
+#include "webrtc/base/bytebuffer.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/messagedigest.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/socketaddress.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,
+ 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::ByteBuffer 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
+
+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 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,
+};
+
+// 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.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 // }
+};
+
+// 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 // }
+};
+
+// 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 (int i = 0; i < ARRAY_SIZE(types); ++i) {
+ EXPECT_EQ(i == 0, IsStunRequestType(types[i]));
+ EXPECT_EQ(i == 1, IsStunIndicationType(types[i]));
+ EXPECT_EQ(i == 2, IsStunSuccessResponseType(types[i]));
+ EXPECT_EQ(i == 3, 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->GetString());
+
+ const StunByteStringAttribute* username =
+ msg.GetByteString(STUN_ATTR_USERNAME);
+ ASSERT_TRUE(username != NULL);
+ EXPECT_EQ(kRfc5769SampleMsgUsername, username->GetString());
+
+ // 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->GetString());
+
+ 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->GetString());
+
+ 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->GetString());
+
+ const StunByteStringAttribute* nonce =
+ msg.GetByteString(STUN_ATTR_NONCE);
+ ASSERT_TRUE(nonce != NULL);
+ EXPECT_EQ(kRfc5769SampleMsgWithAuthNonce, nonce->GetString());
+
+ const StunByteStringAttribute* realm =
+ msg.GetByteString(STUN_ATTR_REALM);
+ ASSERT_TRUE(realm != NULL);
+ EXPECT_EQ(kRfc5769SampleMsgWithAuthRealm, realm->GetString());
+
+ // 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;
+ StunMessage msg2;
+ 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.
+ msg2.SetTransactionID("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::ByteBuffer correct_buf;
+ rtc::ByteBuffer 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.
+ addr2.Read(&correct_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.Consume(wrong_buf.Length());
+ 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;
+ StunMessage msg2;
+ 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.
+ msg2.SetTransactionID("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::ByteBuffer correct_buf;
+ rtc::ByteBuffer 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.
+ EXPECT_TRUE(addr2.Read(&correct_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.Consume(wrong_buf.Length());
+ EXPECT_FALSE(addr2.Write(&wrong_buf));
+}
+
+TEST_F(StunTest, CreateIPv6AddressAttribute) {
+ rtc::IPAddress test_ip(kIPv6TestAddress2);
+
+ StunAddressAttribute* addr =
+ StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
+ rtc::SocketAddress test_addr(test_ip, kTestMessagePort2);
+ addr->SetAddress(test_addr);
+
+ CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6,
+ kTestMessagePort2, test_ip);
+ delete addr;
+}
+
+TEST_F(StunTest, CreateIPv4AddressAttribute) {
+ struct in_addr test_in_addr;
+ test_in_addr.s_addr = 0xBEB0B0BE;
+ rtc::IPAddress test_ip(test_in_addr);
+
+ StunAddressAttribute* addr =
+ StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
+ rtc::SocketAddress test_addr(test_ip, kTestMessagePort2);
+ addr->SetAddress(test_addr);
+
+ CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4,
+ kTestMessagePort2, test_ip);
+ delete addr;
+}
+
+// Test that we don't care what order we set the parts of an address
+TEST_F(StunTest, CreateAddressInArbitraryOrder) {
+ StunAddressAttribute* 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());
+
+ StunAddressAttribute* 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());
+
+ delete addr;
+ delete addr2;
+}
+
+TEST_F(StunTest, WriteMessageWithIPv6AddressAttribute) {
+ StunMessage msg;
+ size_t size = sizeof(kStunMessageWithIPv6MappedAddress);
+
+ rtc::IPAddress test_ip(kIPv6TestAddress1);
+
+ msg.SetType(STUN_BINDING_REQUEST);
+ msg.SetTransactionID(
+ std::string(reinterpret_cast<const char*>(kTestTransactionId1),
+ kStunTransactionIdLength));
+ CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
+
+ StunAddressAttribute* addr =
+ StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
+ rtc::SocketAddress test_addr(test_ip, kTestMessagePort2);
+ addr->SetAddress(test_addr);
+ EXPECT_TRUE(msg.AddAttribute(addr));
+
+ CheckStunHeader(msg, STUN_BINDING_REQUEST, (size - 20));
+
+ rtc::ByteBuffer out;
+ EXPECT_TRUE(msg.Write(&out));
+ ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv6MappedAddress));
+ int len1 = static_cast<int>(out.Length());
+ std::string bytes;
+ out.ReadString(&bytes, len1);
+ ASSERT_EQ(0, memcmp(bytes.c_str(), kStunMessageWithIPv6MappedAddress, len1));
+}
+
+TEST_F(StunTest, WriteMessageWithIPv4AddressAttribute) {
+ StunMessage msg;
+ size_t size = sizeof(kStunMessageWithIPv4MappedAddress);
+
+ rtc::IPAddress test_ip(kIPv4TestAddress1);
+
+ msg.SetType(STUN_BINDING_RESPONSE);
+ msg.SetTransactionID(
+ std::string(reinterpret_cast<const char*>(kTestTransactionId1),
+ kStunTransactionIdLength));
+ CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
+
+ StunAddressAttribute* addr =
+ StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
+ rtc::SocketAddress test_addr(test_ip, kTestMessagePort4);
+ addr->SetAddress(test_addr);
+ EXPECT_TRUE(msg.AddAttribute(addr));
+
+ CheckStunHeader(msg, STUN_BINDING_RESPONSE, (size - 20));
+
+ rtc::ByteBuffer out;
+ EXPECT_TRUE(msg.Write(&out));
+ ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv4MappedAddress));
+ int len1 = static_cast<int>(out.Length());
+ std::string bytes;
+ out.ReadString(&bytes, len1);
+ ASSERT_EQ(0, memcmp(bytes.c_str(), kStunMessageWithIPv4MappedAddress, len1));
+}
+
+TEST_F(StunTest, WriteMessageWithIPv6XorAddressAttribute) {
+ StunMessage msg;
+ size_t size = sizeof(kStunMessageWithIPv6XorMappedAddress);
+
+ rtc::IPAddress test_ip(kIPv6TestAddress1);
+
+ msg.SetType(STUN_BINDING_RESPONSE);
+ msg.SetTransactionID(
+ std::string(reinterpret_cast<const char*>(kTestTransactionId2),
+ kStunTransactionIdLength));
+ CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
+
+ StunAddressAttribute* addr =
+ StunAttribute::CreateXorAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
+ rtc::SocketAddress test_addr(test_ip, kTestMessagePort1);
+ addr->SetAddress(test_addr);
+ EXPECT_TRUE(msg.AddAttribute(addr));
+
+ CheckStunHeader(msg, STUN_BINDING_RESPONSE, (size - 20));
+
+ rtc::ByteBuffer out;
+ EXPECT_TRUE(msg.Write(&out));
+ ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv6XorMappedAddress));
+ int len1 = static_cast<int>(out.Length());
+ std::string bytes;
+ out.ReadString(&bytes, len1);
+ ASSERT_EQ(0,
+ memcmp(bytes.c_str(), kStunMessageWithIPv6XorMappedAddress, len1));
+}
+
+TEST_F(StunTest, WriteMessageWithIPv4XoreAddressAttribute) {
+ StunMessage msg;
+ size_t size = sizeof(kStunMessageWithIPv4XorMappedAddress);
+
+ rtc::IPAddress test_ip(kIPv4TestAddress1);
+
+ msg.SetType(STUN_BINDING_RESPONSE);
+ msg.SetTransactionID(
+ std::string(reinterpret_cast<const char*>(kTestTransactionId1),
+ kStunTransactionIdLength));
+ CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
+
+ StunAddressAttribute* addr =
+ StunAttribute::CreateXorAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
+ rtc::SocketAddress test_addr(test_ip, kTestMessagePort3);
+ addr->SetAddress(test_addr);
+ EXPECT_TRUE(msg.AddAttribute(addr));
+
+ CheckStunHeader(msg, STUN_BINDING_RESPONSE, (size - 20));
+
+ rtc::ByteBuffer out;
+ EXPECT_TRUE(msg.Write(&out));
+ ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv4XorMappedAddress));
+ int len1 = static_cast<int>(out.Length());
+ std::string bytes;
+ out.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->GetString());
+}
+
+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->GetString());
+}
+
+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());
+}
+
+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->GetString());
+}
+
+TEST_F(StunTest, WriteMessageWithAnErrorCodeAttribute) {
+ StunMessage msg;
+ size_t size = sizeof(kStunMessageWithErrorAttribute);
+
+ msg.SetType(STUN_BINDING_ERROR_RESPONSE);
+ msg.SetTransactionID(
+ std::string(reinterpret_cast<const char*>(kTestTransactionId1),
+ kStunTransactionIdLength));
+ CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
+ StunErrorCodeAttribute* errorcode = StunAttribute::CreateErrorCode();
+ errorcode->SetCode(kTestErrorCode);
+ errorcode->SetReason(kTestErrorReason);
+ EXPECT_TRUE(msg.AddAttribute(errorcode));
+ CheckStunHeader(msg, STUN_BINDING_ERROR_RESPONSE, (size - 20));
+
+ rtc::ByteBuffer 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) {
+ StunMessage msg;
+ size_t size = sizeof(kStunMessageWithUInt16ListAttribute);
+
+ msg.SetType(STUN_BINDING_REQUEST);
+ msg.SetTransactionID(
+ std::string(reinterpret_cast<const char*>(kTestTransactionId2),
+ kStunTransactionIdLength));
+ CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
+ StunUInt16ListAttribute* list = StunAttribute::CreateUnknownAttributes();
+ list->AddType(0x1U);
+ list->AddType(0x1000U);
+ list->AddType(0xAB0CU);
+ EXPECT_TRUE(msg.AddAttribute(list));
+ CheckStunHeader(msg, STUN_BINDING_REQUEST, (size - 20));
+
+ rtc::ByteBuffer 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::ByteBuffer 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::ValidateMessageIntegrity(
+ reinterpret_cast<const char*>(kRfc5769SampleRequest),
+ sizeof(kRfc5769SampleRequest),
+ kRfc5769SampleMsgPassword));
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
+ reinterpret_cast<const char*>(kRfc5769SampleRequest),
+ sizeof(kRfc5769SampleRequest),
+ "InvalidPassword"));
+
+ EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
+ reinterpret_cast<const char*>(kRfc5769SampleResponse),
+ sizeof(kRfc5769SampleResponse),
+ kRfc5769SampleMsgPassword));
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
+ reinterpret_cast<const char*>(kRfc5769SampleResponse),
+ sizeof(kRfc5769SampleResponse),
+ "InvalidPassword"));
+
+ EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
+ reinterpret_cast<const char*>(kRfc5769SampleResponseIPv6),
+ sizeof(kRfc5769SampleResponseIPv6),
+ kRfc5769SampleMsgPassword));
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
+ 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::ValidateMessageIntegrity(
+ reinterpret_cast<const char*>(kRfc5769SampleRequestLongTermAuth),
+ sizeof(kRfc5769SampleRequestLongTermAuth), key));
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
+ reinterpret_cast<const char*>(kRfc5769SampleRequestLongTermAuth),
+ sizeof(kRfc5769SampleRequestLongTermAuth),
+ "InvalidPassword"));
+
+ // Try some edge cases.
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
+ reinterpret_cast<const char*>(kStunMessageWithZeroLength),
+ sizeof(kStunMessageWithZeroLength),
+ kRfc5769SampleMsgPassword));
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
+ reinterpret_cast<const char*>(kStunMessageWithExcessLength),
+ sizeof(kStunMessageWithExcessLength),
+ kRfc5769SampleMsgPassword));
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
+ reinterpret_cast<const char*>(kStunMessageWithSmallLength),
+ sizeof(kStunMessageWithSmallLength),
+ 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::ValidateMessageIntegrity(
+ 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::ByteBuffer 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::ByteBuffer buf1;
+ EXPECT_TRUE(msg.Write(&buf1));
+ EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
+ reinterpret_cast<const char*>(buf1.Data()), buf1.Length(),
+ kRfc5769SampleMsgPassword));
+
+ IceMessage msg2;
+ rtc::ByteBuffer 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::ByteBuffer buf3;
+ EXPECT_TRUE(msg2.Write(&buf3));
+ EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
+ reinterpret_cast<const char*>(buf3.Data()), buf3.Length(),
+ kRfc5769SampleMsgPassword));
+}
+
+// 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::ByteBuffer buf(
+ reinterpret_cast<const char*>(kRfc5769SampleRequestWithoutMI),
+ sizeof(kRfc5769SampleRequestWithoutMI));
+ EXPECT_TRUE(msg.Read(&buf));
+ EXPECT_TRUE(msg.AddFingerprint());
+
+ rtc::ByteBuffer buf1;
+ EXPECT_TRUE(msg.Write(&buf1));
+ EXPECT_TRUE(StunMessage::ValidateFingerprint(
+ reinterpret_cast<const char*>(buf1.Data()), buf1.Length()));
+}
+
+// Sample "GTURN" relay message.
+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.
+};
+
+// Test that we can read the GTURN-specific fields.
+TEST_F(StunTest, ReadRelayMessage) {
+ RelayMessage msg, msg2;
+
+ const char* input = reinterpret_cast<const char*>(kRelayMessage);
+ size_t size = sizeof(kRelayMessage);
+ rtc::ByteBuffer 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());
+
+ msg2.SetType(STUN_BINDING_REQUEST);
+ msg2.SetTransactionID("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());
+
+ StunAddressAttribute* addr2 =
+ StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
+ addr2->SetPort(13);
+ addr2->SetIP(legacy_ip);
+ EXPECT_TRUE(msg2.AddAttribute(addr2));
+
+ const StunByteStringAttribute* bytes = msg.GetByteString(STUN_ATTR_USERNAME);
+ ASSERT_TRUE(bytes != NULL);
+ EXPECT_EQ(12U, bytes->length());
+ EXPECT_EQ("abcdefghijkl", bytes->GetString());
+
+ StunByteStringAttribute* bytes2 =
+ StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
+ bytes2->CopyBytes("abcdefghijkl");
+ EXPECT_TRUE(msg2.AddAttribute(bytes2));
+
+ const StunUInt32Attribute* uval = msg.GetUInt32(STUN_ATTR_LIFETIME);
+ ASSERT_TRUE(uval != NULL);
+ EXPECT_EQ(11U, uval->value());
+
+ StunUInt32Attribute* uval2 = StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME);
+ uval2->SetValue(11);
+ EXPECT_TRUE(msg2.AddAttribute(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));
+ EXPECT_TRUE(msg2.AddAttribute(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);
+ EXPECT_TRUE(msg2.AddAttribute(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);
+ EXPECT_TRUE(msg2.AddAttribute(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);
+ EXPECT_TRUE(msg2.AddAttribute(addr2));
+
+ bytes = msg.GetByteString(STUN_ATTR_DATA);
+ ASSERT_TRUE(bytes != NULL);
+ EXPECT_EQ(7U, bytes->length());
+ EXPECT_EQ("abcdefg", bytes->GetString());
+
+ bytes2 = StunAttribute::CreateByteString(STUN_ATTR_DATA);
+ bytes2->CopyBytes("abcdefg");
+ EXPECT_TRUE(msg2.AddAttribute(bytes2));
+
+ rtc::ByteBuffer out;
+ EXPECT_TRUE(msg.Write(&out));
+ EXPECT_EQ(size, out.Length());
+ size_t len1 = out.Length();
+ std::string outstring;
+ out.ReadString(&outstring, len1);
+ EXPECT_EQ(0, memcmp(outstring.c_str(), input, len1));
+
+ rtc::ByteBuffer out2;
+ EXPECT_TRUE(msg2.Write(&out2));
+ EXPECT_EQ(size, out2.Length());
+ size_t len2 = out2.Length();
+ std::string outstring2;
+ out2.ReadString(&outstring2, len2);
+ EXPECT_EQ(0, memcmp(outstring2.c_str(), input, len2));
+}
+
+} // namespace cricket
diff --git a/p2p/base/stunport.cc b/p2p/base/stunport.cc
new file mode 100644
index 00000000..ec6232a6
--- /dev/null
+++ b/p2p/base/stunport.cc
@@ -0,0 +1,451 @@
+/*
+ * 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 "webrtc/p2p/base/stunport.h"
+
+#include "webrtc/p2p/base/common.h"
+#include "webrtc/p2p/base/portallocator.h"
+#include "webrtc/p2p/base/stun.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/nethelpers.h"
+
+namespace cricket {
+
+// TODO: Move these to a common place (used in relayport too)
+const int KEEPALIVE_DELAY = 10 * 1000; // 10 seconds - sort timeouts
+const int RETRY_DELAY = 50; // 50ms, from ICE spec
+const int RETRY_TIMEOUT = 50 * 1000; // ICE says 50 secs
+
+// Handles a binding request sent to the STUN server.
+class StunBindingRequest : public StunRequest {
+ public:
+ StunBindingRequest(UDPPort* port, bool keep_alive,
+ const rtc::SocketAddress& addr)
+ : port_(port), keep_alive_(keep_alive), server_addr_(addr) {
+ start_time_ = rtc::Time();
+ }
+
+ virtual ~StunBindingRequest() {
+ }
+
+ const rtc::SocketAddress& server_addr() const { return server_addr_; }
+
+ virtual void Prepare(StunMessage* request) {
+ request->SetType(STUN_BINDING_REQUEST);
+ }
+
+ virtual void OnResponse(StunMessage* response) {
+ const StunAddressAttribute* addr_attr =
+ response->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
+ if (!addr_attr) {
+ LOG(LS_ERROR) << "Binding response missing mapped address.";
+ } else if (addr_attr->family() != STUN_ADDRESS_IPV4 &&
+ addr_attr->family() != STUN_ADDRESS_IPV6) {
+ LOG(LS_ERROR) << "Binding address has bad family";
+ } else {
+ rtc::SocketAddress addr(addr_attr->ipaddr(), addr_attr->port());
+ port_->OnStunBindingRequestSucceeded(server_addr_, addr);
+ }
+
+ // We will do a keep-alive regardless of whether this request succeeds.
+ // This should have almost no impact on network usage.
+ if (keep_alive_) {
+ port_->requests_.SendDelayed(
+ new StunBindingRequest(port_, true, server_addr_),
+ port_->stun_keepalive_delay());
+ }
+ }
+
+ virtual void OnErrorResponse(StunMessage* response) {
+ const StunErrorCodeAttribute* attr = response->GetErrorCode();
+ if (!attr) {
+ LOG(LS_ERROR) << "Bad allocate response error code";
+ } else {
+ LOG(LS_ERROR) << "Binding error response:"
+ << " class=" << attr->eclass()
+ << " number=" << attr->number()
+ << " reason='" << attr->reason() << "'";
+ }
+
+ port_->OnStunBindingOrResolveRequestFailed(server_addr_);
+
+ if (keep_alive_
+ && (rtc::TimeSince(start_time_) <= RETRY_TIMEOUT)) {
+ port_->requests_.SendDelayed(
+ new StunBindingRequest(port_, true, server_addr_),
+ port_->stun_keepalive_delay());
+ }
+ }
+
+ virtual void OnTimeout() {
+ LOG(LS_ERROR) << "Binding request timed out from "
+ << port_->GetLocalAddress().ToSensitiveString()
+ << " (" << port_->Network()->name() << ")";
+
+ port_->OnStunBindingOrResolveRequestFailed(server_addr_);
+
+ if (keep_alive_
+ && (rtc::TimeSince(start_time_) <= RETRY_TIMEOUT)) {
+ port_->requests_.SendDelayed(
+ new StunBindingRequest(port_, true, server_addr_),
+ RETRY_DELAY);
+ }
+ }
+
+ private:
+ UDPPort* port_;
+ bool keep_alive_;
+ const rtc::SocketAddress server_addr_;
+ uint32 start_time_;
+};
+
+UDPPort::AddressResolver::AddressResolver(
+ rtc::PacketSocketFactory* factory)
+ : socket_factory_(factory) {}
+
+UDPPort::AddressResolver::~AddressResolver() {
+ for (ResolverMap::iterator it = resolvers_.begin();
+ it != resolvers_.end(); ++it) {
+ it->second->Destroy(true);
+ }
+}
+
+void UDPPort::AddressResolver::Resolve(
+ const rtc::SocketAddress& address) {
+ if (resolvers_.find(address) != resolvers_.end())
+ return;
+
+ rtc::AsyncResolverInterface* resolver =
+ socket_factory_->CreateAsyncResolver();
+ resolvers_.insert(
+ std::pair<rtc::SocketAddress, rtc::AsyncResolverInterface*>(
+ address, resolver));
+
+ resolver->SignalDone.connect(this,
+ &UDPPort::AddressResolver::OnResolveResult);
+
+ resolver->Start(address);
+}
+
+bool UDPPort::AddressResolver::GetResolvedAddress(
+ const rtc::SocketAddress& input,
+ int family,
+ rtc::SocketAddress* output) const {
+ ResolverMap::const_iterator it = resolvers_.find(input);
+ if (it == resolvers_.end())
+ return false;
+
+ return it->second->GetResolvedAddress(family, output);
+}
+
+void UDPPort::AddressResolver::OnResolveResult(
+ rtc::AsyncResolverInterface* resolver) {
+ for (ResolverMap::iterator it = resolvers_.begin();
+ it != resolvers_.end(); ++it) {
+ if (it->second == resolver) {
+ SignalDone(it->first, resolver->GetError());
+ return;
+ }
+ }
+}
+
+UDPPort::UDPPort(rtc::Thread* thread,
+ rtc::PacketSocketFactory* factory,
+ rtc::Network* network,
+ rtc::AsyncPacketSocket* socket,
+ const std::string& username, const std::string& password)
+ : Port(thread, factory, network, socket->GetLocalAddress().ipaddr(),
+ username, password),
+ requests_(thread),
+ socket_(socket),
+ error_(0),
+ ready_(false),
+ stun_keepalive_delay_(KEEPALIVE_DELAY) {
+}
+
+UDPPort::UDPPort(rtc::Thread* thread,
+ rtc::PacketSocketFactory* factory,
+ rtc::Network* network,
+ const rtc::IPAddress& ip, int min_port, int max_port,
+ const std::string& username, const std::string& password)
+ : Port(thread, LOCAL_PORT_TYPE, factory, network, ip, min_port, max_port,
+ username, password),
+ requests_(thread),
+ socket_(NULL),
+ error_(0),
+ ready_(false),
+ stun_keepalive_delay_(KEEPALIVE_DELAY) {
+}
+
+bool UDPPort::Init() {
+ if (!SharedSocket()) {
+ ASSERT(socket_ == NULL);
+ socket_ = socket_factory()->CreateUdpSocket(
+ rtc::SocketAddress(ip(), 0), min_port(), max_port());
+ if (!socket_) {
+ LOG_J(LS_WARNING, this) << "UDP socket creation failed";
+ return false;
+ }
+ socket_->SignalReadPacket.connect(this, &UDPPort::OnReadPacket);
+ }
+ socket_->SignalReadyToSend.connect(this, &UDPPort::OnReadyToSend);
+ socket_->SignalAddressReady.connect(this, &UDPPort::OnLocalAddressReady);
+ requests_.SignalSendPacket.connect(this, &UDPPort::OnSendPacket);
+ return true;
+}
+
+UDPPort::~UDPPort() {
+ if (!SharedSocket())
+ delete socket_;
+}
+
+void UDPPort::PrepareAddress() {
+ ASSERT(requests_.empty());
+ if (socket_->GetState() == rtc::AsyncPacketSocket::STATE_BOUND) {
+ OnLocalAddressReady(socket_, socket_->GetLocalAddress());
+ }
+}
+
+void UDPPort::MaybePrepareStunCandidate() {
+ // Sending binding request to the STUN server if address is available to
+ // prepare STUN candidate.
+ if (!server_addresses_.empty()) {
+ SendStunBindingRequests();
+ } else {
+ // Port is done allocating candidates.
+ MaybeSetPortCompleteOrError();
+ }
+}
+
+Connection* UDPPort::CreateConnection(const Candidate& address,
+ CandidateOrigin origin) {
+ if (address.protocol() != "udp")
+ return NULL;
+
+ if (!IsCompatibleAddress(address.address())) {
+ return NULL;
+ }
+
+ if (SharedSocket() && Candidates()[0].type() != LOCAL_PORT_TYPE) {
+ ASSERT(false);
+ return NULL;
+ }
+
+ Connection* conn = new ProxyConnection(this, 0, address);
+ AddConnection(conn);
+ return conn;
+}
+
+int UDPPort::SendTo(const void* data, size_t size,
+ const rtc::SocketAddress& addr,
+ const rtc::PacketOptions& options,
+ bool payload) {
+ int sent = socket_->SendTo(data, size, addr, options);
+ if (sent < 0) {
+ error_ = socket_->GetError();
+ LOG_J(LS_ERROR, this) << "UDP send of " << size
+ << " bytes failed with error " << error_;
+ }
+ return sent;
+}
+
+int UDPPort::SetOption(rtc::Socket::Option opt, int value) {
+ return socket_->SetOption(opt, value);
+}
+
+int UDPPort::GetOption(rtc::Socket::Option opt, int* value) {
+ return socket_->GetOption(opt, value);
+}
+
+int UDPPort::GetError() {
+ return error_;
+}
+
+void UDPPort::OnLocalAddressReady(rtc::AsyncPacketSocket* socket,
+ const rtc::SocketAddress& address) {
+ AddAddress(address, address, rtc::SocketAddress(),
+ UDP_PROTOCOL_NAME, "", LOCAL_PORT_TYPE,
+ ICE_TYPE_PREFERENCE_HOST, 0, false);
+ MaybePrepareStunCandidate();
+}
+
+void UDPPort::OnReadPacket(
+ rtc::AsyncPacketSocket* socket, const char* data, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time) {
+ ASSERT(socket == socket_);
+ ASSERT(!remote_addr.IsUnresolved());
+
+ // Look for a response from the STUN server.
+ // Even if the response doesn't match one of our outstanding requests, we
+ // will eat it because it might be a response to a retransmitted packet, and
+ // we already cleared the request when we got the first response.
+ if (server_addresses_.find(remote_addr) != server_addresses_.end()) {
+ requests_.CheckResponse(data, size);
+ return;
+ }
+
+ if (Connection* conn = GetConnection(remote_addr)) {
+ conn->OnReadPacket(data, size, packet_time);
+ } else {
+ Port::OnReadPacket(data, size, remote_addr, PROTO_UDP);
+ }
+}
+
+void UDPPort::OnReadyToSend(rtc::AsyncPacketSocket* socket) {
+ Port::OnReadyToSend();
+}
+
+void UDPPort::SendStunBindingRequests() {
+ // We will keep pinging the stun server to make sure our NAT pin-hole stays
+ // open during the call.
+ ASSERT(requests_.empty());
+
+ for (ServerAddresses::const_iterator it = server_addresses_.begin();
+ it != server_addresses_.end(); ++it) {
+ SendStunBindingRequest(*it);
+ }
+}
+
+void UDPPort::ResolveStunAddress(const rtc::SocketAddress& stun_addr) {
+ if (!resolver_) {
+ resolver_.reset(new AddressResolver(socket_factory()));
+ resolver_->SignalDone.connect(this, &UDPPort::OnResolveResult);
+ }
+
+ resolver_->Resolve(stun_addr);
+}
+
+void UDPPort::OnResolveResult(const rtc::SocketAddress& input,
+ int error) {
+ ASSERT(resolver_.get() != NULL);
+
+ rtc::SocketAddress resolved;
+ if (error != 0 ||
+ !resolver_->GetResolvedAddress(input, ip().family(), &resolved)) {
+ LOG_J(LS_WARNING, this) << "StunPort: stun host lookup received error "
+ << error;
+ OnStunBindingOrResolveRequestFailed(input);
+ return;
+ }
+
+ server_addresses_.erase(input);
+
+ if (server_addresses_.find(resolved) == server_addresses_.end()) {
+ server_addresses_.insert(resolved);
+ SendStunBindingRequest(resolved);
+ }
+}
+
+void UDPPort::SendStunBindingRequest(
+ const rtc::SocketAddress& stun_addr) {
+ if (stun_addr.IsUnresolved()) {
+ ResolveStunAddress(stun_addr);
+
+ } else if (socket_->GetState() == rtc::AsyncPacketSocket::STATE_BOUND) {
+ // Check if |server_addr_| is compatible with the port's ip.
+ if (IsCompatibleAddress(stun_addr)) {
+ requests_.Send(new StunBindingRequest(this, true, stun_addr));
+ } else {
+ // Since we can't send stun messages to the server, we should mark this
+ // port ready.
+ LOG(LS_WARNING) << "STUN server address is incompatible.";
+ OnStunBindingOrResolveRequestFailed(stun_addr);
+ }
+ }
+}
+
+void UDPPort::OnStunBindingRequestSucceeded(
+ const rtc::SocketAddress& stun_server_addr,
+ const rtc::SocketAddress& stun_reflected_addr) {
+ if (bind_request_succeeded_servers_.find(stun_server_addr) !=
+ bind_request_succeeded_servers_.end()) {
+ return;
+ }
+ bind_request_succeeded_servers_.insert(stun_server_addr);
+
+ // If socket is shared and |stun_reflected_addr| is equal to local socket
+ // address, or if the same address has been added by another STUN server,
+ // then discarding the stun address.
+ // For STUN, related address is the local socket address.
+ if ((!SharedSocket() || stun_reflected_addr != socket_->GetLocalAddress()) &&
+ !HasCandidateWithAddress(stun_reflected_addr)) {
+
+ rtc::SocketAddress related_address = socket_->GetLocalAddress();
+ if (!(candidate_filter() & CF_HOST)) {
+ // If candidate filter doesn't have CF_HOST specified, empty raddr to
+ // avoid local address leakage.
+ related_address = rtc::EmptySocketAddressWithFamily(
+ related_address.family());
+ }
+
+ AddAddress(stun_reflected_addr, socket_->GetLocalAddress(),
+ related_address, UDP_PROTOCOL_NAME, "",
+ STUN_PORT_TYPE, ICE_TYPE_PREFERENCE_SRFLX, 0, false);
+ }
+ MaybeSetPortCompleteOrError();
+}
+
+void UDPPort::OnStunBindingOrResolveRequestFailed(
+ const rtc::SocketAddress& stun_server_addr) {
+ if (bind_request_failed_servers_.find(stun_server_addr) !=
+ bind_request_failed_servers_.end()) {
+ return;
+ }
+ bind_request_failed_servers_.insert(stun_server_addr);
+ MaybeSetPortCompleteOrError();
+}
+
+void UDPPort::MaybeSetPortCompleteOrError() {
+ if (ready_)
+ return;
+
+ // Do not set port ready if we are still waiting for bind responses.
+ const size_t servers_done_bind_request = bind_request_failed_servers_.size() +
+ bind_request_succeeded_servers_.size();
+ if (server_addresses_.size() != servers_done_bind_request) {
+ return;
+ }
+
+ // Setting ready status.
+ ready_ = true;
+
+ // The port is "completed" if there is no stun server provided, or the bind
+ // request succeeded for any stun server, or the socket is shared.
+ if (server_addresses_.empty() ||
+ bind_request_succeeded_servers_.size() > 0 ||
+ SharedSocket()) {
+ SignalPortComplete(this);
+ } else {
+ SignalPortError(this);
+ }
+}
+
+// TODO: merge this with SendTo above.
+void UDPPort::OnSendPacket(const void* data, size_t size, StunRequest* req) {
+ StunBindingRequest* sreq = static_cast<StunBindingRequest*>(req);
+ rtc::PacketOptions options(DefaultDscpValue());
+ if (socket_->SendTo(data, size, sreq->server_addr(), options) < 0)
+ PLOG(LERROR, socket_->GetError()) << "sendto";
+}
+
+bool UDPPort::HasCandidateWithAddress(const rtc::SocketAddress& addr) const {
+ const std::vector<Candidate>& existing_candidates = Candidates();
+ std::vector<Candidate>::const_iterator it = existing_candidates.begin();
+ for (; it != existing_candidates.end(); ++it) {
+ if (it->address() == addr)
+ return true;
+ }
+ return false;
+}
+
+} // namespace cricket
diff --git a/p2p/base/stunport.h b/p2p/base/stunport.h
new file mode 100644
index 00000000..eda7bb90
--- /dev/null
+++ b/p2p/base/stunport.h
@@ -0,0 +1,238 @@
+/*
+ * 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 WEBRTC_P2P_BASE_STUNPORT_H_
+#define WEBRTC_P2P_BASE_STUNPORT_H_
+
+#include <string>
+
+#include "webrtc/p2p/base/port.h"
+#include "webrtc/p2p/base/stunrequest.h"
+#include "webrtc/base/asyncpacketsocket.h"
+
+// TODO(mallinath) - Rename stunport.cc|h to udpport.cc|h.
+namespace rtc {
+class AsyncResolver;
+class SignalThread;
+}
+
+namespace cricket {
+
+// Communicates using the address on the outside of a NAT.
+class UDPPort : public Port {
+ public:
+ static UDPPort* Create(rtc::Thread* thread,
+ rtc::PacketSocketFactory* factory,
+ rtc::Network* network,
+ rtc::AsyncPacketSocket* socket,
+ const std::string& username,
+ const std::string& password) {
+ UDPPort* port = new UDPPort(thread, factory, network, socket,
+ username, password);
+ if (!port->Init()) {
+ delete port;
+ port = NULL;
+ }
+ return port;
+ }
+
+ static UDPPort* Create(rtc::Thread* thread,
+ rtc::PacketSocketFactory* factory,
+ rtc::Network* network,
+ const rtc::IPAddress& ip,
+ int min_port, int max_port,
+ const std::string& username,
+ const std::string& password) {
+ UDPPort* port = new UDPPort(thread, factory, network,
+ ip, min_port, max_port,
+ username, password);
+ if (!port->Init()) {
+ delete port;
+ port = NULL;
+ }
+ return port;
+ }
+ virtual ~UDPPort();
+
+ rtc::SocketAddress GetLocalAddress() const {
+ return socket_->GetLocalAddress();
+ }
+
+ const ServerAddresses& server_addresses() const {
+ return server_addresses_;
+ }
+ void
+ set_server_addresses(const ServerAddresses& addresses) {
+ server_addresses_ = addresses;
+ }
+
+ virtual void PrepareAddress();
+
+ virtual Connection* CreateConnection(const Candidate& address,
+ CandidateOrigin origin);
+ virtual int SetOption(rtc::Socket::Option opt, int value);
+ virtual int GetOption(rtc::Socket::Option opt, int* value);
+ virtual int GetError();
+
+ virtual bool HandleIncomingPacket(
+ rtc::AsyncPacketSocket* socket, const char* data, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time) {
+ // All packets given to UDP port will be consumed.
+ OnReadPacket(socket, data, size, remote_addr, packet_time);
+ return true;
+ }
+
+ void set_stun_keepalive_delay(int delay) {
+ stun_keepalive_delay_ = delay;
+ }
+ int stun_keepalive_delay() const {
+ return stun_keepalive_delay_;
+ }
+
+ protected:
+ UDPPort(rtc::Thread* thread, rtc::PacketSocketFactory* factory,
+ rtc::Network* network, const rtc::IPAddress& ip,
+ int min_port, int max_port,
+ const std::string& username, const std::string& password);
+
+ UDPPort(rtc::Thread* thread, rtc::PacketSocketFactory* factory,
+ rtc::Network* network, rtc::AsyncPacketSocket* socket,
+ const std::string& username, const std::string& password);
+
+ bool Init();
+
+ virtual int SendTo(const void* data, size_t size,
+ const rtc::SocketAddress& addr,
+ const rtc::PacketOptions& options,
+ bool payload);
+
+ void OnLocalAddressReady(rtc::AsyncPacketSocket* socket,
+ const rtc::SocketAddress& address);
+ void OnReadPacket(rtc::AsyncPacketSocket* socket,
+ const char* data, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time);
+
+ void OnReadyToSend(rtc::AsyncPacketSocket* socket);
+
+ // This method will send STUN binding request if STUN server address is set.
+ void MaybePrepareStunCandidate();
+
+ void SendStunBindingRequests();
+
+ private:
+ // A helper class which can be called repeatedly to resolve multiple
+ // addresses, as opposed to rtc::AsyncResolverInterface, which can only
+ // resolve one address per instance.
+ class AddressResolver : public sigslot::has_slots<> {
+ public:
+ explicit AddressResolver(rtc::PacketSocketFactory* factory);
+ ~AddressResolver();
+
+ void Resolve(const rtc::SocketAddress& address);
+ bool GetResolvedAddress(const rtc::SocketAddress& input,
+ int family,
+ rtc::SocketAddress* output) const;
+
+ // The signal is sent when resolving the specified address is finished. The
+ // first argument is the input address, the second argument is the error
+ // or 0 if it succeeded.
+ sigslot::signal2<const rtc::SocketAddress&, int> SignalDone;
+
+ private:
+ typedef std::map<rtc::SocketAddress,
+ rtc::AsyncResolverInterface*> ResolverMap;
+
+ void OnResolveResult(rtc::AsyncResolverInterface* resolver);
+
+ rtc::PacketSocketFactory* socket_factory_;
+ ResolverMap resolvers_;
+ };
+
+ // DNS resolution of the STUN server.
+ void ResolveStunAddress(const rtc::SocketAddress& stun_addr);
+ void OnResolveResult(const rtc::SocketAddress& input, int error);
+
+ void SendStunBindingRequest(const rtc::SocketAddress& stun_addr);
+
+ // Below methods handles binding request responses.
+ void OnStunBindingRequestSucceeded(
+ const rtc::SocketAddress& stun_server_addr,
+ const rtc::SocketAddress& stun_reflected_addr);
+ void OnStunBindingOrResolveRequestFailed(
+ const rtc::SocketAddress& stun_server_addr);
+
+ // Sends STUN requests to the server.
+ void OnSendPacket(const void* data, size_t size, StunRequest* req);
+
+ // TODO(mallinaht) - Move this up to cricket::Port when SignalAddressReady is
+ // changed to SignalPortReady.
+ void MaybeSetPortCompleteOrError();
+
+ bool HasCandidateWithAddress(const rtc::SocketAddress& addr) const;
+
+ ServerAddresses server_addresses_;
+ ServerAddresses bind_request_succeeded_servers_;
+ ServerAddresses bind_request_failed_servers_;
+ StunRequestManager requests_;
+ rtc::AsyncPacketSocket* socket_;
+ int error_;
+ rtc::scoped_ptr<AddressResolver> resolver_;
+ bool ready_;
+ int stun_keepalive_delay_;
+
+ friend class StunBindingRequest;
+};
+
+class StunPort : public UDPPort {
+ public:
+ static StunPort* Create(
+ rtc::Thread* thread,
+ rtc::PacketSocketFactory* factory,
+ rtc::Network* network,
+ const rtc::IPAddress& ip,
+ int min_port, int max_port,
+ const std::string& username,
+ const std::string& password,
+ const ServerAddresses& servers) {
+ StunPort* port = new StunPort(thread, factory, network,
+ ip, min_port, max_port,
+ username, password, servers);
+ if (!port->Init()) {
+ delete port;
+ port = NULL;
+ }
+ return port;
+ }
+
+ virtual ~StunPort() {}
+
+ virtual void PrepareAddress() {
+ SendStunBindingRequests();
+ }
+
+ protected:
+ StunPort(rtc::Thread* thread, rtc::PacketSocketFactory* factory,
+ rtc::Network* network, const rtc::IPAddress& ip,
+ int min_port, int max_port,
+ const std::string& username, const std::string& password,
+ const ServerAddresses& servers)
+ : UDPPort(thread, factory, network, ip, min_port, max_port, username,
+ password) {
+ // UDPPort will set these to local udp, updating these to STUN.
+ set_type(STUN_PORT_TYPE);
+ set_server_addresses(servers);
+ }
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_STUNPORT_H_
diff --git a/p2p/base/stunport_unittest.cc b/p2p/base/stunport_unittest.cc
new file mode 100644
index 00000000..81b68086
--- /dev/null
+++ b/p2p/base/stunport_unittest.cc
@@ -0,0 +1,283 @@
+/*
+ * Copyright 2009 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can 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 "webrtc/p2p/base/basicpacketsocketfactory.h"
+#include "webrtc/p2p/base/stunport.h"
+#include "webrtc/p2p/base/teststunserver.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/physicalsocketserver.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/socketaddress.h"
+#include "webrtc/base/ssladapter.h"
+#include "webrtc/base/virtualsocketserver.h"
+
+using cricket::ServerAddresses;
+using rtc::SocketAddress;
+
+static const SocketAddress kLocalAddr("127.0.0.1", 0);
+static const SocketAddress kStunAddr1("127.0.0.1", 5000);
+static const SocketAddress kStunAddr2("127.0.0.1", 4000);
+static const SocketAddress kBadAddr("0.0.0.1", 5000);
+static const SocketAddress kStunHostnameAddr("localhost", 5000);
+static const SocketAddress kBadHostnameAddr("not-a-real-hostname", 5000);
+static const int kTimeoutMs = 10000;
+// stun prio = 100 << 24 | 30 (IPV4) << 8 | 256 - 0
+static const uint32 kStunCandidatePriority = 1677729535;
+
+// Tests connecting a StunPort to a fake STUN server (cricket::StunServer)
+// TODO: Use a VirtualSocketServer here. We have to use a
+// PhysicalSocketServer right now since DNS is not part of SocketServer yet.
+class StunPortTest : public testing::Test,
+ public sigslot::has_slots<> {
+ public:
+ StunPortTest()
+ : pss_(new rtc::PhysicalSocketServer),
+ ss_(new rtc::VirtualSocketServer(pss_.get())),
+ ss_scope_(ss_.get()),
+ network_("unittest", "unittest", rtc::IPAddress(INADDR_ANY), 32),
+ socket_factory_(rtc::Thread::Current()),
+ stun_server_1_(cricket::TestStunServer::Create(
+ rtc::Thread::Current(), kStunAddr1)),
+ stun_server_2_(cricket::TestStunServer::Create(
+ rtc::Thread::Current(), kStunAddr2)),
+ done_(false), error_(false), stun_keepalive_delay_(0) {
+ }
+
+ const cricket::Port* port() const { return stun_port_.get(); }
+ bool done() const { return done_; }
+ bool error() const { return error_; }
+
+ void CreateStunPort(const rtc::SocketAddress& server_addr) {
+ ServerAddresses stun_servers;
+ stun_servers.insert(server_addr);
+ CreateStunPort(stun_servers);
+ }
+
+ void CreateStunPort(const ServerAddresses& stun_servers) {
+ stun_port_.reset(cricket::StunPort::Create(
+ rtc::Thread::Current(), &socket_factory_, &network_,
+ kLocalAddr.ipaddr(), 0, 0, rtc::CreateRandomString(16),
+ rtc::CreateRandomString(22), stun_servers));
+ stun_port_->set_stun_keepalive_delay(stun_keepalive_delay_);
+ stun_port_->SignalPortComplete.connect(this,
+ &StunPortTest::OnPortComplete);
+ stun_port_->SignalPortError.connect(this,
+ &StunPortTest::OnPortError);
+ }
+
+ void CreateSharedStunPort(const rtc::SocketAddress& server_addr) {
+ socket_.reset(socket_factory_.CreateUdpSocket(
+ rtc::SocketAddress(kLocalAddr.ipaddr(), 0), 0, 0));
+ ASSERT_TRUE(socket_ != NULL);
+ socket_->SignalReadPacket.connect(this, &StunPortTest::OnReadPacket);
+ stun_port_.reset(cricket::UDPPort::Create(
+ rtc::Thread::Current(), &socket_factory_,
+ &network_, socket_.get(),
+ rtc::CreateRandomString(16), rtc::CreateRandomString(22)));
+ ASSERT_TRUE(stun_port_ != NULL);
+ ServerAddresses stun_servers;
+ stun_servers.insert(server_addr);
+ stun_port_->set_server_addresses(stun_servers);
+ stun_port_->SignalPortComplete.connect(this,
+ &StunPortTest::OnPortComplete);
+ stun_port_->SignalPortError.connect(this,
+ &StunPortTest::OnPortError);
+ }
+
+ void PrepareAddress() {
+ stun_port_->PrepareAddress();
+ }
+
+ void OnReadPacket(rtc::AsyncPacketSocket* socket, const char* data,
+ size_t size, const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time) {
+ stun_port_->HandleIncomingPacket(
+ socket, data, size, remote_addr, rtc::PacketTime());
+ }
+
+ void SendData(const char* data, size_t len) {
+ stun_port_->HandleIncomingPacket(
+ socket_.get(), data, len, rtc::SocketAddress("22.22.22.22", 0),
+ rtc::PacketTime());
+ }
+
+ protected:
+ static void SetUpTestCase() {
+ // Ensure the RNG is inited.
+ rtc::InitRandom(NULL, 0);
+
+ }
+
+ void OnPortComplete(cricket::Port* port) {
+ ASSERT_FALSE(done_);
+ done_ = true;
+ error_ = false;
+ }
+ void OnPortError(cricket::Port* port) {
+ done_ = true;
+ error_ = true;
+ }
+ void SetKeepaliveDelay(int delay) {
+ stun_keepalive_delay_ = delay;
+ }
+
+ cricket::TestStunServer* stun_server_1() {
+ return stun_server_1_.get();
+ }
+ cricket::TestStunServer* stun_server_2() {
+ return stun_server_2_.get();
+ }
+
+ private:
+ rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
+ rtc::scoped_ptr<rtc::VirtualSocketServer> ss_;
+ rtc::SocketServerScope ss_scope_;
+ rtc::Network network_;
+ rtc::BasicPacketSocketFactory socket_factory_;
+ rtc::scoped_ptr<cricket::UDPPort> stun_port_;
+ rtc::scoped_ptr<cricket::TestStunServer> stun_server_1_;
+ rtc::scoped_ptr<cricket::TestStunServer> stun_server_2_;
+ rtc::scoped_ptr<rtc::AsyncPacketSocket> socket_;
+ bool done_;
+ bool error_;
+ int stun_keepalive_delay_;
+};
+
+// Test that we can create a STUN port
+TEST_F(StunPortTest, TestBasic) {
+ CreateStunPort(kStunAddr1);
+ EXPECT_EQ("stun", port()->Type());
+ EXPECT_EQ(0U, port()->Candidates().size());
+}
+
+// Test that we can get an address from a STUN server.
+TEST_F(StunPortTest, TestPrepareAddress) {
+ CreateStunPort(kStunAddr1);
+ PrepareAddress();
+ EXPECT_TRUE_WAIT(done(), kTimeoutMs);
+ ASSERT_EQ(1U, port()->Candidates().size());
+ EXPECT_TRUE(kLocalAddr.EqualIPs(port()->Candidates()[0].address()));
+
+ // TODO: Add IPv6 tests here, once either physicalsocketserver supports
+ // IPv6, or this test is changed to use VirtualSocketServer.
+}
+
+// Test that we fail properly if we can't get an address.
+TEST_F(StunPortTest, TestPrepareAddressFail) {
+ CreateStunPort(kBadAddr);
+ PrepareAddress();
+ EXPECT_TRUE_WAIT(done(), kTimeoutMs);
+ EXPECT_TRUE(error());
+ EXPECT_EQ(0U, port()->Candidates().size());
+}
+
+// Test that we can get an address from a STUN server specified by a hostname.
+TEST_F(StunPortTest, TestPrepareAddressHostname) {
+ CreateStunPort(kStunHostnameAddr);
+ PrepareAddress();
+ EXPECT_TRUE_WAIT(done(), kTimeoutMs);
+ ASSERT_EQ(1U, port()->Candidates().size());
+ EXPECT_TRUE(kLocalAddr.EqualIPs(port()->Candidates()[0].address()));
+ EXPECT_EQ(kStunCandidatePriority, port()->Candidates()[0].priority());
+}
+
+// Test that we handle hostname lookup failures properly.
+TEST_F(StunPortTest, TestPrepareAddressHostnameFail) {
+ CreateStunPort(kBadHostnameAddr);
+ PrepareAddress();
+ EXPECT_TRUE_WAIT(done(), kTimeoutMs);
+ EXPECT_TRUE(error());
+ EXPECT_EQ(0U, port()->Candidates().size());
+}
+
+// This test verifies keepalive response messages don't result in
+// additional candidate generation.
+TEST_F(StunPortTest, TestKeepAliveResponse) {
+ SetKeepaliveDelay(500); // 500ms of keepalive delay.
+ CreateStunPort(kStunHostnameAddr);
+ PrepareAddress();
+ EXPECT_TRUE_WAIT(done(), kTimeoutMs);
+ ASSERT_EQ(1U, port()->Candidates().size());
+ EXPECT_TRUE(kLocalAddr.EqualIPs(port()->Candidates()[0].address()));
+ // Waiting for 1 seond, which will allow us to process
+ // response for keepalive binding request. 500 ms is the keepalive delay.
+ rtc::Thread::Current()->ProcessMessages(1000);
+ ASSERT_EQ(1U, port()->Candidates().size());
+}
+
+// Test that a local candidate can be generated using a shared socket.
+TEST_F(StunPortTest, TestSharedSocketPrepareAddress) {
+ CreateSharedStunPort(kStunAddr1);
+ PrepareAddress();
+ EXPECT_TRUE_WAIT(done(), kTimeoutMs);
+ ASSERT_EQ(1U, port()->Candidates().size());
+ EXPECT_TRUE(kLocalAddr.EqualIPs(port()->Candidates()[0].address()));
+}
+
+// Test that we still a get a local candidate with invalid stun server hostname.
+// Also verifing that UDPPort can receive packets when stun address can't be
+// resolved.
+TEST_F(StunPortTest, TestSharedSocketPrepareAddressInvalidHostname) {
+ CreateSharedStunPort(kBadHostnameAddr);
+ PrepareAddress();
+ EXPECT_TRUE_WAIT(done(), kTimeoutMs);
+ ASSERT_EQ(1U, port()->Candidates().size());
+ EXPECT_TRUE(kLocalAddr.EqualIPs(port()->Candidates()[0].address()));
+
+ // Send data to port after it's ready. This is to make sure, UDP port can
+ // handle data with unresolved stun server address.
+ std::string data = "some random data, sending to cricket::Port.";
+ SendData(data.c_str(), data.length());
+ // No crash is success.
+}
+
+// Test that the same address is added only once if two STUN servers are in use.
+TEST_F(StunPortTest, TestNoDuplicatedAddressWithTwoStunServers) {
+ ServerAddresses stun_servers;
+ stun_servers.insert(kStunAddr1);
+ stun_servers.insert(kStunAddr2);
+ CreateStunPort(stun_servers);
+ EXPECT_EQ("stun", port()->Type());
+ PrepareAddress();
+ EXPECT_TRUE_WAIT(done(), kTimeoutMs);
+ EXPECT_EQ(1U, port()->Candidates().size());
+}
+
+// Test that candidates can be allocated for multiple STUN servers, one of which
+// is not reachable.
+TEST_F(StunPortTest, TestMultipleStunServersWithBadServer) {
+ ServerAddresses stun_servers;
+ stun_servers.insert(kStunAddr1);
+ stun_servers.insert(kBadAddr);
+ CreateStunPort(stun_servers);
+ EXPECT_EQ("stun", port()->Type());
+ PrepareAddress();
+ EXPECT_TRUE_WAIT(done(), kTimeoutMs);
+ EXPECT_EQ(1U, port()->Candidates().size());
+}
+
+// Test that two candidates are allocated if the two STUN servers return
+// different mapped addresses.
+TEST_F(StunPortTest, TestTwoCandidatesWithTwoStunServersAcrossNat) {
+ const SocketAddress kStunMappedAddr1("77.77.77.77", 0);
+ const SocketAddress kStunMappedAddr2("88.77.77.77", 0);
+ stun_server_1()->set_fake_stun_addr(kStunMappedAddr1);
+ stun_server_2()->set_fake_stun_addr(kStunMappedAddr2);
+
+ ServerAddresses stun_servers;
+ stun_servers.insert(kStunAddr1);
+ stun_servers.insert(kStunAddr2);
+ CreateStunPort(stun_servers);
+ EXPECT_EQ("stun", port()->Type());
+ PrepareAddress();
+ EXPECT_TRUE_WAIT(done(), kTimeoutMs);
+ EXPECT_EQ(2U, port()->Candidates().size());
+}
diff --git a/p2p/base/stunrequest.cc b/p2p/base/stunrequest.cc
new file mode 100644
index 00000000..65eb027f
--- /dev/null
+++ b/p2p/base/stunrequest.cc
@@ -0,0 +1,193 @@
+/*
+ * 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 "webrtc/p2p/base/stunrequest.h"
+
+#include "webrtc/base/common.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/logging.h"
+
+namespace cricket {
+
+const uint32 MSG_STUN_SEND = 1;
+
+const int MAX_SENDS = 9;
+const int DELAY_UNIT = 100; // 100 milliseconds
+const int DELAY_MAX_FACTOR = 16;
+
+StunRequestManager::StunRequestManager(rtc::Thread* thread)
+ : thread_(thread) {
+}
+
+StunRequestManager::~StunRequestManager() {
+ while (requests_.begin() != requests_.end()) {
+ StunRequest *request = requests_.begin()->second;
+ requests_.erase(requests_.begin());
+ delete request;
+ }
+}
+
+void StunRequestManager::Send(StunRequest* request) {
+ SendDelayed(request, 0);
+}
+
+void StunRequestManager::SendDelayed(StunRequest* request, int delay) {
+ request->set_manager(this);
+ ASSERT(requests_.find(request->id()) == requests_.end());
+ request->Construct();
+ requests_[request->id()] = request;
+ thread_->PostDelayed(delay, request, MSG_STUN_SEND, NULL);
+}
+
+void StunRequestManager::Remove(StunRequest* request) {
+ ASSERT(request->manager() == this);
+ RequestMap::iterator iter = requests_.find(request->id());
+ if (iter != requests_.end()) {
+ ASSERT(iter->second == request);
+ requests_.erase(iter);
+ thread_->Clear(request);
+ }
+}
+
+void StunRequestManager::Clear() {
+ std::vector<StunRequest*> requests;
+ for (RequestMap::iterator i = requests_.begin(); i != requests_.end(); ++i)
+ requests.push_back(i->second);
+
+ for (uint32 i = 0; i < requests.size(); ++i) {
+ // StunRequest destructor calls Remove() which deletes requests
+ // from |requests_|.
+ delete requests[i];
+ }
+}
+
+bool StunRequestManager::CheckResponse(StunMessage* msg) {
+ RequestMap::iterator iter = requests_.find(msg->transaction_id());
+ if (iter == requests_.end())
+ return false;
+
+ StunRequest* request = iter->second;
+ if (msg->type() == GetStunSuccessResponseType(request->type())) {
+ request->OnResponse(msg);
+ } else if (msg->type() == GetStunErrorResponseType(request->type())) {
+ request->OnErrorResponse(msg);
+ } else {
+ LOG(LERROR) << "Received response with wrong type: " << msg->type()
+ << " (expecting "
+ << GetStunSuccessResponseType(request->type()) << ")";
+ return false;
+ }
+
+ delete request;
+ return true;
+}
+
+bool StunRequestManager::CheckResponse(const char* data, size_t size) {
+ // Check the appropriate bytes of the stream to see if they match the
+ // transaction ID of a response we are expecting.
+
+ if (size < 20)
+ return false;
+
+ std::string id;
+ id.append(data + kStunTransactionIdOffset, kStunTransactionIdLength);
+
+ RequestMap::iterator iter = requests_.find(id);
+ if (iter == requests_.end())
+ return false;
+
+ // Parse the STUN message and continue processing as usual.
+
+ rtc::ByteBuffer buf(data, size);
+ rtc::scoped_ptr<StunMessage> response(iter->second->msg_->CreateNew());
+ if (!response->Read(&buf))
+ return false;
+
+ return CheckResponse(response.get());
+}
+
+StunRequest::StunRequest()
+ : count_(0), timeout_(false), manager_(0),
+ msg_(new StunMessage()), tstamp_(0) {
+ msg_->SetTransactionID(
+ rtc::CreateRandomString(kStunTransactionIdLength));
+}
+
+StunRequest::StunRequest(StunMessage* request)
+ : count_(0), timeout_(false), manager_(0),
+ msg_(request), tstamp_(0) {
+ msg_->SetTransactionID(
+ rtc::CreateRandomString(kStunTransactionIdLength));
+}
+
+StunRequest::~StunRequest() {
+ ASSERT(manager_ != NULL);
+ if (manager_) {
+ manager_->Remove(this);
+ manager_->thread_->Clear(this);
+ }
+ delete msg_;
+}
+
+void StunRequest::Construct() {
+ if (msg_->type() == 0) {
+ Prepare(msg_);
+ ASSERT(msg_->type() != 0);
+ }
+}
+
+int StunRequest::type() {
+ ASSERT(msg_ != NULL);
+ return msg_->type();
+}
+
+const StunMessage* StunRequest::msg() const {
+ return msg_;
+}
+
+uint32 StunRequest::Elapsed() const {
+ return rtc::TimeSince(tstamp_);
+}
+
+
+void StunRequest::set_manager(StunRequestManager* manager) {
+ ASSERT(!manager_);
+ manager_ = manager;
+}
+
+void StunRequest::OnMessage(rtc::Message* pmsg) {
+ ASSERT(manager_ != NULL);
+ ASSERT(pmsg->message_id == MSG_STUN_SEND);
+
+ if (timeout_) {
+ OnTimeout();
+ delete this;
+ return;
+ }
+
+ tstamp_ = rtc::Time();
+
+ rtc::ByteBuffer buf;
+ msg_->Write(&buf);
+ manager_->SignalSendPacket(buf.Data(), buf.Length(), this);
+
+ int delay = GetNextDelay();
+ manager_->thread_->PostDelayed(delay, this, MSG_STUN_SEND, NULL);
+}
+
+int StunRequest::GetNextDelay() {
+ int delay = DELAY_UNIT * rtc::_min(1 << count_, DELAY_MAX_FACTOR);
+ count_ += 1;
+ if (count_ == MAX_SENDS)
+ timeout_ = true;
+ return delay;
+}
+
+} // namespace cricket
diff --git a/p2p/base/stunrequest.h b/p2p/base/stunrequest.h
new file mode 100644
index 00000000..5fefc2ff
--- /dev/null
+++ b/p2p/base/stunrequest.h
@@ -0,0 +1,116 @@
+/*
+ * 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 WEBRTC_P2P_BASE_STUNREQUEST_H_
+#define WEBRTC_P2P_BASE_STUNREQUEST_H_
+
+#include <map>
+#include <string>
+#include "webrtc/p2p/base/stun.h"
+#include "webrtc/base/sigslot.h"
+#include "webrtc/base/thread.h"
+
+namespace cricket {
+
+class StunRequest;
+
+// Manages a set of STUN requests, sending and resending until we receive a
+// response or determine that the request has timed out.
+class StunRequestManager {
+public:
+ StunRequestManager(rtc::Thread* thread);
+ ~StunRequestManager();
+
+ // Starts sending the given request (perhaps after a delay).
+ void Send(StunRequest* request);
+ void SendDelayed(StunRequest* request, int delay);
+
+ // Removes a stun request that was added previously. This will happen
+ // automatically when a request succeeds, fails, or times out.
+ void Remove(StunRequest* request);
+
+ // Removes all stun requests that were added previously.
+ void Clear();
+
+ // Determines whether the given message is a response to one of the
+ // outstanding requests, and if so, processes it appropriately.
+ bool CheckResponse(StunMessage* msg);
+ bool CheckResponse(const char* data, size_t size);
+
+ bool empty() { return requests_.empty(); }
+
+ // Raised when there are bytes to be sent.
+ sigslot::signal3<const void*, size_t, StunRequest*> SignalSendPacket;
+
+private:
+ typedef std::map<std::string, StunRequest*> RequestMap;
+
+ rtc::Thread* thread_;
+ RequestMap requests_;
+
+ friend class StunRequest;
+};
+
+// Represents an individual request to be sent. The STUN message can either be
+// constructed beforehand or built on demand.
+class StunRequest : public rtc::MessageHandler {
+public:
+ StunRequest();
+ StunRequest(StunMessage* request);
+ virtual ~StunRequest();
+
+ // Causes our wrapped StunMessage to be Prepared
+ void Construct();
+
+ // The manager handling this request (if it has been scheduled for sending).
+ StunRequestManager* manager() { return manager_; }
+
+ // Returns the transaction ID of this request.
+ const std::string& id() { return msg_->transaction_id(); }
+
+ // Returns the STUN type of the request message.
+ int type();
+
+ // Returns a const pointer to |msg_|.
+ const StunMessage* msg() const;
+
+ // Time elapsed since last send (in ms)
+ uint32 Elapsed() const;
+
+protected:
+ int count_;
+ bool timeout_;
+
+ // Fills in a request object to be sent. Note that request's transaction ID
+ // will already be set and cannot be changed.
+ virtual void Prepare(StunMessage* request) {}
+
+ // Called when the message receives a response or times out.
+ virtual void OnResponse(StunMessage* response) {}
+ virtual void OnErrorResponse(StunMessage* response) {}
+ virtual void OnTimeout() {}
+ virtual int GetNextDelay();
+
+private:
+ void set_manager(StunRequestManager* manager);
+
+ // Handles messages for sending and timeout.
+ void OnMessage(rtc::Message* pmsg);
+
+ StunRequestManager* manager_;
+ StunMessage* msg_;
+ uint32 tstamp_;
+
+ friend class StunRequestManager;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_STUNREQUEST_H_
diff --git a/p2p/base/stunrequest_unittest.cc b/p2p/base/stunrequest_unittest.cc
new file mode 100644
index 00000000..3ff6cbaf
--- /dev/null
+++ b/p2p/base/stunrequest_unittest.cc
@@ -0,0 +1,203 @@
+/*
+ * 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 "webrtc/p2p/base/stunrequest.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/ssladapter.h"
+#include "webrtc/base/timeutils.h"
+
+using namespace cricket;
+
+class StunRequestTest : public testing::Test,
+ public sigslot::has_slots<> {
+ public:
+ StunRequestTest()
+ : manager_(rtc::Thread::Current()),
+ request_count_(0), response_(NULL),
+ success_(false), failure_(false), timeout_(false) {
+ manager_.SignalSendPacket.connect(this, &StunRequestTest::OnSendPacket);
+ }
+
+ void OnSendPacket(const void* data, size_t size, StunRequest* req) {
+ request_count_++;
+ }
+
+ void OnResponse(StunMessage* res) {
+ response_ = res;
+ success_ = true;
+ }
+ void OnErrorResponse(StunMessage* res) {
+ response_ = res;
+ failure_ = true;
+ }
+ void OnTimeout() {
+ timeout_ = true;
+ }
+
+ protected:
+ static StunMessage* CreateStunMessage(StunMessageType type,
+ StunMessage* req) {
+ StunMessage* msg = new StunMessage();
+ msg->SetType(type);
+ if (req) {
+ msg->SetTransactionID(req->transaction_id());
+ }
+ return msg;
+ }
+ static int TotalDelay(int sends) {
+ int total = 0;
+ for (int i = 0; i < sends; i++) {
+ if (i < 4)
+ total += 100 << i;
+ else
+ total += 1600;
+ }
+ return total;
+ }
+
+ StunRequestManager manager_;
+ int request_count_;
+ StunMessage* response_;
+ bool success_;
+ bool failure_;
+ bool timeout_;
+};
+
+// Forwards results to the test class.
+class StunRequestThunker : public StunRequest {
+ public:
+ StunRequestThunker(StunMessage* msg, StunRequestTest* test)
+ : StunRequest(msg), test_(test) {}
+ explicit StunRequestThunker(StunRequestTest* test) : test_(test) {}
+ private:
+ virtual void OnResponse(StunMessage* res) {
+ test_->OnResponse(res);
+ }
+ virtual void OnErrorResponse(StunMessage* res) {
+ test_->OnErrorResponse(res);
+ }
+ virtual void OnTimeout() {
+ test_->OnTimeout();
+ }
+
+ virtual void Prepare(StunMessage* request) {
+ request->SetType(STUN_BINDING_REQUEST);
+ }
+
+ StunRequestTest* test_;
+};
+
+// Test handling of a normal binding response.
+TEST_F(StunRequestTest, TestSuccess) {
+ StunMessage* req = CreateStunMessage(STUN_BINDING_REQUEST, NULL);
+
+ manager_.Send(new StunRequestThunker(req, this));
+ StunMessage* res = CreateStunMessage(STUN_BINDING_RESPONSE, req);
+ EXPECT_TRUE(manager_.CheckResponse(res));
+
+ EXPECT_TRUE(response_ == res);
+ EXPECT_TRUE(success_);
+ EXPECT_FALSE(failure_);
+ EXPECT_FALSE(timeout_);
+ delete res;
+}
+
+// Test handling of an error binding response.
+TEST_F(StunRequestTest, TestError) {
+ StunMessage* req = CreateStunMessage(STUN_BINDING_REQUEST, NULL);
+
+ manager_.Send(new StunRequestThunker(req, this));
+ StunMessage* res = CreateStunMessage(STUN_BINDING_ERROR_RESPONSE, req);
+ EXPECT_TRUE(manager_.CheckResponse(res));
+
+ EXPECT_TRUE(response_ == res);
+ EXPECT_FALSE(success_);
+ EXPECT_TRUE(failure_);
+ EXPECT_FALSE(timeout_);
+ delete res;
+}
+
+// Test handling of a binding response with the wrong transaction id.
+TEST_F(StunRequestTest, TestUnexpected) {
+ StunMessage* req = CreateStunMessage(STUN_BINDING_REQUEST, NULL);
+
+ manager_.Send(new StunRequestThunker(req, this));
+ StunMessage* res = CreateStunMessage(STUN_BINDING_RESPONSE, NULL);
+ EXPECT_FALSE(manager_.CheckResponse(res));
+
+ EXPECT_TRUE(response_ == NULL);
+ EXPECT_FALSE(success_);
+ EXPECT_FALSE(failure_);
+ EXPECT_FALSE(timeout_);
+ delete res;
+}
+
+// Test that requests are sent at the right times, and that the 9th request
+// (sent at 7900 ms) can be properly replied to.
+TEST_F(StunRequestTest, TestBackoff) {
+ StunMessage* req = CreateStunMessage(STUN_BINDING_REQUEST, NULL);
+
+ uint32 start = rtc::Time();
+ manager_.Send(new StunRequestThunker(req, this));
+ StunMessage* res = CreateStunMessage(STUN_BINDING_RESPONSE, req);
+ for (int i = 0; i < 9; ++i) {
+ while (request_count_ == i)
+ rtc::Thread::Current()->ProcessMessages(1);
+ int32 elapsed = rtc::TimeSince(start);
+ LOG(LS_INFO) << "STUN request #" << (i + 1)
+ << " sent at " << elapsed << " ms";
+ EXPECT_GE(TotalDelay(i + 1), elapsed);
+ }
+ EXPECT_TRUE(manager_.CheckResponse(res));
+
+ EXPECT_TRUE(response_ == res);
+ EXPECT_TRUE(success_);
+ EXPECT_FALSE(failure_);
+ EXPECT_FALSE(timeout_);
+ delete res;
+}
+
+// Test that we timeout properly if no response is received in 9500 ms.
+TEST_F(StunRequestTest, TestTimeout) {
+ StunMessage* req = CreateStunMessage(STUN_BINDING_REQUEST, NULL);
+ StunMessage* res = CreateStunMessage(STUN_BINDING_RESPONSE, req);
+
+ manager_.Send(new StunRequestThunker(req, this));
+ rtc::Thread::Current()->ProcessMessages(10000); // > STUN timeout
+ EXPECT_FALSE(manager_.CheckResponse(res));
+
+ EXPECT_TRUE(response_ == NULL);
+ EXPECT_FALSE(success_);
+ EXPECT_FALSE(failure_);
+ EXPECT_TRUE(timeout_);
+ delete res;
+}
+
+// Regression test for specific crash where we receive a response with the
+// same id as a request that doesn't have an underlying StunMessage yet.
+TEST_F(StunRequestTest, TestNoEmptyRequest) {
+ StunRequestThunker* request = new StunRequestThunker(this);
+
+ manager_.SendDelayed(request, 100);
+
+ StunMessage dummy_req;
+ dummy_req.SetTransactionID(request->id());
+ StunMessage* res = CreateStunMessage(STUN_BINDING_RESPONSE, &dummy_req);
+
+ EXPECT_TRUE(manager_.CheckResponse(res));
+
+ EXPECT_TRUE(response_ == res);
+ EXPECT_TRUE(success_);
+ EXPECT_FALSE(failure_);
+ EXPECT_FALSE(timeout_);
+ delete res;
+}
diff --git a/p2p/base/stunserver.cc b/p2p/base/stunserver.cc
new file mode 100644
index 00000000..fbc316bd
--- /dev/null
+++ b/p2p/base/stunserver.cc
@@ -0,0 +1,99 @@
+/*
+ * 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 "webrtc/p2p/base/stunserver.h"
+
+#include "webrtc/base/bytebuffer.h"
+#include "webrtc/base/logging.h"
+
+namespace cricket {
+
+StunServer::StunServer(rtc::AsyncUDPSocket* socket) : socket_(socket) {
+ socket_->SignalReadPacket.connect(this, &StunServer::OnPacket);
+}
+
+StunServer::~StunServer() {
+ socket_->SignalReadPacket.disconnect(this);
+}
+
+void StunServer::OnPacket(
+ rtc::AsyncPacketSocket* socket, const char* buf, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time) {
+ // Parse the STUN message; eat any messages that fail to parse.
+ rtc::ByteBuffer bbuf(buf, size);
+ StunMessage msg;
+ if (!msg.Read(&bbuf)) {
+ return;
+ }
+
+ // TODO: If unknown non-optional (<= 0x7fff) attributes are found, send a
+ // 420 "Unknown Attribute" response.
+
+ // Send the message to the appropriate handler function.
+ switch (msg.type()) {
+ case STUN_BINDING_REQUEST:
+ OnBindingRequest(&msg, remote_addr);
+ break;
+
+ default:
+ SendErrorResponse(msg, remote_addr, 600, "Operation Not Supported");
+ }
+}
+
+void StunServer::OnBindingRequest(
+ StunMessage* msg, const rtc::SocketAddress& remote_addr) {
+ StunMessage response;
+ GetStunBindReqponse(msg, remote_addr, &response);
+ SendResponse(response, remote_addr);
+}
+
+void StunServer::SendErrorResponse(
+ const StunMessage& msg, const rtc::SocketAddress& addr,
+ int error_code, const char* error_desc) {
+ StunMessage err_msg;
+ err_msg.SetType(GetStunErrorResponseType(msg.type()));
+ err_msg.SetTransactionID(msg.transaction_id());
+
+ StunErrorCodeAttribute* err_code = StunAttribute::CreateErrorCode();
+ err_code->SetCode(error_code);
+ err_code->SetReason(error_desc);
+ err_msg.AddAttribute(err_code);
+
+ SendResponse(err_msg, addr);
+}
+
+void StunServer::SendResponse(
+ const StunMessage& msg, const rtc::SocketAddress& addr) {
+ rtc::ByteBuffer buf;
+ msg.Write(&buf);
+ rtc::PacketOptions options;
+ if (socket_->SendTo(buf.Data(), buf.Length(), addr, options) < 0)
+ LOG_ERR(LS_ERROR) << "sendto";
+}
+
+void StunServer::GetStunBindReqponse(StunMessage* request,
+ const rtc::SocketAddress& remote_addr,
+ StunMessage* response) const {
+ response->SetType(STUN_BINDING_RESPONSE);
+ response->SetTransactionID(request->transaction_id());
+
+ // Tell the user the address that we received their request from.
+ StunAddressAttribute* mapped_addr;
+ if (!request->IsLegacy()) {
+ mapped_addr = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
+ } else {
+ mapped_addr = StunAttribute::CreateXorAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
+ }
+ mapped_addr->SetAddress(remote_addr);
+ response->AddAttribute(mapped_addr);
+}
+
+} // namespace cricket
diff --git a/p2p/base/stunserver.h b/p2p/base/stunserver.h
new file mode 100644
index 00000000..a7eeab15
--- /dev/null
+++ b/p2p/base/stunserver.h
@@ -0,0 +1,66 @@
+/*
+ * 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 WEBRTC_P2P_BASE_STUNSERVER_H_
+#define WEBRTC_P2P_BASE_STUNSERVER_H_
+
+#include "webrtc/p2p/base/stun.h"
+#include "webrtc/base/asyncudpsocket.h"
+#include "webrtc/base/scoped_ptr.h"
+
+namespace cricket {
+
+const int STUN_SERVER_PORT = 3478;
+
+class StunServer : public sigslot::has_slots<> {
+ public:
+ // Creates a STUN server, which will listen on the given socket.
+ explicit StunServer(rtc::AsyncUDPSocket* socket);
+ // Removes the STUN server from the socket and deletes the socket.
+ ~StunServer();
+
+ protected:
+ // Slot for AsyncSocket.PacketRead:
+ void OnPacket(
+ rtc::AsyncPacketSocket* socket, const char* buf, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time);
+
+ // Handlers for the different types of STUN/TURN requests:
+ virtual void OnBindingRequest(StunMessage* msg,
+ const rtc::SocketAddress& addr);
+ void OnAllocateRequest(StunMessage* msg,
+ const rtc::SocketAddress& addr);
+ void OnSharedSecretRequest(StunMessage* msg,
+ const rtc::SocketAddress& addr);
+ void OnSendRequest(StunMessage* msg,
+ const rtc::SocketAddress& addr);
+
+ // Sends an error response to the given message back to the user.
+ void SendErrorResponse(
+ const StunMessage& msg, const rtc::SocketAddress& addr,
+ int error_code, const char* error_desc);
+
+ // Sends the given message to the appropriate destination.
+ void SendResponse(const StunMessage& msg,
+ const rtc::SocketAddress& addr);
+
+ // A helper method to compose a STUN binding response.
+ void GetStunBindReqponse(StunMessage* request,
+ const rtc::SocketAddress& remote_addr,
+ StunMessage* response) const;
+
+ private:
+ rtc::scoped_ptr<rtc::AsyncUDPSocket> socket_;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_STUNSERVER_H_
diff --git a/p2p/base/stunserver_unittest.cc b/p2p/base/stunserver_unittest.cc
new file mode 100644
index 00000000..7266eae8
--- /dev/null
+++ b/p2p/base/stunserver_unittest.cc
@@ -0,0 +1,109 @@
+/*
+ * 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 <string>
+
+#include "webrtc/p2p/base/stunserver.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/physicalsocketserver.h"
+#include "webrtc/base/testclient.h"
+#include "webrtc/base/thread.h"
+#include "webrtc/base/virtualsocketserver.h"
+
+using namespace cricket;
+
+static const rtc::SocketAddress server_addr("99.99.99.1", 3478);
+static const rtc::SocketAddress client_addr("1.2.3.4", 1234);
+
+class StunServerTest : public testing::Test {
+ public:
+ StunServerTest()
+ : pss_(new rtc::PhysicalSocketServer),
+ ss_(new rtc::VirtualSocketServer(pss_.get())),
+ worker_(ss_.get()) {
+ }
+ virtual void SetUp() {
+ server_.reset(new StunServer(
+ rtc::AsyncUDPSocket::Create(ss_.get(), server_addr)));
+ client_.reset(new rtc::TestClient(
+ rtc::AsyncUDPSocket::Create(ss_.get(), client_addr)));
+
+ worker_.Start();
+ }
+ void Send(const StunMessage& msg) {
+ rtc::ByteBuffer buf;
+ msg.Write(&buf);
+ Send(buf.Data(), static_cast<int>(buf.Length()));
+ }
+ void Send(const char* buf, int len) {
+ client_->SendTo(buf, len, server_addr);
+ }
+ StunMessage* Receive() {
+ StunMessage* msg = NULL;
+ rtc::TestClient::Packet* packet = client_->NextPacket();
+ if (packet) {
+ rtc::ByteBuffer buf(packet->buf, packet->size);
+ msg = new StunMessage();
+ msg->Read(&buf);
+ delete packet;
+ }
+ return msg;
+ }
+ private:
+ rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
+ rtc::scoped_ptr<rtc::VirtualSocketServer> ss_;
+ rtc::Thread worker_;
+ rtc::scoped_ptr<StunServer> server_;
+ rtc::scoped_ptr<rtc::TestClient> client_;
+};
+
+// Disable for TSan v2, see
+// https://code.google.com/p/webrtc/issues/detail?id=2517 for details.
+#if !defined(THREAD_SANITIZER)
+
+TEST_F(StunServerTest, TestGood) {
+ StunMessage req;
+ std::string transaction_id = "0123456789ab";
+ req.SetType(STUN_BINDING_REQUEST);
+ req.SetTransactionID(transaction_id);
+ Send(req);
+
+ StunMessage* msg = Receive();
+ ASSERT_TRUE(msg != NULL);
+ EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
+ EXPECT_EQ(req.transaction_id(), msg->transaction_id());
+
+ const StunAddressAttribute* mapped_addr =
+ msg->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
+ EXPECT_TRUE(mapped_addr != NULL);
+ EXPECT_EQ(1, mapped_addr->family());
+ EXPECT_EQ(client_addr.port(), mapped_addr->port());
+ if (mapped_addr->ipaddr() != client_addr.ipaddr()) {
+ LOG(LS_WARNING) << "Warning: mapped IP ("
+ << mapped_addr->ipaddr()
+ << ") != local IP (" << client_addr.ipaddr()
+ << ")";
+ }
+
+ delete msg;
+}
+
+#endif // if !defined(THREAD_SANITIZER)
+
+TEST_F(StunServerTest, TestBad) {
+ const char* bad = "this is a completely nonsensical message whose only "
+ "purpose is to make the parser go 'ack'. it doesn't "
+ "look anything like a normal stun message";
+ Send(bad, static_cast<int>(strlen(bad)));
+
+ StunMessage* msg = Receive();
+ ASSERT_TRUE(msg == NULL);
+}
diff --git a/p2p/base/tcpport.cc b/p2p/base/tcpport.cc
new file mode 100644
index 00000000..be3068be
--- /dev/null
+++ b/p2p/base/tcpport.cc
@@ -0,0 +1,321 @@
+/*
+ * 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 "webrtc/p2p/base/tcpport.h"
+
+#include "webrtc/p2p/base/common.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/logging.h"
+
+namespace cricket {
+
+TCPPort::TCPPort(rtc::Thread* thread,
+ rtc::PacketSocketFactory* factory,
+ rtc::Network* network, const rtc::IPAddress& ip,
+ int min_port, int max_port, const std::string& username,
+ const std::string& password, bool allow_listen)
+ : Port(thread, LOCAL_PORT_TYPE, factory, network, ip, min_port, max_port,
+ username, password),
+ incoming_only_(false),
+ allow_listen_(allow_listen),
+ socket_(NULL),
+ error_(0) {
+ // TODO(mallinath) - Set preference value as per RFC 6544.
+ // http://b/issue?id=7141794
+}
+
+bool TCPPort::Init() {
+ if (allow_listen_) {
+ // Treat failure to create or bind a TCP socket as fatal. This
+ // should never happen.
+ socket_ = socket_factory()->CreateServerTcpSocket(
+ rtc::SocketAddress(ip(), 0), min_port(), max_port(),
+ false /* ssl */);
+ if (!socket_) {
+ LOG_J(LS_ERROR, this) << "TCP socket creation failed.";
+ return false;
+ }
+ socket_->SignalNewConnection.connect(this, &TCPPort::OnNewConnection);
+ socket_->SignalAddressReady.connect(this, &TCPPort::OnAddressReady);
+ }
+ return true;
+}
+
+TCPPort::~TCPPort() {
+ delete socket_;
+ std::list<Incoming>::iterator it;
+ for (it = incoming_.begin(); it != incoming_.end(); ++it)
+ delete it->socket;
+ incoming_.clear();
+}
+
+Connection* TCPPort::CreateConnection(const Candidate& address,
+ CandidateOrigin origin) {
+ // We only support TCP protocols
+ if ((address.protocol() != TCP_PROTOCOL_NAME) &&
+ (address.protocol() != SSLTCP_PROTOCOL_NAME)) {
+ return NULL;
+ }
+
+ if (address.tcptype() == TCPTYPE_ACTIVE_STR ||
+ (address.tcptype().empty() && address.address().port() == 0)) {
+ // It's active only candidate, we should not try to create connections
+ // for these candidates.
+ return NULL;
+ }
+
+ // We can't accept TCP connections incoming on other ports
+ if (origin == ORIGIN_OTHER_PORT)
+ return NULL;
+
+ // Check if we are allowed to make outgoing TCP connections
+ if (incoming_only_ && (origin == ORIGIN_MESSAGE))
+ return NULL;
+
+ // We don't know how to act as an ssl server yet
+ if ((address.protocol() == SSLTCP_PROTOCOL_NAME) &&
+ (origin == ORIGIN_THIS_PORT)) {
+ return NULL;
+ }
+
+ if (!IsCompatibleAddress(address.address())) {
+ return NULL;
+ }
+
+ TCPConnection* conn = NULL;
+ if (rtc::AsyncPacketSocket* socket =
+ GetIncoming(address.address(), true)) {
+ socket->SignalReadPacket.disconnect(this);
+ conn = new TCPConnection(this, address, socket);
+ } else {
+ conn = new TCPConnection(this, address);
+ }
+ AddConnection(conn);
+ return conn;
+}
+
+void TCPPort::PrepareAddress() {
+ if (socket_) {
+ // If socket isn't bound yet the address will be added in
+ // OnAddressReady(). Socket may be in the CLOSED state if Listen()
+ // failed, we still want to add the socket address.
+ LOG(LS_VERBOSE) << "Preparing TCP address, current state: "
+ << socket_->GetState();
+ if (socket_->GetState() == rtc::AsyncPacketSocket::STATE_BOUND ||
+ socket_->GetState() == rtc::AsyncPacketSocket::STATE_CLOSED)
+ AddAddress(socket_->GetLocalAddress(), socket_->GetLocalAddress(),
+ rtc::SocketAddress(),
+ TCP_PROTOCOL_NAME, TCPTYPE_PASSIVE_STR, LOCAL_PORT_TYPE,
+ ICE_TYPE_PREFERENCE_HOST_TCP, 0, true);
+ } else {
+ LOG_J(LS_INFO, this) << "Not listening due to firewall restrictions.";
+ // Note: We still add the address, since otherwise the remote side won't
+ // recognize our incoming TCP connections.
+ AddAddress(rtc::SocketAddress(ip(), 0),
+ rtc::SocketAddress(ip(), 0), rtc::SocketAddress(),
+ TCP_PROTOCOL_NAME, TCPTYPE_ACTIVE_STR, LOCAL_PORT_TYPE,
+ ICE_TYPE_PREFERENCE_HOST_TCP, 0, true);
+ }
+}
+
+int TCPPort::SendTo(const void* data, size_t size,
+ const rtc::SocketAddress& addr,
+ const rtc::PacketOptions& options,
+ bool payload) {
+ rtc::AsyncPacketSocket * socket = NULL;
+ if (TCPConnection * conn = static_cast<TCPConnection*>(GetConnection(addr))) {
+ socket = conn->socket();
+ } else {
+ socket = GetIncoming(addr);
+ }
+ if (!socket) {
+ LOG_J(LS_ERROR, this) << "Attempted to send to an unknown destination, "
+ << addr.ToSensitiveString();
+ return -1; // TODO: Set error_
+ }
+
+ int sent = socket->Send(data, size, options);
+ if (sent < 0) {
+ error_ = socket->GetError();
+ LOG_J(LS_ERROR, this) << "TCP send of " << size
+ << " bytes failed with error " << error_;
+ }
+ return sent;
+}
+
+int TCPPort::GetOption(rtc::Socket::Option opt, int* value) {
+ if (socket_) {
+ return socket_->GetOption(opt, value);
+ } else {
+ return SOCKET_ERROR;
+ }
+}
+
+int TCPPort::SetOption(rtc::Socket::Option opt, int value) {
+ if (socket_) {
+ return socket_->SetOption(opt, value);
+ } else {
+ return SOCKET_ERROR;
+ }
+}
+
+int TCPPort::GetError() {
+ return error_;
+}
+
+void TCPPort::OnNewConnection(rtc::AsyncPacketSocket* socket,
+ rtc::AsyncPacketSocket* new_socket) {
+ ASSERT(socket == socket_);
+
+ Incoming incoming;
+ incoming.addr = new_socket->GetRemoteAddress();
+ incoming.socket = new_socket;
+ incoming.socket->SignalReadPacket.connect(this, &TCPPort::OnReadPacket);
+ incoming.socket->SignalReadyToSend.connect(this, &TCPPort::OnReadyToSend);
+
+ LOG_J(LS_VERBOSE, this) << "Accepted connection from "
+ << incoming.addr.ToSensitiveString();
+ incoming_.push_back(incoming);
+}
+
+rtc::AsyncPacketSocket* TCPPort::GetIncoming(
+ const rtc::SocketAddress& addr, bool remove) {
+ rtc::AsyncPacketSocket* socket = NULL;
+ for (std::list<Incoming>::iterator it = incoming_.begin();
+ it != incoming_.end(); ++it) {
+ if (it->addr == addr) {
+ socket = it->socket;
+ if (remove)
+ incoming_.erase(it);
+ break;
+ }
+ }
+ return socket;
+}
+
+void TCPPort::OnReadPacket(rtc::AsyncPacketSocket* socket,
+ const char* data, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time) {
+ Port::OnReadPacket(data, size, remote_addr, PROTO_TCP);
+}
+
+void TCPPort::OnReadyToSend(rtc::AsyncPacketSocket* socket) {
+ Port::OnReadyToSend();
+}
+
+void TCPPort::OnAddressReady(rtc::AsyncPacketSocket* socket,
+ const rtc::SocketAddress& address) {
+ AddAddress(address, address, rtc::SocketAddress(),
+ TCP_PROTOCOL_NAME, TCPTYPE_PASSIVE_STR, LOCAL_PORT_TYPE,
+ ICE_TYPE_PREFERENCE_HOST_TCP, 0, true);
+}
+
+TCPConnection::TCPConnection(TCPPort* port, const Candidate& candidate,
+ rtc::AsyncPacketSocket* socket)
+ : Connection(port, 0, candidate), socket_(socket), error_(0) {
+ bool outgoing = (socket_ == NULL);
+ if (outgoing) {
+ // TODO: Handle failures here (unlikely since TCP).
+ int opts = (candidate.protocol() == SSLTCP_PROTOCOL_NAME) ?
+ rtc::PacketSocketFactory::OPT_SSLTCP : 0;
+ socket_ = port->socket_factory()->CreateClientTcpSocket(
+ rtc::SocketAddress(port->ip(), 0),
+ candidate.address(), port->proxy(), port->user_agent(), opts);
+ if (socket_) {
+ LOG_J(LS_VERBOSE, this) << "Connecting from "
+ << socket_->GetLocalAddress().ToSensitiveString()
+ << " to "
+ << candidate.address().ToSensitiveString();
+ set_connected(false);
+ socket_->SignalConnect.connect(this, &TCPConnection::OnConnect);
+ } else {
+ LOG_J(LS_WARNING, this) << "Failed to create connection to "
+ << candidate.address().ToSensitiveString();
+ }
+ } else {
+ // Incoming connections should match the network address.
+ ASSERT(socket_->GetLocalAddress().ipaddr() == port->ip());
+ }
+
+ if (socket_) {
+ socket_->SignalReadPacket.connect(this, &TCPConnection::OnReadPacket);
+ socket_->SignalReadyToSend.connect(this, &TCPConnection::OnReadyToSend);
+ socket_->SignalClose.connect(this, &TCPConnection::OnClose);
+ }
+}
+
+TCPConnection::~TCPConnection() {
+ delete socket_;
+}
+
+int TCPConnection::Send(const void* data, size_t size,
+ const rtc::PacketOptions& options) {
+ if (!socket_) {
+ error_ = ENOTCONN;
+ return SOCKET_ERROR;
+ }
+
+ if (write_state() != STATE_WRITABLE) {
+ // TODO: Should STATE_WRITE_TIMEOUT return a non-blocking error?
+ error_ = EWOULDBLOCK;
+ return SOCKET_ERROR;
+ }
+ int sent = socket_->Send(data, size, options);
+ if (sent < 0) {
+ error_ = socket_->GetError();
+ } else {
+ send_rate_tracker_.Update(sent);
+ }
+ return sent;
+}
+
+int TCPConnection::GetError() {
+ return error_;
+}
+
+void TCPConnection::OnConnect(rtc::AsyncPacketSocket* socket) {
+ ASSERT(socket == socket_);
+ // Do not use this connection if the socket bound to a different address than
+ // the one we asked for. This is seen in Chrome, where TCP sockets cannot be
+ // given a binding address, and the platform is expected to pick the
+ // correct local address.
+ if (socket->GetLocalAddress().ipaddr() == port()->ip()) {
+ LOG_J(LS_VERBOSE, this) << "Connection established to "
+ << socket->GetRemoteAddress().ToSensitiveString();
+ set_connected(true);
+ } else {
+ LOG_J(LS_WARNING, this) << "Dropping connection as TCP socket bound to a "
+ << "different address from the local candidate.";
+ socket_->Close();
+ }
+}
+
+void TCPConnection::OnClose(rtc::AsyncPacketSocket* socket, int error) {
+ ASSERT(socket == socket_);
+ LOG_J(LS_VERBOSE, this) << "Connection closed with error " << error;
+ set_connected(false);
+ set_write_state(STATE_WRITE_TIMEOUT);
+}
+
+void TCPConnection::OnReadPacket(
+ rtc::AsyncPacketSocket* socket, const char* data, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time) {
+ ASSERT(socket == socket_);
+ Connection::OnReadPacket(data, size, packet_time);
+}
+
+void TCPConnection::OnReadyToSend(rtc::AsyncPacketSocket* socket) {
+ ASSERT(socket == socket_);
+ Connection::OnReadyToSend();
+}
+
+} // namespace cricket
diff --git a/p2p/base/tcpport.h b/p2p/base/tcpport.h
new file mode 100644
index 00000000..43e49366
--- /dev/null
+++ b/p2p/base/tcpport.h
@@ -0,0 +1,136 @@
+/*
+ * 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 WEBRTC_P2P_BASE_TCPPORT_H_
+#define WEBRTC_P2P_BASE_TCPPORT_H_
+
+#include <list>
+#include <string>
+#include "webrtc/p2p/base/port.h"
+#include "webrtc/base/asyncpacketsocket.h"
+
+namespace cricket {
+
+class TCPConnection;
+
+// Communicates using a local TCP port.
+//
+// This class is designed to allow subclasses to take advantage of the
+// connection management provided by this class. A subclass should take of all
+// packet sending and preparation, but when a packet is received, it should
+// call this TCPPort::OnReadPacket (3 arg) to dispatch to a connection.
+class TCPPort : public Port {
+ public:
+ static TCPPort* Create(rtc::Thread* thread,
+ rtc::PacketSocketFactory* factory,
+ rtc::Network* network,
+ const rtc::IPAddress& ip,
+ int min_port, int max_port,
+ const std::string& username,
+ const std::string& password,
+ bool allow_listen) {
+ TCPPort* port = new TCPPort(thread, factory, network,
+ ip, min_port, max_port,
+ username, password, allow_listen);
+ if (!port->Init()) {
+ delete port;
+ port = NULL;
+ }
+ return port;
+ }
+ virtual ~TCPPort();
+
+ virtual Connection* CreateConnection(const Candidate& address,
+ CandidateOrigin origin);
+
+ virtual void PrepareAddress();
+
+ virtual int GetOption(rtc::Socket::Option opt, int* value);
+ virtual int SetOption(rtc::Socket::Option opt, int value);
+ virtual int GetError();
+
+ protected:
+ TCPPort(rtc::Thread* thread, rtc::PacketSocketFactory* factory,
+ rtc::Network* network, const rtc::IPAddress& ip,
+ int min_port, int max_port, const std::string& username,
+ const std::string& password, bool allow_listen);
+ bool Init();
+
+ // Handles sending using the local TCP socket.
+ virtual int SendTo(const void* data, size_t size,
+ const rtc::SocketAddress& addr,
+ const rtc::PacketOptions& options,
+ bool payload);
+
+ // Accepts incoming TCP connection.
+ void OnNewConnection(rtc::AsyncPacketSocket* socket,
+ rtc::AsyncPacketSocket* new_socket);
+
+ private:
+ struct Incoming {
+ rtc::SocketAddress addr;
+ rtc::AsyncPacketSocket* socket;
+ };
+
+ rtc::AsyncPacketSocket* GetIncoming(
+ const rtc::SocketAddress& addr, bool remove = false);
+
+ // Receives packet signal from the local TCP Socket.
+ void OnReadPacket(rtc::AsyncPacketSocket* socket,
+ const char* data, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time);
+
+ void OnReadyToSend(rtc::AsyncPacketSocket* socket);
+
+ void OnAddressReady(rtc::AsyncPacketSocket* socket,
+ const rtc::SocketAddress& address);
+
+ // TODO: Is this still needed?
+ bool incoming_only_;
+ bool allow_listen_;
+ rtc::AsyncPacketSocket* socket_;
+ int error_;
+ std::list<Incoming> incoming_;
+
+ friend class TCPConnection;
+};
+
+class TCPConnection : public Connection {
+ public:
+ // Connection is outgoing unless socket is specified
+ TCPConnection(TCPPort* port, const Candidate& candidate,
+ rtc::AsyncPacketSocket* socket = 0);
+ virtual ~TCPConnection();
+
+ virtual int Send(const void* data, size_t size,
+ const rtc::PacketOptions& options);
+ virtual int GetError();
+
+ rtc::AsyncPacketSocket* socket() { return socket_; }
+
+ private:
+ void OnConnect(rtc::AsyncPacketSocket* socket);
+ void OnClose(rtc::AsyncPacketSocket* socket, int error);
+ void OnReadPacket(rtc::AsyncPacketSocket* socket,
+ const char* data, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time);
+ void OnReadyToSend(rtc::AsyncPacketSocket* socket);
+
+ rtc::AsyncPacketSocket* socket_;
+ int error_;
+
+ friend class TCPPort;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_TCPPORT_H_
diff --git a/p2p/base/testrelayserver.h b/p2p/base/testrelayserver.h
new file mode 100644
index 00000000..87cb9e5d
--- /dev/null
+++ b/p2p/base/testrelayserver.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2008 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_P2P_BASE_TESTRELAYSERVER_H_
+#define WEBRTC_P2P_BASE_TESTRELAYSERVER_H_
+
+#include "webrtc/p2p/base/relayserver.h"
+#include "webrtc/base/asynctcpsocket.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/sigslot.h"
+#include "webrtc/base/socketadapters.h"
+#include "webrtc/base/thread.h"
+
+namespace cricket {
+
+// A test relay server. Useful for unit tests.
+class TestRelayServer : public sigslot::has_slots<> {
+ public:
+ TestRelayServer(rtc::Thread* thread,
+ const rtc::SocketAddress& udp_int_addr,
+ const rtc::SocketAddress& udp_ext_addr,
+ const rtc::SocketAddress& tcp_int_addr,
+ const rtc::SocketAddress& tcp_ext_addr,
+ const rtc::SocketAddress& ssl_int_addr,
+ const rtc::SocketAddress& ssl_ext_addr)
+ : server_(thread) {
+ server_.AddInternalSocket(rtc::AsyncUDPSocket::Create(
+ thread->socketserver(), udp_int_addr));
+ server_.AddExternalSocket(rtc::AsyncUDPSocket::Create(
+ thread->socketserver(), udp_ext_addr));
+
+ tcp_int_socket_.reset(CreateListenSocket(thread, tcp_int_addr));
+ tcp_ext_socket_.reset(CreateListenSocket(thread, tcp_ext_addr));
+ ssl_int_socket_.reset(CreateListenSocket(thread, ssl_int_addr));
+ ssl_ext_socket_.reset(CreateListenSocket(thread, ssl_ext_addr));
+ }
+ int GetConnectionCount() const {
+ return server_.GetConnectionCount();
+ }
+ rtc::SocketAddressPair GetConnection(int connection) const {
+ return server_.GetConnection(connection);
+ }
+ bool HasConnection(const rtc::SocketAddress& address) const {
+ return server_.HasConnection(address);
+ }
+
+ private:
+ rtc::AsyncSocket* CreateListenSocket(rtc::Thread* thread,
+ const rtc::SocketAddress& addr) {
+ rtc::AsyncSocket* socket =
+ thread->socketserver()->CreateAsyncSocket(addr.family(), SOCK_STREAM);
+ socket->Bind(addr);
+ socket->Listen(5);
+ socket->SignalReadEvent.connect(this, &TestRelayServer::OnAccept);
+ return socket;
+ }
+ void OnAccept(rtc::AsyncSocket* socket) {
+ bool external = (socket == tcp_ext_socket_.get() ||
+ socket == ssl_ext_socket_.get());
+ bool ssl = (socket == ssl_int_socket_.get() ||
+ socket == ssl_ext_socket_.get());
+ rtc::AsyncSocket* raw_socket = socket->Accept(NULL);
+ if (raw_socket) {
+ rtc::AsyncTCPSocket* packet_socket = new rtc::AsyncTCPSocket(
+ (!ssl) ? raw_socket :
+ new rtc::AsyncSSLServerSocket(raw_socket), false);
+ if (!external) {
+ packet_socket->SignalClose.connect(this,
+ &TestRelayServer::OnInternalClose);
+ server_.AddInternalSocket(packet_socket);
+ } else {
+ packet_socket->SignalClose.connect(this,
+ &TestRelayServer::OnExternalClose);
+ server_.AddExternalSocket(packet_socket);
+ }
+ }
+ }
+ void OnInternalClose(rtc::AsyncPacketSocket* socket, int error) {
+ server_.RemoveInternalSocket(socket);
+ }
+ void OnExternalClose(rtc::AsyncPacketSocket* socket, int error) {
+ server_.RemoveExternalSocket(socket);
+ }
+ private:
+ cricket::RelayServer server_;
+ rtc::scoped_ptr<rtc::AsyncSocket> tcp_int_socket_;
+ rtc::scoped_ptr<rtc::AsyncSocket> tcp_ext_socket_;
+ rtc::scoped_ptr<rtc::AsyncSocket> ssl_int_socket_;
+ rtc::scoped_ptr<rtc::AsyncSocket> ssl_ext_socket_;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_TESTRELAYSERVER_H_
diff --git a/p2p/base/teststunserver.h b/p2p/base/teststunserver.h
new file mode 100644
index 00000000..a2a8b6fc
--- /dev/null
+++ b/p2p/base/teststunserver.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2008 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_P2P_BASE_TESTSTUNSERVER_H_
+#define WEBRTC_P2P_BASE_TESTSTUNSERVER_H_
+
+#include "webrtc/p2p/base/stunserver.h"
+#include "webrtc/base/socketaddress.h"
+#include "webrtc/base/thread.h"
+
+namespace cricket {
+
+// A test STUN server. Useful for unit tests.
+class TestStunServer : StunServer {
+ public:
+ static TestStunServer* Create(rtc::Thread* thread,
+ const rtc::SocketAddress& addr) {
+ rtc::AsyncSocket* socket =
+ thread->socketserver()->CreateAsyncSocket(addr.family(), SOCK_DGRAM);
+ rtc::AsyncUDPSocket* udp_socket =
+ rtc::AsyncUDPSocket::Create(socket, addr);
+
+ return new TestStunServer(udp_socket);
+ }
+
+ // Set a fake STUN address to return to the client.
+ void set_fake_stun_addr(const rtc::SocketAddress& addr) {
+ fake_stun_addr_ = addr;
+ }
+
+ private:
+ explicit TestStunServer(rtc::AsyncUDPSocket* socket) : StunServer(socket) {}
+
+ void OnBindingRequest(StunMessage* msg,
+ const rtc::SocketAddress& remote_addr) OVERRIDE {
+ if (fake_stun_addr_.IsNil()) {
+ StunServer::OnBindingRequest(msg, remote_addr);
+ } else {
+ StunMessage response;
+ GetStunBindReqponse(msg, fake_stun_addr_, &response);
+ SendResponse(response, remote_addr);
+ }
+ }
+
+ private:
+ rtc::SocketAddress fake_stun_addr_;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_TESTSTUNSERVER_H_
diff --git a/p2p/base/testturnserver.h b/p2p/base/testturnserver.h
new file mode 100644
index 00000000..19f73e7f
--- /dev/null
+++ b/p2p/base/testturnserver.h
@@ -0,0 +1,103 @@
+/*
+ * 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 WEBRTC_P2P_BASE_TESTTURNSERVER_H_
+#define WEBRTC_P2P_BASE_TESTTURNSERVER_H_
+
+#include <string>
+#include <vector>
+
+#include "webrtc/p2p/base/basicpacketsocketfactory.h"
+#include "webrtc/p2p/base/stun.h"
+#include "webrtc/p2p/base/turnserver.h"
+#include "webrtc/base/asyncudpsocket.h"
+#include "webrtc/base/thread.h"
+
+namespace cricket {
+
+static const char kTestRealm[] = "example.org";
+static const char kTestSoftware[] = "TestTurnServer";
+
+class TestTurnRedirector : public TurnRedirectInterface {
+ public:
+ explicit TestTurnRedirector(const std::vector<rtc::SocketAddress>& addresses)
+ : alternate_server_addresses_(addresses),
+ iter_(alternate_server_addresses_.begin()) {
+ }
+
+ virtual bool ShouldRedirect(const rtc::SocketAddress&,
+ rtc::SocketAddress* out) {
+ if (!out || iter_ == alternate_server_addresses_.end()) {
+ return false;
+ }
+ *out = *iter_++;
+ return true;
+ }
+
+ private:
+ const std::vector<rtc::SocketAddress>& alternate_server_addresses_;
+ std::vector<rtc::SocketAddress>::const_iterator iter_;
+};
+
+class TestTurnServer : public TurnAuthInterface {
+ public:
+ TestTurnServer(rtc::Thread* thread,
+ const rtc::SocketAddress& udp_int_addr,
+ const rtc::SocketAddress& udp_ext_addr)
+ : server_(thread) {
+ AddInternalSocket(udp_int_addr, cricket::PROTO_UDP);
+ server_.SetExternalSocketFactory(new rtc::BasicPacketSocketFactory(),
+ udp_ext_addr);
+ server_.set_realm(kTestRealm);
+ server_.set_software(kTestSoftware);
+ server_.set_auth_hook(this);
+ }
+
+ void set_enable_otu_nonce(bool enable) {
+ server_.set_enable_otu_nonce(enable);
+ }
+
+ TurnServer* server() { return &server_; }
+
+ void set_redirect_hook(TurnRedirectInterface* redirect_hook) {
+ server_.set_redirect_hook(redirect_hook);
+ }
+
+ void AddInternalSocket(const rtc::SocketAddress& int_addr,
+ ProtocolType proto) {
+ rtc::Thread* thread = rtc::Thread::Current();
+ if (proto == cricket::PROTO_UDP) {
+ server_.AddInternalSocket(rtc::AsyncUDPSocket::Create(
+ thread->socketserver(), int_addr), proto);
+ } else if (proto == cricket::PROTO_TCP) {
+ // For TCP we need to create a server socket which can listen for incoming
+ // new connections.
+ rtc::AsyncSocket* socket =
+ thread->socketserver()->CreateAsyncSocket(SOCK_STREAM);
+ socket->Bind(int_addr);
+ socket->Listen(5);
+ server_.AddInternalServerSocket(socket, proto);
+ }
+ }
+
+ private:
+ // For this test server, succeed if the password is the same as the username.
+ // Obviously, do not use this in a production environment.
+ virtual bool GetKey(const std::string& username, const std::string& realm,
+ std::string* key) {
+ return ComputeStunCredentialHash(username, realm, username, key);
+ }
+
+ TurnServer server_;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_TESTTURNSERVER_H_
diff --git a/p2p/base/transport.cc b/p2p/base/transport.cc
new file mode 100644
index 00000000..05c455e4
--- /dev/null
+++ b/p2p/base/transport.cc
@@ -0,0 +1,960 @@
+/*
+ * 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 "webrtc/p2p/base/transport.h"
+
+#include "webrtc/p2p/base/candidate.h"
+#include "webrtc/p2p/base/constants.h"
+#include "webrtc/p2p/base/parsing.h"
+#include "webrtc/p2p/base/port.h"
+#include "webrtc/p2p/base/sessionmanager.h"
+#include "webrtc/p2p/base/transportchannelimpl.h"
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/base/bind.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/logging.h"
+
+namespace cricket {
+
+using rtc::Bind;
+
+enum {
+ MSG_ONSIGNALINGREADY = 1,
+ MSG_ONREMOTECANDIDATE,
+ MSG_READSTATE,
+ MSG_WRITESTATE,
+ MSG_REQUESTSIGNALING,
+ MSG_CANDIDATEREADY,
+ MSG_ROUTECHANGE,
+ MSG_CONNECTING,
+ MSG_CANDIDATEALLOCATIONCOMPLETE,
+ MSG_ROLECONFLICT,
+ MSG_COMPLETED,
+ MSG_FAILED,
+};
+
+struct ChannelParams : public rtc::MessageData {
+ ChannelParams() : channel(NULL), candidate(NULL) {}
+ explicit ChannelParams(int component)
+ : component(component), channel(NULL), candidate(NULL) {}
+ explicit ChannelParams(Candidate* candidate)
+ : channel(NULL), candidate(candidate) {
+ }
+
+ ~ChannelParams() {
+ delete candidate;
+ }
+
+ std::string name;
+ int component;
+ TransportChannelImpl* channel;
+ Candidate* candidate;
+};
+
+static std::string IceProtoToString(TransportProtocol proto) {
+ std::string proto_str;
+ switch (proto) {
+ case ICEPROTO_GOOGLE:
+ proto_str = "gice";
+ break;
+ case ICEPROTO_HYBRID:
+ proto_str = "hybrid";
+ break;
+ case ICEPROTO_RFC5245:
+ proto_str = "ice";
+ break;
+ default:
+ ASSERT(false);
+ break;
+ }
+ return proto_str;
+}
+
+static bool VerifyIceParams(const TransportDescription& desc) {
+ // For legacy protocols.
+ if (desc.ice_ufrag.empty() && desc.ice_pwd.empty())
+ return true;
+
+ if (desc.ice_ufrag.length() < ICE_UFRAG_MIN_LENGTH ||
+ desc.ice_ufrag.length() > ICE_UFRAG_MAX_LENGTH) {
+ return false;
+ }
+ if (desc.ice_pwd.length() < ICE_PWD_MIN_LENGTH ||
+ desc.ice_pwd.length() > ICE_PWD_MAX_LENGTH) {
+ return false;
+ }
+ return true;
+}
+
+bool BadTransportDescription(const std::string& desc, std::string* err_desc) {
+ if (err_desc) {
+ *err_desc = desc;
+ }
+ LOG(LS_ERROR) << desc;
+ return false;
+}
+
+bool IceCredentialsChanged(const std::string& old_ufrag,
+ const std::string& old_pwd,
+ const std::string& new_ufrag,
+ const std::string& new_pwd) {
+ // TODO(jiayl): The standard (RFC 5245 Section 9.1.1.1) says that ICE should
+ // restart when both the ufrag and password are changed, but we do restart
+ // when either ufrag or passwrod is changed to keep compatible with GICE. We
+ // should clean this up when GICE is no longer used.
+ return (old_ufrag != new_ufrag) || (old_pwd != new_pwd);
+}
+
+static bool IceCredentialsChanged(const TransportDescription& old_desc,
+ const TransportDescription& new_desc) {
+ return IceCredentialsChanged(old_desc.ice_ufrag, old_desc.ice_pwd,
+ new_desc.ice_ufrag, new_desc.ice_pwd);
+}
+
+Transport::Transport(rtc::Thread* signaling_thread,
+ rtc::Thread* worker_thread,
+ const std::string& content_name,
+ const std::string& type,
+ PortAllocator* allocator)
+ : signaling_thread_(signaling_thread),
+ worker_thread_(worker_thread),
+ content_name_(content_name),
+ type_(type),
+ allocator_(allocator),
+ destroyed_(false),
+ readable_(TRANSPORT_STATE_NONE),
+ writable_(TRANSPORT_STATE_NONE),
+ was_writable_(false),
+ connect_requested_(false),
+ ice_role_(ICEROLE_UNKNOWN),
+ tiebreaker_(0),
+ protocol_(ICEPROTO_HYBRID),
+ remote_ice_mode_(ICEMODE_FULL) {
+}
+
+Transport::~Transport() {
+ ASSERT(signaling_thread_->IsCurrent());
+ ASSERT(destroyed_);
+}
+
+void Transport::SetIceRole(IceRole role) {
+ worker_thread_->Invoke<void>(Bind(&Transport::SetIceRole_w, this, role));
+}
+
+void Transport::SetIdentity(rtc::SSLIdentity* identity) {
+ worker_thread_->Invoke<void>(Bind(&Transport::SetIdentity_w, this, identity));
+}
+
+bool Transport::GetIdentity(rtc::SSLIdentity** identity) {
+ // The identity is set on the worker thread, so for safety it must also be
+ // acquired on the worker thread.
+ return worker_thread_->Invoke<bool>(
+ Bind(&Transport::GetIdentity_w, this, identity));
+}
+
+bool Transport::GetRemoteCertificate(rtc::SSLCertificate** cert) {
+ // Channels can be deleted on the worker thread, so for safety the remote
+ // certificate is acquired on the worker thread.
+ return worker_thread_->Invoke<bool>(
+ Bind(&Transport::GetRemoteCertificate_w, this, cert));
+}
+
+bool Transport::GetRemoteCertificate_w(rtc::SSLCertificate** cert) {
+ ASSERT(worker_thread()->IsCurrent());
+ if (channels_.empty())
+ return false;
+
+ ChannelMap::iterator iter = channels_.begin();
+ return iter->second->GetRemoteCertificate(cert);
+}
+
+bool Transport::SetLocalTransportDescription(
+ const TransportDescription& description,
+ ContentAction action,
+ std::string* error_desc) {
+ return worker_thread_->Invoke<bool>(Bind(
+ &Transport::SetLocalTransportDescription_w, this,
+ description, action, error_desc));
+}
+
+bool Transport::SetRemoteTransportDescription(
+ const TransportDescription& description,
+ ContentAction action,
+ std::string* error_desc) {
+ return worker_thread_->Invoke<bool>(Bind(
+ &Transport::SetRemoteTransportDescription_w, this,
+ description, action, error_desc));
+}
+
+TransportChannelImpl* Transport::CreateChannel(int component) {
+ return worker_thread_->Invoke<TransportChannelImpl*>(Bind(
+ &Transport::CreateChannel_w, this, component));
+}
+
+TransportChannelImpl* Transport::CreateChannel_w(int component) {
+ ASSERT(worker_thread()->IsCurrent());
+ TransportChannelImpl *impl;
+ rtc::CritScope cs(&crit_);
+
+ // Create the entry if it does not exist.
+ bool impl_exists = false;
+ if (channels_.find(component) == channels_.end()) {
+ impl = CreateTransportChannel(component);
+ channels_[component] = ChannelMapEntry(impl);
+ } else {
+ impl = channels_[component].get();
+ impl_exists = true;
+ }
+
+ // Increase the ref count.
+ channels_[component].AddRef();
+ destroyed_ = false;
+
+ if (impl_exists) {
+ // If this is an existing channel, we should just return it without
+ // connecting to all the signal again.
+ return impl;
+ }
+
+ // Push down our transport state to the new channel.
+ impl->SetIceRole(ice_role_);
+ impl->SetIceTiebreaker(tiebreaker_);
+ // TODO(ronghuawu): Change CreateChannel_w to be able to return error since
+ // below Apply**Description_w calls can fail.
+ if (local_description_)
+ ApplyLocalTransportDescription_w(impl, NULL);
+ if (remote_description_)
+ ApplyRemoteTransportDescription_w(impl, NULL);
+ if (local_description_ && remote_description_)
+ ApplyNegotiatedTransportDescription_w(impl, NULL);
+
+ impl->SignalReadableState.connect(this, &Transport::OnChannelReadableState);
+ impl->SignalWritableState.connect(this, &Transport::OnChannelWritableState);
+ impl->SignalRequestSignaling.connect(
+ this, &Transport::OnChannelRequestSignaling);
+ impl->SignalCandidateReady.connect(this, &Transport::OnChannelCandidateReady);
+ impl->SignalRouteChange.connect(this, &Transport::OnChannelRouteChange);
+ impl->SignalCandidatesAllocationDone.connect(
+ this, &Transport::OnChannelCandidatesAllocationDone);
+ impl->SignalRoleConflict.connect(this, &Transport::OnRoleConflict);
+ impl->SignalConnectionRemoved.connect(
+ this, &Transport::OnChannelConnectionRemoved);
+
+ if (connect_requested_) {
+ impl->Connect();
+ if (channels_.size() == 1) {
+ // If this is the first channel, then indicate that we have started
+ // connecting.
+ signaling_thread()->Post(this, MSG_CONNECTING, NULL);
+ }
+ }
+ return impl;
+}
+
+TransportChannelImpl* Transport::GetChannel(int component) {
+ rtc::CritScope cs(&crit_);
+ ChannelMap::iterator iter = channels_.find(component);
+ return (iter != channels_.end()) ? iter->second.get() : NULL;
+}
+
+bool Transport::HasChannels() {
+ rtc::CritScope cs(&crit_);
+ return !channels_.empty();
+}
+
+void Transport::DestroyChannel(int component) {
+ worker_thread_->Invoke<void>(Bind(
+ &Transport::DestroyChannel_w, this, component));
+}
+
+void Transport::DestroyChannel_w(int component) {
+ ASSERT(worker_thread()->IsCurrent());
+
+ TransportChannelImpl* impl = NULL;
+ {
+ rtc::CritScope cs(&crit_);
+ ChannelMap::iterator iter = channels_.find(component);
+ if (iter == channels_.end())
+ return;
+
+ iter->second.DecRef();
+ if (!iter->second.ref()) {
+ impl = iter->second.get();
+ channels_.erase(iter);
+ }
+ }
+
+ if (connect_requested_ && channels_.empty()) {
+ // We're no longer attempting to connect.
+ signaling_thread()->Post(this, MSG_CONNECTING, NULL);
+ }
+
+ if (impl) {
+ // Check in case the deleted channel was the only non-writable channel.
+ OnChannelWritableState(impl);
+ DestroyTransportChannel(impl);
+ }
+}
+
+void Transport::ConnectChannels() {
+ ASSERT(signaling_thread()->IsCurrent());
+ worker_thread_->Invoke<void>(Bind(&Transport::ConnectChannels_w, this));
+}
+
+void Transport::ConnectChannels_w() {
+ ASSERT(worker_thread()->IsCurrent());
+ if (connect_requested_ || channels_.empty())
+ return;
+ connect_requested_ = true;
+ signaling_thread()->Post(
+ this, MSG_CANDIDATEREADY, NULL);
+
+ if (!local_description_) {
+ // TOOD(mallinath) : TransportDescription(TD) shouldn't be generated here.
+ // As Transport must know TD is offer or answer and cricket::Transport
+ // doesn't have the capability to decide it. This should be set by the
+ // Session.
+ // Session must generate local TD before remote candidates pushed when
+ // initiate request initiated by the remote.
+ LOG(LS_INFO) << "Transport::ConnectChannels_w: No local description has "
+ << "been set. Will generate one.";
+ TransportDescription desc(NS_GINGLE_P2P, std::vector<std::string>(),
+ rtc::CreateRandomString(ICE_UFRAG_LENGTH),
+ rtc::CreateRandomString(ICE_PWD_LENGTH),
+ ICEMODE_FULL, CONNECTIONROLE_NONE, NULL,
+ Candidates());
+ SetLocalTransportDescription_w(desc, CA_OFFER, NULL);
+ }
+
+ CallChannels_w(&TransportChannelImpl::Connect);
+ if (!channels_.empty()) {
+ signaling_thread()->Post(this, MSG_CONNECTING, NULL);
+ }
+}
+
+void Transport::OnConnecting_s() {
+ ASSERT(signaling_thread()->IsCurrent());
+ SignalConnecting(this);
+}
+
+void Transport::DestroyAllChannels() {
+ ASSERT(signaling_thread()->IsCurrent());
+ worker_thread_->Invoke<void>(
+ Bind(&Transport::DestroyAllChannels_w, this));
+ worker_thread()->Clear(this);
+ signaling_thread()->Clear(this);
+ destroyed_ = true;
+}
+
+void Transport::DestroyAllChannels_w() {
+ ASSERT(worker_thread()->IsCurrent());
+ std::vector<TransportChannelImpl*> impls;
+ {
+ rtc::CritScope cs(&crit_);
+ for (ChannelMap::iterator iter = channels_.begin();
+ iter != channels_.end();
+ ++iter) {
+ iter->second.DecRef();
+ if (!iter->second.ref())
+ impls.push_back(iter->second.get());
+ }
+ }
+ channels_.clear();
+
+
+ for (size_t i = 0; i < impls.size(); ++i)
+ DestroyTransportChannel(impls[i]);
+}
+
+void Transport::ResetChannels() {
+ ASSERT(signaling_thread()->IsCurrent());
+ worker_thread_->Invoke<void>(Bind(&Transport::ResetChannels_w, this));
+}
+
+void Transport::ResetChannels_w() {
+ ASSERT(worker_thread()->IsCurrent());
+
+ // We are no longer attempting to connect
+ connect_requested_ = false;
+
+ // Clear out the old messages, they aren't relevant
+ rtc::CritScope cs(&crit_);
+ ready_candidates_.clear();
+
+ // Reset all of the channels
+ CallChannels_w(&TransportChannelImpl::Reset);
+}
+
+void Transport::OnSignalingReady() {
+ ASSERT(signaling_thread()->IsCurrent());
+ if (destroyed_) return;
+
+ worker_thread()->Post(this, MSG_ONSIGNALINGREADY, NULL);
+
+ // Notify the subclass.
+ OnTransportSignalingReady();
+}
+
+void Transport::CallChannels_w(TransportChannelFunc func) {
+ ASSERT(worker_thread()->IsCurrent());
+ rtc::CritScope cs(&crit_);
+ for (ChannelMap::iterator iter = channels_.begin();
+ iter != channels_.end();
+ ++iter) {
+ ((iter->second.get())->*func)();
+ }
+}
+
+bool Transport::VerifyCandidate(const Candidate& cand, std::string* error) {
+ // No address zero.
+ if (cand.address().IsNil() || cand.address().IsAny()) {
+ *error = "candidate has address of zero";
+ return false;
+ }
+
+ // Disallow all ports below 1024, except for 80 and 443 on public addresses.
+ int port = cand.address().port();
+ if (cand.protocol() == TCP_PROTOCOL_NAME &&
+ (cand.tcptype() == TCPTYPE_ACTIVE_STR || port == 0)) {
+ // Expected for active-only candidates per
+ // http://tools.ietf.org/html/rfc6544#section-4.5 so no error.
+ // Libjingle clients emit port 0, in "active" mode.
+ return true;
+ }
+ if (port < 1024) {
+ if ((port != 80) && (port != 443)) {
+ *error = "candidate has port below 1024, but not 80 or 443";
+ return false;
+ }
+
+ if (cand.address().IsPrivateIP()) {
+ *error = "candidate has port of 80 or 443 with private IP address";
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+bool Transport::GetStats(TransportStats* stats) {
+ ASSERT(signaling_thread()->IsCurrent());
+ return worker_thread_->Invoke<bool>(Bind(
+ &Transport::GetStats_w, this, stats));
+}
+
+bool Transport::GetStats_w(TransportStats* stats) {
+ ASSERT(worker_thread()->IsCurrent());
+ stats->content_name = content_name();
+ stats->channel_stats.clear();
+ for (ChannelMap::iterator iter = channels_.begin();
+ iter != channels_.end();
+ ++iter) {
+ TransportChannelStats substats;
+ substats.component = iter->second->component();
+ if (!iter->second->GetStats(&substats.connection_infos)) {
+ return false;
+ }
+ stats->channel_stats.push_back(substats);
+ }
+ return true;
+}
+
+bool Transport::GetSslRole(rtc::SSLRole* ssl_role) const {
+ return worker_thread_->Invoke<bool>(Bind(
+ &Transport::GetSslRole_w, this, ssl_role));
+}
+
+void Transport::OnRemoteCandidates(const std::vector<Candidate>& candidates) {
+ for (std::vector<Candidate>::const_iterator iter = candidates.begin();
+ iter != candidates.end();
+ ++iter) {
+ OnRemoteCandidate(*iter);
+ }
+}
+
+void Transport::OnRemoteCandidate(const Candidate& candidate) {
+ ASSERT(signaling_thread()->IsCurrent());
+ if (destroyed_) return;
+
+ if (!HasChannel(candidate.component())) {
+ LOG(LS_WARNING) << "Ignoring candidate for unknown component "
+ << candidate.component();
+ return;
+ }
+
+ ChannelParams* params = new ChannelParams(new Candidate(candidate));
+ worker_thread()->Post(this, MSG_ONREMOTECANDIDATE, params);
+}
+
+void Transport::OnRemoteCandidate_w(const Candidate& candidate) {
+ ASSERT(worker_thread()->IsCurrent());
+ ChannelMap::iterator iter = channels_.find(candidate.component());
+ // It's ok for a channel to go away while this message is in transit.
+ if (iter != channels_.end()) {
+ iter->second->OnCandidate(candidate);
+ }
+}
+
+void Transport::OnChannelReadableState(TransportChannel* channel) {
+ ASSERT(worker_thread()->IsCurrent());
+ signaling_thread()->Post(this, MSG_READSTATE, NULL);
+}
+
+void Transport::OnChannelReadableState_s() {
+ ASSERT(signaling_thread()->IsCurrent());
+ TransportState readable = GetTransportState_s(true);
+ if (readable_ != readable) {
+ readable_ = readable;
+ SignalReadableState(this);
+ }
+}
+
+void Transport::OnChannelWritableState(TransportChannel* channel) {
+ ASSERT(worker_thread()->IsCurrent());
+ signaling_thread()->Post(this, MSG_WRITESTATE, NULL);
+
+ MaybeCompleted_w();
+}
+
+void Transport::OnChannelWritableState_s() {
+ ASSERT(signaling_thread()->IsCurrent());
+ TransportState writable = GetTransportState_s(false);
+ if (writable_ != writable) {
+ was_writable_ = (writable_ == TRANSPORT_STATE_ALL);
+ writable_ = writable;
+ SignalWritableState(this);
+ }
+}
+
+TransportState Transport::GetTransportState_s(bool read) {
+ ASSERT(signaling_thread()->IsCurrent());
+ rtc::CritScope cs(&crit_);
+ bool any = false;
+ bool all = !channels_.empty();
+ for (ChannelMap::iterator iter = channels_.begin();
+ iter != channels_.end();
+ ++iter) {
+ bool b = (read ? iter->second->readable() :
+ iter->second->writable());
+ any = any || b;
+ all = all && b;
+ }
+ if (all) {
+ return TRANSPORT_STATE_ALL;
+ } else if (any) {
+ return TRANSPORT_STATE_SOME;
+ } else {
+ return TRANSPORT_STATE_NONE;
+ }
+}
+
+void Transport::OnChannelRequestSignaling(TransportChannelImpl* channel) {
+ ASSERT(worker_thread()->IsCurrent());
+ ChannelParams* params = new ChannelParams(channel->component());
+ signaling_thread()->Post(this, MSG_REQUESTSIGNALING, params);
+}
+
+void Transport::OnChannelRequestSignaling_s(int component) {
+ ASSERT(signaling_thread()->IsCurrent());
+ LOG(LS_INFO) << "Transport: " << content_name_ << ", allocating candidates";
+ // Resetting ICE state for the channel.
+ {
+ rtc::CritScope cs(&crit_);
+ ChannelMap::iterator iter = channels_.find(component);
+ if (iter != channels_.end())
+ iter->second.set_candidates_allocated(false);
+ }
+ SignalRequestSignaling(this);
+}
+
+void Transport::OnChannelCandidateReady(TransportChannelImpl* channel,
+ const Candidate& candidate) {
+ ASSERT(worker_thread()->IsCurrent());
+ rtc::CritScope cs(&crit_);
+ ready_candidates_.push_back(candidate);
+
+ // We hold any messages until the client lets us connect.
+ if (connect_requested_) {
+ signaling_thread()->Post(
+ this, MSG_CANDIDATEREADY, NULL);
+ }
+}
+
+void Transport::OnChannelCandidateReady_s() {
+ ASSERT(signaling_thread()->IsCurrent());
+ ASSERT(connect_requested_);
+
+ std::vector<Candidate> candidates;
+ {
+ rtc::CritScope cs(&crit_);
+ candidates.swap(ready_candidates_);
+ }
+
+ // we do the deleting of Candidate* here to keep the new above and
+ // delete below close to each other
+ if (!candidates.empty()) {
+ SignalCandidatesReady(this, candidates);
+ }
+}
+
+void Transport::OnChannelRouteChange(TransportChannel* channel,
+ const Candidate& remote_candidate) {
+ ASSERT(worker_thread()->IsCurrent());
+ ChannelParams* params = new ChannelParams(new Candidate(remote_candidate));
+ params->channel = static_cast<cricket::TransportChannelImpl*>(channel);
+ signaling_thread()->Post(this, MSG_ROUTECHANGE, params);
+}
+
+void Transport::OnChannelRouteChange_s(const TransportChannel* channel,
+ const Candidate& remote_candidate) {
+ ASSERT(signaling_thread()->IsCurrent());
+ SignalRouteChange(this, remote_candidate.component(), remote_candidate);
+}
+
+void Transport::OnChannelCandidatesAllocationDone(
+ TransportChannelImpl* channel) {
+ ASSERT(worker_thread()->IsCurrent());
+ rtc::CritScope cs(&crit_);
+ ChannelMap::iterator iter = channels_.find(channel->component());
+ ASSERT(iter != channels_.end());
+ LOG(LS_INFO) << "Transport: " << content_name_ << ", component "
+ << channel->component() << " allocation complete";
+ iter->second.set_candidates_allocated(true);
+
+ // If all channels belonging to this Transport got signal, then
+ // forward this signal to upper layer.
+ // Can this signal arrive before all transport channels are created?
+ for (iter = channels_.begin(); iter != channels_.end(); ++iter) {
+ if (!iter->second.candidates_allocated())
+ return;
+ }
+ signaling_thread_->Post(this, MSG_CANDIDATEALLOCATIONCOMPLETE);
+
+ MaybeCompleted_w();
+}
+
+void Transport::OnChannelCandidatesAllocationDone_s() {
+ ASSERT(signaling_thread()->IsCurrent());
+ LOG(LS_INFO) << "Transport: " << content_name_ << " allocation complete";
+ SignalCandidatesAllocationDone(this);
+}
+
+void Transport::OnRoleConflict(TransportChannelImpl* channel) {
+ signaling_thread_->Post(this, MSG_ROLECONFLICT);
+}
+
+void Transport::OnChannelConnectionRemoved(TransportChannelImpl* channel) {
+ ASSERT(worker_thread()->IsCurrent());
+ MaybeCompleted_w();
+
+ // Check if the state is now Failed.
+ // Failed is only available in the Controlling ICE role.
+ if (channel->GetIceRole() != ICEROLE_CONTROLLING) {
+ return;
+ }
+
+ ChannelMap::iterator iter = channels_.find(channel->component());
+ ASSERT(iter != channels_.end());
+ // Failed can only occur after candidate allocation has stopped.
+ if (!iter->second.candidates_allocated()) {
+ return;
+ }
+
+ size_t connections = channel->GetConnectionCount();
+ if (connections == 0) {
+ // A Transport has failed if any of its channels have no remaining
+ // connections.
+ signaling_thread_->Post(this, MSG_FAILED);
+ }
+}
+
+void Transport::MaybeCompleted_w() {
+ ASSERT(worker_thread()->IsCurrent());
+
+ // A Transport's ICE process is completed if all of its channels are writable,
+ // have finished allocating candidates, and have pruned all but one of their
+ // connections.
+ ChannelMap::const_iterator iter;
+ for (iter = channels_.begin(); iter != channels_.end(); ++iter) {
+ const TransportChannelImpl* channel = iter->second.get();
+ if (!(channel->writable() &&
+ channel->GetConnectionCount() == 1 &&
+ channel->GetIceRole() == ICEROLE_CONTROLLING &&
+ iter->second.candidates_allocated())) {
+ return;
+ }
+ }
+
+ signaling_thread_->Post(this, MSG_COMPLETED);
+}
+
+void Transport::SetIceRole_w(IceRole role) {
+ rtc::CritScope cs(&crit_);
+ ice_role_ = role;
+ for (ChannelMap::iterator iter = channels_.begin();
+ iter != channels_.end(); ++iter) {
+ iter->second->SetIceRole(ice_role_);
+ }
+}
+
+void Transport::SetRemoteIceMode_w(IceMode mode) {
+ rtc::CritScope cs(&crit_);
+ remote_ice_mode_ = mode;
+ // Shouldn't channels be created after this method executed?
+ for (ChannelMap::iterator iter = channels_.begin();
+ iter != channels_.end(); ++iter) {
+ iter->second->SetRemoteIceMode(remote_ice_mode_);
+ }
+}
+
+bool Transport::SetLocalTransportDescription_w(
+ const TransportDescription& desc,
+ ContentAction action,
+ std::string* error_desc) {
+ bool ret = true;
+ rtc::CritScope cs(&crit_);
+
+ if (!VerifyIceParams(desc)) {
+ return BadTransportDescription("Invalid ice-ufrag or ice-pwd length",
+ error_desc);
+ }
+
+ if (local_description_ && IceCredentialsChanged(*local_description_, desc)) {
+ IceRole new_ice_role = (action == CA_OFFER) ? ICEROLE_CONTROLLING
+ : ICEROLE_CONTROLLED;
+
+ // It must be called before ApplyLocalTransportDescription_w, which may
+ // trigger an ICE restart and depends on the new ICE role.
+ SetIceRole_w(new_ice_role);
+ }
+
+ local_description_.reset(new TransportDescription(desc));
+
+ for (ChannelMap::iterator iter = channels_.begin();
+ iter != channels_.end(); ++iter) {
+ ret &= ApplyLocalTransportDescription_w(iter->second.get(), error_desc);
+ }
+ if (!ret)
+ return false;
+
+ // If PRANSWER/ANSWER is set, we should decide transport protocol type.
+ if (action == CA_PRANSWER || action == CA_ANSWER) {
+ ret &= NegotiateTransportDescription_w(action, error_desc);
+ }
+ return ret;
+}
+
+bool Transport::SetRemoteTransportDescription_w(
+ const TransportDescription& desc,
+ ContentAction action,
+ std::string* error_desc) {
+ bool ret = true;
+ rtc::CritScope cs(&crit_);
+
+ if (!VerifyIceParams(desc)) {
+ return BadTransportDescription("Invalid ice-ufrag or ice-pwd length",
+ error_desc);
+ }
+
+ remote_description_.reset(new TransportDescription(desc));
+ for (ChannelMap::iterator iter = channels_.begin();
+ iter != channels_.end(); ++iter) {
+ ret &= ApplyRemoteTransportDescription_w(iter->second.get(), error_desc);
+ }
+
+ // If PRANSWER/ANSWER is set, we should decide transport protocol type.
+ if (action == CA_PRANSWER || action == CA_ANSWER) {
+ ret = NegotiateTransportDescription_w(CA_OFFER, error_desc);
+ }
+ return ret;
+}
+
+bool Transport::ApplyLocalTransportDescription_w(TransportChannelImpl* ch,
+ std::string* error_desc) {
+ // If existing protocol_type is HYBRID, we may have not chosen the final
+ // protocol type, so update the channel protocol type from the
+ // local description. Otherwise, skip updating the protocol type.
+ // We check for HYBRID to avoid accidental changes; in the case of a
+ // session renegotiation, the new offer will have the google-ice ICE option,
+ // so we need to make sure we don't switch back from ICE mode to HYBRID
+ // when this happens.
+ // There are some other ways we could have solved this, but this is the
+ // simplest. The ultimate solution will be to get rid of GICE altogether.
+ IceProtocolType protocol_type;
+ if (ch->GetIceProtocolType(&protocol_type) &&
+ protocol_type == ICEPROTO_HYBRID) {
+ ch->SetIceProtocolType(
+ TransportProtocolFromDescription(local_description()));
+ }
+ ch->SetIceCredentials(local_description_->ice_ufrag,
+ local_description_->ice_pwd);
+ return true;
+}
+
+bool Transport::ApplyRemoteTransportDescription_w(TransportChannelImpl* ch,
+ std::string* error_desc) {
+ ch->SetRemoteIceCredentials(remote_description_->ice_ufrag,
+ remote_description_->ice_pwd);
+ return true;
+}
+
+bool Transport::ApplyNegotiatedTransportDescription_w(
+ TransportChannelImpl* channel, std::string* error_desc) {
+ channel->SetIceProtocolType(protocol_);
+ channel->SetRemoteIceMode(remote_ice_mode_);
+ return true;
+}
+
+bool Transport::NegotiateTransportDescription_w(ContentAction local_role,
+ std::string* error_desc) {
+ // TODO(ekr@rtfm.com): This is ICE-specific stuff. Refactor into
+ // P2PTransport.
+ const TransportDescription* offer;
+ const TransportDescription* answer;
+
+ if (local_role == CA_OFFER) {
+ offer = local_description_.get();
+ answer = remote_description_.get();
+ } else {
+ offer = remote_description_.get();
+ answer = local_description_.get();
+ }
+
+ TransportProtocol offer_proto = TransportProtocolFromDescription(offer);
+ TransportProtocol answer_proto = TransportProtocolFromDescription(answer);
+
+ // If offered protocol is gice/ice, then we expect to receive matching
+ // protocol in answer, anything else is treated as an error.
+ // HYBRID is not an option when offered specific protocol.
+ // If offered protocol is HYBRID and answered protocol is HYBRID then
+ // gice is preferred protocol.
+ // TODO(mallinath) - Answer from local or remote should't have both ice
+ // and gice support. It should always pick which protocol it wants to use.
+ // Once WebRTC stops supporting gice (for backward compatibility), HYBRID in
+ // answer must be treated as error.
+ if ((offer_proto == ICEPROTO_GOOGLE || offer_proto == ICEPROTO_RFC5245) &&
+ (offer_proto != answer_proto)) {
+ std::ostringstream desc;
+ desc << "Offer and answer protocol mismatch: "
+ << IceProtoToString(offer_proto)
+ << " vs "
+ << IceProtoToString(answer_proto);
+ return BadTransportDescription(desc.str(), error_desc);
+ }
+ protocol_ = answer_proto == ICEPROTO_HYBRID ? ICEPROTO_GOOGLE : answer_proto;
+
+ // If transport is in ICEROLE_CONTROLLED and remote end point supports only
+ // ice_lite, this local end point should take CONTROLLING role.
+ if (ice_role_ == ICEROLE_CONTROLLED &&
+ remote_description_->ice_mode == ICEMODE_LITE) {
+ SetIceRole_w(ICEROLE_CONTROLLING);
+ }
+
+ // Update remote ice_mode to all existing channels.
+ remote_ice_mode_ = remote_description_->ice_mode;
+
+ // Now that we have negotiated everything, push it downward.
+ // Note that we cache the result so that if we have race conditions
+ // between future SetRemote/SetLocal invocations and new channel
+ // creation, we have the negotiation state saved until a new
+ // negotiation happens.
+ for (ChannelMap::iterator iter = channels_.begin();
+ iter != channels_.end();
+ ++iter) {
+ if (!ApplyNegotiatedTransportDescription_w(iter->second.get(), error_desc))
+ return false;
+ }
+ return true;
+}
+
+void Transport::OnMessage(rtc::Message* msg) {
+ switch (msg->message_id) {
+ case MSG_ONSIGNALINGREADY:
+ CallChannels_w(&TransportChannelImpl::OnSignalingReady);
+ break;
+ case MSG_ONREMOTECANDIDATE: {
+ ChannelParams* params = static_cast<ChannelParams*>(msg->pdata);
+ OnRemoteCandidate_w(*params->candidate);
+ delete params;
+ }
+ break;
+ case MSG_CONNECTING:
+ OnConnecting_s();
+ break;
+ case MSG_READSTATE:
+ OnChannelReadableState_s();
+ break;
+ case MSG_WRITESTATE:
+ OnChannelWritableState_s();
+ break;
+ case MSG_REQUESTSIGNALING: {
+ ChannelParams* params = static_cast<ChannelParams*>(msg->pdata);
+ OnChannelRequestSignaling_s(params->component);
+ delete params;
+ }
+ break;
+ case MSG_CANDIDATEREADY:
+ OnChannelCandidateReady_s();
+ break;
+ case MSG_ROUTECHANGE: {
+ ChannelParams* params = static_cast<ChannelParams*>(msg->pdata);
+ OnChannelRouteChange_s(params->channel, *params->candidate);
+ delete params;
+ }
+ break;
+ case MSG_CANDIDATEALLOCATIONCOMPLETE:
+ OnChannelCandidatesAllocationDone_s();
+ break;
+ case MSG_ROLECONFLICT:
+ SignalRoleConflict();
+ break;
+ case MSG_COMPLETED:
+ SignalCompleted(this);
+ break;
+ case MSG_FAILED:
+ SignalFailed(this);
+ break;
+ }
+}
+
+bool TransportParser::ParseAddress(const buzz::XmlElement* elem,
+ const buzz::QName& address_name,
+ const buzz::QName& port_name,
+ rtc::SocketAddress* address,
+ ParseError* error) {
+ if (!elem->HasAttr(address_name))
+ return BadParse("address does not have " + address_name.LocalPart(), error);
+ if (!elem->HasAttr(port_name))
+ return BadParse("address does not have " + port_name.LocalPart(), error);
+
+ address->SetIP(elem->Attr(address_name));
+ std::istringstream ist(elem->Attr(port_name));
+ int port = 0;
+ ist >> port;
+ address->SetPort(port);
+
+ return true;
+}
+
+// We're GICE if the namespace is NS_GOOGLE_P2P, or if NS_JINGLE_ICE_UDP is
+// used and the GICE ice-option is set.
+TransportProtocol TransportProtocolFromDescription(
+ const TransportDescription* desc) {
+ ASSERT(desc != NULL);
+ if (desc->transport_type == NS_JINGLE_ICE_UDP) {
+ return (desc->HasOption(ICE_OPTION_GICE)) ?
+ ICEPROTO_HYBRID : ICEPROTO_RFC5245;
+ }
+ return ICEPROTO_GOOGLE;
+}
+
+} // namespace cricket
diff --git a/p2p/base/transport.h b/p2p/base/transport.h
new file mode 100644
index 00000000..ab772fe5
--- /dev/null
+++ b/p2p/base/transport.h
@@ -0,0 +1,513 @@
+/*
+ * 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.
+ */
+
+// A Transport manages a set of named channels of the same type.
+//
+// Subclasses choose the appropriate class to instantiate for each channel;
+// however, this base class keeps track of the channels by name, watches their
+// state changes (in order to update the manager's state), and forwards
+// requests to begin connecting or to reset to each of the channels.
+//
+// On Threading: Transport performs work on both the signaling and worker
+// threads. For subclasses, the rule is that all signaling related calls will
+// be made on the signaling thread and all channel related calls (including
+// signaling for a channel) will be made on the worker thread. When
+// information needs to be sent between the two threads, this class should do
+// the work (e.g., OnRemoteCandidate).
+//
+// Note: Subclasses must call DestroyChannels() in their own constructors.
+// It is not possible to do so here because the subclass constructor will
+// already have run.
+
+#ifndef WEBRTC_P2P_BASE_TRANSPORT_H_
+#define WEBRTC_P2P_BASE_TRANSPORT_H_
+
+#include <map>
+#include <string>
+#include <vector>
+#include "webrtc/p2p/base/candidate.h"
+#include "webrtc/p2p/base/constants.h"
+#include "webrtc/p2p/base/sessiondescription.h"
+#include "webrtc/p2p/base/transportinfo.h"
+#include "webrtc/base/criticalsection.h"
+#include "webrtc/base/messagequeue.h"
+#include "webrtc/base/sigslot.h"
+#include "webrtc/base/sslstreamadapter.h"
+
+namespace rtc {
+class Thread;
+}
+
+namespace buzz {
+class QName;
+class XmlElement;
+}
+
+namespace cricket {
+
+struct ParseError;
+struct WriteError;
+class CandidateTranslator;
+class PortAllocator;
+class SessionManager;
+class Session;
+class TransportChannel;
+class TransportChannelImpl;
+
+typedef std::vector<buzz::XmlElement*> XmlElements;
+typedef std::vector<Candidate> Candidates;
+
+// Used to parse and serialize (write) transport candidates. For
+// convenience of old code, Transports will implement TransportParser.
+// Parse/Write seems better than Serialize/Deserialize or
+// Create/Translate.
+class TransportParser {
+ public:
+ // The incoming Translator value may be null, in which case
+ // ParseCandidates should return false if there are candidates to
+ // parse (indicating a failure to parse). If the Translator is null
+ // and there are no candidates to parse, then return true,
+ // indicating a successful parse of 0 candidates.
+
+ // Parse or write a transport description, including ICE credentials and
+ // any DTLS fingerprint. Since only Jingle has transport descriptions, these
+ // functions are only used when serializing to Jingle.
+ virtual bool ParseTransportDescription(const buzz::XmlElement* elem,
+ const CandidateTranslator* translator,
+ TransportDescription* tdesc,
+ ParseError* error) = 0;
+ virtual bool WriteTransportDescription(const TransportDescription& tdesc,
+ const CandidateTranslator* translator,
+ buzz::XmlElement** tdesc_elem,
+ WriteError* error) = 0;
+
+
+ // Parse a single candidate. This must be used when parsing Gingle
+ // candidates, since there is no enclosing transport description.
+ virtual bool ParseGingleCandidate(const buzz::XmlElement* elem,
+ const CandidateTranslator* translator,
+ Candidate* candidates,
+ ParseError* error) = 0;
+ virtual bool WriteGingleCandidate(const Candidate& candidate,
+ const CandidateTranslator* translator,
+ buzz::XmlElement** candidate_elem,
+ WriteError* error) = 0;
+
+ // Helper function to parse an element describing an address. This
+ // retrieves the IP and port from the given element and verifies
+ // that they look like plausible values.
+ bool ParseAddress(const buzz::XmlElement* elem,
+ const buzz::QName& address_name,
+ const buzz::QName& port_name,
+ rtc::SocketAddress* address,
+ ParseError* error);
+
+ virtual ~TransportParser() {}
+};
+
+// For "writable" and "readable", we need to differentiate between
+// none, all, and some.
+enum TransportState {
+ TRANSPORT_STATE_NONE = 0,
+ TRANSPORT_STATE_SOME,
+ TRANSPORT_STATE_ALL
+};
+
+// Stats that we can return about the connections for a transport channel.
+// TODO(hta): Rename to ConnectionStats
+struct ConnectionInfo {
+ ConnectionInfo()
+ : best_connection(false),
+ writable(false),
+ readable(false),
+ timeout(false),
+ new_connection(false),
+ rtt(0),
+ sent_total_bytes(0),
+ sent_bytes_second(0),
+ recv_total_bytes(0),
+ recv_bytes_second(0),
+ key(NULL) {}
+
+ bool best_connection; // Is this the best connection we have?
+ bool writable; // Has this connection received a STUN response?
+ bool readable; // Has this connection received a STUN request?
+ bool timeout; // Has this connection timed out?
+ bool new_connection; // Is this a newly created connection?
+ size_t rtt; // The STUN RTT for this connection.
+ size_t sent_total_bytes; // Total bytes sent on this connection.
+ size_t sent_bytes_second; // Bps over the last measurement interval.
+ size_t recv_total_bytes; // Total bytes received on this connection.
+ size_t recv_bytes_second; // Bps over the last measurement interval.
+ Candidate local_candidate; // The local candidate for this connection.
+ Candidate remote_candidate; // The remote candidate for this connection.
+ void* key; // A static value that identifies this conn.
+};
+
+// Information about all the connections of a channel.
+typedef std::vector<ConnectionInfo> ConnectionInfos;
+
+// Information about a specific channel
+struct TransportChannelStats {
+ int component;
+ ConnectionInfos connection_infos;
+};
+
+// Information about all the channels of a transport.
+// TODO(hta): Consider if a simple vector is as good as a map.
+typedef std::vector<TransportChannelStats> TransportChannelStatsList;
+
+// Information about the stats of a transport.
+struct TransportStats {
+ std::string content_name;
+ TransportChannelStatsList channel_stats;
+};
+
+bool BadTransportDescription(const std::string& desc, std::string* err_desc);
+
+bool IceCredentialsChanged(const std::string& old_ufrag,
+ const std::string& old_pwd,
+ const std::string& new_ufrag,
+ const std::string& new_pwd);
+
+class Transport : public rtc::MessageHandler,
+ public sigslot::has_slots<> {
+ public:
+ Transport(rtc::Thread* signaling_thread,
+ rtc::Thread* worker_thread,
+ const std::string& content_name,
+ const std::string& type,
+ PortAllocator* allocator);
+ virtual ~Transport();
+
+ // Returns the signaling thread. The app talks to Transport on this thread.
+ rtc::Thread* signaling_thread() { return signaling_thread_; }
+ // Returns the worker thread. The actual networking is done on this thread.
+ rtc::Thread* worker_thread() { return worker_thread_; }
+
+ // Returns the content_name of this transport.
+ const std::string& content_name() const { return content_name_; }
+ // Returns the type of this transport.
+ const std::string& type() const { return type_; }
+
+ // Returns the port allocator object for this transport.
+ PortAllocator* port_allocator() { return allocator_; }
+
+ // Returns the readable and states of this manager. These bits are the ORs
+ // of the corresponding bits on the managed channels. Each time one of these
+ // states changes, a signal is raised.
+ // TODO: Replace uses of readable() and writable() with
+ // any_channels_readable() and any_channels_writable().
+ bool readable() const { return any_channels_readable(); }
+ bool writable() const { return any_channels_writable(); }
+ bool was_writable() const { return was_writable_; }
+ bool any_channels_readable() const {
+ return (readable_ == TRANSPORT_STATE_SOME ||
+ readable_ == TRANSPORT_STATE_ALL);
+ }
+ bool any_channels_writable() const {
+ return (writable_ == TRANSPORT_STATE_SOME ||
+ writable_ == TRANSPORT_STATE_ALL);
+ }
+ bool all_channels_readable() const {
+ return (readable_ == TRANSPORT_STATE_ALL);
+ }
+ bool all_channels_writable() const {
+ return (writable_ == TRANSPORT_STATE_ALL);
+ }
+ sigslot::signal1<Transport*> SignalReadableState;
+ sigslot::signal1<Transport*> SignalWritableState;
+ sigslot::signal1<Transport*> SignalCompleted;
+ sigslot::signal1<Transport*> SignalFailed;
+
+ // Returns whether the client has requested the channels to connect.
+ bool connect_requested() const { return connect_requested_; }
+
+ void SetIceRole(IceRole role);
+ IceRole ice_role() const { return ice_role_; }
+
+ void SetIceTiebreaker(uint64 IceTiebreaker) { tiebreaker_ = IceTiebreaker; }
+ uint64 IceTiebreaker() { return tiebreaker_; }
+
+ // Must be called before applying local session description.
+ void SetIdentity(rtc::SSLIdentity* identity);
+
+ // Get a copy of the local identity provided by SetIdentity.
+ bool GetIdentity(rtc::SSLIdentity** identity);
+
+ // Get a copy of the remote certificate in use by the specified channel.
+ bool GetRemoteCertificate(rtc::SSLCertificate** cert);
+
+ TransportProtocol protocol() const { return protocol_; }
+
+ // Create, destroy, and lookup the channels of this type by their components.
+ TransportChannelImpl* CreateChannel(int component);
+ // Note: GetChannel may lead to race conditions, since the mutex is not held
+ // after the pointer is returned.
+ TransportChannelImpl* GetChannel(int component);
+ // Note: HasChannel does not lead to race conditions, unlike GetChannel.
+ bool HasChannel(int component) {
+ return (NULL != GetChannel(component));
+ }
+ bool HasChannels();
+ void DestroyChannel(int component);
+
+ // Set the local TransportDescription to be used by TransportChannels.
+ // This should be called before ConnectChannels().
+ bool SetLocalTransportDescription(const TransportDescription& description,
+ ContentAction action,
+ std::string* error_desc);
+
+ // Set the remote TransportDescription to be used by TransportChannels.
+ bool SetRemoteTransportDescription(const TransportDescription& description,
+ ContentAction action,
+ std::string* error_desc);
+
+ // Tells all current and future channels to start connecting. When the first
+ // channel begins connecting, the following signal is raised.
+ void ConnectChannels();
+ sigslot::signal1<Transport*> SignalConnecting;
+
+ // Resets all of the channels back to their initial state. They are no
+ // longer connecting.
+ void ResetChannels();
+
+ // Destroys every channel created so far.
+ void DestroyAllChannels();
+
+ bool GetStats(TransportStats* stats);
+
+ // Before any stanza is sent, the manager will request signaling. Once
+ // signaling is available, the client should call OnSignalingReady. Once
+ // this occurs, the transport (or its channels) can send any waiting stanzas.
+ // OnSignalingReady invokes OnTransportSignalingReady and then forwards this
+ // signal to each channel.
+ sigslot::signal1<Transport*> SignalRequestSignaling;
+ void OnSignalingReady();
+
+ // Handles sending of ready candidates and receiving of remote candidates.
+ sigslot::signal2<Transport*,
+ const std::vector<Candidate>&> SignalCandidatesReady;
+
+ sigslot::signal1<Transport*> SignalCandidatesAllocationDone;
+ void OnRemoteCandidates(const std::vector<Candidate>& candidates);
+
+ // If candidate is not acceptable, returns false and sets error.
+ // Call this before calling OnRemoteCandidates.
+ virtual bool VerifyCandidate(const Candidate& candidate,
+ std::string* error);
+
+ // Signals when the best connection for a channel changes.
+ sigslot::signal3<Transport*,
+ int, // component
+ const Candidate&> SignalRouteChange;
+
+ // A transport message has generated an transport-specific error. The
+ // stanza that caused the error is available in session_msg. If false is
+ // returned, the error is considered unrecoverable, and the session is
+ // terminated.
+ // TODO(juberti): Remove these obsolete functions once Session no longer
+ // references them.
+ virtual void OnTransportError(const buzz::XmlElement* error) {}
+ sigslot::signal6<Transport*, const buzz::XmlElement*, const buzz::QName&,
+ const std::string&, const std::string&,
+ const buzz::XmlElement*>
+ SignalTransportError;
+
+ // Forwards the signal from TransportChannel to BaseSession.
+ sigslot::signal0<> SignalRoleConflict;
+
+ virtual bool GetSslRole(rtc::SSLRole* ssl_role) const;
+
+ protected:
+ // These are called by Create/DestroyChannel above in order to create or
+ // destroy the appropriate type of channel.
+ virtual TransportChannelImpl* CreateTransportChannel(int component) = 0;
+ virtual void DestroyTransportChannel(TransportChannelImpl* channel) = 0;
+
+ // Informs the subclass that we received the signaling ready message.
+ virtual void OnTransportSignalingReady() {}
+
+ // The current local transport description, for use by derived classes
+ // when performing transport description negotiation.
+ const TransportDescription* local_description() const {
+ return local_description_.get();
+ }
+
+ // The current remote transport description, for use by derived classes
+ // when performing transport description negotiation.
+ const TransportDescription* remote_description() const {
+ return remote_description_.get();
+ }
+
+ virtual void SetIdentity_w(rtc::SSLIdentity* identity) {}
+
+ virtual bool GetIdentity_w(rtc::SSLIdentity** identity) {
+ return false;
+ }
+
+ // Pushes down the transport parameters from the local description, such
+ // as the ICE ufrag and pwd.
+ // Derived classes can override, but must call the base as well.
+ virtual bool ApplyLocalTransportDescription_w(TransportChannelImpl* channel,
+ std::string* error_desc);
+
+ // Pushes down remote ice credentials from the remote description to the
+ // transport channel.
+ virtual bool ApplyRemoteTransportDescription_w(TransportChannelImpl* ch,
+ std::string* error_desc);
+
+ // Negotiates the transport parameters based on the current local and remote
+ // transport description, such at the version of ICE to use, and whether DTLS
+ // should be activated.
+ // Derived classes can negotiate their specific parameters here, but must call
+ // the base as well.
+ virtual bool NegotiateTransportDescription_w(ContentAction local_role,
+ std::string* error_desc);
+
+ // Pushes down the transport parameters obtained via negotiation.
+ // Derived classes can set their specific parameters here, but must call the
+ // base as well.
+ virtual bool ApplyNegotiatedTransportDescription_w(
+ TransportChannelImpl* channel, std::string* error_desc);
+
+ virtual bool GetSslRole_w(rtc::SSLRole* ssl_role) const {
+ return false;
+ }
+
+ private:
+ struct ChannelMapEntry {
+ ChannelMapEntry() : impl_(NULL), candidates_allocated_(false), ref_(0) {}
+ explicit ChannelMapEntry(TransportChannelImpl *impl)
+ : impl_(impl),
+ candidates_allocated_(false),
+ ref_(0) {
+ }
+
+ void AddRef() { ++ref_; }
+ void DecRef() {
+ ASSERT(ref_ > 0);
+ --ref_;
+ }
+ int ref() const { return ref_; }
+
+ TransportChannelImpl* get() const { return impl_; }
+ TransportChannelImpl* operator->() const { return impl_; }
+ void set_candidates_allocated(bool status) {
+ candidates_allocated_ = status;
+ }
+ bool candidates_allocated() const { return candidates_allocated_; }
+
+ private:
+ TransportChannelImpl *impl_;
+ bool candidates_allocated_;
+ int ref_;
+ };
+
+ // Candidate component => ChannelMapEntry
+ typedef std::map<int, ChannelMapEntry> ChannelMap;
+
+ // Called when the state of a channel changes.
+ void OnChannelReadableState(TransportChannel* channel);
+ void OnChannelWritableState(TransportChannel* channel);
+
+ // Called when a channel requests signaling.
+ void OnChannelRequestSignaling(TransportChannelImpl* channel);
+
+ // Called when a candidate is ready from remote peer.
+ void OnRemoteCandidate(const Candidate& candidate);
+ // Called when a candidate is ready from channel.
+ void OnChannelCandidateReady(TransportChannelImpl* channel,
+ const Candidate& candidate);
+ void OnChannelRouteChange(TransportChannel* channel,
+ const Candidate& remote_candidate);
+ void OnChannelCandidatesAllocationDone(TransportChannelImpl* channel);
+ // Called when there is ICE role change.
+ void OnRoleConflict(TransportChannelImpl* channel);
+ // Called when the channel removes a connection.
+ void OnChannelConnectionRemoved(TransportChannelImpl* channel);
+
+ // Dispatches messages to the appropriate handler (below).
+ void OnMessage(rtc::Message* msg);
+
+ // These are versions of the above methods that are called only on a
+ // particular thread (s = signaling, w = worker). The above methods post or
+ // send a message to invoke this version.
+ TransportChannelImpl* CreateChannel_w(int component);
+ void DestroyChannel_w(int component);
+ void ConnectChannels_w();
+ void ResetChannels_w();
+ void DestroyAllChannels_w();
+ void OnRemoteCandidate_w(const Candidate& candidate);
+ void OnChannelReadableState_s();
+ void OnChannelWritableState_s();
+ void OnChannelRequestSignaling_s(int component);
+ void OnConnecting_s();
+ void OnChannelRouteChange_s(const TransportChannel* channel,
+ const Candidate& remote_candidate);
+ void OnChannelCandidatesAllocationDone_s();
+
+ // Helper function that invokes the given function on every channel.
+ typedef void (TransportChannelImpl::* TransportChannelFunc)();
+ void CallChannels_w(TransportChannelFunc func);
+
+ // Computes the OR of the channel's read or write state (argument picks).
+ TransportState GetTransportState_s(bool read);
+
+ void OnChannelCandidateReady_s();
+
+ void SetIceRole_w(IceRole role);
+ void SetRemoteIceMode_w(IceMode mode);
+ bool SetLocalTransportDescription_w(const TransportDescription& desc,
+ ContentAction action,
+ std::string* error_desc);
+ bool SetRemoteTransportDescription_w(const TransportDescription& desc,
+ ContentAction action,
+ std::string* error_desc);
+ bool GetStats_w(TransportStats* infos);
+ bool GetRemoteCertificate_w(rtc::SSLCertificate** cert);
+
+ // Sends SignalCompleted if we are now in that state.
+ void MaybeCompleted_w();
+
+ rtc::Thread* signaling_thread_;
+ rtc::Thread* worker_thread_;
+ std::string content_name_;
+ std::string type_;
+ PortAllocator* allocator_;
+ bool destroyed_;
+ TransportState readable_;
+ TransportState writable_;
+ bool was_writable_;
+ bool connect_requested_;
+ IceRole ice_role_;
+ uint64 tiebreaker_;
+ TransportProtocol protocol_;
+ IceMode remote_ice_mode_;
+ rtc::scoped_ptr<TransportDescription> local_description_;
+ rtc::scoped_ptr<TransportDescription> remote_description_;
+
+ ChannelMap channels_;
+ // Buffers the ready_candidates so that SignalCanidatesReady can
+ // provide them in multiples.
+ std::vector<Candidate> ready_candidates_;
+ // Protects changes to channels and messages
+ rtc::CriticalSection crit_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(Transport);
+};
+
+// Extract a TransportProtocol from a TransportDescription.
+TransportProtocol TransportProtocolFromDescription(
+ const TransportDescription* desc);
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_TRANSPORT_H_
diff --git a/p2p/base/transport_unittest.cc b/p2p/base/transport_unittest.cc
new file mode 100644
index 00000000..abcf32ce
--- /dev/null
+++ b/p2p/base/transport_unittest.cc
@@ -0,0 +1,438 @@
+/*
+ * 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.
+ */
+
+#include "webrtc/p2p/base/constants.h"
+#include "webrtc/p2p/base/fakesession.h"
+#include "webrtc/p2p/base/p2ptransport.h"
+#include "webrtc/p2p/base/parsing.h"
+#include "webrtc/p2p/base/rawtransport.h"
+#include "webrtc/p2p/base/sessionmessages.h"
+#include "webrtc/libjingle/xmllite/xmlelement.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/base/fakesslidentity.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/thread.h"
+
+using cricket::Candidate;
+using cricket::Candidates;
+using cricket::Transport;
+using cricket::FakeTransport;
+using cricket::TransportChannel;
+using cricket::FakeTransportChannel;
+using cricket::IceRole;
+using cricket::TransportDescription;
+using cricket::WriteError;
+using cricket::ParseError;
+using rtc::SocketAddress;
+
+static const char kIceUfrag1[] = "TESTICEUFRAG0001";
+static const char kIcePwd1[] = "TESTICEPWD00000000000001";
+
+static const char kIceUfrag2[] = "TESTICEUFRAG0002";
+static const char kIcePwd2[] = "TESTICEPWD00000000000002";
+
+class TransportTest : public testing::Test,
+ public sigslot::has_slots<> {
+ public:
+ TransportTest()
+ : thread_(rtc::Thread::Current()),
+ transport_(new FakeTransport(
+ thread_, thread_, "test content name", NULL)),
+ channel_(NULL),
+ connecting_signalled_(false),
+ completed_(false),
+ failed_(false) {
+ transport_->SignalConnecting.connect(this, &TransportTest::OnConnecting);
+ transport_->SignalCompleted.connect(this, &TransportTest::OnCompleted);
+ transport_->SignalFailed.connect(this, &TransportTest::OnFailed);
+ }
+ ~TransportTest() {
+ transport_->DestroyAllChannels();
+ }
+ bool SetupChannel() {
+ channel_ = CreateChannel(1);
+ return (channel_ != NULL);
+ }
+ FakeTransportChannel* CreateChannel(int component) {
+ return static_cast<FakeTransportChannel*>(
+ transport_->CreateChannel(component));
+ }
+ void DestroyChannel() {
+ transport_->DestroyChannel(1);
+ channel_ = NULL;
+ }
+
+ protected:
+ void OnConnecting(Transport* transport) {
+ connecting_signalled_ = true;
+ }
+ void OnCompleted(Transport* transport) {
+ completed_ = true;
+ }
+ void OnFailed(Transport* transport) {
+ failed_ = true;
+ }
+
+ rtc::Thread* thread_;
+ rtc::scoped_ptr<FakeTransport> transport_;
+ FakeTransportChannel* channel_;
+ bool connecting_signalled_;
+ bool completed_;
+ bool failed_;
+};
+
+class FakeCandidateTranslator : public cricket::CandidateTranslator {
+ public:
+ void AddMapping(int component, const std::string& channel_name) {
+ name_to_component[channel_name] = component;
+ component_to_name[component] = channel_name;
+ }
+
+ bool GetChannelNameFromComponent(
+ int component, std::string* channel_name) const {
+ if (component_to_name.find(component) == component_to_name.end()) {
+ return false;
+ }
+ *channel_name = component_to_name.find(component)->second;
+ return true;
+ }
+ bool GetComponentFromChannelName(
+ const std::string& channel_name, int* component) const {
+ if (name_to_component.find(channel_name) == name_to_component.end()) {
+ return false;
+ }
+ *component = name_to_component.find(channel_name)->second;
+ return true;
+ }
+
+ std::map<std::string, int> name_to_component;
+ std::map<int, std::string> component_to_name;
+};
+
+// Test that calling ConnectChannels triggers an OnConnecting signal.
+TEST_F(TransportTest, TestConnectChannelsDoesSignal) {
+ EXPECT_TRUE(SetupChannel());
+ transport_->ConnectChannels();
+ EXPECT_FALSE(connecting_signalled_);
+
+ EXPECT_TRUE_WAIT(connecting_signalled_, 100);
+}
+
+// Test that DestroyAllChannels kills any pending OnConnecting signals.
+TEST_F(TransportTest, TestDestroyAllClearsPosts) {
+ EXPECT_TRUE(transport_->CreateChannel(1) != NULL);
+
+ transport_->ConnectChannels();
+ transport_->DestroyAllChannels();
+
+ thread_->ProcessMessages(0);
+ EXPECT_FALSE(connecting_signalled_);
+}
+
+// This test verifies channels are created with proper ICE
+// role, tiebreaker and remote ice mode and credentials after offer and
+// answer negotiations.
+TEST_F(TransportTest, TestChannelIceParameters) {
+ transport_->SetIceRole(cricket::ICEROLE_CONTROLLING);
+ transport_->SetIceTiebreaker(99U);
+ cricket::TransportDescription local_desc(
+ cricket::NS_JINGLE_ICE_UDP, kIceUfrag1, kIcePwd1);
+ ASSERT_TRUE(transport_->SetLocalTransportDescription(local_desc,
+ cricket::CA_OFFER,
+ NULL));
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLING, transport_->ice_role());
+ EXPECT_TRUE(SetupChannel());
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel_->GetIceRole());
+ EXPECT_EQ(cricket::ICEMODE_FULL, channel_->remote_ice_mode());
+ EXPECT_EQ(kIceUfrag1, channel_->ice_ufrag());
+ EXPECT_EQ(kIcePwd1, channel_->ice_pwd());
+
+ cricket::TransportDescription remote_desc(
+ cricket::NS_JINGLE_ICE_UDP, kIceUfrag1, kIcePwd1);
+ ASSERT_TRUE(transport_->SetRemoteTransportDescription(remote_desc,
+ cricket::CA_ANSWER,
+ NULL));
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel_->GetIceRole());
+ EXPECT_EQ(99U, channel_->IceTiebreaker());
+ EXPECT_EQ(cricket::ICEMODE_FULL, channel_->remote_ice_mode());
+ // Changing the transport role from CONTROLLING to CONTROLLED.
+ transport_->SetIceRole(cricket::ICEROLE_CONTROLLED);
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel_->GetIceRole());
+ EXPECT_EQ(cricket::ICEMODE_FULL, channel_->remote_ice_mode());
+ EXPECT_EQ(kIceUfrag1, channel_->remote_ice_ufrag());
+ EXPECT_EQ(kIcePwd1, channel_->remote_ice_pwd());
+}
+
+// Verifies that IceCredentialsChanged returns true when either ufrag or pwd
+// changed, and false in other cases.
+TEST_F(TransportTest, TestIceCredentialsChanged) {
+ EXPECT_TRUE(cricket::IceCredentialsChanged("u1", "p1", "u2", "p2"));
+ EXPECT_TRUE(cricket::IceCredentialsChanged("u1", "p1", "u2", "p1"));
+ EXPECT_TRUE(cricket::IceCredentialsChanged("u1", "p1", "u1", "p2"));
+ EXPECT_FALSE(cricket::IceCredentialsChanged("u1", "p1", "u1", "p1"));
+}
+
+// This test verifies that the callee's ICE role changes from controlled to
+// controlling when the callee triggers an ICE restart.
+TEST_F(TransportTest, TestIceControlledToControllingOnIceRestart) {
+ EXPECT_TRUE(SetupChannel());
+ transport_->SetIceRole(cricket::ICEROLE_CONTROLLED);
+
+ cricket::TransportDescription desc(
+ cricket::NS_JINGLE_ICE_UDP, kIceUfrag1, kIcePwd1);
+ ASSERT_TRUE(transport_->SetRemoteTransportDescription(desc,
+ cricket::CA_OFFER,
+ NULL));
+ ASSERT_TRUE(transport_->SetLocalTransportDescription(desc,
+ cricket::CA_ANSWER,
+ NULL));
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLED, transport_->ice_role());
+
+ cricket::TransportDescription new_local_desc(
+ cricket::NS_JINGLE_ICE_UDP, kIceUfrag2, kIcePwd2);
+ ASSERT_TRUE(transport_->SetLocalTransportDescription(new_local_desc,
+ cricket::CA_OFFER,
+ NULL));
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLING, transport_->ice_role());
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel_->GetIceRole());
+}
+
+// This test verifies that the caller's ICE role changes from controlling to
+// controlled when the callee triggers an ICE restart.
+TEST_F(TransportTest, TestIceControllingToControlledOnIceRestart) {
+ EXPECT_TRUE(SetupChannel());
+ transport_->SetIceRole(cricket::ICEROLE_CONTROLLING);
+
+ cricket::TransportDescription desc(
+ cricket::NS_JINGLE_ICE_UDP, kIceUfrag1, kIcePwd1);
+ ASSERT_TRUE(transport_->SetLocalTransportDescription(desc,
+ cricket::CA_OFFER,
+ NULL));
+ ASSERT_TRUE(transport_->SetRemoteTransportDescription(desc,
+ cricket::CA_ANSWER,
+ NULL));
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLING, transport_->ice_role());
+
+ cricket::TransportDescription new_local_desc(
+ cricket::NS_JINGLE_ICE_UDP, kIceUfrag2, kIcePwd2);
+ ASSERT_TRUE(transport_->SetLocalTransportDescription(new_local_desc,
+ cricket::CA_ANSWER,
+ NULL));
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLED, transport_->ice_role());
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel_->GetIceRole());
+}
+
+// This test verifies that the caller's ICE role is still controlling after the
+// callee triggers ICE restart if the callee's ICE mode is LITE.
+TEST_F(TransportTest, TestIceControllingOnIceRestartIfRemoteIsIceLite) {
+ EXPECT_TRUE(SetupChannel());
+ transport_->SetIceRole(cricket::ICEROLE_CONTROLLING);
+
+ cricket::TransportDescription desc(
+ cricket::NS_JINGLE_ICE_UDP, kIceUfrag1, kIcePwd1);
+ ASSERT_TRUE(transport_->SetLocalTransportDescription(desc,
+ cricket::CA_OFFER,
+ NULL));
+
+ cricket::TransportDescription remote_desc(
+ cricket::NS_JINGLE_ICE_UDP, std::vector<std::string>(),
+ kIceUfrag1, kIcePwd1, cricket::ICEMODE_LITE,
+ cricket::CONNECTIONROLE_NONE, NULL, cricket::Candidates());
+ ASSERT_TRUE(transport_->SetRemoteTransportDescription(remote_desc,
+ cricket::CA_ANSWER,
+ NULL));
+
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLING, transport_->ice_role());
+
+ cricket::TransportDescription new_local_desc(
+ cricket::NS_JINGLE_ICE_UDP, kIceUfrag2, kIcePwd2);
+ ASSERT_TRUE(transport_->SetLocalTransportDescription(new_local_desc,
+ cricket::CA_ANSWER,
+ NULL));
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLING, transport_->ice_role());
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel_->GetIceRole());
+}
+
+// This test verifies that the Completed and Failed states can be reached.
+TEST_F(TransportTest, TestChannelCompletedAndFailed) {
+ transport_->SetIceRole(cricket::ICEROLE_CONTROLLING);
+ cricket::TransportDescription local_desc(
+ cricket::NS_JINGLE_ICE_UDP, kIceUfrag1, kIcePwd1);
+ ASSERT_TRUE(transport_->SetLocalTransportDescription(local_desc,
+ cricket::CA_OFFER,
+ NULL));
+ EXPECT_TRUE(SetupChannel());
+
+ cricket::TransportDescription remote_desc(
+ cricket::NS_JINGLE_ICE_UDP, kIceUfrag1, kIcePwd1);
+ ASSERT_TRUE(transport_->SetRemoteTransportDescription(remote_desc,
+ cricket::CA_ANSWER,
+ NULL));
+
+ channel_->SetConnectionCount(2);
+ channel_->SignalCandidatesAllocationDone(channel_);
+ channel_->SetWritable(true);
+ EXPECT_TRUE_WAIT(transport_->all_channels_writable(), 100);
+ // ICE is not yet completed because there is still more than one connection.
+ EXPECT_FALSE(completed_);
+ EXPECT_FALSE(failed_);
+
+ // When the connection count drops to 1, SignalCompleted should be emitted,
+ // and completed() should be true.
+ channel_->SetConnectionCount(1);
+ EXPECT_TRUE_WAIT(completed_, 100);
+ completed_ = false;
+
+ // When the connection count drops to 0, SignalFailed should be emitted, and
+ // completed() should be false.
+ channel_->SetConnectionCount(0);
+ EXPECT_TRUE_WAIT(failed_, 100);
+ EXPECT_FALSE(completed_);
+}
+
+// Tests channel role is reversed after receiving ice-lite from remote.
+TEST_F(TransportTest, TestSetRemoteIceLiteInOffer) {
+ transport_->SetIceRole(cricket::ICEROLE_CONTROLLED);
+ cricket::TransportDescription remote_desc(
+ cricket::NS_JINGLE_ICE_UDP, std::vector<std::string>(),
+ kIceUfrag1, kIcePwd1, cricket::ICEMODE_LITE,
+ cricket::CONNECTIONROLE_ACTPASS, NULL, cricket::Candidates());
+ ASSERT_TRUE(transport_->SetRemoteTransportDescription(remote_desc,
+ cricket::CA_OFFER,
+ NULL));
+ cricket::TransportDescription local_desc(
+ cricket::NS_JINGLE_ICE_UDP, kIceUfrag1, kIcePwd1);
+ ASSERT_TRUE(transport_->SetLocalTransportDescription(local_desc,
+ cricket::CA_ANSWER,
+ NULL));
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLING, transport_->ice_role());
+ EXPECT_TRUE(SetupChannel());
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel_->GetIceRole());
+ EXPECT_EQ(cricket::ICEMODE_LITE, channel_->remote_ice_mode());
+}
+
+// Tests ice-lite in remote answer.
+TEST_F(TransportTest, TestSetRemoteIceLiteInAnswer) {
+ transport_->SetIceRole(cricket::ICEROLE_CONTROLLING);
+ cricket::TransportDescription local_desc(
+ cricket::NS_JINGLE_ICE_UDP, kIceUfrag1, kIcePwd1);
+ ASSERT_TRUE(transport_->SetLocalTransportDescription(local_desc,
+ cricket::CA_OFFER,
+ NULL));
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLING, transport_->ice_role());
+ EXPECT_TRUE(SetupChannel());
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel_->GetIceRole());
+ // Channels will be created in ICEFULL_MODE.
+ EXPECT_EQ(cricket::ICEMODE_FULL, channel_->remote_ice_mode());
+ cricket::TransportDescription remote_desc(
+ cricket::NS_JINGLE_ICE_UDP, std::vector<std::string>(),
+ kIceUfrag1, kIcePwd1, cricket::ICEMODE_LITE,
+ cricket::CONNECTIONROLE_NONE, NULL, cricket::Candidates());
+ ASSERT_TRUE(transport_->SetRemoteTransportDescription(remote_desc,
+ cricket::CA_ANSWER,
+ NULL));
+ EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel_->GetIceRole());
+ // After receiving remote description with ICEMODE_LITE, channel should
+ // have mode set to ICEMODE_LITE.
+ EXPECT_EQ(cricket::ICEMODE_LITE, channel_->remote_ice_mode());
+}
+
+// Tests that we can properly serialize/deserialize candidates.
+TEST_F(TransportTest, TestP2PTransportWriteAndParseCandidate) {
+ Candidate test_candidate(
+ "", 1, "udp",
+ rtc::SocketAddress("2001:db8:fefe::1", 9999),
+ 738197504, "abcdef", "ghijkl", "foo", "testnet", 50, "");
+ Candidate test_candidate2(
+ "", 2, "tcp",
+ rtc::SocketAddress("192.168.7.1", 9999),
+ 1107296256, "mnopqr", "stuvwx", "bar", "testnet2", 100, "");
+ rtc::SocketAddress host_address("www.google.com", 24601);
+ host_address.SetResolvedIP(rtc::IPAddress(0x0A000001));
+ Candidate test_candidate3(
+ "", 3, "spdy", host_address, 1476395008, "yzabcd",
+ "efghij", "baz", "testnet3", 150, "");
+ WriteError write_error;
+ ParseError parse_error;
+ rtc::scoped_ptr<buzz::XmlElement> elem;
+ cricket::Candidate parsed_candidate;
+ cricket::P2PTransportParser parser;
+
+ FakeCandidateTranslator translator;
+ translator.AddMapping(1, "test");
+ translator.AddMapping(2, "test2");
+ translator.AddMapping(3, "test3");
+
+ EXPECT_TRUE(parser.WriteGingleCandidate(test_candidate, &translator,
+ elem.accept(), &write_error));
+ EXPECT_EQ("", write_error.text);
+ EXPECT_EQ("test", elem->Attr(buzz::QN_NAME));
+ EXPECT_EQ("udp", elem->Attr(cricket::QN_PROTOCOL));
+ EXPECT_EQ("2001:db8:fefe::1", elem->Attr(cricket::QN_ADDRESS));
+ EXPECT_EQ("9999", elem->Attr(cricket::QN_PORT));
+ EXPECT_EQ("0.34", elem->Attr(cricket::QN_PREFERENCE));
+ EXPECT_EQ("abcdef", elem->Attr(cricket::QN_USERNAME));
+ EXPECT_EQ("ghijkl", elem->Attr(cricket::QN_PASSWORD));
+ EXPECT_EQ("foo", elem->Attr(cricket::QN_TYPE));
+ EXPECT_EQ("testnet", elem->Attr(cricket::QN_NETWORK));
+ EXPECT_EQ("50", elem->Attr(cricket::QN_GENERATION));
+
+ EXPECT_TRUE(parser.ParseGingleCandidate(elem.get(), &translator,
+ &parsed_candidate, &parse_error));
+ EXPECT_TRUE(test_candidate.IsEquivalent(parsed_candidate));
+
+ EXPECT_TRUE(parser.WriteGingleCandidate(test_candidate2, &translator,
+ elem.accept(), &write_error));
+ EXPECT_EQ("test2", elem->Attr(buzz::QN_NAME));
+ EXPECT_EQ("tcp", elem->Attr(cricket::QN_PROTOCOL));
+ EXPECT_EQ("192.168.7.1", elem->Attr(cricket::QN_ADDRESS));
+ EXPECT_EQ("9999", elem->Attr(cricket::QN_PORT));
+ EXPECT_EQ("0.51", elem->Attr(cricket::QN_PREFERENCE));
+ EXPECT_EQ("mnopqr", elem->Attr(cricket::QN_USERNAME));
+ EXPECT_EQ("stuvwx", elem->Attr(cricket::QN_PASSWORD));
+ EXPECT_EQ("bar", elem->Attr(cricket::QN_TYPE));
+ EXPECT_EQ("testnet2", elem->Attr(cricket::QN_NETWORK));
+ EXPECT_EQ("100", elem->Attr(cricket::QN_GENERATION));
+
+ EXPECT_TRUE(parser.ParseGingleCandidate(elem.get(), &translator,
+ &parsed_candidate, &parse_error));
+ EXPECT_TRUE(test_candidate2.IsEquivalent(parsed_candidate));
+
+ // Check that an ip is preferred over hostname.
+ EXPECT_TRUE(parser.WriteGingleCandidate(test_candidate3, &translator,
+ elem.accept(), &write_error));
+ EXPECT_EQ("test3", elem->Attr(cricket::QN_NAME));
+ EXPECT_EQ("spdy", elem->Attr(cricket::QN_PROTOCOL));
+ EXPECT_EQ("10.0.0.1", elem->Attr(cricket::QN_ADDRESS));
+ EXPECT_EQ("24601", elem->Attr(cricket::QN_PORT));
+ EXPECT_EQ("0.69", elem->Attr(cricket::QN_PREFERENCE));
+ EXPECT_EQ("yzabcd", elem->Attr(cricket::QN_USERNAME));
+ EXPECT_EQ("efghij", elem->Attr(cricket::QN_PASSWORD));
+ EXPECT_EQ("baz", elem->Attr(cricket::QN_TYPE));
+ EXPECT_EQ("testnet3", elem->Attr(cricket::QN_NETWORK));
+ EXPECT_EQ("150", elem->Attr(cricket::QN_GENERATION));
+
+ EXPECT_TRUE(parser.ParseGingleCandidate(elem.get(), &translator,
+ &parsed_candidate, &parse_error));
+ EXPECT_TRUE(test_candidate3.IsEquivalent(parsed_candidate));
+}
+
+TEST_F(TransportTest, TestGetStats) {
+ EXPECT_TRUE(SetupChannel());
+ cricket::TransportStats stats;
+ EXPECT_TRUE(transport_->GetStats(&stats));
+ // Note that this tests the behavior of a FakeTransportChannel.
+ ASSERT_EQ(1U, stats.channel_stats.size());
+ EXPECT_EQ(1, stats.channel_stats[0].component);
+ transport_->ConnectChannels();
+ EXPECT_TRUE(transport_->GetStats(&stats));
+ ASSERT_EQ(1U, stats.channel_stats.size());
+ EXPECT_EQ(1, stats.channel_stats[0].component);
+}
diff --git a/p2p/base/transportchannel.cc b/p2p/base/transportchannel.cc
new file mode 100644
index 00000000..16ae27d1
--- /dev/null
+++ b/p2p/base/transportchannel.cc
@@ -0,0 +1,43 @@
+/*
+ * 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 <sstream>
+#include "webrtc/p2p/base/transportchannel.h"
+
+namespace cricket {
+
+std::string TransportChannel::ToString() const {
+ const char READABLE_ABBREV[2] = { '_', 'R' };
+ const char WRITABLE_ABBREV[2] = { '_', 'W' };
+ std::stringstream ss;
+ ss << "Channel[" << content_name_
+ << "|" << component_
+ << "|" << READABLE_ABBREV[readable_] << WRITABLE_ABBREV[writable_] << "]";
+ return ss.str();
+}
+
+void TransportChannel::set_readable(bool readable) {
+ if (readable_ != readable) {
+ readable_ = readable;
+ SignalReadableState(this);
+ }
+}
+
+void TransportChannel::set_writable(bool writable) {
+ if (writable_ != writable) {
+ writable_ = writable;
+ if (writable_) {
+ SignalReadyToSend(this);
+ }
+ SignalWritableState(this);
+ }
+}
+
+} // namespace cricket
diff --git a/p2p/base/transportchannel.h b/p2p/base/transportchannel.h
new file mode 100644
index 00000000..f91c4a8e
--- /dev/null
+++ b/p2p/base/transportchannel.h
@@ -0,0 +1,143 @@
+/*
+ * 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 WEBRTC_P2P_BASE_TRANSPORTCHANNEL_H_
+#define WEBRTC_P2P_BASE_TRANSPORTCHANNEL_H_
+
+#include <string>
+#include <vector>
+
+#include "webrtc/p2p/base/candidate.h"
+#include "webrtc/p2p/base/transport.h"
+#include "webrtc/p2p/base/transportdescription.h"
+#include "webrtc/base/asyncpacketsocket.h"
+#include "webrtc/base/basictypes.h"
+#include "webrtc/base/dscp.h"
+#include "webrtc/base/sigslot.h"
+#include "webrtc/base/socket.h"
+#include "webrtc/base/sslidentity.h"
+#include "webrtc/base/sslstreamadapter.h"
+
+namespace cricket {
+
+class Candidate;
+
+// Flags for SendPacket/SignalReadPacket.
+enum PacketFlags {
+ PF_NORMAL = 0x00, // A normal packet.
+ PF_SRTP_BYPASS = 0x01, // An encrypted SRTP packet; bypass any additional
+ // crypto provided by the transport (e.g. DTLS)
+};
+
+// A TransportChannel represents one logical stream of packets that are sent
+// between the two sides of a session.
+class TransportChannel : public sigslot::has_slots<> {
+ public:
+ explicit TransportChannel(const std::string& content_name, int component)
+ : content_name_(content_name),
+ component_(component),
+ readable_(false), writable_(false) {}
+ virtual ~TransportChannel() {}
+
+ // TODO(mallinath) - Remove this API, as it's no longer useful.
+ // Returns the session id of this channel.
+ virtual const std::string SessionId() const { return std::string(); }
+
+ const std::string& content_name() const { return content_name_; }
+ int component() const { return component_; }
+
+ // Returns the readable and states of this channel. Each time one of these
+ // states changes, a signal is raised. These states are aggregated by the
+ // TransportManager.
+ bool readable() const { return readable_; }
+ bool writable() const { return writable_; }
+ sigslot::signal1<TransportChannel*> SignalReadableState;
+ sigslot::signal1<TransportChannel*> SignalWritableState;
+ // Emitted when the TransportChannel's ability to send has changed.
+ sigslot::signal1<TransportChannel*> SignalReadyToSend;
+
+ // Attempts to send the given packet. The return value is < 0 on failure.
+ // TODO: Remove the default argument once channel code is updated.
+ virtual int SendPacket(const char* data, size_t len,
+ const rtc::PacketOptions& options,
+ int flags = 0) = 0;
+
+ // Sets a socket option on this channel. Note that not all options are
+ // supported by all transport types.
+ virtual int SetOption(rtc::Socket::Option opt, int value) = 0;
+
+ // Returns the most recent error that occurred on this channel.
+ virtual int GetError() = 0;
+
+ // Returns the current stats for this connection.
+ virtual bool GetStats(ConnectionInfos* infos) = 0;
+
+ // Is DTLS active?
+ virtual bool IsDtlsActive() const = 0;
+
+ // Default implementation.
+ virtual bool GetSslRole(rtc::SSLRole* role) const = 0;
+
+ // Sets up the ciphers to use for DTLS-SRTP.
+ virtual bool SetSrtpCiphers(const std::vector<std::string>& ciphers) = 0;
+
+ // Finds out which DTLS-SRTP cipher was negotiated
+ virtual bool GetSrtpCipher(std::string* cipher) = 0;
+
+ // Gets a copy of the local SSL identity, owned by the caller.
+ virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const = 0;
+
+ // Gets a copy of the remote side's SSL certificate, owned by the caller.
+ virtual bool GetRemoteCertificate(rtc::SSLCertificate** cert) const = 0;
+
+ // Allows key material to be extracted for external encryption.
+ virtual bool ExportKeyingMaterial(const std::string& label,
+ const uint8* context,
+ size_t context_len,
+ bool use_context,
+ uint8* result,
+ size_t result_len) = 0;
+
+ // Signalled each time a packet is received on this channel.
+ sigslot::signal5<TransportChannel*, const char*,
+ size_t, const rtc::PacketTime&, int> SignalReadPacket;
+
+ // This signal occurs when there is a change in the way that packets are
+ // being routed, i.e. to a different remote location. The candidate
+ // indicates where and how we are currently sending media.
+ sigslot::signal2<TransportChannel*, const Candidate&> SignalRouteChange;
+
+ // Invoked when the channel is being destroyed.
+ sigslot::signal1<TransportChannel*> SignalDestroyed;
+
+ // Debugging description of this transport channel.
+ std::string ToString() const;
+
+ protected:
+ // Sets the readable state, signaling if necessary.
+ void set_readable(bool readable);
+
+ // Sets the writable state, signaling if necessary.
+ void set_writable(bool writable);
+
+
+ private:
+ // Used mostly for debugging.
+ std::string content_name_;
+ int component_;
+ bool readable_;
+ bool writable_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(TransportChannel);
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_TRANSPORTCHANNEL_H_
diff --git a/p2p/base/transportchannelimpl.h b/p2p/base/transportchannelimpl.h
new file mode 100644
index 00000000..060df7fd
--- /dev/null
+++ b/p2p/base/transportchannelimpl.h
@@ -0,0 +1,111 @@
+/*
+ * 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 WEBRTC_P2P_BASE_TRANSPORTCHANNELIMPL_H_
+#define WEBRTC_P2P_BASE_TRANSPORTCHANNELIMPL_H_
+
+#include <string>
+#include "webrtc/p2p/base/transport.h"
+#include "webrtc/p2p/base/transportchannel.h"
+
+namespace buzz { class XmlElement; }
+
+namespace cricket {
+
+class Candidate;
+
+// Base class for real implementations of TransportChannel. This includes some
+// methods called only by Transport, which do not need to be exposed to the
+// client.
+class TransportChannelImpl : public TransportChannel {
+ public:
+ explicit TransportChannelImpl(const std::string& content_name, int component)
+ : TransportChannel(content_name, component) {}
+
+ // Returns the transport that created this channel.
+ virtual Transport* GetTransport() = 0;
+
+ // For ICE channels.
+ virtual IceRole GetIceRole() const = 0;
+ virtual void SetIceRole(IceRole role) = 0;
+ virtual void SetIceTiebreaker(uint64 tiebreaker) = 0;
+ virtual size_t GetConnectionCount() const = 0;
+ // To toggle G-ICE/ICE.
+ virtual bool GetIceProtocolType(IceProtocolType* type) const = 0;
+ virtual void SetIceProtocolType(IceProtocolType type) = 0;
+ // SetIceCredentials only need to be implemented by the ICE
+ // transport channels. Non-ICE transport channels can just ignore.
+ // The ufrag and pwd should be set before the Connect() is called.
+ virtual void SetIceCredentials(const std::string& ice_ufrag,
+ const std::string& ice_pwd) = 0;
+ // SetRemoteIceCredentials only need to be implemented by the ICE
+ // transport channels. Non-ICE transport channels can just ignore.
+ virtual void SetRemoteIceCredentials(const std::string& ice_ufrag,
+ const std::string& ice_pwd) = 0;
+
+ // SetRemoteIceMode must be implemented only by the ICE transport channels.
+ virtual void SetRemoteIceMode(IceMode mode) = 0;
+
+ // Begins the process of attempting to make a connection to the other client.
+ virtual void Connect() = 0;
+
+ // Resets this channel back to the initial state (i.e., not connecting).
+ virtual void Reset() = 0;
+
+ // Allows an individual channel to request signaling and be notified when it
+ // is ready. This is useful if the individual named channels have need to
+ // send their own transport-info stanzas.
+ sigslot::signal1<TransportChannelImpl*> SignalRequestSignaling;
+ virtual void OnSignalingReady() = 0;
+
+ // Handles sending and receiving of candidates. The Transport
+ // receives the candidates and may forward them to the relevant
+ // channel.
+ //
+ // Note: Since candidates are delivered asynchronously to the
+ // channel, they cannot return an error if the message is invalid.
+ // It is assumed that the Transport will have checked validity
+ // before forwarding.
+ sigslot::signal2<TransportChannelImpl*,
+ const Candidate&> SignalCandidateReady;
+ virtual void OnCandidate(const Candidate& candidate) = 0;
+
+ // DTLS methods
+ // Set DTLS local identity. The identity object is not copied, but the caller
+ // retains ownership and must delete it after this TransportChannelImpl is
+ // destroyed.
+ // TODO(bemasc): Fix the ownership semantics of this method.
+ virtual bool SetLocalIdentity(rtc::SSLIdentity* identity) = 0;
+
+ // Set DTLS Remote fingerprint. Must be after local identity set.
+ virtual bool SetRemoteFingerprint(const std::string& digest_alg,
+ const uint8* digest,
+ size_t digest_len) = 0;
+
+ virtual bool SetSslRole(rtc::SSLRole role) = 0;
+
+ // TransportChannel is forwarding this signal from PortAllocatorSession.
+ sigslot::signal1<TransportChannelImpl*> SignalCandidatesAllocationDone;
+
+ // Invoked when there is conflict in the ICE role between local and remote
+ // agents.
+ sigslot::signal1<TransportChannelImpl*> SignalRoleConflict;
+
+ // Emitted whenever the number of connections available to the transport
+ // channel decreases.
+ sigslot::signal1<TransportChannelImpl*> SignalConnectionRemoved;
+
+ private:
+ DISALLOW_EVIL_CONSTRUCTORS(TransportChannelImpl);
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_TRANSPORTCHANNELIMPL_H_
diff --git a/p2p/base/transportchannelproxy.cc b/p2p/base/transportchannelproxy.cc
new file mode 100644
index 00000000..b5e09571
--- /dev/null
+++ b/p2p/base/transportchannelproxy.cc
@@ -0,0 +1,249 @@
+/*
+ * 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 "webrtc/p2p/base/transport.h"
+#include "webrtc/p2p/base/transportchannelimpl.h"
+#include "webrtc/p2p/base/transportchannelproxy.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/thread.h"
+
+namespace cricket {
+
+enum {
+ MSG_UPDATESTATE,
+};
+
+TransportChannelProxy::TransportChannelProxy(const std::string& content_name,
+ const std::string& name,
+ int component)
+ : TransportChannel(content_name, component),
+ name_(name),
+ impl_(NULL) {
+ worker_thread_ = rtc::Thread::Current();
+}
+
+TransportChannelProxy::~TransportChannelProxy() {
+ // Clearing any pending signal.
+ worker_thread_->Clear(this);
+ if (impl_)
+ impl_->GetTransport()->DestroyChannel(impl_->component());
+}
+
+void TransportChannelProxy::SetImplementation(TransportChannelImpl* impl) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+
+ if (impl == impl_) {
+ // Ignore if the |impl| has already been set.
+ LOG(LS_WARNING) << "Ignored TransportChannelProxy::SetImplementation call "
+ << "with a same impl as the existing one.";
+ return;
+ }
+
+ // Destroy any existing impl_.
+ if (impl_) {
+ impl_->GetTransport()->DestroyChannel(impl_->component());
+ }
+
+ // Adopt the supplied impl, and connect to its signals.
+ impl_ = impl;
+
+ if (impl_) {
+ impl_->SignalReadableState.connect(
+ this, &TransportChannelProxy::OnReadableState);
+ impl_->SignalWritableState.connect(
+ this, &TransportChannelProxy::OnWritableState);
+ impl_->SignalReadPacket.connect(
+ this, &TransportChannelProxy::OnReadPacket);
+ impl_->SignalReadyToSend.connect(
+ this, &TransportChannelProxy::OnReadyToSend);
+ impl_->SignalRouteChange.connect(
+ this, &TransportChannelProxy::OnRouteChange);
+ for (OptionList::iterator it = pending_options_.begin();
+ it != pending_options_.end();
+ ++it) {
+ impl_->SetOption(it->first, it->second);
+ }
+
+ // Push down the SRTP ciphers, if any were set.
+ if (!pending_srtp_ciphers_.empty()) {
+ impl_->SetSrtpCiphers(pending_srtp_ciphers_);
+ }
+ pending_options_.clear();
+ }
+
+ // Post ourselves a message to see if we need to fire state callbacks.
+ worker_thread_->Post(this, MSG_UPDATESTATE);
+}
+
+int TransportChannelProxy::SendPacket(const char* data, size_t len,
+ const rtc::PacketOptions& options,
+ int flags) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ // Fail if we don't have an impl yet.
+ if (!impl_) {
+ return -1;
+ }
+ return impl_->SendPacket(data, len, options, flags);
+}
+
+int TransportChannelProxy::SetOption(rtc::Socket::Option opt, int value) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ if (!impl_) {
+ pending_options_.push_back(OptionPair(opt, value));
+ return 0;
+ }
+ return impl_->SetOption(opt, value);
+}
+
+int TransportChannelProxy::GetError() {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ if (!impl_) {
+ return 0;
+ }
+ return impl_->GetError();
+}
+
+bool TransportChannelProxy::GetStats(ConnectionInfos* infos) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ if (!impl_) {
+ return false;
+ }
+ return impl_->GetStats(infos);
+}
+
+bool TransportChannelProxy::IsDtlsActive() const {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ if (!impl_) {
+ return false;
+ }
+ return impl_->IsDtlsActive();
+}
+
+bool TransportChannelProxy::GetSslRole(rtc::SSLRole* role) const {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ if (!impl_) {
+ return false;
+ }
+ return impl_->GetSslRole(role);
+}
+
+bool TransportChannelProxy::SetSslRole(rtc::SSLRole role) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ if (!impl_) {
+ return false;
+ }
+ return impl_->SetSslRole(role);
+}
+
+bool TransportChannelProxy::SetSrtpCiphers(const std::vector<std::string>&
+ ciphers) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ pending_srtp_ciphers_ = ciphers; // Cache so we can send later, but always
+ // set so it stays consistent.
+ if (impl_) {
+ return impl_->SetSrtpCiphers(ciphers);
+ }
+ return true;
+}
+
+bool TransportChannelProxy::GetSrtpCipher(std::string* cipher) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ if (!impl_) {
+ return false;
+ }
+ return impl_->GetSrtpCipher(cipher);
+}
+
+bool TransportChannelProxy::GetLocalIdentity(
+ rtc::SSLIdentity** identity) const {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ if (!impl_) {
+ return false;
+ }
+ return impl_->GetLocalIdentity(identity);
+}
+
+bool TransportChannelProxy::GetRemoteCertificate(
+ rtc::SSLCertificate** cert) const {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ if (!impl_) {
+ return false;
+ }
+ return impl_->GetRemoteCertificate(cert);
+}
+
+bool TransportChannelProxy::ExportKeyingMaterial(const std::string& label,
+ const uint8* context,
+ size_t context_len,
+ bool use_context,
+ uint8* result,
+ size_t result_len) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ if (!impl_) {
+ return false;
+ }
+ return impl_->ExportKeyingMaterial(label, context, context_len, use_context,
+ result, result_len);
+}
+
+IceRole TransportChannelProxy::GetIceRole() const {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ if (!impl_) {
+ return ICEROLE_UNKNOWN;
+ }
+ return impl_->GetIceRole();
+}
+
+void TransportChannelProxy::OnReadableState(TransportChannel* channel) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ ASSERT(channel == impl_);
+ set_readable(impl_->readable());
+ // Note: SignalReadableState fired by set_readable.
+}
+
+void TransportChannelProxy::OnWritableState(TransportChannel* channel) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ ASSERT(channel == impl_);
+ set_writable(impl_->writable());
+ // Note: SignalWritableState fired by set_readable.
+}
+
+void TransportChannelProxy::OnReadPacket(
+ TransportChannel* channel, const char* data, size_t size,
+ const rtc::PacketTime& packet_time, int flags) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ ASSERT(channel == impl_);
+ SignalReadPacket(this, data, size, packet_time, flags);
+}
+
+void TransportChannelProxy::OnReadyToSend(TransportChannel* channel) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ ASSERT(channel == impl_);
+ SignalReadyToSend(this);
+}
+
+void TransportChannelProxy::OnRouteChange(TransportChannel* channel,
+ const Candidate& candidate) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ ASSERT(channel == impl_);
+ SignalRouteChange(this, candidate);
+}
+
+void TransportChannelProxy::OnMessage(rtc::Message* msg) {
+ ASSERT(rtc::Thread::Current() == worker_thread_);
+ if (msg->message_id == MSG_UPDATESTATE) {
+ // If impl_ is already readable or writable, push up those signals.
+ set_readable(impl_ ? impl_->readable() : false);
+ set_writable(impl_ ? impl_->writable() : false);
+ }
+}
+
+} // namespace cricket
diff --git a/p2p/base/transportchannelproxy.h b/p2p/base/transportchannelproxy.h
new file mode 100644
index 00000000..cfd07f85
--- /dev/null
+++ b/p2p/base/transportchannelproxy.h
@@ -0,0 +1,95 @@
+/*
+ * 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 WEBRTC_P2P_BASE_TRANSPORTCHANNELPROXY_H_
+#define WEBRTC_P2P_BASE_TRANSPORTCHANNELPROXY_H_
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "webrtc/p2p/base/transportchannel.h"
+#include "webrtc/base/messagehandler.h"
+
+namespace rtc {
+class Thread;
+}
+
+namespace cricket {
+
+class TransportChannelImpl;
+
+// Proxies calls between the client and the transport channel implementation.
+// This is needed because clients are allowed to create channels before the
+// network negotiation is complete. Hence, we create a proxy up front, and
+// when negotiation completes, connect the proxy to the implementaiton.
+class TransportChannelProxy : public TransportChannel,
+ public rtc::MessageHandler {
+ public:
+ TransportChannelProxy(const std::string& content_name,
+ const std::string& name,
+ int component);
+ virtual ~TransportChannelProxy();
+
+ const std::string& name() const { return name_; }
+ TransportChannelImpl* impl() { return impl_; }
+
+ // Sets the implementation to which we will proxy.
+ void SetImplementation(TransportChannelImpl* impl);
+
+ // Implementation of the TransportChannel interface. These simply forward to
+ // the implementation.
+ virtual int SendPacket(const char* data, size_t len,
+ const rtc::PacketOptions& options,
+ int flags);
+ virtual int SetOption(rtc::Socket::Option opt, int value);
+ virtual int GetError();
+ virtual IceRole GetIceRole() const;
+ virtual bool GetStats(ConnectionInfos* infos);
+ virtual bool IsDtlsActive() const;
+ virtual bool GetSslRole(rtc::SSLRole* role) const;
+ virtual bool SetSslRole(rtc::SSLRole role);
+ virtual bool SetSrtpCiphers(const std::vector<std::string>& ciphers);
+ virtual bool GetSrtpCipher(std::string* cipher);
+ virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const;
+ virtual bool GetRemoteCertificate(rtc::SSLCertificate** cert) const;
+ virtual bool ExportKeyingMaterial(const std::string& label,
+ const uint8* context,
+ size_t context_len,
+ bool use_context,
+ uint8* result,
+ size_t result_len);
+
+ private:
+ // Catch signals from the implementation channel. These just forward to the
+ // client (after updating our state to match).
+ void OnReadableState(TransportChannel* channel);
+ void OnWritableState(TransportChannel* channel);
+ void OnReadPacket(TransportChannel* channel, const char* data, size_t size,
+ const rtc::PacketTime& packet_time, int flags);
+ void OnReadyToSend(TransportChannel* channel);
+ void OnRouteChange(TransportChannel* channel, const Candidate& candidate);
+
+ void OnMessage(rtc::Message* message);
+
+ typedef std::pair<rtc::Socket::Option, int> OptionPair;
+ typedef std::vector<OptionPair> OptionList;
+ std::string name_;
+ rtc::Thread* worker_thread_;
+ TransportChannelImpl* impl_;
+ OptionList pending_options_;
+ std::vector<std::string> pending_srtp_ciphers_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(TransportChannelProxy);
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_TRANSPORTCHANNELPROXY_H_
diff --git a/p2p/base/transportdescription.cc b/p2p/base/transportdescription.cc
new file mode 100644
index 00000000..01c6a8f0
--- /dev/null
+++ b/p2p/base/transportdescription.cc
@@ -0,0 +1,55 @@
+/*
+ * Copyright 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.
+ */
+
+#include "webrtc/p2p/base/transportdescription.h"
+
+#include "webrtc/p2p/base/constants.h"
+#include "webrtc/base/stringutils.h"
+
+namespace cricket {
+
+bool StringToConnectionRole(const std::string& role_str, ConnectionRole* role) {
+ const char* const roles[] = {
+ CONNECTIONROLE_ACTIVE_STR,
+ CONNECTIONROLE_PASSIVE_STR,
+ CONNECTIONROLE_ACTPASS_STR,
+ CONNECTIONROLE_HOLDCONN_STR
+ };
+
+ for (size_t i = 0; i < ARRAY_SIZE(roles); ++i) {
+ if (_stricmp(roles[i], role_str.c_str()) == 0) {
+ *role = static_cast<ConnectionRole>(CONNECTIONROLE_ACTIVE + i);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ConnectionRoleToString(const ConnectionRole& role, std::string* role_str) {
+ switch (role) {
+ case cricket::CONNECTIONROLE_ACTIVE:
+ *role_str = cricket::CONNECTIONROLE_ACTIVE_STR;
+ break;
+ case cricket::CONNECTIONROLE_ACTPASS:
+ *role_str = cricket::CONNECTIONROLE_ACTPASS_STR;
+ break;
+ case cricket::CONNECTIONROLE_PASSIVE:
+ *role_str = cricket::CONNECTIONROLE_PASSIVE_STR;
+ break;
+ case cricket::CONNECTIONROLE_HOLDCONN:
+ *role_str = cricket::CONNECTIONROLE_HOLDCONN_STR;
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+} // namespace cricket
diff --git a/p2p/base/transportdescription.h b/p2p/base/transportdescription.h
new file mode 100644
index 00000000..5ab1cd6a
--- /dev/null
+++ b/p2p/base/transportdescription.h
@@ -0,0 +1,171 @@
+/*
+ * 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 WEBRTC_P2P_BASE_TRANSPORTDESCRIPTION_H_
+#define WEBRTC_P2P_BASE_TRANSPORTDESCRIPTION_H_
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include "webrtc/p2p/base/candidate.h"
+#include "webrtc/p2p/base/constants.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/sslfingerprint.h"
+
+namespace cricket {
+
+// SEC_ENABLED and SEC_REQUIRED should only be used if the session
+// was negotiated over TLS, to protect the inline crypto material
+// exchange.
+// SEC_DISABLED: No crypto in outgoing offer, ignore any supplied crypto.
+// SEC_ENABLED: Crypto in outgoing offer and answer (if supplied in offer).
+// SEC_REQUIRED: Crypto in outgoing offer and answer. Fail any offer with absent
+// or unsupported crypto.
+enum SecurePolicy {
+ SEC_DISABLED,
+ SEC_ENABLED,
+ SEC_REQUIRED
+};
+
+// The transport protocol we've elected to use.
+enum TransportProtocol {
+ ICEPROTO_GOOGLE, // Google version of ICE protocol.
+ ICEPROTO_HYBRID, // ICE, but can fall back to the Google version.
+ ICEPROTO_RFC5245 // Standard RFC 5245 version of ICE.
+};
+// The old name for TransportProtocol.
+// TODO(juberti): remove this.
+typedef TransportProtocol IceProtocolType;
+
+// Whether our side of the call is driving the negotiation, or the other side.
+enum IceRole {
+ ICEROLE_CONTROLLING = 0,
+ ICEROLE_CONTROLLED,
+ ICEROLE_UNKNOWN
+};
+
+// ICE RFC 5245 implementation type.
+enum IceMode {
+ ICEMODE_FULL, // As defined in http://tools.ietf.org/html/rfc5245#section-4.1
+ ICEMODE_LITE // As defined in http://tools.ietf.org/html/rfc5245#section-4.2
+};
+
+// RFC 4145 - http://tools.ietf.org/html/rfc4145#section-4
+// 'active': The endpoint will initiate an outgoing connection.
+// 'passive': The endpoint will accept an incoming connection.
+// 'actpass': The endpoint is willing to accept an incoming
+// connection or to initiate an outgoing connection.
+enum ConnectionRole {
+ CONNECTIONROLE_NONE = 0,
+ CONNECTIONROLE_ACTIVE,
+ CONNECTIONROLE_PASSIVE,
+ CONNECTIONROLE_ACTPASS,
+ CONNECTIONROLE_HOLDCONN,
+};
+
+extern const char CONNECTIONROLE_ACTIVE_STR[];
+extern const char CONNECTIONROLE_PASSIVE_STR[];
+extern const char CONNECTIONROLE_ACTPASS_STR[];
+extern const char CONNECTIONROLE_HOLDCONN_STR[];
+
+bool StringToConnectionRole(const std::string& role_str, ConnectionRole* role);
+bool ConnectionRoleToString(const ConnectionRole& role, std::string* role_str);
+
+typedef std::vector<Candidate> Candidates;
+
+struct TransportDescription {
+ TransportDescription()
+ : ice_mode(ICEMODE_FULL),
+ connection_role(CONNECTIONROLE_NONE) {}
+
+ TransportDescription(const std::string& transport_type,
+ const std::vector<std::string>& transport_options,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd,
+ IceMode ice_mode,
+ ConnectionRole role,
+ const rtc::SSLFingerprint* identity_fingerprint,
+ const Candidates& candidates)
+ : transport_type(transport_type),
+ transport_options(transport_options),
+ ice_ufrag(ice_ufrag),
+ ice_pwd(ice_pwd),
+ ice_mode(ice_mode),
+ connection_role(role),
+ identity_fingerprint(CopyFingerprint(identity_fingerprint)),
+ candidates(candidates) {}
+ TransportDescription(const std::string& transport_type,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd)
+ : transport_type(transport_type),
+ ice_ufrag(ice_ufrag),
+ ice_pwd(ice_pwd),
+ ice_mode(ICEMODE_FULL),
+ connection_role(CONNECTIONROLE_NONE) {}
+ TransportDescription(const TransportDescription& from)
+ : transport_type(from.transport_type),
+ transport_options(from.transport_options),
+ ice_ufrag(from.ice_ufrag),
+ ice_pwd(from.ice_pwd),
+ ice_mode(from.ice_mode),
+ connection_role(from.connection_role),
+ identity_fingerprint(CopyFingerprint(from.identity_fingerprint.get())),
+ candidates(from.candidates) {}
+
+ TransportDescription& operator=(const TransportDescription& from) {
+ // Self-assignment
+ if (this == &from)
+ return *this;
+
+ transport_type = from.transport_type;
+ transport_options = from.transport_options;
+ ice_ufrag = from.ice_ufrag;
+ ice_pwd = from.ice_pwd;
+ ice_mode = from.ice_mode;
+ connection_role = from.connection_role;
+
+ identity_fingerprint.reset(CopyFingerprint(
+ from.identity_fingerprint.get()));
+ candidates = from.candidates;
+ return *this;
+ }
+
+ bool HasOption(const std::string& option) const {
+ return (std::find(transport_options.begin(), transport_options.end(),
+ option) != transport_options.end());
+ }
+ void AddOption(const std::string& option) {
+ transport_options.push_back(option);
+ }
+ bool secure() const { return identity_fingerprint != NULL; }
+
+ static rtc::SSLFingerprint* CopyFingerprint(
+ const rtc::SSLFingerprint* from) {
+ if (!from)
+ return NULL;
+
+ return new rtc::SSLFingerprint(*from);
+ }
+
+ std::string transport_type; // xmlns of <transport>
+ std::vector<std::string> transport_options;
+ std::string ice_ufrag;
+ std::string ice_pwd;
+ IceMode ice_mode;
+ ConnectionRole connection_role;
+
+ rtc::scoped_ptr<rtc::SSLFingerprint> identity_fingerprint;
+ Candidates candidates;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_TRANSPORTDESCRIPTION_H_
diff --git a/p2p/base/transportdescriptionfactory.cc b/p2p/base/transportdescriptionfactory.cc
new file mode 100644
index 00000000..619c9d16
--- /dev/null
+++ b/p2p/base/transportdescriptionfactory.cc
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ */
+
+#include "webrtc/p2p/base/transportdescriptionfactory.h"
+
+#include "webrtc/p2p/base/transportdescription.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/messagedigest.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/sslfingerprint.h"
+
+namespace cricket {
+
+static TransportProtocol kDefaultProtocol = ICEPROTO_GOOGLE;
+
+TransportDescriptionFactory::TransportDescriptionFactory()
+ : protocol_(kDefaultProtocol),
+ secure_(SEC_DISABLED),
+ identity_(NULL) {
+}
+
+TransportDescription* TransportDescriptionFactory::CreateOffer(
+ const TransportOptions& options,
+ const TransportDescription* current_description) const {
+ rtc::scoped_ptr<TransportDescription> desc(new TransportDescription());
+
+ // Set the transport type depending on the selected protocol.
+ if (protocol_ == ICEPROTO_RFC5245) {
+ desc->transport_type = NS_JINGLE_ICE_UDP;
+ } else if (protocol_ == ICEPROTO_HYBRID) {
+ desc->transport_type = NS_JINGLE_ICE_UDP;
+ desc->AddOption(ICE_OPTION_GICE);
+ } else if (protocol_ == ICEPROTO_GOOGLE) {
+ desc->transport_type = NS_GINGLE_P2P;
+ }
+
+ // Generate the ICE credentials if we don't already have them.
+ if (!current_description || options.ice_restart) {
+ desc->ice_ufrag = rtc::CreateRandomString(ICE_UFRAG_LENGTH);
+ desc->ice_pwd = rtc::CreateRandomString(ICE_PWD_LENGTH);
+ } else {
+ desc->ice_ufrag = current_description->ice_ufrag;
+ desc->ice_pwd = current_description->ice_pwd;
+ }
+
+ // If we are trying to establish a secure transport, add a fingerprint.
+ if (secure_ == SEC_ENABLED || secure_ == SEC_REQUIRED) {
+ // Fail if we can't create the fingerprint.
+ // If we are the initiator set role to "actpass".
+ if (!SetSecurityInfo(desc.get(), CONNECTIONROLE_ACTPASS)) {
+ return NULL;
+ }
+ }
+
+ return desc.release();
+}
+
+TransportDescription* TransportDescriptionFactory::CreateAnswer(
+ const TransportDescription* offer,
+ const TransportOptions& options,
+ const TransportDescription* current_description) const {
+ // A NULL offer is treated as a GICE transport description.
+ // TODO(juberti): Figure out why we get NULL offers, and fix this upstream.
+ rtc::scoped_ptr<TransportDescription> desc(new TransportDescription());
+
+ // Figure out which ICE variant to negotiate; prefer RFC 5245 ICE, but fall
+ // back to G-ICE if needed. Note that we never create a hybrid answer, since
+ // we know what the other side can support already.
+ if (offer && offer->transport_type == NS_JINGLE_ICE_UDP &&
+ (protocol_ == ICEPROTO_RFC5245 || protocol_ == ICEPROTO_HYBRID)) {
+ // Offer is ICE or hybrid, we support ICE or hybrid: use ICE.
+ desc->transport_type = NS_JINGLE_ICE_UDP;
+ } else if (offer && offer->transport_type == NS_JINGLE_ICE_UDP &&
+ offer->HasOption(ICE_OPTION_GICE) &&
+ protocol_ == ICEPROTO_GOOGLE) {
+ desc->transport_type = NS_GINGLE_P2P;
+ // Offer is hybrid, we support GICE: use GICE.
+ } else if ((!offer || offer->transport_type == NS_GINGLE_P2P) &&
+ (protocol_ == ICEPROTO_HYBRID || protocol_ == ICEPROTO_GOOGLE)) {
+ // Offer is GICE, we support hybrid or GICE: use GICE.
+ desc->transport_type = NS_GINGLE_P2P;
+ } else {
+ // Mismatch.
+ LOG(LS_WARNING) << "Failed to create TransportDescription answer "
+ "because of incompatible transport types";
+ return NULL;
+ }
+
+ // Generate the ICE credentials if we don't already have them or ice is
+ // being restarted.
+ if (!current_description || options.ice_restart) {
+ desc->ice_ufrag = rtc::CreateRandomString(ICE_UFRAG_LENGTH);
+ desc->ice_pwd = rtc::CreateRandomString(ICE_PWD_LENGTH);
+ } else {
+ desc->ice_ufrag = current_description->ice_ufrag;
+ desc->ice_pwd = current_description->ice_pwd;
+ }
+
+ // Negotiate security params.
+ if (offer && offer->identity_fingerprint.get()) {
+ // The offer supports DTLS, so answer with DTLS, as long as we support it.
+ if (secure_ == SEC_ENABLED || secure_ == SEC_REQUIRED) {
+ // Fail if we can't create the fingerprint.
+ // Setting DTLS role to active.
+ ConnectionRole role = (options.prefer_passive_role) ?
+ CONNECTIONROLE_PASSIVE : CONNECTIONROLE_ACTIVE;
+
+ if (!SetSecurityInfo(desc.get(), role)) {
+ return NULL;
+ }
+ }
+ } else if (secure_ == SEC_REQUIRED) {
+ // We require DTLS, but the other side didn't offer it. Fail.
+ LOG(LS_WARNING) << "Failed to create TransportDescription answer "
+ "because of incompatible security settings";
+ return NULL;
+ }
+
+ return desc.release();
+}
+
+bool TransportDescriptionFactory::SetSecurityInfo(
+ TransportDescription* desc, ConnectionRole role) const {
+ if (!identity_) {
+ LOG(LS_ERROR) << "Cannot create identity digest with no identity";
+ return false;
+ }
+
+ // This digest algorithm is used to produce the a=fingerprint lines in SDP.
+ // RFC 4572 Section 5 requires that those lines use the same hash function as
+ // the certificate's signature.
+ std::string digest_alg;
+ if (!identity_->certificate().GetSignatureDigestAlgorithm(&digest_alg)) {
+ LOG(LS_ERROR) << "Failed to retrieve the certificate's digest algorithm";
+ return false;
+ }
+
+ desc->identity_fingerprint.reset(
+ rtc::SSLFingerprint::Create(digest_alg, identity_));
+ if (!desc->identity_fingerprint.get()) {
+ LOG(LS_ERROR) << "Failed to create identity fingerprint, alg="
+ << digest_alg;
+ return false;
+ }
+
+ // Assign security role.
+ desc->connection_role = role;
+ return true;
+}
+
+} // namespace cricket
+
diff --git a/p2p/base/transportdescriptionfactory.h b/p2p/base/transportdescriptionfactory.h
new file mode 100644
index 00000000..a137f721
--- /dev/null
+++ b/p2p/base/transportdescriptionfactory.h
@@ -0,0 +1,66 @@
+/*
+ * 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 WEBRTC_P2P_BASE_TRANSPORTDESCRIPTIONFACTORY_H_
+#define WEBRTC_P2P_BASE_TRANSPORTDESCRIPTIONFACTORY_H_
+
+#include "webrtc/p2p/base/transportdescription.h"
+
+namespace rtc {
+class SSLIdentity;
+}
+
+namespace cricket {
+
+struct TransportOptions {
+ TransportOptions() : ice_restart(false), prefer_passive_role(false) {}
+ bool ice_restart;
+ bool prefer_passive_role;
+};
+
+// Creates transport descriptions according to the supplied configuration.
+// When creating answers, performs the appropriate negotiation
+// of the various fields to determine the proper result.
+class TransportDescriptionFactory {
+ public:
+ // Default ctor; use methods below to set configuration.
+ TransportDescriptionFactory();
+ SecurePolicy secure() const { return secure_; }
+ // The identity to use when setting up DTLS.
+ rtc::SSLIdentity* identity() const { return identity_; }
+
+ // Specifies the transport protocol to be use.
+ void set_protocol(TransportProtocol protocol) { protocol_ = protocol; }
+ // Specifies the transport security policy to use.
+ void set_secure(SecurePolicy s) { secure_ = s; }
+ // Specifies the identity to use (only used when secure is not SEC_DISABLED).
+ void set_identity(rtc::SSLIdentity* identity) { identity_ = identity; }
+
+ // Creates a transport description suitable for use in an offer.
+ TransportDescription* CreateOffer(const TransportOptions& options,
+ const TransportDescription* current_description) const;
+ // Create a transport description that is a response to an offer.
+ TransportDescription* CreateAnswer(
+ const TransportDescription* offer,
+ const TransportOptions& options,
+ const TransportDescription* current_description) const;
+
+ private:
+ bool SetSecurityInfo(TransportDescription* description,
+ ConnectionRole role) const;
+
+ TransportProtocol protocol_;
+ SecurePolicy secure_;
+ rtc::SSLIdentity* identity_;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_TRANSPORTDESCRIPTIONFACTORY_H_
diff --git a/p2p/base/transportdescriptionfactory_unittest.cc b/p2p/base/transportdescriptionfactory_unittest.cc
new file mode 100644
index 00000000..22816a2f
--- /dev/null
+++ b/p2p/base/transportdescriptionfactory_unittest.cc
@@ -0,0 +1,365 @@
+/*
+ * 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.
+ */
+
+#include <string>
+#include <vector>
+
+#include "webrtc/p2p/base/constants.h"
+#include "webrtc/p2p/base/transportdescription.h"
+#include "webrtc/p2p/base/transportdescriptionfactory.h"
+#include "webrtc/base/fakesslidentity.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/ssladapter.h"
+
+using rtc::scoped_ptr;
+using cricket::TransportDescriptionFactory;
+using cricket::TransportDescription;
+using cricket::TransportOptions;
+
+class TransportDescriptionFactoryTest : public testing::Test {
+ public:
+ TransportDescriptionFactoryTest()
+ : id1_(new rtc::FakeSSLIdentity("User1")),
+ id2_(new rtc::FakeSSLIdentity("User2")) {
+ }
+
+ void CheckDesc(const TransportDescription* desc, const std::string& type,
+ const std::string& opt, const std::string& ice_ufrag,
+ const std::string& ice_pwd, const std::string& dtls_alg) {
+ ASSERT_TRUE(desc != NULL);
+ EXPECT_EQ(type, desc->transport_type);
+ EXPECT_EQ(!opt.empty(), desc->HasOption(opt));
+ if (ice_ufrag.empty() && ice_pwd.empty()) {
+ EXPECT_EQ(static_cast<size_t>(cricket::ICE_UFRAG_LENGTH),
+ desc->ice_ufrag.size());
+ EXPECT_EQ(static_cast<size_t>(cricket::ICE_PWD_LENGTH),
+ desc->ice_pwd.size());
+ } else {
+ EXPECT_EQ(ice_ufrag, desc->ice_ufrag);
+ EXPECT_EQ(ice_pwd, desc->ice_pwd);
+ }
+ if (dtls_alg.empty()) {
+ EXPECT_TRUE(desc->identity_fingerprint.get() == NULL);
+ } else {
+ ASSERT_TRUE(desc->identity_fingerprint.get() != NULL);
+ EXPECT_EQ(desc->identity_fingerprint->algorithm, dtls_alg);
+ EXPECT_GT(desc->identity_fingerprint->digest.length(), 0U);
+ }
+ }
+
+ // This test ice restart by doing two offer answer exchanges. On the second
+ // exchange ice is restarted. The test verifies that the ufrag and password
+ // in the offer and answer is changed.
+ // If |dtls| is true, the test verifies that the finger print is not changed.
+ void TestIceRestart(bool dtls) {
+ if (dtls) {
+ f1_.set_secure(cricket::SEC_ENABLED);
+ f2_.set_secure(cricket::SEC_ENABLED);
+ f1_.set_identity(id1_.get());
+ f2_.set_identity(id2_.get());
+ } else {
+ f1_.set_secure(cricket::SEC_DISABLED);
+ f2_.set_secure(cricket::SEC_DISABLED);
+ }
+
+ cricket::TransportOptions options;
+ // The initial offer / answer exchange.
+ rtc::scoped_ptr<TransportDescription> offer(f1_.CreateOffer(
+ options, NULL));
+ rtc::scoped_ptr<TransportDescription> answer(
+ f2_.CreateAnswer(offer.get(),
+ options, NULL));
+
+ // Create an updated offer where we restart ice.
+ options.ice_restart = true;
+ rtc::scoped_ptr<TransportDescription> restart_offer(f1_.CreateOffer(
+ options, offer.get()));
+
+ VerifyUfragAndPasswordChanged(dtls, offer.get(), restart_offer.get());
+
+ // Create a new answer. The transport ufrag and password is changed since
+ // |options.ice_restart == true|
+ rtc::scoped_ptr<TransportDescription> restart_answer(
+ f2_.CreateAnswer(restart_offer.get(), options, answer.get()));
+ ASSERT_TRUE(restart_answer.get() != NULL);
+
+ VerifyUfragAndPasswordChanged(dtls, answer.get(), restart_answer.get());
+ }
+
+ void VerifyUfragAndPasswordChanged(bool dtls,
+ const TransportDescription* org_desc,
+ const TransportDescription* restart_desc) {
+ EXPECT_NE(org_desc->ice_pwd, restart_desc->ice_pwd);
+ EXPECT_NE(org_desc->ice_ufrag, restart_desc->ice_ufrag);
+ EXPECT_EQ(static_cast<size_t>(cricket::ICE_UFRAG_LENGTH),
+ restart_desc->ice_ufrag.size());
+ EXPECT_EQ(static_cast<size_t>(cricket::ICE_PWD_LENGTH),
+ restart_desc->ice_pwd.size());
+ // If DTLS is enabled, make sure the finger print is unchanged.
+ if (dtls) {
+ EXPECT_FALSE(
+ org_desc->identity_fingerprint->GetRfc4572Fingerprint().empty());
+ EXPECT_EQ(org_desc->identity_fingerprint->GetRfc4572Fingerprint(),
+ restart_desc->identity_fingerprint->GetRfc4572Fingerprint());
+ }
+ }
+
+ protected:
+ TransportDescriptionFactory f1_;
+ TransportDescriptionFactory f2_;
+ scoped_ptr<rtc::SSLIdentity> id1_;
+ scoped_ptr<rtc::SSLIdentity> id2_;
+};
+
+// Test that in the default case, we generate the expected G-ICE offer.
+TEST_F(TransportDescriptionFactoryTest, TestOfferGice) {
+ f1_.set_protocol(cricket::ICEPROTO_GOOGLE);
+ scoped_ptr<TransportDescription> desc(f1_.CreateOffer(
+ TransportOptions(), NULL));
+ CheckDesc(desc.get(), cricket::NS_GINGLE_P2P, "", "", "", "");
+}
+
+// Test generating a hybrid offer.
+TEST_F(TransportDescriptionFactoryTest, TestOfferHybrid) {
+ f1_.set_protocol(cricket::ICEPROTO_HYBRID);
+ scoped_ptr<TransportDescription> desc(f1_.CreateOffer(
+ TransportOptions(), NULL));
+ CheckDesc(desc.get(), cricket::NS_JINGLE_ICE_UDP, "google-ice", "", "", "");
+}
+
+// Test generating an ICE-only offer.
+TEST_F(TransportDescriptionFactoryTest, TestOfferIce) {
+ f1_.set_protocol(cricket::ICEPROTO_RFC5245);
+ scoped_ptr<TransportDescription> desc(f1_.CreateOffer(
+ TransportOptions(), NULL));
+ CheckDesc(desc.get(), cricket::NS_JINGLE_ICE_UDP, "", "", "", "");
+}
+
+// Test generating a hybrid offer with DTLS.
+TEST_F(TransportDescriptionFactoryTest, TestOfferHybridDtls) {
+ f1_.set_protocol(cricket::ICEPROTO_HYBRID);
+ f1_.set_secure(cricket::SEC_ENABLED);
+ f1_.set_identity(id1_.get());
+ std::string digest_alg;
+ ASSERT_TRUE(id1_->certificate().GetSignatureDigestAlgorithm(&digest_alg));
+ scoped_ptr<TransportDescription> desc(f1_.CreateOffer(
+ TransportOptions(), NULL));
+ CheckDesc(desc.get(), cricket::NS_JINGLE_ICE_UDP, "google-ice", "", "",
+ digest_alg);
+ // Ensure it also works with SEC_REQUIRED.
+ f1_.set_secure(cricket::SEC_REQUIRED);
+ desc.reset(f1_.CreateOffer(TransportOptions(), NULL));
+ CheckDesc(desc.get(), cricket::NS_JINGLE_ICE_UDP, "google-ice", "", "",
+ digest_alg);
+}
+
+// Test generating a hybrid offer with DTLS fails with no identity.
+TEST_F(TransportDescriptionFactoryTest, TestOfferHybridDtlsWithNoIdentity) {
+ f1_.set_protocol(cricket::ICEPROTO_HYBRID);
+ f1_.set_secure(cricket::SEC_ENABLED);
+ scoped_ptr<TransportDescription> desc(f1_.CreateOffer(
+ TransportOptions(), NULL));
+ ASSERT_TRUE(desc.get() == NULL);
+}
+
+// Test updating a hybrid offer with DTLS to pick ICE.
+// The ICE credentials should stay the same in the new offer.
+TEST_F(TransportDescriptionFactoryTest, TestOfferHybridDtlsReofferIceDtls) {
+ f1_.set_protocol(cricket::ICEPROTO_HYBRID);
+ f1_.set_secure(cricket::SEC_ENABLED);
+ f1_.set_identity(id1_.get());
+ std::string digest_alg;
+ ASSERT_TRUE(id1_->certificate().GetSignatureDigestAlgorithm(&digest_alg));
+ scoped_ptr<TransportDescription> old_desc(f1_.CreateOffer(
+ TransportOptions(), NULL));
+ ASSERT_TRUE(old_desc.get() != NULL);
+ f1_.set_protocol(cricket::ICEPROTO_RFC5245);
+ scoped_ptr<TransportDescription> desc(
+ f1_.CreateOffer(TransportOptions(), old_desc.get()));
+ CheckDesc(desc.get(), cricket::NS_JINGLE_ICE_UDP, "",
+ old_desc->ice_ufrag, old_desc->ice_pwd, digest_alg);
+}
+
+// Test that we can answer a GICE offer with GICE.
+TEST_F(TransportDescriptionFactoryTest, TestAnswerGiceToGice) {
+ f1_.set_protocol(cricket::ICEPROTO_GOOGLE);
+ f2_.set_protocol(cricket::ICEPROTO_GOOGLE);
+ scoped_ptr<TransportDescription> offer(f1_.CreateOffer(
+ TransportOptions(), NULL));
+ ASSERT_TRUE(offer.get() != NULL);
+ scoped_ptr<TransportDescription> desc(f2_.CreateAnswer(
+ offer.get(), TransportOptions(), NULL));
+ CheckDesc(desc.get(), cricket::NS_GINGLE_P2P, "", "", "", "");
+ // Should get the same result when answering as hybrid.
+ f2_.set_protocol(cricket::ICEPROTO_HYBRID);
+ desc.reset(f2_.CreateAnswer(offer.get(), TransportOptions(),
+ NULL));
+ CheckDesc(desc.get(), cricket::NS_GINGLE_P2P, "", "", "", "");
+}
+
+// Test that we can answer a hybrid offer with GICE.
+TEST_F(TransportDescriptionFactoryTest, TestAnswerGiceToHybrid) {
+ f1_.set_protocol(cricket::ICEPROTO_HYBRID);
+ f2_.set_protocol(cricket::ICEPROTO_GOOGLE);
+ scoped_ptr<TransportDescription> offer(f1_.CreateOffer(
+ TransportOptions(), NULL));
+ ASSERT_TRUE(offer.get() != NULL);
+ scoped_ptr<TransportDescription> desc(
+ f2_.CreateAnswer(offer.get(), TransportOptions(), NULL));
+ CheckDesc(desc.get(), cricket::NS_GINGLE_P2P, "", "", "", "");
+}
+
+// Test that we can answer a hybrid offer with ICE.
+TEST_F(TransportDescriptionFactoryTest, TestAnswerIceToHybrid) {
+ f1_.set_protocol(cricket::ICEPROTO_HYBRID);
+ f2_.set_protocol(cricket::ICEPROTO_RFC5245);
+ scoped_ptr<TransportDescription> offer(f1_.CreateOffer(
+ TransportOptions(), NULL));
+ ASSERT_TRUE(offer.get() != NULL);
+ scoped_ptr<TransportDescription> desc(
+ f2_.CreateAnswer(offer.get(), TransportOptions(), NULL));
+ CheckDesc(desc.get(), cricket::NS_JINGLE_ICE_UDP, "", "", "", "");
+ // Should get the same result when answering as hybrid.
+ f2_.set_protocol(cricket::ICEPROTO_HYBRID);
+ desc.reset(f2_.CreateAnswer(offer.get(), TransportOptions(),
+ NULL));
+ CheckDesc(desc.get(), cricket::NS_JINGLE_ICE_UDP, "", "", "", "");
+}
+
+// Test that we can answer an ICE offer with ICE.
+TEST_F(TransportDescriptionFactoryTest, TestAnswerIceToIce) {
+ f1_.set_protocol(cricket::ICEPROTO_RFC5245);
+ f2_.set_protocol(cricket::ICEPROTO_RFC5245);
+ scoped_ptr<TransportDescription> offer(f1_.CreateOffer(
+ TransportOptions(), NULL));
+ ASSERT_TRUE(offer.get() != NULL);
+ scoped_ptr<TransportDescription> desc(f2_.CreateAnswer(
+ offer.get(), TransportOptions(), NULL));
+ CheckDesc(desc.get(), cricket::NS_JINGLE_ICE_UDP, "", "", "", "");
+ // Should get the same result when answering as hybrid.
+ f2_.set_protocol(cricket::ICEPROTO_HYBRID);
+ desc.reset(f2_.CreateAnswer(offer.get(), TransportOptions(),
+ NULL));
+ CheckDesc(desc.get(), cricket::NS_JINGLE_ICE_UDP, "", "", "", "");
+}
+
+// Test that we can't answer a GICE offer with ICE.
+TEST_F(TransportDescriptionFactoryTest, TestAnswerIceToGice) {
+ f1_.set_protocol(cricket::ICEPROTO_GOOGLE);
+ f2_.set_protocol(cricket::ICEPROTO_RFC5245);
+ scoped_ptr<TransportDescription> offer(
+ f1_.CreateOffer(TransportOptions(), NULL));
+ ASSERT_TRUE(offer.get() != NULL);
+ scoped_ptr<TransportDescription> desc(
+ f2_.CreateAnswer(offer.get(), TransportOptions(), NULL));
+ ASSERT_TRUE(desc.get() == NULL);
+}
+
+// Test that we can't answer an ICE offer with GICE.
+TEST_F(TransportDescriptionFactoryTest, TestAnswerGiceToIce) {
+ f1_.set_protocol(cricket::ICEPROTO_RFC5245);
+ f2_.set_protocol(cricket::ICEPROTO_GOOGLE);
+ scoped_ptr<TransportDescription> offer(
+ f1_.CreateOffer(TransportOptions(), NULL));
+ ASSERT_TRUE(offer.get() != NULL);
+ scoped_ptr<TransportDescription> desc(f2_.CreateAnswer(
+ offer.get(), TransportOptions(), NULL));
+ ASSERT_TRUE(desc.get() == NULL);
+}
+
+// Test that we can update an answer properly; ICE credentials shouldn't change.
+TEST_F(TransportDescriptionFactoryTest, TestAnswerIceToIceReanswer) {
+ f1_.set_protocol(cricket::ICEPROTO_RFC5245);
+ f2_.set_protocol(cricket::ICEPROTO_RFC5245);
+ scoped_ptr<TransportDescription> offer(
+ f1_.CreateOffer(TransportOptions(), NULL));
+ ASSERT_TRUE(offer.get() != NULL);
+ scoped_ptr<TransportDescription> old_desc(
+ f2_.CreateAnswer(offer.get(), TransportOptions(), NULL));
+ ASSERT_TRUE(old_desc.get() != NULL);
+ scoped_ptr<TransportDescription> desc(
+ f2_.CreateAnswer(offer.get(), TransportOptions(),
+ old_desc.get()));
+ ASSERT_TRUE(desc.get() != NULL);
+ CheckDesc(desc.get(), cricket::NS_JINGLE_ICE_UDP, "",
+ old_desc->ice_ufrag, old_desc->ice_pwd, "");
+}
+
+// Test that we handle answering an offer with DTLS with no DTLS.
+TEST_F(TransportDescriptionFactoryTest, TestAnswerHybridToHybridDtls) {
+ f1_.set_protocol(cricket::ICEPROTO_HYBRID);
+ f1_.set_secure(cricket::SEC_ENABLED);
+ f1_.set_identity(id1_.get());
+ f2_.set_protocol(cricket::ICEPROTO_HYBRID);
+ scoped_ptr<TransportDescription> offer(
+ f1_.CreateOffer(TransportOptions(), NULL));
+ ASSERT_TRUE(offer.get() != NULL);
+ scoped_ptr<TransportDescription> desc(
+ f2_.CreateAnswer(offer.get(), TransportOptions(), NULL));
+ CheckDesc(desc.get(), cricket::NS_JINGLE_ICE_UDP, "", "", "", "");
+}
+
+// Test that we handle answering an offer without DTLS if we have DTLS enabled,
+// but fail if we require DTLS.
+TEST_F(TransportDescriptionFactoryTest, TestAnswerHybridDtlsToHybrid) {
+ f1_.set_protocol(cricket::ICEPROTO_HYBRID);
+ f2_.set_protocol(cricket::ICEPROTO_HYBRID);
+ f2_.set_secure(cricket::SEC_ENABLED);
+ f2_.set_identity(id2_.get());
+ scoped_ptr<TransportDescription> offer(
+ f1_.CreateOffer(TransportOptions(), NULL));
+ ASSERT_TRUE(offer.get() != NULL);
+ scoped_ptr<TransportDescription> desc(
+ f2_.CreateAnswer(offer.get(), TransportOptions(), NULL));
+ CheckDesc(desc.get(), cricket::NS_JINGLE_ICE_UDP, "", "", "", "");
+ f2_.set_secure(cricket::SEC_REQUIRED);
+ desc.reset(f2_.CreateAnswer(offer.get(), TransportOptions(),
+ NULL));
+ ASSERT_TRUE(desc.get() == NULL);
+}
+
+// Test that we handle answering an DTLS offer with DTLS, both if we have
+// DTLS enabled and required.
+TEST_F(TransportDescriptionFactoryTest, TestAnswerHybridDtlsToHybridDtls) {
+ f1_.set_protocol(cricket::ICEPROTO_HYBRID);
+ f1_.set_secure(cricket::SEC_ENABLED);
+ f1_.set_identity(id1_.get());
+
+ f2_.set_protocol(cricket::ICEPROTO_HYBRID);
+ f2_.set_secure(cricket::SEC_ENABLED);
+ f2_.set_identity(id2_.get());
+ // f2_ produces the answer that is being checked in this test, so the
+ // answer must contain fingerprint lines with id2_'s digest algorithm.
+ std::string digest_alg2;
+ ASSERT_TRUE(id2_->certificate().GetSignatureDigestAlgorithm(&digest_alg2));
+
+ scoped_ptr<TransportDescription> offer(
+ f1_.CreateOffer(TransportOptions(), NULL));
+ ASSERT_TRUE(offer.get() != NULL);
+ scoped_ptr<TransportDescription> desc(
+ f2_.CreateAnswer(offer.get(), TransportOptions(), NULL));
+ CheckDesc(desc.get(), cricket::NS_JINGLE_ICE_UDP, "", "", "", digest_alg2);
+ f2_.set_secure(cricket::SEC_REQUIRED);
+ desc.reset(f2_.CreateAnswer(offer.get(), TransportOptions(),
+ NULL));
+ CheckDesc(desc.get(), cricket::NS_JINGLE_ICE_UDP, "", "", "", digest_alg2);
+}
+
+// Test that ice ufrag and password is changed in an updated offer and answer
+// if |TransportDescriptionOptions::ice_restart| is true.
+TEST_F(TransportDescriptionFactoryTest, TestIceRestart) {
+ TestIceRestart(false);
+}
+
+// Test that ice ufrag and password is changed in an updated offer and answer
+// if |TransportDescriptionOptions::ice_restart| is true and DTLS is enabled.
+TEST_F(TransportDescriptionFactoryTest, TestIceRestartWithDtls) {
+ TestIceRestart(true);
+}
diff --git a/p2p/base/transportinfo.h b/p2p/base/transportinfo.h
new file mode 100644
index 00000000..3fbf204d
--- /dev/null
+++ b/p2p/base/transportinfo.h
@@ -0,0 +1,43 @@
+/*
+ * 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 WEBRTC_P2P_BASE_TRANSPORTINFO_H_
+#define WEBRTC_P2P_BASE_TRANSPORTINFO_H_
+
+#include <string>
+#include <vector>
+
+#include "webrtc/p2p/base/candidate.h"
+#include "webrtc/p2p/base/constants.h"
+#include "webrtc/p2p/base/transportdescription.h"
+#include "webrtc/base/helpers.h"
+
+namespace cricket {
+
+// A TransportInfo is NOT a transport-info message. It is comparable
+// to a "ContentInfo". A transport-infos message is basically just a
+// collection of TransportInfos.
+struct TransportInfo {
+ TransportInfo() {}
+
+ TransportInfo(const std::string& content_name,
+ const TransportDescription& description)
+ : content_name(content_name),
+ description(description) {}
+
+ std::string content_name;
+ TransportDescription description;
+};
+
+typedef std::vector<TransportInfo> TransportInfos;
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_TRANSPORTINFO_H_
diff --git a/p2p/base/turnport.cc b/p2p/base/turnport.cc
new file mode 100644
index 00000000..e7626fe0
--- /dev/null
+++ b/p2p/base/turnport.cc
@@ -0,0 +1,1196 @@
+/*
+ * 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.
+ */
+
+#include "webrtc/p2p/base/turnport.h"
+
+#include <functional>
+
+#include "webrtc/p2p/base/common.h"
+#include "webrtc/p2p/base/stun.h"
+#include "webrtc/base/asyncpacketsocket.h"
+#include "webrtc/base/byteorder.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/nethelpers.h"
+#include "webrtc/base/socketaddress.h"
+#include "webrtc/base/stringencode.h"
+
+namespace cricket {
+
+// TODO(juberti): Move to stun.h when relay messages have been renamed.
+static const int TURN_ALLOCATE_REQUEST = STUN_ALLOCATE_REQUEST;
+
+// TODO(juberti): Extract to turnmessage.h
+static const int TURN_DEFAULT_PORT = 3478;
+static const int TURN_CHANNEL_NUMBER_START = 0x4000;
+static const int TURN_PERMISSION_TIMEOUT = 5 * 60 * 1000; // 5 minutes
+
+static const size_t TURN_CHANNEL_HEADER_SIZE = 4U;
+
+// Retry at most twice (i.e. three different ALLOCATE requests) on
+// STUN_ERROR_ALLOCATION_MISMATCH error per rfc5766.
+static const size_t MAX_ALLOCATE_MISMATCH_RETRIES = 2;
+
+inline bool IsTurnChannelData(uint16 msg_type) {
+ return ((msg_type & 0xC000) == 0x4000); // MSB are 0b01
+}
+
+static int GetRelayPreference(cricket::ProtocolType proto, bool secure) {
+ int relay_preference = ICE_TYPE_PREFERENCE_RELAY;
+ if (proto == cricket::PROTO_TCP) {
+ relay_preference -= 1;
+ if (secure)
+ relay_preference -= 1;
+ }
+
+ ASSERT(relay_preference >= 0);
+ return relay_preference;
+}
+
+class TurnAllocateRequest : public StunRequest {
+ public:
+ explicit TurnAllocateRequest(TurnPort* port);
+ virtual void Prepare(StunMessage* request);
+ virtual void OnResponse(StunMessage* response);
+ virtual void OnErrorResponse(StunMessage* response);
+ virtual void OnTimeout();
+
+ private:
+ // Handles authentication challenge from the server.
+ void OnAuthChallenge(StunMessage* response, int code);
+ void OnTryAlternate(StunMessage* response, int code);
+ void OnUnknownAttribute(StunMessage* response);
+
+ TurnPort* port_;
+};
+
+class TurnRefreshRequest : public StunRequest {
+ public:
+ explicit TurnRefreshRequest(TurnPort* port);
+ virtual void Prepare(StunMessage* request);
+ virtual void OnResponse(StunMessage* response);
+ virtual void OnErrorResponse(StunMessage* response);
+ virtual void OnTimeout();
+
+ private:
+ TurnPort* port_;
+};
+
+class TurnCreatePermissionRequest : public StunRequest,
+ public sigslot::has_slots<> {
+ public:
+ TurnCreatePermissionRequest(TurnPort* port, TurnEntry* entry,
+ const rtc::SocketAddress& ext_addr);
+ virtual void Prepare(StunMessage* request);
+ virtual void OnResponse(StunMessage* response);
+ virtual void OnErrorResponse(StunMessage* response);
+ virtual void OnTimeout();
+
+ private:
+ void OnEntryDestroyed(TurnEntry* entry);
+
+ TurnPort* port_;
+ TurnEntry* entry_;
+ rtc::SocketAddress ext_addr_;
+};
+
+class TurnChannelBindRequest : public StunRequest,
+ public sigslot::has_slots<> {
+ public:
+ TurnChannelBindRequest(TurnPort* port, TurnEntry* entry, int channel_id,
+ const rtc::SocketAddress& ext_addr);
+ virtual void Prepare(StunMessage* request);
+ virtual void OnResponse(StunMessage* response);
+ virtual void OnErrorResponse(StunMessage* response);
+ virtual void OnTimeout();
+
+ private:
+ void OnEntryDestroyed(TurnEntry* entry);
+
+ TurnPort* port_;
+ TurnEntry* entry_;
+ int channel_id_;
+ rtc::SocketAddress ext_addr_;
+};
+
+// Manages a "connection" to a remote destination. We will attempt to bring up
+// a channel for this remote destination to reduce the overhead of sending data.
+class TurnEntry : public sigslot::has_slots<> {
+ public:
+ enum BindState { STATE_UNBOUND, STATE_BINDING, STATE_BOUND };
+ TurnEntry(TurnPort* port, int channel_id,
+ const rtc::SocketAddress& ext_addr);
+
+ TurnPort* port() { return port_; }
+
+ int channel_id() const { return channel_id_; }
+ const rtc::SocketAddress& address() const { return ext_addr_; }
+ BindState state() const { return state_; }
+
+ // Helper methods to send permission and channel bind requests.
+ void SendCreatePermissionRequest();
+ void SendChannelBindRequest(int delay);
+ // Sends a packet to the given destination address.
+ // This will wrap the packet in STUN if necessary.
+ int Send(const void* data, size_t size, bool payload,
+ const rtc::PacketOptions& options);
+
+ void OnCreatePermissionSuccess();
+ void OnCreatePermissionError(StunMessage* response, int code);
+ void OnChannelBindSuccess();
+ void OnChannelBindError(StunMessage* response, int code);
+ // Signal sent when TurnEntry is destroyed.
+ sigslot::signal1<TurnEntry*> SignalDestroyed;
+
+ private:
+ TurnPort* port_;
+ int channel_id_;
+ rtc::SocketAddress ext_addr_;
+ BindState state_;
+};
+
+TurnPort::TurnPort(rtc::Thread* thread,
+ rtc::PacketSocketFactory* factory,
+ rtc::Network* network,
+ rtc::AsyncPacketSocket* socket,
+ const std::string& username,
+ const std::string& password,
+ const ProtocolAddress& server_address,
+ const RelayCredentials& credentials,
+ int server_priority)
+ : Port(thread, factory, network, socket->GetLocalAddress().ipaddr(),
+ username, password),
+ server_address_(server_address),
+ credentials_(credentials),
+ socket_(socket),
+ resolver_(NULL),
+ error_(0),
+ request_manager_(thread),
+ next_channel_number_(TURN_CHANNEL_NUMBER_START),
+ connected_(false),
+ server_priority_(server_priority),
+ allocate_mismatch_retries_(0) {
+ request_manager_.SignalSendPacket.connect(this, &TurnPort::OnSendStunPacket);
+}
+
+TurnPort::TurnPort(rtc::Thread* thread,
+ rtc::PacketSocketFactory* factory,
+ rtc::Network* network,
+ const rtc::IPAddress& ip,
+ int min_port, int max_port,
+ const std::string& username,
+ const std::string& password,
+ const ProtocolAddress& server_address,
+ const RelayCredentials& credentials,
+ int server_priority)
+ : Port(thread, RELAY_PORT_TYPE, factory, network, ip, min_port, max_port,
+ username, password),
+ server_address_(server_address),
+ credentials_(credentials),
+ socket_(NULL),
+ resolver_(NULL),
+ error_(0),
+ request_manager_(thread),
+ next_channel_number_(TURN_CHANNEL_NUMBER_START),
+ connected_(false),
+ server_priority_(server_priority),
+ allocate_mismatch_retries_(0) {
+ request_manager_.SignalSendPacket.connect(this, &TurnPort::OnSendStunPacket);
+}
+
+TurnPort::~TurnPort() {
+ // TODO(juberti): Should this even be necessary?
+ while (!entries_.empty()) {
+ DestroyEntry(entries_.front()->address());
+ }
+ if (resolver_) {
+ resolver_->Destroy(false);
+ }
+ if (!SharedSocket()) {
+ delete socket_;
+ }
+}
+
+void TurnPort::PrepareAddress() {
+ if (credentials_.username.empty() ||
+ credentials_.password.empty()) {
+ LOG(LS_ERROR) << "Allocation can't be started without setting the"
+ << " TURN server credentials for the user.";
+ OnAllocateError();
+ return;
+ }
+
+ if (!server_address_.address.port()) {
+ // We will set default TURN port, if no port is set in the address.
+ server_address_.address.SetPort(TURN_DEFAULT_PORT);
+ }
+
+ if (server_address_.address.IsUnresolved()) {
+ ResolveTurnAddress(server_address_.address);
+ } else {
+ // If protocol family of server address doesn't match with local, return.
+ if (!IsCompatibleAddress(server_address_.address)) {
+ LOG(LS_ERROR) << "Server IP address family does not match with "
+ << "local host address family type";
+ OnAllocateError();
+ return;
+ }
+
+ // Insert the current address to prevent redirection pingpong.
+ attempted_server_addresses_.insert(server_address_.address);
+
+ LOG_J(LS_INFO, this) << "Trying to connect to TURN server via "
+ << ProtoToString(server_address_.proto) << " @ "
+ << server_address_.address.ToSensitiveString();
+ if (!CreateTurnClientSocket()) {
+ OnAllocateError();
+ } else if (server_address_.proto == PROTO_UDP) {
+ // If its UDP, send AllocateRequest now.
+ // For TCP and TLS AllcateRequest will be sent by OnSocketConnect.
+ SendRequest(new TurnAllocateRequest(this), 0);
+ }
+ }
+}
+
+bool TurnPort::CreateTurnClientSocket() {
+ ASSERT(!socket_ || SharedSocket());
+
+ if (server_address_.proto == PROTO_UDP && !SharedSocket()) {
+ socket_ = socket_factory()->CreateUdpSocket(
+ rtc::SocketAddress(ip(), 0), min_port(), max_port());
+ } else if (server_address_.proto == PROTO_TCP) {
+ ASSERT(!SharedSocket());
+ int opts = rtc::PacketSocketFactory::OPT_STUN;
+ // If secure bit is enabled in server address, use TLS over TCP.
+ if (server_address_.secure) {
+ opts |= rtc::PacketSocketFactory::OPT_TLS;
+ }
+ socket_ = socket_factory()->CreateClientTcpSocket(
+ rtc::SocketAddress(ip(), 0), server_address_.address,
+ proxy(), user_agent(), opts);
+ }
+
+ if (!socket_) {
+ error_ = SOCKET_ERROR;
+ return false;
+ }
+
+ // Apply options if any.
+ for (SocketOptionsMap::iterator iter = socket_options_.begin();
+ iter != socket_options_.end(); ++iter) {
+ socket_->SetOption(iter->first, iter->second);
+ }
+
+ if (!SharedSocket()) {
+ // If socket is shared, AllocationSequence will receive the packet.
+ socket_->SignalReadPacket.connect(this, &TurnPort::OnReadPacket);
+ }
+
+ socket_->SignalReadyToSend.connect(this, &TurnPort::OnReadyToSend);
+
+ if (server_address_.proto == PROTO_TCP) {
+ socket_->SignalConnect.connect(this, &TurnPort::OnSocketConnect);
+ socket_->SignalClose.connect(this, &TurnPort::OnSocketClose);
+ }
+ return true;
+}
+
+void TurnPort::OnSocketConnect(rtc::AsyncPacketSocket* socket) {
+ ASSERT(server_address_.proto == PROTO_TCP);
+ // Do not use this port if the socket bound to a different address than
+ // the one we asked for. This is seen in Chrome, where TCP sockets cannot be
+ // given a binding address, and the platform is expected to pick the
+ // correct local address.
+ if (socket->GetLocalAddress().ipaddr() != ip()) {
+ LOG(LS_WARNING) << "Socket is bound to a different address then the "
+ << "local port. Discarding TURN port.";
+ OnAllocateError();
+ return;
+ }
+
+ if (server_address_.address.IsUnresolved()) {
+ server_address_.address = socket_->GetRemoteAddress();
+ }
+
+ LOG(LS_INFO) << "TurnPort connected to " << socket->GetRemoteAddress()
+ << " using tcp.";
+ SendRequest(new TurnAllocateRequest(this), 0);
+}
+
+void TurnPort::OnSocketClose(rtc::AsyncPacketSocket* socket, int error) {
+ LOG_J(LS_WARNING, this) << "Connection with server failed, error=" << error;
+ if (!connected_) {
+ OnAllocateError();
+ }
+}
+
+void TurnPort::OnAllocateMismatch() {
+ if (allocate_mismatch_retries_ >= MAX_ALLOCATE_MISMATCH_RETRIES) {
+ LOG_J(LS_WARNING, this) << "Giving up on the port after "
+ << allocate_mismatch_retries_
+ << " retries for STUN_ERROR_ALLOCATION_MISMATCH";
+ OnAllocateError();
+ return;
+ }
+
+ LOG_J(LS_INFO, this) << "Allocating a new socket after "
+ << "STUN_ERROR_ALLOCATION_MISMATCH, retry = "
+ << allocate_mismatch_retries_ + 1;
+ if (SharedSocket()) {
+ ResetSharedSocket();
+ } else {
+ delete socket_;
+ }
+ socket_ = NULL;
+
+ PrepareAddress();
+ ++allocate_mismatch_retries_;
+}
+
+Connection* TurnPort::CreateConnection(const Candidate& address,
+ CandidateOrigin origin) {
+ // TURN-UDP can only connect to UDP candidates.
+ if (address.protocol() != UDP_PROTOCOL_NAME) {
+ return NULL;
+ }
+
+ if (!IsCompatibleAddress(address.address())) {
+ return NULL;
+ }
+
+ // Create an entry, if needed, so we can get our permissions set up correctly.
+ CreateEntry(address.address());
+
+ // A TURN port will have two candiates, STUN and TURN. STUN may not
+ // present in all cases. If present stun candidate will be added first
+ // and TURN candidate later.
+ for (size_t index = 0; index < Candidates().size(); ++index) {
+ if (Candidates()[index].type() == RELAY_PORT_TYPE) {
+ ProxyConnection* conn = new ProxyConnection(this, index, address);
+ conn->SignalDestroyed.connect(this, &TurnPort::OnConnectionDestroyed);
+ AddConnection(conn);
+ return conn;
+ }
+ }
+ return NULL;
+}
+
+int TurnPort::SetOption(rtc::Socket::Option opt, int value) {
+ if (!socket_) {
+ // If socket is not created yet, these options will be applied during socket
+ // creation.
+ socket_options_[opt] = value;
+ return 0;
+ }
+ return socket_->SetOption(opt, value);
+}
+
+int TurnPort::GetOption(rtc::Socket::Option opt, int* value) {
+ if (!socket_) {
+ SocketOptionsMap::const_iterator it = socket_options_.find(opt);
+ if (it == socket_options_.end()) {
+ return -1;
+ }
+ *value = it->second;
+ return 0;
+ }
+
+ return socket_->GetOption(opt, value);
+}
+
+int TurnPort::GetError() {
+ return error_;
+}
+
+int TurnPort::SendTo(const void* data, size_t size,
+ const rtc::SocketAddress& addr,
+ const rtc::PacketOptions& options,
+ bool payload) {
+ // Try to find an entry for this specific address; we should have one.
+ TurnEntry* entry = FindEntry(addr);
+ ASSERT(entry != NULL);
+ if (!entry) {
+ return 0;
+ }
+
+ if (!connected()) {
+ error_ = EWOULDBLOCK;
+ return SOCKET_ERROR;
+ }
+
+ // Send the actual contents to the server using the usual mechanism.
+ int sent = entry->Send(data, size, payload, options);
+ if (sent <= 0) {
+ return SOCKET_ERROR;
+ }
+
+ // The caller of the function is expecting the number of user data bytes,
+ // rather than the size of the packet.
+ return static_cast<int>(size);
+}
+
+void TurnPort::OnReadPacket(
+ rtc::AsyncPacketSocket* socket, const char* data, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time) {
+ ASSERT(socket == socket_);
+ ASSERT(remote_addr == server_address_.address);
+
+ // The message must be at least the size of a channel header.
+ if (size < TURN_CHANNEL_HEADER_SIZE) {
+ LOG_J(LS_WARNING, this) << "Received TURN message that was too short";
+ return;
+ }
+
+ // Check the message type, to see if is a Channel Data message.
+ // The message will either be channel data, a TURN data indication, or
+ // a response to a previous request.
+ uint16 msg_type = rtc::GetBE16(data);
+ if (IsTurnChannelData(msg_type)) {
+ HandleChannelData(msg_type, data, size, packet_time);
+ } else if (msg_type == TURN_DATA_INDICATION) {
+ HandleDataIndication(data, size, packet_time);
+ } else {
+ // This must be a response for one of our requests.
+ // Check success responses, but not errors, for MESSAGE-INTEGRITY.
+ if (IsStunSuccessResponseType(msg_type) &&
+ !StunMessage::ValidateMessageIntegrity(data, size, hash())) {
+ LOG_J(LS_WARNING, this) << "Received TURN message with invalid "
+ << "message integrity, msg_type=" << msg_type;
+ return;
+ }
+ request_manager_.CheckResponse(data, size);
+ }
+}
+
+void TurnPort::OnReadyToSend(rtc::AsyncPacketSocket* socket) {
+ if (connected_) {
+ Port::OnReadyToSend();
+ }
+}
+
+
+// Update current server address port with the alternate server address port.
+bool TurnPort::SetAlternateServer(const rtc::SocketAddress& address) {
+ // Check if we have seen this address before and reject if we did.
+ AttemptedServerSet::iterator iter = attempted_server_addresses_.find(address);
+ if (iter != attempted_server_addresses_.end()) {
+ LOG_J(LS_WARNING, this) << "Redirection to ["
+ << address.ToSensitiveString()
+ << "] ignored, allocation failed.";
+ return false;
+ }
+
+ // If protocol family of server address doesn't match with local, return.
+ if (!IsCompatibleAddress(address)) {
+ LOG(LS_WARNING) << "Server IP address family does not match with "
+ << "local host address family type";
+ return false;
+ }
+
+ LOG_J(LS_INFO, this) << "Redirecting from TURN server ["
+ << server_address_.address.ToSensitiveString()
+ << "] to TURN server ["
+ << address.ToSensitiveString()
+ << "]";
+ server_address_ = ProtocolAddress(address, server_address_.proto,
+ server_address_.secure);
+
+ // Insert the current address to prevent redirection pingpong.
+ attempted_server_addresses_.insert(server_address_.address);
+ return true;
+}
+
+void TurnPort::ResolveTurnAddress(const rtc::SocketAddress& address) {
+ if (resolver_)
+ return;
+
+ resolver_ = socket_factory()->CreateAsyncResolver();
+ resolver_->SignalDone.connect(this, &TurnPort::OnResolveResult);
+ resolver_->Start(address);
+}
+
+void TurnPort::OnResolveResult(rtc::AsyncResolverInterface* resolver) {
+ ASSERT(resolver == resolver_);
+ // If DNS resolve is failed when trying to connect to the server using TCP,
+ // one of the reason could be due to DNS queries blocked by firewall.
+ // In such cases we will try to connect to the server with hostname, assuming
+ // socket layer will resolve the hostname through a HTTP proxy (if any).
+ if (resolver_->GetError() != 0 && server_address_.proto == PROTO_TCP) {
+ if (!CreateTurnClientSocket()) {
+ OnAllocateError();
+ }
+ return;
+ }
+
+ // Copy the original server address in |resolved_address|. For TLS based
+ // sockets we need hostname along with resolved address.
+ rtc::SocketAddress resolved_address = server_address_.address;
+ if (resolver_->GetError() != 0 ||
+ !resolver_->GetResolvedAddress(ip().family(), &resolved_address)) {
+ LOG_J(LS_WARNING, this) << "TURN host lookup received error "
+ << resolver_->GetError();
+ error_ = resolver_->GetError();
+ OnAllocateError();
+ return;
+ }
+ // Signal needs both resolved and unresolved address. After signal is sent
+ // we can copy resolved address back into |server_address_|.
+ SignalResolvedServerAddress(this, server_address_.address,
+ resolved_address);
+ server_address_.address = resolved_address;
+ PrepareAddress();
+}
+
+void TurnPort::OnSendStunPacket(const void* data, size_t size,
+ StunRequest* request) {
+ rtc::PacketOptions options(DefaultDscpValue());
+ if (Send(data, size, options) < 0) {
+ LOG_J(LS_ERROR, this) << "Failed to send TURN message, err="
+ << socket_->GetError();
+ }
+}
+
+void TurnPort::OnStunAddress(const rtc::SocketAddress& address) {
+ // STUN Port will discover STUN candidate, as it's supplied with first TURN
+ // server address.
+ // Why not using this address? - P2PTransportChannel will start creating
+ // connections after first candidate, which means it could start creating the
+ // connections before TURN candidate added. For that to handle, we need to
+ // supply STUN candidate from this port to UDPPort, and TurnPort should have
+ // handle to UDPPort to pass back the address.
+}
+
+void TurnPort::OnAllocateSuccess(const rtc::SocketAddress& address,
+ const rtc::SocketAddress& stun_address) {
+ connected_ = true;
+
+ rtc::SocketAddress related_address = stun_address;
+ if (!(candidate_filter() & CF_REFLEXIVE)) {
+ // If candidate filter only allows relay type of address, empty raddr to
+ // avoid local address leakage.
+ related_address = rtc::EmptySocketAddressWithFamily(stun_address.family());
+ }
+
+ // For relayed candidate, Base is the candidate itself.
+ AddAddress(address, // Candidate address.
+ address, // Base address.
+ related_address, // Related address.
+ UDP_PROTOCOL_NAME,
+ "", // TCP canddiate type, empty for turn candidates.
+ RELAY_PORT_TYPE,
+ GetRelayPreference(server_address_.proto, server_address_.secure),
+ server_priority_,
+ true);
+}
+
+void TurnPort::OnAllocateError() {
+ // We will send SignalPortError asynchronously as this can be sent during
+ // port initialization. This way it will not be blocking other port
+ // creation.
+ thread()->Post(this, MSG_ERROR);
+}
+
+void TurnPort::OnMessage(rtc::Message* message) {
+ if (message->message_id == MSG_ERROR) {
+ SignalPortError(this);
+ return;
+ } else if (message->message_id == MSG_ALLOCATE_MISMATCH) {
+ OnAllocateMismatch();
+ return;
+ }
+
+ Port::OnMessage(message);
+}
+
+void TurnPort::OnAllocateRequestTimeout() {
+ OnAllocateError();
+}
+
+void TurnPort::HandleDataIndication(const char* data, size_t size,
+ const rtc::PacketTime& packet_time) {
+ // Read in the message, and process according to RFC5766, Section 10.4.
+ rtc::ByteBuffer buf(data, size);
+ TurnMessage msg;
+ if (!msg.Read(&buf)) {
+ LOG_J(LS_WARNING, this) << "Received invalid TURN data indication";
+ return;
+ }
+
+ // Check mandatory attributes.
+ const StunAddressAttribute* addr_attr =
+ msg.GetAddress(STUN_ATTR_XOR_PEER_ADDRESS);
+ if (!addr_attr) {
+ LOG_J(LS_WARNING, this) << "Missing STUN_ATTR_XOR_PEER_ADDRESS attribute "
+ << "in data indication.";
+ return;
+ }
+
+ const StunByteStringAttribute* data_attr =
+ msg.GetByteString(STUN_ATTR_DATA);
+ if (!data_attr) {
+ LOG_J(LS_WARNING, this) << "Missing STUN_ATTR_DATA attribute in "
+ << "data indication.";
+ return;
+ }
+
+ // Verify that the data came from somewhere we think we have a permission for.
+ rtc::SocketAddress ext_addr(addr_attr->GetAddress());
+ if (!HasPermission(ext_addr.ipaddr())) {
+ LOG_J(LS_WARNING, this) << "Received TURN data indication with invalid "
+ << "peer address, addr="
+ << ext_addr.ToSensitiveString();
+ return;
+ }
+
+ DispatchPacket(data_attr->bytes(), data_attr->length(), ext_addr,
+ PROTO_UDP, packet_time);
+}
+
+void TurnPort::HandleChannelData(int channel_id, const char* data,
+ size_t size,
+ const rtc::PacketTime& packet_time) {
+ // Read the message, and process according to RFC5766, Section 11.6.
+ // 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
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | Channel Number | Length |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | |
+ // / Application Data /
+ // / /
+ // | |
+ // | +-------------------------------+
+ // | |
+ // +-------------------------------+
+
+ // Extract header fields from the message.
+ uint16 len = rtc::GetBE16(data + 2);
+ if (len > size - TURN_CHANNEL_HEADER_SIZE) {
+ LOG_J(LS_WARNING, this) << "Received TURN channel data message with "
+ << "incorrect length, len=" << len;
+ return;
+ }
+ // Allowing messages larger than |len|, as ChannelData can be padded.
+
+ TurnEntry* entry = FindEntry(channel_id);
+ if (!entry) {
+ LOG_J(LS_WARNING, this) << "Received TURN channel data message for invalid "
+ << "channel, channel_id=" << channel_id;
+ return;
+ }
+
+ DispatchPacket(data + TURN_CHANNEL_HEADER_SIZE, len, entry->address(),
+ PROTO_UDP, packet_time);
+}
+
+void TurnPort::DispatchPacket(const char* data, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ ProtocolType proto, const rtc::PacketTime& packet_time) {
+ if (Connection* conn = GetConnection(remote_addr)) {
+ conn->OnReadPacket(data, size, packet_time);
+ } else {
+ Port::OnReadPacket(data, size, remote_addr, proto);
+ }
+}
+
+bool TurnPort::ScheduleRefresh(int lifetime) {
+ // Lifetime is in seconds; we schedule a refresh for one minute less.
+ if (lifetime < 2 * 60) {
+ LOG_J(LS_WARNING, this) << "Received response with lifetime that was "
+ << "too short, lifetime=" << lifetime;
+ return false;
+ }
+
+ SendRequest(new TurnRefreshRequest(this), (lifetime - 60) * 1000);
+ return true;
+}
+
+void TurnPort::SendRequest(StunRequest* req, int delay) {
+ request_manager_.SendDelayed(req, delay);
+}
+
+void TurnPort::AddRequestAuthInfo(StunMessage* msg) {
+ // If we've gotten the necessary data from the server, add it to our request.
+ VERIFY(!hash_.empty());
+ VERIFY(msg->AddAttribute(new StunByteStringAttribute(
+ STUN_ATTR_USERNAME, credentials_.username)));
+ VERIFY(msg->AddAttribute(new StunByteStringAttribute(
+ STUN_ATTR_REALM, realm_)));
+ VERIFY(msg->AddAttribute(new StunByteStringAttribute(
+ STUN_ATTR_NONCE, nonce_)));
+ VERIFY(msg->AddMessageIntegrity(hash()));
+}
+
+int TurnPort::Send(const void* data, size_t len,
+ const rtc::PacketOptions& options) {
+ return socket_->SendTo(data, len, server_address_.address, options);
+}
+
+void TurnPort::UpdateHash() {
+ VERIFY(ComputeStunCredentialHash(credentials_.username, realm_,
+ credentials_.password, &hash_));
+}
+
+bool TurnPort::UpdateNonce(StunMessage* response) {
+ // When stale nonce error received, we should update
+ // hash and store realm and nonce.
+ // Check the mandatory attributes.
+ const StunByteStringAttribute* realm_attr =
+ response->GetByteString(STUN_ATTR_REALM);
+ if (!realm_attr) {
+ LOG(LS_ERROR) << "Missing STUN_ATTR_REALM attribute in "
+ << "stale nonce error response.";
+ return false;
+ }
+ set_realm(realm_attr->GetString());
+
+ const StunByteStringAttribute* nonce_attr =
+ response->GetByteString(STUN_ATTR_NONCE);
+ if (!nonce_attr) {
+ LOG(LS_ERROR) << "Missing STUN_ATTR_NONCE attribute in "
+ << "stale nonce error response.";
+ return false;
+ }
+ set_nonce(nonce_attr->GetString());
+ return true;
+}
+
+static bool MatchesIP(TurnEntry* e, rtc::IPAddress ipaddr) {
+ return e->address().ipaddr() == ipaddr;
+}
+bool TurnPort::HasPermission(const rtc::IPAddress& ipaddr) const {
+ return (std::find_if(entries_.begin(), entries_.end(),
+ std::bind2nd(std::ptr_fun(MatchesIP), ipaddr)) != entries_.end());
+}
+
+static bool MatchesAddress(TurnEntry* e, rtc::SocketAddress addr) {
+ return e->address() == addr;
+}
+TurnEntry* TurnPort::FindEntry(const rtc::SocketAddress& addr) const {
+ EntryList::const_iterator it = std::find_if(entries_.begin(), entries_.end(),
+ std::bind2nd(std::ptr_fun(MatchesAddress), addr));
+ return (it != entries_.end()) ? *it : NULL;
+}
+
+static bool MatchesChannelId(TurnEntry* e, int id) {
+ return e->channel_id() == id;
+}
+TurnEntry* TurnPort::FindEntry(int channel_id) const {
+ EntryList::const_iterator it = std::find_if(entries_.begin(), entries_.end(),
+ std::bind2nd(std::ptr_fun(MatchesChannelId), channel_id));
+ return (it != entries_.end()) ? *it : NULL;
+}
+
+TurnEntry* TurnPort::CreateEntry(const rtc::SocketAddress& addr) {
+ ASSERT(FindEntry(addr) == NULL);
+ TurnEntry* entry = new TurnEntry(this, next_channel_number_++, addr);
+ entries_.push_back(entry);
+ return entry;
+}
+
+void TurnPort::DestroyEntry(const rtc::SocketAddress& addr) {
+ TurnEntry* entry = FindEntry(addr);
+ ASSERT(entry != NULL);
+ entry->SignalDestroyed(entry);
+ entries_.remove(entry);
+ delete entry;
+}
+
+void TurnPort::OnConnectionDestroyed(Connection* conn) {
+ // Destroying TurnEntry for the connection, which is already destroyed.
+ DestroyEntry(conn->remote_candidate().address());
+}
+
+TurnAllocateRequest::TurnAllocateRequest(TurnPort* port)
+ : StunRequest(new TurnMessage()),
+ port_(port) {
+}
+
+void TurnAllocateRequest::Prepare(StunMessage* request) {
+ // Create the request as indicated in RFC 5766, Section 6.1.
+ request->SetType(TURN_ALLOCATE_REQUEST);
+ StunUInt32Attribute* transport_attr = StunAttribute::CreateUInt32(
+ STUN_ATTR_REQUESTED_TRANSPORT);
+ transport_attr->SetValue(IPPROTO_UDP << 24);
+ VERIFY(request->AddAttribute(transport_attr));
+ if (!port_->hash().empty()) {
+ port_->AddRequestAuthInfo(request);
+ }
+}
+
+void TurnAllocateRequest::OnResponse(StunMessage* response) {
+ // Check mandatory attributes as indicated in RFC5766, Section 6.3.
+ const StunAddressAttribute* mapped_attr =
+ response->GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
+ if (!mapped_attr) {
+ LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_XOR_MAPPED_ADDRESS "
+ << "attribute in allocate success response";
+ return;
+ }
+ // Using XOR-Mapped-Address for stun.
+ port_->OnStunAddress(mapped_attr->GetAddress());
+
+ const StunAddressAttribute* relayed_attr =
+ response->GetAddress(STUN_ATTR_XOR_RELAYED_ADDRESS);
+ if (!relayed_attr) {
+ LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_XOR_RELAYED_ADDRESS "
+ << "attribute in allocate success response";
+ return;
+ }
+
+ const StunUInt32Attribute* lifetime_attr =
+ response->GetUInt32(STUN_ATTR_TURN_LIFETIME);
+ if (!lifetime_attr) {
+ LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_TURN_LIFETIME attribute in "
+ << "allocate success response";
+ return;
+ }
+ // Notify the port the allocate succeeded, and schedule a refresh request.
+ port_->OnAllocateSuccess(relayed_attr->GetAddress(),
+ mapped_attr->GetAddress());
+ port_->ScheduleRefresh(lifetime_attr->value());
+}
+
+void TurnAllocateRequest::OnErrorResponse(StunMessage* response) {
+ // Process error response according to RFC5766, Section 6.4.
+ const StunErrorCodeAttribute* error_code = response->GetErrorCode();
+ switch (error_code->code()) {
+ case STUN_ERROR_UNAUTHORIZED: // Unauthrorized.
+ OnAuthChallenge(response, error_code->code());
+ break;
+ case STUN_ERROR_TRY_ALTERNATE:
+ OnTryAlternate(response, error_code->code());
+ break;
+ case STUN_ERROR_ALLOCATION_MISMATCH:
+ // We must handle this error async because trying to delete the socket in
+ // OnErrorResponse will cause a deadlock on the socket.
+ port_->thread()->Post(port_, TurnPort::MSG_ALLOCATE_MISMATCH);
+ break;
+ default:
+ LOG_J(LS_WARNING, port_) << "Allocate response error, code="
+ << error_code->code();
+ port_->OnAllocateError();
+ }
+}
+
+void TurnAllocateRequest::OnTimeout() {
+ LOG_J(LS_WARNING, port_) << "Allocate request timeout";
+ port_->OnAllocateRequestTimeout();
+}
+
+void TurnAllocateRequest::OnAuthChallenge(StunMessage* response, int code) {
+ // If we failed to authenticate even after we sent our credentials, fail hard.
+ if (code == STUN_ERROR_UNAUTHORIZED && !port_->hash().empty()) {
+ LOG_J(LS_WARNING, port_) << "Failed to authenticate with the server "
+ << "after challenge.";
+ port_->OnAllocateError();
+ return;
+ }
+
+ // Check the mandatory attributes.
+ const StunByteStringAttribute* realm_attr =
+ response->GetByteString(STUN_ATTR_REALM);
+ if (!realm_attr) {
+ LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_REALM attribute in "
+ << "allocate unauthorized response.";
+ return;
+ }
+ port_->set_realm(realm_attr->GetString());
+
+ const StunByteStringAttribute* nonce_attr =
+ response->GetByteString(STUN_ATTR_NONCE);
+ if (!nonce_attr) {
+ LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_NONCE attribute in "
+ << "allocate unauthorized response.";
+ return;
+ }
+ port_->set_nonce(nonce_attr->GetString());
+
+ // Send another allocate request, with the received realm and nonce values.
+ port_->SendRequest(new TurnAllocateRequest(port_), 0);
+}
+
+void TurnAllocateRequest::OnTryAlternate(StunMessage* response, int code) {
+ // TODO(guoweis): Currently, we only support UDP redirect
+ if (port_->server_address().proto != PROTO_UDP) {
+ LOG_J(LS_WARNING, port_) << "Receiving 300 Alternate Server on non-UDP "
+ << "allocating request from ["
+ << port_->server_address().address.ToSensitiveString()
+ << "], failed as currently not supported";
+ port_->OnAllocateError();
+ return;
+ }
+
+ // According to RFC 5389 section 11, there are use cases where
+ // authentication of response is not possible, we're not validating
+ // message integrity.
+
+ // Get the alternate server address attribute value.
+ const StunAddressAttribute* alternate_server_attr =
+ response->GetAddress(STUN_ATTR_ALTERNATE_SERVER);
+ if (!alternate_server_attr) {
+ LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_ALTERNATE_SERVER "
+ << "attribute in try alternate error response";
+ port_->OnAllocateError();
+ return;
+ }
+ if (!port_->SetAlternateServer(alternate_server_attr->GetAddress())) {
+ port_->OnAllocateError();
+ return;
+ }
+
+ // Check the attributes.
+ const StunByteStringAttribute* realm_attr =
+ response->GetByteString(STUN_ATTR_REALM);
+ if (realm_attr) {
+ LOG_J(LS_INFO, port_) << "Applying STUN_ATTR_REALM attribute in "
+ << "try alternate error response.";
+ port_->set_realm(realm_attr->GetString());
+ }
+
+ const StunByteStringAttribute* nonce_attr =
+ response->GetByteString(STUN_ATTR_NONCE);
+ if (nonce_attr) {
+ LOG_J(LS_INFO, port_) << "Applying STUN_ATTR_NONCE attribute in "
+ << "try alternate error response.";
+ port_->set_nonce(nonce_attr->GetString());
+ }
+
+ // Send another allocate request to alternate server,
+ // with the received realm and nonce values.
+ port_->SendRequest(new TurnAllocateRequest(port_), 0);
+}
+
+TurnRefreshRequest::TurnRefreshRequest(TurnPort* port)
+ : StunRequest(new TurnMessage()),
+ port_(port) {
+}
+
+void TurnRefreshRequest::Prepare(StunMessage* request) {
+ // Create the request as indicated in RFC 5766, Section 7.1.
+ // No attributes need to be included.
+ request->SetType(TURN_REFRESH_REQUEST);
+ port_->AddRequestAuthInfo(request);
+}
+
+void TurnRefreshRequest::OnResponse(StunMessage* response) {
+ // Check mandatory attributes as indicated in RFC5766, Section 7.3.
+ const StunUInt32Attribute* lifetime_attr =
+ response->GetUInt32(STUN_ATTR_TURN_LIFETIME);
+ if (!lifetime_attr) {
+ LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_TURN_LIFETIME attribute in "
+ << "refresh success response.";
+ return;
+ }
+
+ // Schedule a refresh based on the returned lifetime value.
+ port_->ScheduleRefresh(lifetime_attr->value());
+}
+
+void TurnRefreshRequest::OnErrorResponse(StunMessage* response) {
+ const StunErrorCodeAttribute* error_code = response->GetErrorCode();
+ LOG_J(LS_WARNING, port_) << "Refresh response error, code="
+ << error_code->code();
+
+ if (error_code->code() == STUN_ERROR_STALE_NONCE) {
+ if (port_->UpdateNonce(response)) {
+ // Send RefreshRequest immediately.
+ port_->SendRequest(new TurnRefreshRequest(port_), 0);
+ }
+ }
+}
+
+void TurnRefreshRequest::OnTimeout() {
+}
+
+TurnCreatePermissionRequest::TurnCreatePermissionRequest(
+ TurnPort* port, TurnEntry* entry,
+ const rtc::SocketAddress& ext_addr)
+ : StunRequest(new TurnMessage()),
+ port_(port),
+ entry_(entry),
+ ext_addr_(ext_addr) {
+ entry_->SignalDestroyed.connect(
+ this, &TurnCreatePermissionRequest::OnEntryDestroyed);
+}
+
+void TurnCreatePermissionRequest::Prepare(StunMessage* request) {
+ // Create the request as indicated in RFC5766, Section 9.1.
+ request->SetType(TURN_CREATE_PERMISSION_REQUEST);
+ VERIFY(request->AddAttribute(new StunXorAddressAttribute(
+ STUN_ATTR_XOR_PEER_ADDRESS, ext_addr_)));
+ port_->AddRequestAuthInfo(request);
+}
+
+void TurnCreatePermissionRequest::OnResponse(StunMessage* response) {
+ if (entry_) {
+ entry_->OnCreatePermissionSuccess();
+ }
+}
+
+void TurnCreatePermissionRequest::OnErrorResponse(StunMessage* response) {
+ if (entry_) {
+ const StunErrorCodeAttribute* error_code = response->GetErrorCode();
+ entry_->OnCreatePermissionError(response, error_code->code());
+ }
+}
+
+void TurnCreatePermissionRequest::OnTimeout() {
+ LOG_J(LS_WARNING, port_) << "Create permission timeout";
+}
+
+void TurnCreatePermissionRequest::OnEntryDestroyed(TurnEntry* entry) {
+ ASSERT(entry_ == entry);
+ entry_ = NULL;
+}
+
+TurnChannelBindRequest::TurnChannelBindRequest(
+ TurnPort* port, TurnEntry* entry,
+ int channel_id, const rtc::SocketAddress& ext_addr)
+ : StunRequest(new TurnMessage()),
+ port_(port),
+ entry_(entry),
+ channel_id_(channel_id),
+ ext_addr_(ext_addr) {
+ entry_->SignalDestroyed.connect(
+ this, &TurnChannelBindRequest::OnEntryDestroyed);
+}
+
+void TurnChannelBindRequest::Prepare(StunMessage* request) {
+ // Create the request as indicated in RFC5766, Section 11.1.
+ request->SetType(TURN_CHANNEL_BIND_REQUEST);
+ VERIFY(request->AddAttribute(new StunUInt32Attribute(
+ STUN_ATTR_CHANNEL_NUMBER, channel_id_ << 16)));
+ VERIFY(request->AddAttribute(new StunXorAddressAttribute(
+ STUN_ATTR_XOR_PEER_ADDRESS, ext_addr_)));
+ port_->AddRequestAuthInfo(request);
+}
+
+void TurnChannelBindRequest::OnResponse(StunMessage* response) {
+ if (entry_) {
+ entry_->OnChannelBindSuccess();
+ // Refresh the channel binding just under the permission timeout
+ // threshold. The channel binding has a longer lifetime, but
+ // this is the easiest way to keep both the channel and the
+ // permission from expiring.
+ entry_->SendChannelBindRequest(TURN_PERMISSION_TIMEOUT - 60 * 1000);
+ }
+}
+
+void TurnChannelBindRequest::OnErrorResponse(StunMessage* response) {
+ if (entry_) {
+ const StunErrorCodeAttribute* error_code = response->GetErrorCode();
+ entry_->OnChannelBindError(response, error_code->code());
+ }
+}
+
+void TurnChannelBindRequest::OnTimeout() {
+ LOG_J(LS_WARNING, port_) << "Channel bind timeout";
+}
+
+void TurnChannelBindRequest::OnEntryDestroyed(TurnEntry* entry) {
+ ASSERT(entry_ == entry);
+ entry_ = NULL;
+}
+
+TurnEntry::TurnEntry(TurnPort* port, int channel_id,
+ const rtc::SocketAddress& ext_addr)
+ : port_(port),
+ channel_id_(channel_id),
+ ext_addr_(ext_addr),
+ state_(STATE_UNBOUND) {
+ // Creating permission for |ext_addr_|.
+ SendCreatePermissionRequest();
+}
+
+void TurnEntry::SendCreatePermissionRequest() {
+ port_->SendRequest(new TurnCreatePermissionRequest(
+ port_, this, ext_addr_), 0);
+}
+
+void TurnEntry::SendChannelBindRequest(int delay) {
+ port_->SendRequest(new TurnChannelBindRequest(
+ port_, this, channel_id_, ext_addr_), delay);
+}
+
+int TurnEntry::Send(const void* data, size_t size, bool payload,
+ const rtc::PacketOptions& options) {
+ rtc::ByteBuffer buf;
+ if (state_ != STATE_BOUND) {
+ // If we haven't bound the channel yet, we have to use a Send Indication.
+ TurnMessage msg;
+ msg.SetType(TURN_SEND_INDICATION);
+ msg.SetTransactionID(
+ rtc::CreateRandomString(kStunTransactionIdLength));
+ VERIFY(msg.AddAttribute(new StunXorAddressAttribute(
+ STUN_ATTR_XOR_PEER_ADDRESS, ext_addr_)));
+ VERIFY(msg.AddAttribute(new StunByteStringAttribute(
+ STUN_ATTR_DATA, data, size)));
+ VERIFY(msg.Write(&buf));
+
+ // If we're sending real data, request a channel bind that we can use later.
+ if (state_ == STATE_UNBOUND && payload) {
+ SendChannelBindRequest(0);
+ state_ = STATE_BINDING;
+ }
+ } else {
+ // If the channel is bound, we can send the data as a Channel Message.
+ buf.WriteUInt16(channel_id_);
+ buf.WriteUInt16(static_cast<uint16>(size));
+ buf.WriteBytes(reinterpret_cast<const char*>(data), size);
+ }
+ return port_->Send(buf.Data(), buf.Length(), options);
+}
+
+void TurnEntry::OnCreatePermissionSuccess() {
+ LOG_J(LS_INFO, port_) << "Create permission for "
+ << ext_addr_.ToSensitiveString()
+ << " succeeded";
+ // For success result code will be 0.
+ port_->SignalCreatePermissionResult(port_, ext_addr_, 0);
+}
+
+void TurnEntry::OnCreatePermissionError(StunMessage* response, int code) {
+ LOG_J(LS_WARNING, port_) << "Create permission for "
+ << ext_addr_.ToSensitiveString()
+ << " failed, code=" << code;
+ if (code == STUN_ERROR_STALE_NONCE) {
+ if (port_->UpdateNonce(response)) {
+ SendCreatePermissionRequest();
+ }
+ } else {
+ // Send signal with error code.
+ port_->SignalCreatePermissionResult(port_, ext_addr_, code);
+ }
+}
+
+void TurnEntry::OnChannelBindSuccess() {
+ LOG_J(LS_INFO, port_) << "Channel bind for " << ext_addr_.ToSensitiveString()
+ << " succeeded";
+ ASSERT(state_ == STATE_BINDING || state_ == STATE_BOUND);
+ state_ = STATE_BOUND;
+}
+
+void TurnEntry::OnChannelBindError(StunMessage* response, int code) {
+ // TODO(mallinath) - Implement handling of error response for channel
+ // bind request as per http://tools.ietf.org/html/rfc5766#section-11.3
+ LOG_J(LS_WARNING, port_) << "Channel bind for "
+ << ext_addr_.ToSensitiveString()
+ << " failed, code=" << code;
+ if (code == STUN_ERROR_STALE_NONCE) {
+ if (port_->UpdateNonce(response)) {
+ // Send channel bind request with fresh nonce.
+ SendChannelBindRequest(0);
+ }
+ }
+}
+
+} // namespace cricket
diff --git a/p2p/base/turnport.h b/p2p/base/turnport.h
new file mode 100644
index 00000000..17fad176
--- /dev/null
+++ b/p2p/base/turnport.h
@@ -0,0 +1,237 @@
+/*
+ * 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 WEBRTC_P2P_BASE_TURNPORT_H_
+#define WEBRTC_P2P_BASE_TURNPORT_H_
+
+#include <stdio.h>
+#include <list>
+#include <set>
+#include <string>
+
+#include "webrtc/p2p/base/port.h"
+#include "webrtc/p2p/client/basicportallocator.h"
+#include "webrtc/base/asyncpacketsocket.h"
+
+namespace rtc {
+class AsyncResolver;
+class SignalThread;
+}
+
+namespace cricket {
+
+extern const char TURN_PORT_TYPE[];
+class TurnAllocateRequest;
+class TurnEntry;
+
+class TurnPort : public Port {
+ public:
+ static TurnPort* Create(rtc::Thread* thread,
+ rtc::PacketSocketFactory* factory,
+ rtc::Network* network,
+ rtc::AsyncPacketSocket* socket,
+ const std::string& username, // ice username.
+ const std::string& password, // ice password.
+ const ProtocolAddress& server_address,
+ const RelayCredentials& credentials,
+ int server_priority) {
+ return new TurnPort(thread, factory, network, socket,
+ username, password, server_address,
+ credentials, server_priority);
+ }
+
+ static TurnPort* Create(rtc::Thread* thread,
+ rtc::PacketSocketFactory* factory,
+ rtc::Network* network,
+ const rtc::IPAddress& ip,
+ int min_port, int max_port,
+ const std::string& username, // ice username.
+ const std::string& password, // ice password.
+ const ProtocolAddress& server_address,
+ const RelayCredentials& credentials,
+ int server_priority) {
+ return new TurnPort(thread, factory, network, ip, min_port, max_port,
+ username, password, server_address, credentials,
+ server_priority);
+ }
+
+ virtual ~TurnPort();
+
+ const ProtocolAddress& server_address() const { return server_address_; }
+
+ bool connected() const { return connected_; }
+ const RelayCredentials& credentials() const { return credentials_; }
+
+ virtual void PrepareAddress();
+ virtual Connection* CreateConnection(
+ const Candidate& c, PortInterface::CandidateOrigin origin);
+ virtual int SendTo(const void* data, size_t size,
+ const rtc::SocketAddress& addr,
+ const rtc::PacketOptions& options,
+ bool payload);
+ virtual int SetOption(rtc::Socket::Option opt, int value);
+ virtual int GetOption(rtc::Socket::Option opt, int* value);
+ virtual int GetError();
+
+ virtual bool HandleIncomingPacket(
+ rtc::AsyncPacketSocket* socket, const char* data, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time) {
+ OnReadPacket(socket, data, size, remote_addr, packet_time);
+ return true;
+ }
+ virtual void OnReadPacket(rtc::AsyncPacketSocket* socket,
+ const char* data, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time);
+
+ virtual void OnReadyToSend(rtc::AsyncPacketSocket* socket);
+
+ void OnSocketConnect(rtc::AsyncPacketSocket* socket);
+ void OnSocketClose(rtc::AsyncPacketSocket* socket, int error);
+
+
+ const std::string& hash() const { return hash_; }
+ const std::string& nonce() const { return nonce_; }
+
+ int error() const { return error_; }
+
+ void OnAllocateMismatch();
+
+ rtc::AsyncPacketSocket* socket() const {
+ return socket_;
+ }
+
+ // Signal with resolved server address.
+ // Parameters are port, server address and resolved server address.
+ // This signal will be sent only if server address is resolved successfully.
+ sigslot::signal3<TurnPort*,
+ const rtc::SocketAddress&,
+ const rtc::SocketAddress&> SignalResolvedServerAddress;
+
+ // This signal is only for testing purpose.
+ sigslot::signal3<TurnPort*, const rtc::SocketAddress&, int>
+ SignalCreatePermissionResult;
+
+ protected:
+ TurnPort(rtc::Thread* thread,
+ rtc::PacketSocketFactory* factory,
+ rtc::Network* network,
+ rtc::AsyncPacketSocket* socket,
+ const std::string& username,
+ const std::string& password,
+ const ProtocolAddress& server_address,
+ const RelayCredentials& credentials,
+ int server_priority);
+
+ TurnPort(rtc::Thread* thread,
+ rtc::PacketSocketFactory* factory,
+ rtc::Network* network,
+ const rtc::IPAddress& ip,
+ int min_port, int max_port,
+ const std::string& username,
+ const std::string& password,
+ const ProtocolAddress& server_address,
+ const RelayCredentials& credentials,
+ int server_priority);
+
+ private:
+ enum {
+ MSG_ERROR = MSG_FIRST_AVAILABLE,
+ MSG_ALLOCATE_MISMATCH
+ };
+
+ typedef std::list<TurnEntry*> EntryList;
+ typedef std::map<rtc::Socket::Option, int> SocketOptionsMap;
+ typedef std::set<rtc::SocketAddress> AttemptedServerSet;
+
+ virtual void OnMessage(rtc::Message* pmsg);
+
+ bool CreateTurnClientSocket();
+
+ void set_nonce(const std::string& nonce) { nonce_ = nonce; }
+ void set_realm(const std::string& realm) {
+ if (realm != realm_) {
+ realm_ = realm;
+ UpdateHash();
+ }
+ }
+
+ bool SetAlternateServer(const rtc::SocketAddress& address);
+ void ResolveTurnAddress(const rtc::SocketAddress& address);
+ void OnResolveResult(rtc::AsyncResolverInterface* resolver);
+
+ void AddRequestAuthInfo(StunMessage* msg);
+ void OnSendStunPacket(const void* data, size_t size, StunRequest* request);
+ // Stun address from allocate success response.
+ // Currently used only for testing.
+ void OnStunAddress(const rtc::SocketAddress& address);
+ void OnAllocateSuccess(const rtc::SocketAddress& address,
+ const rtc::SocketAddress& stun_address);
+ void OnAllocateError();
+ void OnAllocateRequestTimeout();
+
+ void HandleDataIndication(const char* data, size_t size,
+ const rtc::PacketTime& packet_time);
+ void HandleChannelData(int channel_id, const char* data, size_t size,
+ const rtc::PacketTime& packet_time);
+ void DispatchPacket(const char* data, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ ProtocolType proto, const rtc::PacketTime& packet_time);
+
+ bool ScheduleRefresh(int lifetime);
+ void SendRequest(StunRequest* request, int delay);
+ int Send(const void* data, size_t size,
+ const rtc::PacketOptions& options);
+ void UpdateHash();
+ bool UpdateNonce(StunMessage* response);
+
+ bool HasPermission(const rtc::IPAddress& ipaddr) const;
+ TurnEntry* FindEntry(const rtc::SocketAddress& address) const;
+ TurnEntry* FindEntry(int channel_id) const;
+ TurnEntry* CreateEntry(const rtc::SocketAddress& address);
+ void DestroyEntry(const rtc::SocketAddress& address);
+ void OnConnectionDestroyed(Connection* conn);
+
+ ProtocolAddress server_address_;
+ RelayCredentials credentials_;
+ AttemptedServerSet attempted_server_addresses_;
+
+ rtc::AsyncPacketSocket* socket_;
+ SocketOptionsMap socket_options_;
+ rtc::AsyncResolverInterface* resolver_;
+ int error_;
+
+ StunRequestManager request_manager_;
+ std::string realm_; // From 401/438 response message.
+ std::string nonce_; // From 401/438 response message.
+ std::string hash_; // Digest of username:realm:password
+
+ int next_channel_number_;
+ EntryList entries_;
+
+ bool connected_;
+ // By default the value will be set to 0. This value will be used in
+ // calculating the candidate priority.
+ int server_priority_;
+
+ // The number of retries made due to allocate mismatch error.
+ size_t allocate_mismatch_retries_;
+
+ friend class TurnEntry;
+ friend class TurnAllocateRequest;
+ friend class TurnRefreshRequest;
+ friend class TurnCreatePermissionRequest;
+ friend class TurnChannelBindRequest;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_TURNPORT_H_
diff --git a/p2p/base/turnport_unittest.cc b/p2p/base/turnport_unittest.cc
new file mode 100644
index 00000000..4b524d5b
--- /dev/null
+++ b/p2p/base/turnport_unittest.cc
@@ -0,0 +1,668 @@
+/*
+ * 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.
+ */
+#if defined(WEBRTC_POSIX)
+#include <dirent.h>
+#endif
+
+#include "webrtc/p2p/base/basicpacketsocketfactory.h"
+#include "webrtc/p2p/base/constants.h"
+#include "webrtc/p2p/base/tcpport.h"
+#include "webrtc/p2p/base/testturnserver.h"
+#include "webrtc/p2p/base/turnport.h"
+#include "webrtc/p2p/base/udpport.h"
+#include "webrtc/base/asynctcpsocket.h"
+#include "webrtc/base/buffer.h"
+#include "webrtc/base/dscp.h"
+#include "webrtc/base/firewallsocketserver.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/physicalsocketserver.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/socketaddress.h"
+#include "webrtc/base/ssladapter.h"
+#include "webrtc/base/thread.h"
+#include "webrtc/base/virtualsocketserver.h"
+
+using rtc::SocketAddress;
+using cricket::Connection;
+using cricket::Port;
+using cricket::PortInterface;
+using cricket::TurnPort;
+using cricket::UDPPort;
+
+static const SocketAddress kLocalAddr1("11.11.11.11", 0);
+static const SocketAddress kLocalAddr2("22.22.22.22", 0);
+static const SocketAddress kLocalIPv6Addr(
+ "2401:fa00:4:1000:be30:5bff:fee5:c3", 0);
+static const SocketAddress kTurnUdpIntAddr("99.99.99.3",
+ cricket::TURN_SERVER_PORT);
+static const SocketAddress kTurnTcpIntAddr("99.99.99.4",
+ cricket::TURN_SERVER_PORT);
+static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
+static const SocketAddress kTurnAlternateUdpIntAddr(
+ "99.99.99.6", cricket::TURN_SERVER_PORT);
+static const SocketAddress kTurnUdpIPv6IntAddr(
+ "2400:4030:1:2c00:be30:abcd:efab:cdef", cricket::TURN_SERVER_PORT);
+static const SocketAddress kTurnUdpIPv6ExtAddr(
+ "2620:0:1000:1b03:2e41:38ff:fea6:f2a4", 0);
+
+static const char kIceUfrag1[] = "TESTICEUFRAG0001";
+static const char kIceUfrag2[] = "TESTICEUFRAG0002";
+static const char kIcePwd1[] = "TESTICEPWD00000000000001";
+static const char kIcePwd2[] = "TESTICEPWD00000000000002";
+static const char kTurnUsername[] = "test";
+static const char kTurnPassword[] = "test";
+static const unsigned int kTimeout = 1000;
+
+static const cricket::ProtocolAddress kTurnUdpProtoAddr(
+ kTurnUdpIntAddr, cricket::PROTO_UDP);
+static const cricket::ProtocolAddress kTurnTcpProtoAddr(
+ kTurnTcpIntAddr, cricket::PROTO_TCP);
+static const cricket::ProtocolAddress kTurnUdpIPv6ProtoAddr(
+ kTurnUdpIPv6IntAddr, cricket::PROTO_UDP);
+
+static const unsigned int MSG_TESTFINISH = 0;
+
+#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
+static int GetFDCount() {
+ struct dirent *dp;
+ int fd_count = 0;
+ DIR *dir = opendir("/proc/self/fd/");
+ while ((dp = readdir(dir)) != NULL) {
+ if (dp->d_name[0] == '.')
+ continue;
+ ++fd_count;
+ }
+ closedir(dir);
+ return fd_count;
+}
+#endif
+
+class TurnPortTest : public testing::Test,
+ public sigslot::has_slots<>,
+ public rtc::MessageHandler {
+ public:
+ TurnPortTest()
+ : main_(rtc::Thread::Current()),
+ pss_(new rtc::PhysicalSocketServer),
+ ss_(new rtc::VirtualSocketServer(pss_.get())),
+ ss_scope_(ss_.get()),
+ network_("unittest", "unittest", rtc::IPAddress(INADDR_ANY), 32),
+ socket_factory_(rtc::Thread::Current()),
+ turn_server_(main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
+ turn_ready_(false),
+ turn_error_(false),
+ turn_unknown_address_(false),
+ turn_create_permission_success_(false),
+ udp_ready_(false),
+ test_finish_(false) {
+ network_.AddIP(rtc::IPAddress(INADDR_ANY));
+ }
+
+ virtual void OnMessage(rtc::Message* msg) {
+ ASSERT(msg->message_id == MSG_TESTFINISH);
+ if (msg->message_id == MSG_TESTFINISH)
+ test_finish_ = true;
+ }
+
+ void OnTurnPortComplete(Port* port) {
+ turn_ready_ = true;
+ }
+ void OnTurnPortError(Port* port) {
+ turn_error_ = true;
+ }
+ void OnTurnUnknownAddress(PortInterface* port, const SocketAddress& addr,
+ cricket::ProtocolType proto,
+ cricket::IceMessage* msg, const std::string& rf,
+ bool /*port_muxed*/) {
+ turn_unknown_address_ = true;
+ }
+ void OnTurnCreatePermissionResult(TurnPort* port, const SocketAddress& addr,
+ int code) {
+ // Ignoring the address.
+ if (code == 0) {
+ turn_create_permission_success_ = true;
+ }
+ }
+ void OnTurnReadPacket(Connection* conn, const char* data, size_t size,
+ const rtc::PacketTime& packet_time) {
+ turn_packets_.push_back(rtc::Buffer(data, size));
+ }
+ void OnUdpPortComplete(Port* port) {
+ udp_ready_ = true;
+ }
+ void OnUdpReadPacket(Connection* conn, const char* data, size_t size,
+ const rtc::PacketTime& packet_time) {
+ udp_packets_.push_back(rtc::Buffer(data, size));
+ }
+ void OnSocketReadPacket(rtc::AsyncPacketSocket* socket,
+ const char* data, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time) {
+ turn_port_->HandleIncomingPacket(socket, data, size, remote_addr,
+ packet_time);
+ }
+ rtc::AsyncSocket* CreateServerSocket(const SocketAddress addr) {
+ rtc::AsyncSocket* socket = ss_->CreateAsyncSocket(SOCK_STREAM);
+ EXPECT_GE(socket->Bind(addr), 0);
+ EXPECT_GE(socket->Listen(5), 0);
+ return socket;
+ }
+
+ void CreateTurnPort(const std::string& username,
+ const std::string& password,
+ const cricket::ProtocolAddress& server_address) {
+ CreateTurnPort(kLocalAddr1, username, password, server_address);
+ }
+ void CreateTurnPort(const rtc::SocketAddress& local_address,
+ const std::string& username,
+ const std::string& password,
+ const cricket::ProtocolAddress& server_address) {
+ cricket::RelayCredentials credentials(username, password);
+ turn_port_.reset(TurnPort::Create(main_, &socket_factory_, &network_,
+ local_address.ipaddr(), 0, 0,
+ kIceUfrag1, kIcePwd1,
+ server_address, credentials, 0));
+ // Set ICE protocol type to ICEPROTO_RFC5245, as port by default will be
+ // in Hybrid mode. Protocol type is necessary to send correct type STUN ping
+ // messages.
+ // This TURN port will be the controlling.
+ turn_port_->SetIceProtocolType(cricket::ICEPROTO_RFC5245);
+ turn_port_->SetIceRole(cricket::ICEROLE_CONTROLLING);
+ ConnectSignals();
+ }
+
+ void CreateSharedTurnPort(const std::string& username,
+ const std::string& password,
+ const cricket::ProtocolAddress& server_address) {
+ ASSERT(server_address.proto == cricket::PROTO_UDP);
+
+ if (!socket_) {
+ socket_.reset(socket_factory_.CreateUdpSocket(
+ rtc::SocketAddress(kLocalAddr1.ipaddr(), 0), 0, 0));
+ ASSERT_TRUE(socket_ != NULL);
+ socket_->SignalReadPacket.connect(
+ this, &TurnPortTest::OnSocketReadPacket);
+ }
+
+ cricket::RelayCredentials credentials(username, password);
+ turn_port_.reset(cricket::TurnPort::Create(
+ main_, &socket_factory_, &network_, socket_.get(),
+ kIceUfrag1, kIcePwd1, server_address, credentials, 0));
+ // Set ICE protocol type to ICEPROTO_RFC5245, as port by default will be
+ // in Hybrid mode. Protocol type is necessary to send correct type STUN ping
+ // messages.
+ // This TURN port will be the controlling.
+ turn_port_->SetIceProtocolType(cricket::ICEPROTO_RFC5245);
+ turn_port_->SetIceRole(cricket::ICEROLE_CONTROLLING);
+ ConnectSignals();
+ }
+
+ void ConnectSignals() {
+ turn_port_->SignalPortComplete.connect(this,
+ &TurnPortTest::OnTurnPortComplete);
+ turn_port_->SignalPortError.connect(this,
+ &TurnPortTest::OnTurnPortError);
+ turn_port_->SignalUnknownAddress.connect(this,
+ &TurnPortTest::OnTurnUnknownAddress);
+ turn_port_->SignalCreatePermissionResult.connect(this,
+ &TurnPortTest::OnTurnCreatePermissionResult);
+ }
+ void CreateUdpPort() {
+ udp_port_.reset(UDPPort::Create(main_, &socket_factory_, &network_,
+ kLocalAddr2.ipaddr(), 0, 0,
+ kIceUfrag2, kIcePwd2));
+ // Set protocol type to RFC5245, as turn port is also in same mode.
+ // UDP port will be controlled.
+ udp_port_->SetIceProtocolType(cricket::ICEPROTO_RFC5245);
+ udp_port_->SetIceRole(cricket::ICEROLE_CONTROLLED);
+ udp_port_->SignalPortComplete.connect(
+ this, &TurnPortTest::OnUdpPortComplete);
+ }
+
+ void TestTurnConnection() {
+ // Create ports and prepare addresses.
+ ASSERT_TRUE(turn_port_ != NULL);
+ turn_port_->PrepareAddress();
+ ASSERT_TRUE_WAIT(turn_ready_, kTimeout);
+ CreateUdpPort();
+ udp_port_->PrepareAddress();
+ ASSERT_TRUE_WAIT(udp_ready_, kTimeout);
+
+ // Send ping from UDP to TURN.
+ Connection* conn1 = udp_port_->CreateConnection(
+ turn_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
+ ASSERT_TRUE(conn1 != NULL);
+ conn1->Ping(0);
+ WAIT(!turn_unknown_address_, kTimeout);
+ EXPECT_FALSE(turn_unknown_address_);
+ EXPECT_EQ(Connection::STATE_READ_INIT, conn1->read_state());
+ EXPECT_EQ(Connection::STATE_WRITE_INIT, conn1->write_state());
+
+ // Send ping from TURN to UDP.
+ Connection* conn2 = turn_port_->CreateConnection(
+ udp_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
+ ASSERT_TRUE(conn2 != NULL);
+ ASSERT_TRUE_WAIT(turn_create_permission_success_, kTimeout);
+ conn2->Ping(0);
+
+ EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, conn2->write_state(), kTimeout);
+ EXPECT_EQ(Connection::STATE_READABLE, conn1->read_state());
+ EXPECT_EQ(Connection::STATE_READ_INIT, conn2->read_state());
+ EXPECT_EQ(Connection::STATE_WRITE_INIT, conn1->write_state());
+
+ // Send another ping from UDP to TURN.
+ conn1->Ping(0);
+ EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, conn1->write_state(), kTimeout);
+ EXPECT_EQ(Connection::STATE_READABLE, conn2->read_state());
+ }
+
+ void TestTurnSendData() {
+ turn_port_->PrepareAddress();
+ EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
+ CreateUdpPort();
+ udp_port_->PrepareAddress();
+ EXPECT_TRUE_WAIT(udp_ready_, kTimeout);
+ // Create connections and send pings.
+ Connection* conn1 = turn_port_->CreateConnection(
+ udp_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
+ Connection* conn2 = udp_port_->CreateConnection(
+ turn_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
+ ASSERT_TRUE(conn1 != NULL);
+ ASSERT_TRUE(conn2 != NULL);
+ conn1->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
+ &TurnPortTest::OnTurnReadPacket);
+ conn2->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
+ &TurnPortTest::OnUdpReadPacket);
+ conn1->Ping(0);
+ EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, conn1->write_state(), kTimeout);
+ conn2->Ping(0);
+ EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, conn2->write_state(), kTimeout);
+
+ // Send some data.
+ size_t num_packets = 256;
+ for (size_t i = 0; i < num_packets; ++i) {
+ unsigned char buf[256] = { 0 };
+ for (size_t j = 0; j < i + 1; ++j) {
+ buf[j] = 0xFF - static_cast<unsigned char>(j);
+ }
+ conn1->Send(buf, i + 1, options);
+ conn2->Send(buf, i + 1, options);
+ main_->ProcessMessages(0);
+ }
+
+ // Check the data.
+ ASSERT_EQ_WAIT(num_packets, turn_packets_.size(), kTimeout);
+ ASSERT_EQ_WAIT(num_packets, udp_packets_.size(), kTimeout);
+ for (size_t i = 0; i < num_packets; ++i) {
+ EXPECT_EQ(i + 1, turn_packets_[i].length());
+ EXPECT_EQ(i + 1, udp_packets_[i].length());
+ EXPECT_EQ(turn_packets_[i], udp_packets_[i]);
+ }
+ }
+
+ protected:
+ rtc::Thread* main_;
+ rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
+ rtc::scoped_ptr<rtc::VirtualSocketServer> ss_;
+ rtc::SocketServerScope ss_scope_;
+ rtc::Network network_;
+ rtc::BasicPacketSocketFactory socket_factory_;
+ rtc::scoped_ptr<rtc::AsyncPacketSocket> socket_;
+ cricket::TestTurnServer turn_server_;
+ rtc::scoped_ptr<TurnPort> turn_port_;
+ rtc::scoped_ptr<UDPPort> udp_port_;
+ bool turn_ready_;
+ bool turn_error_;
+ bool turn_unknown_address_;
+ bool turn_create_permission_success_;
+ bool udp_ready_;
+ bool test_finish_;
+ std::vector<rtc::Buffer> turn_packets_;
+ std::vector<rtc::Buffer> udp_packets_;
+ rtc::PacketOptions options;
+};
+
+// Do a normal TURN allocation.
+TEST_F(TurnPortTest, TestTurnAllocate) {
+ CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
+ EXPECT_EQ(0, turn_port_->SetOption(rtc::Socket::OPT_SNDBUF, 10*1024));
+ turn_port_->PrepareAddress();
+ EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
+ ASSERT_EQ(1U, turn_port_->Candidates().size());
+ EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
+ turn_port_->Candidates()[0].address().ipaddr());
+ EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
+}
+
+// Testing a normal UDP allocation using TCP connection.
+TEST_F(TurnPortTest, TestTurnTcpAllocate) {
+ turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
+ CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
+ EXPECT_EQ(0, turn_port_->SetOption(rtc::Socket::OPT_SNDBUF, 10*1024));
+ turn_port_->PrepareAddress();
+ EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
+ ASSERT_EQ(1U, turn_port_->Candidates().size());
+ EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
+ turn_port_->Candidates()[0].address().ipaddr());
+ EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
+}
+
+// Testing turn port will attempt to create TCP socket on address resolution
+// failure.
+TEST_F(TurnPortTest, DISABLED_TestTurnTcpOnAddressResolveFailure) {
+ turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
+ CreateTurnPort(kTurnUsername, kTurnPassword, cricket::ProtocolAddress(
+ rtc::SocketAddress("www.webrtc-blah-blah.com", 3478),
+ cricket::PROTO_TCP));
+ turn_port_->PrepareAddress();
+ EXPECT_TRUE_WAIT(turn_error_, kTimeout);
+ // As VSS doesn't provide a DNS resolution, name resolve will fail. TurnPort
+ // will proceed in creating a TCP socket which will fail as there is no
+ // server on the above domain and error will be set to SOCKET_ERROR.
+ EXPECT_EQ(SOCKET_ERROR, turn_port_->error());
+}
+
+// In case of UDP on address resolve failure, TurnPort will not create socket
+// and return allocate failure.
+TEST_F(TurnPortTest, DISABLED_TestTurnUdpOnAdressResolveFailure) {
+ CreateTurnPort(kTurnUsername, kTurnPassword, cricket::ProtocolAddress(
+ rtc::SocketAddress("www.webrtc-blah-blah.com", 3478),
+ cricket::PROTO_UDP));
+ turn_port_->PrepareAddress();
+ EXPECT_TRUE_WAIT(turn_error_, kTimeout);
+ // Error from turn port will not be socket error.
+ EXPECT_NE(SOCKET_ERROR, turn_port_->error());
+}
+
+// Try to do a TURN allocation with an invalid password.
+TEST_F(TurnPortTest, TestTurnAllocateBadPassword) {
+ CreateTurnPort(kTurnUsername, "bad", kTurnUdpProtoAddr);
+ turn_port_->PrepareAddress();
+ EXPECT_TRUE_WAIT(turn_error_, kTimeout);
+ ASSERT_EQ(0U, turn_port_->Candidates().size());
+}
+
+// Tests that a new local address is created after
+// STUN_ERROR_ALLOCATION_MISMATCH.
+TEST_F(TurnPortTest, TestTurnAllocateMismatch) {
+ // Do a normal allocation first.
+ CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
+ turn_port_->PrepareAddress();
+ EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
+ rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
+
+ // Forces the socket server to assign the same port.
+ ss_->SetNextPortForTesting(first_addr.port());
+
+ turn_ready_ = false;
+ CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
+ turn_port_->PrepareAddress();
+
+ // Verifies that the new port has the same address.
+ EXPECT_EQ(first_addr, turn_port_->socket()->GetLocalAddress());
+
+ EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
+
+ // Verifies that the new port has a different address now.
+ EXPECT_NE(first_addr, turn_port_->socket()->GetLocalAddress());
+}
+
+// Tests that a shared-socket-TurnPort creates its own socket after
+// STUN_ERROR_ALLOCATION_MISMATCH.
+TEST_F(TurnPortTest, TestSharedSocketAllocateMismatch) {
+ // Do a normal allocation first.
+ CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
+ turn_port_->PrepareAddress();
+ EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
+ rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
+
+ turn_ready_ = false;
+ CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
+
+ // Verifies that the new port has the same address.
+ EXPECT_EQ(first_addr, turn_port_->socket()->GetLocalAddress());
+ EXPECT_TRUE(turn_port_->SharedSocket());
+
+ turn_port_->PrepareAddress();
+ EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
+
+ // Verifies that the new port has a different address now.
+ EXPECT_NE(first_addr, turn_port_->socket()->GetLocalAddress());
+ EXPECT_FALSE(turn_port_->SharedSocket());
+}
+
+TEST_F(TurnPortTest, TestTurnTcpAllocateMismatch) {
+ turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
+ CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
+
+ // Do a normal allocation first.
+ turn_port_->PrepareAddress();
+ EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
+ rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
+
+ // Forces the socket server to assign the same port.
+ ss_->SetNextPortForTesting(first_addr.port());
+
+ turn_ready_ = false;
+ CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
+ turn_port_->PrepareAddress();
+
+ // Verifies that the new port has the same address.
+ EXPECT_EQ(first_addr, turn_port_->socket()->GetLocalAddress());
+
+ EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
+
+ // Verifies that the new port has a different address now.
+ EXPECT_NE(first_addr, turn_port_->socket()->GetLocalAddress());
+}
+
+// Do a TURN allocation and try to send a packet to it from the outside.
+// The packet should be dropped. Then, try to send a packet from TURN to the
+// outside. It should reach its destination. Finally, try again from the
+// outside. It should now work as well.
+TEST_F(TurnPortTest, TestTurnConnection) {
+ CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
+ TestTurnConnection();
+}
+
+// Similar to above, except that this test will use the shared socket.
+TEST_F(TurnPortTest, TestTurnConnectionUsingSharedSocket) {
+ CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
+ TestTurnConnection();
+}
+
+// Test that we can establish a TCP connection with TURN server.
+TEST_F(TurnPortTest, TestTurnTcpConnection) {
+ turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
+ CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
+ TestTurnConnection();
+}
+
+// Test that we fail to create a connection when we want to use TLS over TCP.
+// This test should be removed once we have TLS support.
+TEST_F(TurnPortTest, TestTurnTlsTcpConnectionFails) {
+ cricket::ProtocolAddress secure_addr(kTurnTcpProtoAddr.address,
+ kTurnTcpProtoAddr.proto,
+ true);
+ CreateTurnPort(kTurnUsername, kTurnPassword, secure_addr);
+ turn_port_->PrepareAddress();
+ EXPECT_TRUE_WAIT(turn_error_, kTimeout);
+ ASSERT_EQ(0U, turn_port_->Candidates().size());
+}
+
+// Test try-alternate-server feature.
+TEST_F(TurnPortTest, TestTurnAlternateServer) {
+ std::vector<rtc::SocketAddress> redirect_addresses;
+ redirect_addresses.push_back(kTurnAlternateUdpIntAddr);
+
+ cricket::TestTurnRedirector redirector(redirect_addresses);
+ turn_server_.AddInternalSocket(kTurnAlternateUdpIntAddr,
+ cricket::PROTO_UDP);
+ turn_server_.set_redirect_hook(&redirector);
+ CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
+
+ // Retrieve the address before we run the state machine.
+ const SocketAddress old_addr = turn_port_->server_address().address;
+
+ turn_port_->PrepareAddress();
+ EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
+ // Retrieve the address again, the turn port's address should be
+ // changed.
+ const SocketAddress new_addr = turn_port_->server_address().address;
+ EXPECT_NE(old_addr, new_addr);
+ ASSERT_EQ(1U, turn_port_->Candidates().size());
+ EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
+ turn_port_->Candidates()[0].address().ipaddr());
+ EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
+}
+
+// Test that we fail when we redirect to an address different from
+// current IP family.
+TEST_F(TurnPortTest, TestTurnAlternateServerV4toV6) {
+ std::vector<rtc::SocketAddress> redirect_addresses;
+ redirect_addresses.push_back(kTurnUdpIPv6IntAddr);
+
+ cricket::TestTurnRedirector redirector(redirect_addresses);
+ turn_server_.AddInternalSocket(kTurnAlternateUdpIntAddr,
+ cricket::PROTO_UDP);
+ turn_server_.set_redirect_hook(&redirector);
+ CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
+ turn_port_->PrepareAddress();
+ EXPECT_TRUE_WAIT(turn_error_, kTimeout);
+}
+
+// Test that we fail to handle alternate-server response over TCP protocol.
+TEST_F(TurnPortTest, TestTurnAlternateServerTcp) {
+ std::vector<rtc::SocketAddress> redirect_addresses;
+ redirect_addresses.push_back(kTurnAlternateUdpIntAddr);
+
+ cricket::TestTurnRedirector redirector(redirect_addresses);
+ turn_server_.set_redirect_hook(&redirector);
+ turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
+ CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
+
+ turn_server_.AddInternalSocket(kTurnAlternateUdpIntAddr, cricket::PROTO_TCP);
+ turn_port_->PrepareAddress();
+ EXPECT_TRUE_WAIT(turn_error_, kTimeout);
+}
+
+// Test try-alternate-server catches the case of pingpong.
+TEST_F(TurnPortTest, TestTurnAlternateServerPingPong) {
+ std::vector<rtc::SocketAddress> redirect_addresses;
+ redirect_addresses.push_back(kTurnAlternateUdpIntAddr);
+ redirect_addresses.push_back(kTurnUdpIntAddr);
+
+ cricket::TestTurnRedirector redirector(redirect_addresses);
+
+ turn_server_.AddInternalSocket(kTurnAlternateUdpIntAddr,
+ cricket::PROTO_UDP);
+ turn_server_.set_redirect_hook(&redirector);
+ CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
+
+ turn_port_->PrepareAddress();
+ EXPECT_TRUE_WAIT(turn_error_, kTimeout);
+ ASSERT_EQ(0U, turn_port_->Candidates().size());
+ rtc::SocketAddress address;
+ // Verify that we have exhausted all alternate servers instead of
+ // failure caused by other errors.
+ EXPECT_FALSE(redirector.ShouldRedirect(address, &address));
+}
+
+// Test try-alternate-server catch the case of repeated server.
+TEST_F(TurnPortTest, TestTurnAlternateServerDetectRepetition) {
+ std::vector<rtc::SocketAddress> redirect_addresses;
+ redirect_addresses.push_back(kTurnAlternateUdpIntAddr);
+ redirect_addresses.push_back(kTurnAlternateUdpIntAddr);
+
+ cricket::TestTurnRedirector redirector(redirect_addresses);
+
+ turn_server_.AddInternalSocket(kTurnAlternateUdpIntAddr,
+ cricket::PROTO_UDP);
+ turn_server_.set_redirect_hook(&redirector);
+ CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
+
+ turn_port_->PrepareAddress();
+ EXPECT_TRUE_WAIT(turn_error_, kTimeout);
+ ASSERT_EQ(0U, turn_port_->Candidates().size());
+}
+
+
+// Run TurnConnectionTest with one-time-use nonce feature.
+// Here server will send a 438 STALE_NONCE error message for
+// every TURN transaction.
+TEST_F(TurnPortTest, TestTurnConnectionUsingOTUNonce) {
+ turn_server_.set_enable_otu_nonce(true);
+ CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
+ TestTurnConnection();
+}
+
+// Do a TURN allocation, establish a UDP connection, and send some data.
+TEST_F(TurnPortTest, TestTurnSendDataTurnUdpToUdp) {
+ // Create ports and prepare addresses.
+ CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
+ TestTurnSendData();
+}
+
+// Do a TURN allocation, establish a TCP connection, and send some data.
+TEST_F(TurnPortTest, TestTurnSendDataTurnTcpToUdp) {
+ turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
+ // Create ports and prepare addresses.
+ CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
+ TestTurnSendData();
+}
+
+// Test TURN fails to make a connection from IPv6 address to a server which has
+// IPv4 address.
+TEST_F(TurnPortTest, TestTurnLocalIPv6AddressServerIPv4) {
+ turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, cricket::PROTO_UDP);
+ CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
+ kTurnUdpProtoAddr);
+ turn_port_->PrepareAddress();
+ ASSERT_TRUE_WAIT(turn_error_, kTimeout);
+ EXPECT_TRUE(turn_port_->Candidates().empty());
+}
+
+// Test TURN make a connection from IPv6 address to a server which has
+// IPv6 intenal address. But in this test external address is a IPv4 address,
+// hence allocated address will be a IPv4 address.
+TEST_F(TurnPortTest, TestTurnLocalIPv6AddressServerIPv6ExtenalIPv4) {
+ turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, cricket::PROTO_UDP);
+ CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
+ kTurnUdpIPv6ProtoAddr);
+ turn_port_->PrepareAddress();
+ EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
+ ASSERT_EQ(1U, turn_port_->Candidates().size());
+ EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
+ turn_port_->Candidates()[0].address().ipaddr());
+ EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
+}
+
+// This test verifies any FD's are not leaked after TurnPort is destroyed.
+// https://code.google.com/p/webrtc/issues/detail?id=2651
+#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
+TEST_F(TurnPortTest, TestResolverShutdown) {
+ turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, cricket::PROTO_UDP);
+ int last_fd_count = GetFDCount();
+ // Need to supply unresolved address to kick off resolver.
+ CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
+ cricket::ProtocolAddress(rtc::SocketAddress(
+ "stun.l.google.com", 3478), cricket::PROTO_UDP));
+ turn_port_->PrepareAddress();
+ ASSERT_TRUE_WAIT(turn_error_, kTimeout);
+ EXPECT_TRUE(turn_port_->Candidates().empty());
+ turn_port_.reset();
+ rtc::Thread::Current()->Post(this, MSG_TESTFINISH);
+ // Waiting for above message to be processed.
+ ASSERT_TRUE_WAIT(test_finish_, kTimeout);
+ EXPECT_EQ(last_fd_count, GetFDCount());
+}
+#endif
diff --git a/p2p/base/turnserver.cc b/p2p/base/turnserver.cc
new file mode 100644
index 00000000..8605e98d
--- /dev/null
+++ b/p2p/base/turnserver.cc
@@ -0,0 +1,1011 @@
+/*
+ * 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.
+ */
+
+#include "webrtc/p2p/base/turnserver.h"
+
+#include "webrtc/p2p/base/asyncstuntcpsocket.h"
+#include "webrtc/p2p/base/common.h"
+#include "webrtc/p2p/base/packetsocketfactory.h"
+#include "webrtc/p2p/base/stun.h"
+#include "webrtc/base/bytebuffer.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/messagedigest.h"
+#include "webrtc/base/socketadapters.h"
+#include "webrtc/base/stringencode.h"
+#include "webrtc/base/thread.h"
+
+namespace cricket {
+
+// TODO(juberti): Move this all to a future turnmessage.h
+//static const int IPPROTO_UDP = 17;
+static const int kNonceTimeout = 60 * 60 * 1000; // 60 minutes
+static const int kDefaultAllocationTimeout = 10 * 60 * 1000; // 10 minutes
+static const int kPermissionTimeout = 5 * 60 * 1000; // 5 minutes
+static const int kChannelTimeout = 10 * 60 * 1000; // 10 minutes
+
+static const int kMinChannelNumber = 0x4000;
+static const int kMaxChannelNumber = 0x7FFF;
+
+static const size_t kNonceKeySize = 16;
+static const size_t kNonceSize = 40;
+
+static const size_t TURN_CHANNEL_HEADER_SIZE = 4U;
+
+// TODO(mallinath) - Move these to a common place.
+inline bool IsTurnChannelData(uint16 msg_type) {
+ // The first two bits of a channel data message are 0b01.
+ return ((msg_type & 0xC000) == 0x4000);
+}
+
+// IDs used for posted messages for TurnServer::Allocation.
+enum {
+ MSG_ALLOCATION_TIMEOUT,
+};
+
+// Encapsulates a TURN allocation.
+// The object is created when an allocation request is received, and then
+// handles TURN messages (via HandleTurnMessage) and channel data messages
+// (via HandleChannelData) for this allocation when received by the server.
+// The object self-deletes and informs the server if its lifetime timer expires.
+class TurnServer::Allocation : public rtc::MessageHandler,
+ public sigslot::has_slots<> {
+ public:
+ Allocation(TurnServer* server_,
+ rtc::Thread* thread, const Connection& conn,
+ rtc::AsyncPacketSocket* server_socket,
+ const std::string& key);
+ virtual ~Allocation();
+
+ Connection* conn() { return &conn_; }
+ const std::string& key() const { return key_; }
+ const std::string& transaction_id() const { return transaction_id_; }
+ const std::string& username() const { return username_; }
+ const std::string& last_nonce() const { return last_nonce_; }
+ void set_last_nonce(const std::string& nonce) { last_nonce_ = nonce; }
+
+ std::string ToString() const;
+
+ void HandleTurnMessage(const TurnMessage* msg);
+ void HandleChannelData(const char* data, size_t size);
+
+ sigslot::signal1<Allocation*> SignalDestroyed;
+
+ private:
+ typedef std::list<Permission*> PermissionList;
+ typedef std::list<Channel*> ChannelList;
+
+ void HandleAllocateRequest(const TurnMessage* msg);
+ void HandleRefreshRequest(const TurnMessage* msg);
+ void HandleSendIndication(const TurnMessage* msg);
+ void HandleCreatePermissionRequest(const TurnMessage* msg);
+ void HandleChannelBindRequest(const TurnMessage* msg);
+
+ void OnExternalPacket(rtc::AsyncPacketSocket* socket,
+ const char* data, size_t size,
+ const rtc::SocketAddress& addr,
+ const rtc::PacketTime& packet_time);
+
+ static int ComputeLifetime(const TurnMessage* msg);
+ bool HasPermission(const rtc::IPAddress& addr);
+ void AddPermission(const rtc::IPAddress& addr);
+ Permission* FindPermission(const rtc::IPAddress& addr) const;
+ Channel* FindChannel(int channel_id) const;
+ Channel* FindChannel(const rtc::SocketAddress& addr) const;
+
+ void SendResponse(TurnMessage* msg);
+ void SendBadRequestResponse(const TurnMessage* req);
+ void SendErrorResponse(const TurnMessage* req, int code,
+ const std::string& reason);
+ void SendExternal(const void* data, size_t size,
+ const rtc::SocketAddress& peer);
+
+ void OnPermissionDestroyed(Permission* perm);
+ void OnChannelDestroyed(Channel* channel);
+ virtual void OnMessage(rtc::Message* msg);
+
+ TurnServer* server_;
+ rtc::Thread* thread_;
+ Connection conn_;
+ rtc::scoped_ptr<rtc::AsyncPacketSocket> external_socket_;
+ std::string key_;
+ std::string transaction_id_;
+ std::string username_;
+ std::string last_nonce_;
+ PermissionList perms_;
+ ChannelList channels_;
+};
+
+// Encapsulates a TURN permission.
+// The object is created when a create permission request is received by an
+// allocation, and self-deletes when its lifetime timer expires.
+class TurnServer::Permission : public rtc::MessageHandler {
+ public:
+ Permission(rtc::Thread* thread, const rtc::IPAddress& peer);
+ ~Permission();
+
+ const rtc::IPAddress& peer() const { return peer_; }
+ void Refresh();
+
+ sigslot::signal1<Permission*> SignalDestroyed;
+
+ private:
+ virtual void OnMessage(rtc::Message* msg);
+
+ rtc::Thread* thread_;
+ rtc::IPAddress peer_;
+};
+
+// Encapsulates a TURN channel binding.
+// The object is created when a channel bind request is received by an
+// allocation, and self-deletes when its lifetime timer expires.
+class TurnServer::Channel : public rtc::MessageHandler {
+ public:
+ Channel(rtc::Thread* thread, int id,
+ const rtc::SocketAddress& peer);
+ ~Channel();
+
+ int id() const { return id_; }
+ const rtc::SocketAddress& peer() const { return peer_; }
+ void Refresh();
+
+ sigslot::signal1<Channel*> SignalDestroyed;
+
+ private:
+ virtual void OnMessage(rtc::Message* msg);
+
+ rtc::Thread* thread_;
+ int id_;
+ rtc::SocketAddress peer_;
+};
+
+static bool InitResponse(const StunMessage* req, StunMessage* resp) {
+ int resp_type = (req) ? GetStunSuccessResponseType(req->type()) : -1;
+ if (resp_type == -1)
+ return false;
+ resp->SetType(resp_type);
+ resp->SetTransactionID(req->transaction_id());
+ return true;
+}
+
+static bool InitErrorResponse(const StunMessage* req, int code,
+ const std::string& reason, StunMessage* resp) {
+ int resp_type = (req) ? GetStunErrorResponseType(req->type()) : -1;
+ if (resp_type == -1)
+ return false;
+ resp->SetType(resp_type);
+ resp->SetTransactionID(req->transaction_id());
+ VERIFY(resp->AddAttribute(new cricket::StunErrorCodeAttribute(
+ STUN_ATTR_ERROR_CODE, code, reason)));
+ return true;
+}
+
+TurnServer::TurnServer(rtc::Thread* thread)
+ : thread_(thread),
+ nonce_key_(rtc::CreateRandomString(kNonceKeySize)),
+ auth_hook_(NULL),
+ redirect_hook_(NULL),
+ enable_otu_nonce_(false) {
+}
+
+TurnServer::~TurnServer() {
+ for (AllocationMap::iterator it = allocations_.begin();
+ it != allocations_.end(); ++it) {
+ delete it->second;
+ }
+
+ for (InternalSocketMap::iterator it = server_sockets_.begin();
+ it != server_sockets_.end(); ++it) {
+ rtc::AsyncPacketSocket* socket = it->first;
+ delete socket;
+ }
+
+ for (ServerSocketMap::iterator it = server_listen_sockets_.begin();
+ it != server_listen_sockets_.end(); ++it) {
+ rtc::AsyncSocket* socket = it->first;
+ delete socket;
+ }
+}
+
+void TurnServer::AddInternalSocket(rtc::AsyncPacketSocket* socket,
+ ProtocolType proto) {
+ ASSERT(server_sockets_.end() == server_sockets_.find(socket));
+ server_sockets_[socket] = proto;
+ socket->SignalReadPacket.connect(this, &TurnServer::OnInternalPacket);
+}
+
+void TurnServer::AddInternalServerSocket(rtc::AsyncSocket* socket,
+ ProtocolType proto) {
+ ASSERT(server_listen_sockets_.end() ==
+ server_listen_sockets_.find(socket));
+ server_listen_sockets_[socket] = proto;
+ socket->SignalReadEvent.connect(this, &TurnServer::OnNewInternalConnection);
+}
+
+void TurnServer::SetExternalSocketFactory(
+ rtc::PacketSocketFactory* factory,
+ const rtc::SocketAddress& external_addr) {
+ external_socket_factory_.reset(factory);
+ external_addr_ = external_addr;
+}
+
+void TurnServer::OnNewInternalConnection(rtc::AsyncSocket* socket) {
+ ASSERT(server_listen_sockets_.find(socket) != server_listen_sockets_.end());
+ AcceptConnection(socket);
+}
+
+void TurnServer::AcceptConnection(rtc::AsyncSocket* server_socket) {
+ // Check if someone is trying to connect to us.
+ rtc::SocketAddress accept_addr;
+ rtc::AsyncSocket* accepted_socket = server_socket->Accept(&accept_addr);
+ if (accepted_socket != NULL) {
+ ProtocolType proto = server_listen_sockets_[server_socket];
+ cricket::AsyncStunTCPSocket* tcp_socket =
+ new cricket::AsyncStunTCPSocket(accepted_socket, false);
+
+ tcp_socket->SignalClose.connect(this, &TurnServer::OnInternalSocketClose);
+ // Finally add the socket so it can start communicating with the client.
+ AddInternalSocket(tcp_socket, proto);
+ }
+}
+
+void TurnServer::OnInternalSocketClose(rtc::AsyncPacketSocket* socket,
+ int err) {
+ DestroyInternalSocket(socket);
+}
+
+void TurnServer::OnInternalPacket(rtc::AsyncPacketSocket* socket,
+ const char* data, size_t size,
+ const rtc::SocketAddress& addr,
+ const rtc::PacketTime& packet_time) {
+ // Fail if the packet is too small to even contain a channel header.
+ if (size < TURN_CHANNEL_HEADER_SIZE) {
+ return;
+ }
+ InternalSocketMap::iterator iter = server_sockets_.find(socket);
+ ASSERT(iter != server_sockets_.end());
+ Connection conn(addr, iter->second, socket);
+ uint16 msg_type = rtc::GetBE16(data);
+ if (!IsTurnChannelData(msg_type)) {
+ // This is a STUN message.
+ HandleStunMessage(&conn, data, size);
+ } else {
+ // This is a channel message; let the allocation handle it.
+ Allocation* allocation = FindAllocation(&conn);
+ if (allocation) {
+ allocation->HandleChannelData(data, size);
+ }
+ }
+}
+
+void TurnServer::HandleStunMessage(Connection* conn, const char* data,
+ size_t size) {
+ TurnMessage msg;
+ rtc::ByteBuffer buf(data, size);
+ if (!msg.Read(&buf) || (buf.Length() > 0)) {
+ LOG(LS_WARNING) << "Received invalid STUN message";
+ return;
+ }
+
+ // If it's a STUN binding request, handle that specially.
+ if (msg.type() == STUN_BINDING_REQUEST) {
+ HandleBindingRequest(conn, &msg);
+ return;
+ }
+
+ if (redirect_hook_ != NULL && msg.type() == STUN_ALLOCATE_REQUEST) {
+ rtc::SocketAddress address;
+ if (redirect_hook_->ShouldRedirect(conn->src(), &address)) {
+ SendErrorResponseWithAlternateServer(
+ conn, &msg, address);
+ return;
+ }
+ }
+
+ // Look up the key that we'll use to validate the M-I. If we have an
+ // existing allocation, the key will already be cached.
+ Allocation* allocation = FindAllocation(conn);
+ std::string key;
+ if (!allocation) {
+ GetKey(&msg, &key);
+ } else {
+ key = allocation->key();
+ }
+
+ // Ensure the message is authorized; only needed for requests.
+ if (IsStunRequestType(msg.type())) {
+ if (!CheckAuthorization(conn, &msg, data, size, key)) {
+ return;
+ }
+ }
+
+ if (!allocation && msg.type() == STUN_ALLOCATE_REQUEST) {
+ HandleAllocateRequest(conn, &msg, key);
+ } else if (allocation &&
+ (msg.type() != STUN_ALLOCATE_REQUEST ||
+ msg.transaction_id() == allocation->transaction_id())) {
+ // This is a non-allocate request, or a retransmit of an allocate.
+ // Check that the username matches the previous username used.
+ if (IsStunRequestType(msg.type()) &&
+ msg.GetByteString(STUN_ATTR_USERNAME)->GetString() !=
+ allocation->username()) {
+ SendErrorResponse(conn, &msg, STUN_ERROR_WRONG_CREDENTIALS,
+ STUN_ERROR_REASON_WRONG_CREDENTIALS);
+ return;
+ }
+ allocation->HandleTurnMessage(&msg);
+ } else {
+ // Allocation mismatch.
+ SendErrorResponse(conn, &msg, STUN_ERROR_ALLOCATION_MISMATCH,
+ STUN_ERROR_REASON_ALLOCATION_MISMATCH);
+ }
+}
+
+bool TurnServer::GetKey(const StunMessage* msg, std::string* key) {
+ const StunByteStringAttribute* username_attr =
+ msg->GetByteString(STUN_ATTR_USERNAME);
+ if (!username_attr) {
+ return false;
+ }
+
+ std::string username = username_attr->GetString();
+ return (auth_hook_ != NULL && auth_hook_->GetKey(username, realm_, key));
+}
+
+bool TurnServer::CheckAuthorization(Connection* conn,
+ const StunMessage* msg,
+ const char* data, size_t size,
+ const std::string& key) {
+ // RFC 5389, 10.2.2.
+ ASSERT(IsStunRequestType(msg->type()));
+ const StunByteStringAttribute* mi_attr =
+ msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
+ const StunByteStringAttribute* username_attr =
+ msg->GetByteString(STUN_ATTR_USERNAME);
+ const StunByteStringAttribute* realm_attr =
+ msg->GetByteString(STUN_ATTR_REALM);
+ const StunByteStringAttribute* nonce_attr =
+ msg->GetByteString(STUN_ATTR_NONCE);
+
+ // Fail if no M-I.
+ if (!mi_attr) {
+ SendErrorResponseWithRealmAndNonce(conn, msg, STUN_ERROR_UNAUTHORIZED,
+ STUN_ERROR_REASON_UNAUTHORIZED);
+ return false;
+ }
+
+ // Fail if there is M-I but no username, nonce, or realm.
+ if (!username_attr || !realm_attr || !nonce_attr) {
+ SendErrorResponse(conn, msg, STUN_ERROR_BAD_REQUEST,
+ STUN_ERROR_REASON_BAD_REQUEST);
+ return false;
+ }
+
+ // Fail if bad nonce.
+ if (!ValidateNonce(nonce_attr->GetString())) {
+ SendErrorResponseWithRealmAndNonce(conn, msg, STUN_ERROR_STALE_NONCE,
+ STUN_ERROR_REASON_STALE_NONCE);
+ return false;
+ }
+
+ // Fail if bad username or M-I.
+ // We need |data| and |size| for the call to ValidateMessageIntegrity.
+ if (key.empty() || !StunMessage::ValidateMessageIntegrity(data, size, key)) {
+ SendErrorResponseWithRealmAndNonce(conn, msg, STUN_ERROR_UNAUTHORIZED,
+ STUN_ERROR_REASON_UNAUTHORIZED);
+ return false;
+ }
+
+ // Fail if one-time-use nonce feature is enabled.
+ Allocation* allocation = FindAllocation(conn);
+ if (enable_otu_nonce_ && allocation &&
+ allocation->last_nonce() == nonce_attr->GetString()) {
+ SendErrorResponseWithRealmAndNonce(conn, msg, STUN_ERROR_STALE_NONCE,
+ STUN_ERROR_REASON_STALE_NONCE);
+ return false;
+ }
+
+ if (allocation) {
+ allocation->set_last_nonce(nonce_attr->GetString());
+ }
+ // Success.
+ return true;
+}
+
+void TurnServer::HandleBindingRequest(Connection* conn,
+ const StunMessage* req) {
+ StunMessage response;
+ InitResponse(req, &response);
+
+ // Tell the user the address that we received their request from.
+ StunAddressAttribute* mapped_addr_attr;
+ mapped_addr_attr = new StunXorAddressAttribute(
+ STUN_ATTR_XOR_MAPPED_ADDRESS, conn->src());
+ VERIFY(response.AddAttribute(mapped_addr_attr));
+
+ SendStun(conn, &response);
+}
+
+void TurnServer::HandleAllocateRequest(Connection* conn,
+ const TurnMessage* msg,
+ const std::string& key) {
+ // Check the parameters in the request.
+ const StunUInt32Attribute* transport_attr =
+ msg->GetUInt32(STUN_ATTR_REQUESTED_TRANSPORT);
+ if (!transport_attr) {
+ SendErrorResponse(conn, msg, STUN_ERROR_BAD_REQUEST,
+ STUN_ERROR_REASON_BAD_REQUEST);
+ return;
+ }
+
+ // Only UDP is supported right now.
+ int proto = transport_attr->value() >> 24;
+ if (proto != IPPROTO_UDP) {
+ SendErrorResponse(conn, msg, STUN_ERROR_UNSUPPORTED_PROTOCOL,
+ STUN_ERROR_REASON_UNSUPPORTED_PROTOCOL);
+ return;
+ }
+
+ // Create the allocation and let it send the success response.
+ // If the actual socket allocation fails, send an internal error.
+ Allocation* alloc = CreateAllocation(conn, proto, key);
+ if (alloc) {
+ alloc->HandleTurnMessage(msg);
+ } else {
+ SendErrorResponse(conn, msg, STUN_ERROR_SERVER_ERROR,
+ "Failed to allocate socket");
+ }
+}
+
+std::string TurnServer::GenerateNonce() const {
+ // Generate a nonce of the form hex(now + HMAC-MD5(nonce_key_, now))
+ uint32 now = rtc::Time();
+ std::string input(reinterpret_cast<const char*>(&now), sizeof(now));
+ std::string nonce = rtc::hex_encode(input.c_str(), input.size());
+ nonce += rtc::ComputeHmac(rtc::DIGEST_MD5, nonce_key_, input);
+ ASSERT(nonce.size() == kNonceSize);
+ return nonce;
+}
+
+bool TurnServer::ValidateNonce(const std::string& nonce) const {
+ // Check the size.
+ if (nonce.size() != kNonceSize) {
+ return false;
+ }
+
+ // Decode the timestamp.
+ uint32 then;
+ char* p = reinterpret_cast<char*>(&then);
+ size_t len = rtc::hex_decode(p, sizeof(then),
+ nonce.substr(0, sizeof(then) * 2));
+ if (len != sizeof(then)) {
+ return false;
+ }
+
+ // Verify the HMAC.
+ if (nonce.substr(sizeof(then) * 2) != rtc::ComputeHmac(
+ rtc::DIGEST_MD5, nonce_key_, std::string(p, sizeof(then)))) {
+ return false;
+ }
+
+ // Validate the timestamp.
+ return rtc::TimeSince(then) < kNonceTimeout;
+}
+
+TurnServer::Allocation* TurnServer::FindAllocation(Connection* conn) {
+ AllocationMap::const_iterator it = allocations_.find(*conn);
+ return (it != allocations_.end()) ? it->second : NULL;
+}
+
+TurnServer::Allocation* TurnServer::CreateAllocation(Connection* conn,
+ int proto,
+ const std::string& key) {
+ rtc::AsyncPacketSocket* external_socket = (external_socket_factory_) ?
+ external_socket_factory_->CreateUdpSocket(external_addr_, 0, 0) : NULL;
+ if (!external_socket) {
+ return NULL;
+ }
+
+ // The Allocation takes ownership of the socket.
+ Allocation* allocation = new Allocation(this,
+ thread_, *conn, external_socket, key);
+ allocation->SignalDestroyed.connect(this, &TurnServer::OnAllocationDestroyed);
+ allocations_[*conn] = allocation;
+ return allocation;
+}
+
+void TurnServer::SendErrorResponse(Connection* conn,
+ const StunMessage* req,
+ int code, const std::string& reason) {
+ TurnMessage resp;
+ InitErrorResponse(req, code, reason, &resp);
+ LOG(LS_INFO) << "Sending error response, type=" << resp.type()
+ << ", code=" << code << ", reason=" << reason;
+ SendStun(conn, &resp);
+}
+
+void TurnServer::SendErrorResponseWithRealmAndNonce(
+ Connection* conn, const StunMessage* msg,
+ int code, const std::string& reason) {
+ TurnMessage resp;
+ InitErrorResponse(msg, code, reason, &resp);
+ VERIFY(resp.AddAttribute(new StunByteStringAttribute(
+ STUN_ATTR_NONCE, GenerateNonce())));
+ VERIFY(resp.AddAttribute(new StunByteStringAttribute(
+ STUN_ATTR_REALM, realm_)));
+ SendStun(conn, &resp);
+}
+
+void TurnServer::SendErrorResponseWithAlternateServer(
+ Connection* conn, const StunMessage* msg,
+ const rtc::SocketAddress& addr) {
+ TurnMessage resp;
+ InitErrorResponse(msg, STUN_ERROR_TRY_ALTERNATE,
+ STUN_ERROR_REASON_TRY_ALTERNATE_SERVER, &resp);
+ VERIFY(resp.AddAttribute(new StunAddressAttribute(
+ STUN_ATTR_ALTERNATE_SERVER, addr)));
+ SendStun(conn, &resp);
+}
+
+void TurnServer::SendStun(Connection* conn, StunMessage* msg) {
+ rtc::ByteBuffer buf;
+ // Add a SOFTWARE attribute if one is set.
+ if (!software_.empty()) {
+ VERIFY(msg->AddAttribute(
+ new StunByteStringAttribute(STUN_ATTR_SOFTWARE, software_)));
+ }
+ msg->Write(&buf);
+ Send(conn, buf);
+}
+
+void TurnServer::Send(Connection* conn,
+ const rtc::ByteBuffer& buf) {
+ rtc::PacketOptions options;
+ conn->socket()->SendTo(buf.Data(), buf.Length(), conn->src(), options);
+}
+
+void TurnServer::OnAllocationDestroyed(Allocation* allocation) {
+ // Removing the internal socket if the connection is not udp.
+ rtc::AsyncPacketSocket* socket = allocation->conn()->socket();
+ InternalSocketMap::iterator iter = server_sockets_.find(socket);
+ ASSERT(iter != server_sockets_.end());
+ // Skip if the socket serving this allocation is UDP, as this will be shared
+ // by all allocations.
+ if (iter->second != cricket::PROTO_UDP) {
+ DestroyInternalSocket(socket);
+ }
+
+ AllocationMap::iterator it = allocations_.find(*(allocation->conn()));
+ if (it != allocations_.end())
+ allocations_.erase(it);
+}
+
+void TurnServer::DestroyInternalSocket(rtc::AsyncPacketSocket* socket) {
+ InternalSocketMap::iterator iter = server_sockets_.find(socket);
+ if (iter != server_sockets_.end()) {
+ rtc::AsyncPacketSocket* socket = iter->first;
+ // We must destroy the socket async to avoid invalidating the sigslot
+ // callback list iterator inside a sigslot callback.
+ rtc::Thread::Current()->Dispose(socket);
+ server_sockets_.erase(iter);
+ }
+}
+
+TurnServer::Connection::Connection(const rtc::SocketAddress& src,
+ ProtocolType proto,
+ rtc::AsyncPacketSocket* socket)
+ : src_(src),
+ dst_(socket->GetRemoteAddress()),
+ proto_(proto),
+ socket_(socket) {
+}
+
+bool TurnServer::Connection::operator==(const Connection& c) const {
+ return src_ == c.src_ && dst_ == c.dst_ && proto_ == c.proto_;
+}
+
+bool TurnServer::Connection::operator<(const Connection& c) const {
+ return src_ < c.src_ || dst_ < c.dst_ || proto_ < c.proto_;
+}
+
+std::string TurnServer::Connection::ToString() const {
+ const char* const kProtos[] = {
+ "unknown", "udp", "tcp", "ssltcp"
+ };
+ std::ostringstream ost;
+ ost << src_.ToString() << "-" << dst_.ToString() << ":"<< kProtos[proto_];
+ return ost.str();
+}
+
+TurnServer::Allocation::Allocation(TurnServer* server,
+ rtc::Thread* thread,
+ const Connection& conn,
+ rtc::AsyncPacketSocket* socket,
+ const std::string& key)
+ : server_(server),
+ thread_(thread),
+ conn_(conn),
+ external_socket_(socket),
+ key_(key) {
+ external_socket_->SignalReadPacket.connect(
+ this, &TurnServer::Allocation::OnExternalPacket);
+}
+
+TurnServer::Allocation::~Allocation() {
+ for (ChannelList::iterator it = channels_.begin();
+ it != channels_.end(); ++it) {
+ delete *it;
+ }
+ for (PermissionList::iterator it = perms_.begin();
+ it != perms_.end(); ++it) {
+ delete *it;
+ }
+ thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
+ LOG_J(LS_INFO, this) << "Allocation destroyed";
+}
+
+std::string TurnServer::Allocation::ToString() const {
+ std::ostringstream ost;
+ ost << "Alloc[" << conn_.ToString() << "]";
+ return ost.str();
+}
+
+void TurnServer::Allocation::HandleTurnMessage(const TurnMessage* msg) {
+ ASSERT(msg != NULL);
+ switch (msg->type()) {
+ case STUN_ALLOCATE_REQUEST:
+ HandleAllocateRequest(msg);
+ break;
+ case TURN_REFRESH_REQUEST:
+ HandleRefreshRequest(msg);
+ break;
+ case TURN_SEND_INDICATION:
+ HandleSendIndication(msg);
+ break;
+ case TURN_CREATE_PERMISSION_REQUEST:
+ HandleCreatePermissionRequest(msg);
+ break;
+ case TURN_CHANNEL_BIND_REQUEST:
+ HandleChannelBindRequest(msg);
+ break;
+ default:
+ // Not sure what to do with this, just eat it.
+ LOG_J(LS_WARNING, this) << "Invalid TURN message type received: "
+ << msg->type();
+ }
+}
+
+void TurnServer::Allocation::HandleAllocateRequest(const TurnMessage* msg) {
+ // Copy the important info from the allocate request.
+ transaction_id_ = msg->transaction_id();
+ const StunByteStringAttribute* username_attr =
+ msg->GetByteString(STUN_ATTR_USERNAME);
+ ASSERT(username_attr != NULL);
+ username_ = username_attr->GetString();
+
+ // Figure out the lifetime and start the allocation timer.
+ int lifetime_secs = ComputeLifetime(msg);
+ thread_->PostDelayed(lifetime_secs * 1000, this, MSG_ALLOCATION_TIMEOUT);
+
+ LOG_J(LS_INFO, this) << "Created allocation, lifetime=" << lifetime_secs;
+
+ // We've already validated all the important bits; just send a response here.
+ TurnMessage response;
+ InitResponse(msg, &response);
+
+ StunAddressAttribute* mapped_addr_attr =
+ new StunXorAddressAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, conn_.src());
+ StunAddressAttribute* relayed_addr_attr =
+ new StunXorAddressAttribute(STUN_ATTR_XOR_RELAYED_ADDRESS,
+ external_socket_->GetLocalAddress());
+ StunUInt32Attribute* lifetime_attr =
+ new StunUInt32Attribute(STUN_ATTR_LIFETIME, lifetime_secs);
+ VERIFY(response.AddAttribute(mapped_addr_attr));
+ VERIFY(response.AddAttribute(relayed_addr_attr));
+ VERIFY(response.AddAttribute(lifetime_attr));
+
+ SendResponse(&response);
+}
+
+void TurnServer::Allocation::HandleRefreshRequest(const TurnMessage* msg) {
+ // Figure out the new lifetime.
+ int lifetime_secs = ComputeLifetime(msg);
+
+ // Reset the expiration timer.
+ thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
+ thread_->PostDelayed(lifetime_secs * 1000, this, MSG_ALLOCATION_TIMEOUT);
+
+ LOG_J(LS_INFO, this) << "Refreshed allocation, lifetime=" << lifetime_secs;
+
+ // Send a success response with a LIFETIME attribute.
+ TurnMessage response;
+ InitResponse(msg, &response);
+
+ StunUInt32Attribute* lifetime_attr =
+ new StunUInt32Attribute(STUN_ATTR_LIFETIME, lifetime_secs);
+ VERIFY(response.AddAttribute(lifetime_attr));
+
+ SendResponse(&response);
+}
+
+void TurnServer::Allocation::HandleSendIndication(const TurnMessage* msg) {
+ // Check mandatory attributes.
+ const StunByteStringAttribute* data_attr = msg->GetByteString(STUN_ATTR_DATA);
+ const StunAddressAttribute* peer_attr =
+ msg->GetAddress(STUN_ATTR_XOR_PEER_ADDRESS);
+ if (!data_attr || !peer_attr) {
+ LOG_J(LS_WARNING, this) << "Received invalid send indication";
+ return;
+ }
+
+ // If a permission exists, send the data on to the peer.
+ if (HasPermission(peer_attr->GetAddress().ipaddr())) {
+ SendExternal(data_attr->bytes(), data_attr->length(),
+ peer_attr->GetAddress());
+ } else {
+ LOG_J(LS_WARNING, this) << "Received send indication without permission"
+ << "peer=" << peer_attr->GetAddress();
+ }
+}
+
+void TurnServer::Allocation::HandleCreatePermissionRequest(
+ const TurnMessage* msg) {
+ // Check mandatory attributes.
+ const StunAddressAttribute* peer_attr =
+ msg->GetAddress(STUN_ATTR_XOR_PEER_ADDRESS);
+ if (!peer_attr) {
+ SendBadRequestResponse(msg);
+ return;
+ }
+
+ // Add this permission.
+ AddPermission(peer_attr->GetAddress().ipaddr());
+
+ LOG_J(LS_INFO, this) << "Created permission, peer="
+ << peer_attr->GetAddress();
+
+ // Send a success response.
+ TurnMessage response;
+ InitResponse(msg, &response);
+ SendResponse(&response);
+}
+
+void TurnServer::Allocation::HandleChannelBindRequest(const TurnMessage* msg) {
+ // Check mandatory attributes.
+ const StunUInt32Attribute* channel_attr =
+ msg->GetUInt32(STUN_ATTR_CHANNEL_NUMBER);
+ const StunAddressAttribute* peer_attr =
+ msg->GetAddress(STUN_ATTR_XOR_PEER_ADDRESS);
+ if (!channel_attr || !peer_attr) {
+ SendBadRequestResponse(msg);
+ return;
+ }
+
+ // Check that channel id is valid.
+ int channel_id = channel_attr->value() >> 16;
+ if (channel_id < kMinChannelNumber || channel_id > kMaxChannelNumber) {
+ SendBadRequestResponse(msg);
+ return;
+ }
+
+ // Check that this channel id isn't bound to another transport address, and
+ // that this transport address isn't bound to another channel id.
+ Channel* channel1 = FindChannel(channel_id);
+ Channel* channel2 = FindChannel(peer_attr->GetAddress());
+ if (channel1 != channel2) {
+ SendBadRequestResponse(msg);
+ return;
+ }
+
+ // Add or refresh this channel.
+ if (!channel1) {
+ channel1 = new Channel(thread_, channel_id, peer_attr->GetAddress());
+ channel1->SignalDestroyed.connect(this,
+ &TurnServer::Allocation::OnChannelDestroyed);
+ channels_.push_back(channel1);
+ } else {
+ channel1->Refresh();
+ }
+
+ // Channel binds also refresh permissions.
+ AddPermission(peer_attr->GetAddress().ipaddr());
+
+ LOG_J(LS_INFO, this) << "Bound channel, id=" << channel_id
+ << ", peer=" << peer_attr->GetAddress();
+
+ // Send a success response.
+ TurnMessage response;
+ InitResponse(msg, &response);
+ SendResponse(&response);
+}
+
+void TurnServer::Allocation::HandleChannelData(const char* data, size_t size) {
+ // Extract the channel number from the data.
+ uint16 channel_id = rtc::GetBE16(data);
+ Channel* channel = FindChannel(channel_id);
+ if (channel) {
+ // Send the data to the peer address.
+ SendExternal(data + TURN_CHANNEL_HEADER_SIZE,
+ size - TURN_CHANNEL_HEADER_SIZE, channel->peer());
+ } else {
+ LOG_J(LS_WARNING, this) << "Received channel data for invalid channel, id="
+ << channel_id;
+ }
+}
+
+void TurnServer::Allocation::OnExternalPacket(
+ rtc::AsyncPacketSocket* socket,
+ const char* data, size_t size,
+ const rtc::SocketAddress& addr,
+ const rtc::PacketTime& packet_time) {
+ ASSERT(external_socket_.get() == socket);
+ Channel* channel = FindChannel(addr);
+ if (channel) {
+ // There is a channel bound to this address. Send as a channel message.
+ rtc::ByteBuffer buf;
+ buf.WriteUInt16(channel->id());
+ buf.WriteUInt16(static_cast<uint16>(size));
+ buf.WriteBytes(data, size);
+ server_->Send(&conn_, buf);
+ } else if (HasPermission(addr.ipaddr())) {
+ // No channel, but a permission exists. Send as a data indication.
+ TurnMessage msg;
+ msg.SetType(TURN_DATA_INDICATION);
+ msg.SetTransactionID(
+ rtc::CreateRandomString(kStunTransactionIdLength));
+ VERIFY(msg.AddAttribute(new StunXorAddressAttribute(
+ STUN_ATTR_XOR_PEER_ADDRESS, addr)));
+ VERIFY(msg.AddAttribute(new StunByteStringAttribute(
+ STUN_ATTR_DATA, data, size)));
+ server_->SendStun(&conn_, &msg);
+ } else {
+ LOG_J(LS_WARNING, this) << "Received external packet without permission, "
+ << "peer=" << addr;
+ }
+}
+
+int TurnServer::Allocation::ComputeLifetime(const TurnMessage* msg) {
+ // Return the smaller of our default lifetime and the requested lifetime.
+ uint32 lifetime = kDefaultAllocationTimeout / 1000; // convert to seconds
+ const StunUInt32Attribute* lifetime_attr = msg->GetUInt32(STUN_ATTR_LIFETIME);
+ if (lifetime_attr && lifetime_attr->value() < lifetime) {
+ lifetime = lifetime_attr->value();
+ }
+ return lifetime;
+}
+
+bool TurnServer::Allocation::HasPermission(const rtc::IPAddress& addr) {
+ return (FindPermission(addr) != NULL);
+}
+
+void TurnServer::Allocation::AddPermission(const rtc::IPAddress& addr) {
+ Permission* perm = FindPermission(addr);
+ if (!perm) {
+ perm = new Permission(thread_, addr);
+ perm->SignalDestroyed.connect(
+ this, &TurnServer::Allocation::OnPermissionDestroyed);
+ perms_.push_back(perm);
+ } else {
+ perm->Refresh();
+ }
+}
+
+TurnServer::Permission* TurnServer::Allocation::FindPermission(
+ const rtc::IPAddress& addr) const {
+ for (PermissionList::const_iterator it = perms_.begin();
+ it != perms_.end(); ++it) {
+ if ((*it)->peer() == addr)
+ return *it;
+ }
+ return NULL;
+}
+
+TurnServer::Channel* TurnServer::Allocation::FindChannel(int channel_id) const {
+ for (ChannelList::const_iterator it = channels_.begin();
+ it != channels_.end(); ++it) {
+ if ((*it)->id() == channel_id)
+ return *it;
+ }
+ return NULL;
+}
+
+TurnServer::Channel* TurnServer::Allocation::FindChannel(
+ const rtc::SocketAddress& addr) const {
+ for (ChannelList::const_iterator it = channels_.begin();
+ it != channels_.end(); ++it) {
+ if ((*it)->peer() == addr)
+ return *it;
+ }
+ return NULL;
+}
+
+void TurnServer::Allocation::SendResponse(TurnMessage* msg) {
+ // Success responses always have M-I.
+ msg->AddMessageIntegrity(key_);
+ server_->SendStun(&conn_, msg);
+}
+
+void TurnServer::Allocation::SendBadRequestResponse(const TurnMessage* req) {
+ SendErrorResponse(req, STUN_ERROR_BAD_REQUEST, STUN_ERROR_REASON_BAD_REQUEST);
+}
+
+void TurnServer::Allocation::SendErrorResponse(const TurnMessage* req, int code,
+ const std::string& reason) {
+ server_->SendErrorResponse(&conn_, req, code, reason);
+}
+
+void TurnServer::Allocation::SendExternal(const void* data, size_t size,
+ const rtc::SocketAddress& peer) {
+ rtc::PacketOptions options;
+ external_socket_->SendTo(data, size, peer, options);
+}
+
+void TurnServer::Allocation::OnMessage(rtc::Message* msg) {
+ ASSERT(msg->message_id == MSG_ALLOCATION_TIMEOUT);
+ SignalDestroyed(this);
+ delete this;
+}
+
+void TurnServer::Allocation::OnPermissionDestroyed(Permission* perm) {
+ PermissionList::iterator it = std::find(perms_.begin(), perms_.end(), perm);
+ ASSERT(it != perms_.end());
+ perms_.erase(it);
+}
+
+void TurnServer::Allocation::OnChannelDestroyed(Channel* channel) {
+ ChannelList::iterator it =
+ std::find(channels_.begin(), channels_.end(), channel);
+ ASSERT(it != channels_.end());
+ channels_.erase(it);
+}
+
+TurnServer::Permission::Permission(rtc::Thread* thread,
+ const rtc::IPAddress& peer)
+ : thread_(thread), peer_(peer) {
+ Refresh();
+}
+
+TurnServer::Permission::~Permission() {
+ thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
+}
+
+void TurnServer::Permission::Refresh() {
+ thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
+ thread_->PostDelayed(kPermissionTimeout, this, MSG_ALLOCATION_TIMEOUT);
+}
+
+void TurnServer::Permission::OnMessage(rtc::Message* msg) {
+ ASSERT(msg->message_id == MSG_ALLOCATION_TIMEOUT);
+ SignalDestroyed(this);
+ delete this;
+}
+
+TurnServer::Channel::Channel(rtc::Thread* thread, int id,
+ const rtc::SocketAddress& peer)
+ : thread_(thread), id_(id), peer_(peer) {
+ Refresh();
+}
+
+TurnServer::Channel::~Channel() {
+ thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
+}
+
+void TurnServer::Channel::Refresh() {
+ thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
+ thread_->PostDelayed(kChannelTimeout, this, MSG_ALLOCATION_TIMEOUT);
+}
+
+void TurnServer::Channel::OnMessage(rtc::Message* msg) {
+ ASSERT(msg->message_id == MSG_ALLOCATION_TIMEOUT);
+ SignalDestroyed(this);
+ delete this;
+}
+
+} // namespace cricket
diff --git a/p2p/base/turnserver.h b/p2p/base/turnserver.h
new file mode 100644
index 00000000..670b6180
--- /dev/null
+++ b/p2p/base/turnserver.h
@@ -0,0 +1,190 @@
+/*
+ * 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 WEBRTC_P2P_BASE_TURNSERVER_H_
+#define WEBRTC_P2P_BASE_TURNSERVER_H_
+
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+
+#include "webrtc/p2p/base/portinterface.h"
+#include "webrtc/base/asyncpacketsocket.h"
+#include "webrtc/base/messagequeue.h"
+#include "webrtc/base/sigslot.h"
+#include "webrtc/base/socketaddress.h"
+
+namespace rtc {
+class ByteBuffer;
+class PacketSocketFactory;
+class Thread;
+}
+
+namespace cricket {
+
+class StunMessage;
+class TurnMessage;
+
+// The default server port for TURN, as specified in RFC5766.
+const int TURN_SERVER_PORT = 3478;
+
+// An interface through which the MD5 credential hash can be retrieved.
+class TurnAuthInterface {
+ public:
+ // Gets HA1 for the specified user and realm.
+ // HA1 = MD5(A1) = MD5(username:realm:password).
+ // Return true if the given username and realm are valid, or false if not.
+ virtual bool GetKey(const std::string& username, const std::string& realm,
+ std::string* key) = 0;
+};
+
+// An interface enables Turn Server to control redirection behavior.
+class TurnRedirectInterface {
+ public:
+ virtual bool ShouldRedirect(const rtc::SocketAddress& address,
+ rtc::SocketAddress* out) = 0;
+ virtual ~TurnRedirectInterface() {}
+};
+
+// The core TURN server class. Give it a socket to listen on via
+// AddInternalServerSocket, and a factory to create external sockets via
+// SetExternalSocketFactory, and it's ready to go.
+// Not yet wired up: TCP support.
+class TurnServer : public sigslot::has_slots<> {
+ public:
+ explicit TurnServer(rtc::Thread* thread);
+ ~TurnServer();
+
+ // Gets/sets the realm value to use for the server.
+ const std::string& realm() const { return realm_; }
+ void set_realm(const std::string& realm) { realm_ = realm; }
+
+ // Gets/sets the value for the SOFTWARE attribute for TURN messages.
+ const std::string& software() const { return software_; }
+ void set_software(const std::string& software) { software_ = software; }
+
+ // Sets the authentication callback; does not take ownership.
+ void set_auth_hook(TurnAuthInterface* auth_hook) { auth_hook_ = auth_hook; }
+
+ void set_redirect_hook(TurnRedirectInterface* redirect_hook) {
+ redirect_hook_ = redirect_hook;
+ }
+
+ void set_enable_otu_nonce(bool enable) { enable_otu_nonce_ = enable; }
+
+ // Starts listening for packets from internal clients.
+ void AddInternalSocket(rtc::AsyncPacketSocket* socket,
+ ProtocolType proto);
+ // Starts listening for the connections on this socket. When someone tries
+ // to connect, the connection will be accepted and a new internal socket
+ // will be added.
+ void AddInternalServerSocket(rtc::AsyncSocket* socket,
+ ProtocolType proto);
+ // Specifies the factory to use for creating external sockets.
+ void SetExternalSocketFactory(rtc::PacketSocketFactory* factory,
+ const rtc::SocketAddress& address);
+
+ private:
+ // Encapsulates the client's connection to the server.
+ class Connection {
+ public:
+ Connection() : proto_(PROTO_UDP), socket_(NULL) {}
+ Connection(const rtc::SocketAddress& src,
+ ProtocolType proto,
+ rtc::AsyncPacketSocket* socket);
+ const rtc::SocketAddress& src() const { return src_; }
+ rtc::AsyncPacketSocket* socket() { return socket_; }
+ bool operator==(const Connection& t) const;
+ bool operator<(const Connection& t) const;
+ std::string ToString() const;
+
+ private:
+ rtc::SocketAddress src_;
+ rtc::SocketAddress dst_;
+ cricket::ProtocolType proto_;
+ rtc::AsyncPacketSocket* socket_;
+ };
+ class Allocation;
+ class Permission;
+ class Channel;
+ typedef std::map<Connection, Allocation*> AllocationMap;
+
+ void OnInternalPacket(rtc::AsyncPacketSocket* socket, const char* data,
+ size_t size, const rtc::SocketAddress& address,
+ const rtc::PacketTime& packet_time);
+
+ void OnNewInternalConnection(rtc::AsyncSocket* socket);
+
+ // Accept connections on this server socket.
+ void AcceptConnection(rtc::AsyncSocket* server_socket);
+ void OnInternalSocketClose(rtc::AsyncPacketSocket* socket, int err);
+
+ void HandleStunMessage(Connection* conn, const char* data, size_t size);
+ void HandleBindingRequest(Connection* conn, const StunMessage* msg);
+ void HandleAllocateRequest(Connection* conn, const TurnMessage* msg,
+ const std::string& key);
+
+ bool GetKey(const StunMessage* msg, std::string* key);
+ bool CheckAuthorization(Connection* conn, const StunMessage* msg,
+ const char* data, size_t size,
+ const std::string& key);
+ std::string GenerateNonce() const;
+ bool ValidateNonce(const std::string& nonce) const;
+
+ Allocation* FindAllocation(Connection* conn);
+ Allocation* CreateAllocation(Connection* conn, int proto,
+ const std::string& key);
+
+ void SendErrorResponse(Connection* conn, const StunMessage* req,
+ int code, const std::string& reason);
+
+ void SendErrorResponseWithRealmAndNonce(Connection* conn,
+ const StunMessage* req,
+ int code,
+ const std::string& reason);
+
+ void SendErrorResponseWithAlternateServer(Connection* conn,
+ const StunMessage* req,
+ const rtc::SocketAddress& addr);
+
+ void SendStun(Connection* conn, StunMessage* msg);
+ void Send(Connection* conn, const rtc::ByteBuffer& buf);
+
+ void OnAllocationDestroyed(Allocation* allocation);
+ void DestroyInternalSocket(rtc::AsyncPacketSocket* socket);
+
+ typedef std::map<rtc::AsyncPacketSocket*,
+ ProtocolType> InternalSocketMap;
+ typedef std::map<rtc::AsyncSocket*,
+ ProtocolType> ServerSocketMap;
+
+ rtc::Thread* thread_;
+ std::string nonce_key_;
+ std::string realm_;
+ std::string software_;
+ TurnAuthInterface* auth_hook_;
+ TurnRedirectInterface* redirect_hook_;
+ // otu - one-time-use. Server will respond with 438 if it's
+ // sees the same nonce in next transaction.
+ bool enable_otu_nonce_;
+
+ InternalSocketMap server_sockets_;
+ ServerSocketMap server_listen_sockets_;
+ rtc::scoped_ptr<rtc::PacketSocketFactory>
+ external_socket_factory_;
+ rtc::SocketAddress external_addr_;
+
+ AllocationMap allocations_;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_BASE_TURNSERVER_H_
diff --git a/p2p/base/udpport.h b/p2p/base/udpport.h
new file mode 100644
index 00000000..9f868644
--- /dev/null
+++ b/p2p/base/udpport.h
@@ -0,0 +1,17 @@
+/*
+ * 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 WEBRTC_P2P_BASE_UDPPORT_H_
+#define WEBRTC_P2P_BASE_UDPPORT_H_
+
+// StunPort will be handling UDPPort functionality.
+#include "webrtc/p2p/base/stunport.h"
+
+#endif // WEBRTC_P2P_BASE_UDPPORT_H_
diff --git a/p2p/client/autoportallocator.h b/p2p/client/autoportallocator.h
new file mode 100644
index 00000000..5df1f0d6
--- /dev/null
+++ b/p2p/client/autoportallocator.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_P2P_CLIENT_AUTOPORTALLOCATOR_H_
+#define WEBRTC_P2P_CLIENT_AUTOPORTALLOCATOR_H_
+
+#include <string>
+#include <vector>
+
+#include "webrtc/p2p/client/httpportallocator.h"
+#include "webrtc/libjingle/xmpp/jingleinfotask.h"
+#include "webrtc/libjingle/xmpp/xmppclient.h"
+#include "webrtc/base/sigslot.h"
+
+// This class sets the relay and stun servers using XmppClient.
+// It enables the client to traverse Proxy and NAT.
+class AutoPortAllocator : public cricket::HttpPortAllocator {
+ public:
+ AutoPortAllocator(rtc::NetworkManager* network_manager,
+ const std::string& user_agent)
+ : cricket::HttpPortAllocator(network_manager, user_agent) {
+ }
+
+ // Creates and initiates a task to get relay token from XmppClient and set
+ // it appropriately.
+ void SetXmppClient(buzz::XmppClient* client) {
+ // The JingleInfoTask is freed by the task-runner.
+ buzz::JingleInfoTask* jit = new buzz::JingleInfoTask(client);
+ jit->SignalJingleInfo.connect(this, &AutoPortAllocator::OnJingleInfo);
+ jit->Start();
+ jit->RefreshJingleInfoNow();
+ }
+
+ private:
+ void OnJingleInfo(
+ const std::string& token,
+ const std::vector<std::string>& relay_hosts,
+ const std::vector<rtc::SocketAddress>& stun_hosts) {
+ SetRelayToken(token);
+ SetStunHosts(stun_hosts);
+ SetRelayHosts(relay_hosts);
+ }
+};
+
+#endif // WEBRTC_P2P_CLIENT_AUTOPORTALLOCATOR_H_
diff --git a/p2p/client/basicportallocator.cc b/p2p/client/basicportallocator.cc
new file mode 100644
index 00000000..5013a575
--- /dev/null
+++ b/p2p/client/basicportallocator.cc
@@ -0,0 +1,1190 @@
+/*
+ * 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 "webrtc/p2p/client/basicportallocator.h"
+
+#include <string>
+#include <vector>
+
+#include "webrtc/p2p/base/basicpacketsocketfactory.h"
+#include "webrtc/p2p/base/common.h"
+#include "webrtc/p2p/base/port.h"
+#include "webrtc/p2p/base/relayport.h"
+#include "webrtc/p2p/base/stunport.h"
+#include "webrtc/p2p/base/tcpport.h"
+#include "webrtc/p2p/base/turnport.h"
+#include "webrtc/p2p/base/udpport.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/logging.h"
+
+using rtc::CreateRandomId;
+using rtc::CreateRandomString;
+
+namespace {
+
+enum {
+ MSG_CONFIG_START,
+ MSG_CONFIG_READY,
+ MSG_ALLOCATE,
+ MSG_ALLOCATION_PHASE,
+ MSG_SHAKE,
+ MSG_SEQUENCEOBJECTS_CREATED,
+ MSG_CONFIG_STOP,
+};
+
+const int PHASE_UDP = 0;
+const int PHASE_RELAY = 1;
+const int PHASE_TCP = 2;
+const int PHASE_SSLTCP = 3;
+
+const int kNumPhases = 4;
+
+const int SHAKE_MIN_DELAY = 45 * 1000; // 45 seconds
+const int SHAKE_MAX_DELAY = 90 * 1000; // 90 seconds
+
+int ShakeDelay() {
+ int range = SHAKE_MAX_DELAY - SHAKE_MIN_DELAY + 1;
+ return SHAKE_MIN_DELAY + CreateRandomId() % range;
+}
+
+} // namespace
+
+namespace cricket {
+
+const uint32 DISABLE_ALL_PHASES =
+ PORTALLOCATOR_DISABLE_UDP
+ | PORTALLOCATOR_DISABLE_TCP
+ | PORTALLOCATOR_DISABLE_STUN
+ | PORTALLOCATOR_DISABLE_RELAY;
+
+// Performs the allocation of ports, in a sequenced (timed) manner, for a given
+// network and IP address.
+class AllocationSequence : public rtc::MessageHandler,
+ public sigslot::has_slots<> {
+ public:
+ enum State {
+ kInit, // Initial state.
+ kRunning, // Started allocating ports.
+ kStopped, // Stopped from running.
+ kCompleted, // All ports are allocated.
+
+ // kInit --> kRunning --> {kCompleted|kStopped}
+ };
+
+ AllocationSequence(BasicPortAllocatorSession* session,
+ rtc::Network* network,
+ PortConfiguration* config,
+ uint32 flags);
+ ~AllocationSequence();
+ bool Init();
+ void Clear();
+
+ State state() const { return state_; }
+
+ // Disables the phases for a new sequence that this one already covers for an
+ // equivalent network setup.
+ void DisableEquivalentPhases(rtc::Network* network,
+ PortConfiguration* config, uint32* flags);
+
+ // Starts and stops the sequence. When started, it will continue allocating
+ // new ports on its own timed schedule.
+ void Start();
+ void Stop();
+
+ // MessageHandler
+ void OnMessage(rtc::Message* msg);
+
+ void EnableProtocol(ProtocolType proto);
+ bool ProtocolEnabled(ProtocolType proto) const;
+
+ // Signal from AllocationSequence, when it's done with allocating ports.
+ // This signal is useful, when port allocation fails which doesn't result
+ // in any candidates. Using this signal BasicPortAllocatorSession can send
+ // its candidate discovery conclusion signal. Without this signal,
+ // BasicPortAllocatorSession doesn't have any event to trigger signal. This
+ // can also be achieved by starting timer in BPAS.
+ sigslot::signal1<AllocationSequence*> SignalPortAllocationComplete;
+
+ private:
+ typedef std::vector<ProtocolType> ProtocolList;
+
+ bool IsFlagSet(uint32 flag) {
+ return ((flags_ & flag) != 0);
+ }
+ void CreateUDPPorts();
+ void CreateTCPPorts();
+ void CreateStunPorts();
+ void CreateRelayPorts();
+ void CreateGturnPort(const RelayServerConfig& config);
+ void CreateTurnPort(const RelayServerConfig& config);
+
+ void OnReadPacket(rtc::AsyncPacketSocket* socket,
+ const char* data, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time);
+
+ void OnPortDestroyed(PortInterface* port);
+
+ BasicPortAllocatorSession* session_;
+ rtc::Network* network_;
+ rtc::IPAddress ip_;
+ PortConfiguration* config_;
+ State state_;
+ uint32 flags_;
+ ProtocolList protocols_;
+ rtc::scoped_ptr<rtc::AsyncPacketSocket> udp_socket_;
+ // There will be only one udp port per AllocationSequence.
+ UDPPort* udp_port_;
+ std::vector<TurnPort*> turn_ports_;
+ int phase_;
+};
+
+// BasicPortAllocator
+BasicPortAllocator::BasicPortAllocator(
+ rtc::NetworkManager* network_manager,
+ rtc::PacketSocketFactory* socket_factory)
+ : network_manager_(network_manager),
+ socket_factory_(socket_factory) {
+ ASSERT(socket_factory_ != NULL);
+ Construct();
+}
+
+BasicPortAllocator::BasicPortAllocator(
+ rtc::NetworkManager* network_manager)
+ : network_manager_(network_manager),
+ socket_factory_(NULL) {
+ Construct();
+}
+
+BasicPortAllocator::BasicPortAllocator(
+ rtc::NetworkManager* network_manager,
+ rtc::PacketSocketFactory* socket_factory,
+ const ServerAddresses& stun_servers)
+ : network_manager_(network_manager),
+ socket_factory_(socket_factory),
+ stun_servers_(stun_servers) {
+ ASSERT(socket_factory_ != NULL);
+ Construct();
+}
+
+BasicPortAllocator::BasicPortAllocator(
+ rtc::NetworkManager* network_manager,
+ const ServerAddresses& stun_servers,
+ const rtc::SocketAddress& relay_address_udp,
+ const rtc::SocketAddress& relay_address_tcp,
+ const rtc::SocketAddress& relay_address_ssl)
+ : network_manager_(network_manager),
+ socket_factory_(NULL),
+ stun_servers_(stun_servers) {
+
+ RelayServerConfig config(RELAY_GTURN);
+ if (!relay_address_udp.IsNil())
+ config.ports.push_back(ProtocolAddress(relay_address_udp, PROTO_UDP));
+ if (!relay_address_tcp.IsNil())
+ config.ports.push_back(ProtocolAddress(relay_address_tcp, PROTO_TCP));
+ if (!relay_address_ssl.IsNil())
+ config.ports.push_back(ProtocolAddress(relay_address_ssl, PROTO_SSLTCP));
+
+ if (!config.ports.empty())
+ AddRelay(config);
+
+ Construct();
+}
+
+void BasicPortAllocator::Construct() {
+ allow_tcp_listen_ = true;
+}
+
+BasicPortAllocator::~BasicPortAllocator() {
+}
+
+PortAllocatorSession *BasicPortAllocator::CreateSessionInternal(
+ const std::string& content_name, int component,
+ const std::string& ice_ufrag, const std::string& ice_pwd) {
+ return new BasicPortAllocatorSession(
+ this, content_name, component, ice_ufrag, ice_pwd);
+}
+
+
+// BasicPortAllocatorSession
+BasicPortAllocatorSession::BasicPortAllocatorSession(
+ BasicPortAllocator *allocator,
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd)
+ : PortAllocatorSession(content_name, component,
+ ice_ufrag, ice_pwd, allocator->flags()),
+ allocator_(allocator), network_thread_(NULL),
+ socket_factory_(allocator->socket_factory()),
+ allocation_started_(false),
+ network_manager_started_(false),
+ running_(false),
+ allocation_sequences_created_(false) {
+ allocator_->network_manager()->SignalNetworksChanged.connect(
+ this, &BasicPortAllocatorSession::OnNetworksChanged);
+ allocator_->network_manager()->StartUpdating();
+}
+
+BasicPortAllocatorSession::~BasicPortAllocatorSession() {
+ allocator_->network_manager()->StopUpdating();
+ if (network_thread_ != NULL)
+ network_thread_->Clear(this);
+
+ for (uint32 i = 0; i < sequences_.size(); ++i) {
+ // AllocationSequence should clear it's map entry for turn ports before
+ // ports are destroyed.
+ sequences_[i]->Clear();
+ }
+
+ std::vector<PortData>::iterator it;
+ for (it = ports_.begin(); it != ports_.end(); it++)
+ delete it->port();
+
+ for (uint32 i = 0; i < configs_.size(); ++i)
+ delete configs_[i];
+
+ for (uint32 i = 0; i < sequences_.size(); ++i)
+ delete sequences_[i];
+}
+
+void BasicPortAllocatorSession::StartGettingPorts() {
+ network_thread_ = rtc::Thread::Current();
+ if (!socket_factory_) {
+ owned_socket_factory_.reset(
+ new rtc::BasicPacketSocketFactory(network_thread_));
+ socket_factory_ = owned_socket_factory_.get();
+ }
+
+ running_ = true;
+ network_thread_->Post(this, MSG_CONFIG_START);
+
+ if (flags() & PORTALLOCATOR_ENABLE_SHAKER)
+ network_thread_->PostDelayed(ShakeDelay(), this, MSG_SHAKE);
+}
+
+void BasicPortAllocatorSession::StopGettingPorts() {
+ ASSERT(rtc::Thread::Current() == network_thread_);
+ running_ = false;
+ network_thread_->Clear(this, MSG_ALLOCATE);
+ for (uint32 i = 0; i < sequences_.size(); ++i)
+ sequences_[i]->Stop();
+ network_thread_->Post(this, MSG_CONFIG_STOP);
+}
+
+void BasicPortAllocatorSession::OnMessage(rtc::Message *message) {
+ switch (message->message_id) {
+ case MSG_CONFIG_START:
+ ASSERT(rtc::Thread::Current() == network_thread_);
+ GetPortConfigurations();
+ break;
+
+ case MSG_CONFIG_READY:
+ ASSERT(rtc::Thread::Current() == network_thread_);
+ OnConfigReady(static_cast<PortConfiguration*>(message->pdata));
+ break;
+
+ case MSG_ALLOCATE:
+ ASSERT(rtc::Thread::Current() == network_thread_);
+ OnAllocate();
+ break;
+
+ case MSG_SHAKE:
+ ASSERT(rtc::Thread::Current() == network_thread_);
+ OnShake();
+ break;
+ case MSG_SEQUENCEOBJECTS_CREATED:
+ ASSERT(rtc::Thread::Current() == network_thread_);
+ OnAllocationSequenceObjectsCreated();
+ break;
+ case MSG_CONFIG_STOP:
+ ASSERT(rtc::Thread::Current() == network_thread_);
+ OnConfigStop();
+ break;
+ default:
+ ASSERT(false);
+ }
+}
+
+void BasicPortAllocatorSession::GetPortConfigurations() {
+ PortConfiguration* config = new PortConfiguration(allocator_->stun_servers(),
+ username(),
+ password());
+
+ for (size_t i = 0; i < allocator_->relays().size(); ++i) {
+ config->AddRelay(allocator_->relays()[i]);
+ }
+ ConfigReady(config);
+}
+
+void BasicPortAllocatorSession::ConfigReady(PortConfiguration* config) {
+ network_thread_->Post(this, MSG_CONFIG_READY, config);
+}
+
+// Adds a configuration to the list.
+void BasicPortAllocatorSession::OnConfigReady(PortConfiguration* config) {
+ if (config)
+ configs_.push_back(config);
+
+ AllocatePorts();
+}
+
+void BasicPortAllocatorSession::OnConfigStop() {
+ ASSERT(rtc::Thread::Current() == network_thread_);
+
+ // If any of the allocated ports have not completed the candidates allocation,
+ // mark those as error. Since session doesn't need any new candidates
+ // at this stage of the allocation, it's safe to discard any new candidates.
+ bool send_signal = false;
+ for (std::vector<PortData>::iterator it = ports_.begin();
+ it != ports_.end(); ++it) {
+ if (!it->complete()) {
+ // Updating port state to error, which didn't finish allocating candidates
+ // yet.
+ it->set_error();
+ send_signal = true;
+ }
+ }
+
+ // Did we stop any running sequences?
+ for (std::vector<AllocationSequence*>::iterator it = sequences_.begin();
+ it != sequences_.end() && !send_signal; ++it) {
+ if ((*it)->state() == AllocationSequence::kStopped) {
+ send_signal = true;
+ }
+ }
+
+ // If we stopped anything that was running, send a done signal now.
+ if (send_signal) {
+ MaybeSignalCandidatesAllocationDone();
+ }
+}
+
+void BasicPortAllocatorSession::AllocatePorts() {
+ ASSERT(rtc::Thread::Current() == network_thread_);
+ network_thread_->Post(this, MSG_ALLOCATE);
+}
+
+void BasicPortAllocatorSession::OnAllocate() {
+ if (network_manager_started_)
+ DoAllocate();
+
+ allocation_started_ = true;
+}
+
+// For each network, see if we have a sequence that covers it already. If not,
+// create a new sequence to create the appropriate ports.
+void BasicPortAllocatorSession::DoAllocate() {
+ bool done_signal_needed = false;
+ std::vector<rtc::Network*> networks;
+ allocator_->network_manager()->GetNetworks(&networks);
+ if (networks.empty()) {
+ LOG(LS_WARNING) << "Machine has no networks; no ports will be allocated";
+ done_signal_needed = true;
+ } else {
+ for (uint32 i = 0; i < networks.size(); ++i) {
+ PortConfiguration* config = NULL;
+ if (configs_.size() > 0)
+ config = configs_.back();
+
+ uint32 sequence_flags = flags();
+ if ((sequence_flags & DISABLE_ALL_PHASES) == DISABLE_ALL_PHASES) {
+ // If all the ports are disabled we should just fire the allocation
+ // done event and return.
+ done_signal_needed = true;
+ break;
+ }
+
+ // Disables phases that are not specified in this config.
+ if (!config || config->StunServers().empty()) {
+ // No STUN ports specified in this config.
+ sequence_flags |= PORTALLOCATOR_DISABLE_STUN;
+ }
+ if (!config || config->relays.empty()) {
+ // No relay ports specified in this config.
+ sequence_flags |= PORTALLOCATOR_DISABLE_RELAY;
+ }
+
+ if (!(sequence_flags & PORTALLOCATOR_ENABLE_IPV6) &&
+#ifdef USE_WEBRTC_DEV_BRANCH
+ networks[i]->GetBestIP().family() == AF_INET6) {
+#else // USE_WEBRTC_DEV_BRANCH
+ networks[i]->ip().family() == AF_INET6) {
+#endif // USE_WEBRTC_DEV_BRANCH
+ // Skip IPv6 networks unless the flag's been set.
+ continue;
+ }
+
+ // Disable phases that would only create ports equivalent to
+ // ones that we have already made.
+ DisableEquivalentPhases(networks[i], config, &sequence_flags);
+
+ if ((sequence_flags & DISABLE_ALL_PHASES) == DISABLE_ALL_PHASES) {
+ // New AllocationSequence would have nothing to do, so don't make it.
+ continue;
+ }
+
+ AllocationSequence* sequence =
+ new AllocationSequence(this, networks[i], config, sequence_flags);
+ if (!sequence->Init()) {
+ delete sequence;
+ continue;
+ }
+ done_signal_needed = true;
+ sequence->SignalPortAllocationComplete.connect(
+ this, &BasicPortAllocatorSession::OnPortAllocationComplete);
+ if (running_)
+ sequence->Start();
+ sequences_.push_back(sequence);
+ }
+ }
+ if (done_signal_needed) {
+ network_thread_->Post(this, MSG_SEQUENCEOBJECTS_CREATED);
+ }
+}
+
+void BasicPortAllocatorSession::OnNetworksChanged() {
+ network_manager_started_ = true;
+ if (allocation_started_)
+ DoAllocate();
+}
+
+void BasicPortAllocatorSession::DisableEquivalentPhases(
+ rtc::Network* network, PortConfiguration* config, uint32* flags) {
+ for (uint32 i = 0; i < sequences_.size() &&
+ (*flags & DISABLE_ALL_PHASES) != DISABLE_ALL_PHASES; ++i) {
+ sequences_[i]->DisableEquivalentPhases(network, config, flags);
+ }
+}
+
+void BasicPortAllocatorSession::AddAllocatedPort(Port* port,
+ AllocationSequence * seq,
+ bool prepare_address) {
+ if (!port)
+ return;
+
+ LOG(LS_INFO) << "Adding allocated port for " << content_name();
+ port->set_content_name(content_name());
+ port->set_component(component_);
+ port->set_generation(generation());
+ if (allocator_->proxy().type != rtc::PROXY_NONE)
+ port->set_proxy(allocator_->user_agent(), allocator_->proxy());
+ port->set_send_retransmit_count_attribute((allocator_->flags() &
+ PORTALLOCATOR_ENABLE_STUN_RETRANSMIT_ATTRIBUTE) != 0);
+
+ // Push down the candidate_filter to individual port.
+ port->set_candidate_filter(allocator_->candidate_filter());
+
+ PortData data(port, seq);
+ ports_.push_back(data);
+
+ port->SignalCandidateReady.connect(
+ this, &BasicPortAllocatorSession::OnCandidateReady);
+ port->SignalPortComplete.connect(this,
+ &BasicPortAllocatorSession::OnPortComplete);
+ port->SignalDestroyed.connect(this,
+ &BasicPortAllocatorSession::OnPortDestroyed);
+ port->SignalPortError.connect(
+ this, &BasicPortAllocatorSession::OnPortError);
+ LOG_J(LS_INFO, port) << "Added port to allocator";
+
+ if (prepare_address)
+ port->PrepareAddress();
+}
+
+void BasicPortAllocatorSession::OnAllocationSequenceObjectsCreated() {
+ allocation_sequences_created_ = true;
+ // Send candidate allocation complete signal if we have no sequences.
+ MaybeSignalCandidatesAllocationDone();
+}
+
+void BasicPortAllocatorSession::OnCandidateReady(
+ Port* port, const Candidate& c) {
+ ASSERT(rtc::Thread::Current() == network_thread_);
+ PortData* data = FindPort(port);
+ ASSERT(data != NULL);
+ // Discarding any candidate signal if port allocation status is
+ // already in completed state.
+ if (data->complete())
+ return;
+
+ // Send candidates whose protocol is enabled.
+ std::vector<Candidate> candidates;
+ ProtocolType pvalue;
+ bool candidate_allowed_to_send = CheckCandidateFilter(c);
+ if (StringToProto(c.protocol().c_str(), &pvalue) &&
+ data->sequence()->ProtocolEnabled(pvalue) &&
+ candidate_allowed_to_send) {
+ candidates.push_back(c);
+ }
+
+ if (!candidates.empty()) {
+ SignalCandidatesReady(this, candidates);
+ }
+
+ // Moving to READY state as we have atleast one candidate from the port.
+ // Since this port has atleast one candidate we should forward this port
+ // to listners, to allow connections from this port.
+ // Also we should make sure that candidate gathered from this port is allowed
+ // to send outside.
+ if (!data->ready() && candidate_allowed_to_send) {
+ data->set_ready();
+ SignalPortReady(this, port);
+ }
+}
+
+void BasicPortAllocatorSession::OnPortComplete(Port* port) {
+ ASSERT(rtc::Thread::Current() == network_thread_);
+ PortData* data = FindPort(port);
+ ASSERT(data != NULL);
+
+ // Ignore any late signals.
+ if (data->complete())
+ return;
+
+ // Moving to COMPLETE state.
+ data->set_complete();
+ // Send candidate allocation complete signal if this was the last port.
+ MaybeSignalCandidatesAllocationDone();
+}
+
+void BasicPortAllocatorSession::OnPortError(Port* port) {
+ ASSERT(rtc::Thread::Current() == network_thread_);
+ PortData* data = FindPort(port);
+ ASSERT(data != NULL);
+ // We might have already given up on this port and stopped it.
+ if (data->complete())
+ return;
+
+ // SignalAddressError is currently sent from StunPort/TurnPort.
+ // But this signal itself is generic.
+ data->set_error();
+ // Send candidate allocation complete signal if this was the last port.
+ MaybeSignalCandidatesAllocationDone();
+}
+
+void BasicPortAllocatorSession::OnProtocolEnabled(AllocationSequence* seq,
+ ProtocolType proto) {
+ std::vector<Candidate> candidates;
+ for (std::vector<PortData>::iterator it = ports_.begin();
+ it != ports_.end(); ++it) {
+ if (it->sequence() != seq)
+ continue;
+
+ const std::vector<Candidate>& potentials = it->port()->Candidates();
+ for (size_t i = 0; i < potentials.size(); ++i) {
+ if (!CheckCandidateFilter(potentials[i]))
+ continue;
+ ProtocolType pvalue;
+ if (!StringToProto(potentials[i].protocol().c_str(), &pvalue))
+ continue;
+ if (pvalue == proto) {
+ candidates.push_back(potentials[i]);
+ }
+ }
+ }
+
+ if (!candidates.empty()) {
+ SignalCandidatesReady(this, candidates);
+ }
+}
+
+bool BasicPortAllocatorSession::CheckCandidateFilter(const Candidate& c) {
+ uint32 filter = allocator_->candidate_filter();
+ bool allowed = false;
+ if (filter & CF_RELAY) {
+ allowed |= (c.type() == RELAY_PORT_TYPE);
+ }
+
+ if (filter & CF_REFLEXIVE) {
+ // We allow host candidates if the filter allows server-reflexive candidates
+ // and the candidate is a public IP. Because we don't generate
+ // server-reflexive candidates if they have the same IP as the host
+ // candidate (i.e. when the host candidate is a public IP), filtering to
+ // only server-reflexive candidates won't work right when the host
+ // candidates have public IPs.
+ allowed |= (c.type() == STUN_PORT_TYPE) ||
+ (c.type() == LOCAL_PORT_TYPE && !c.address().IsPrivateIP());
+ }
+
+ if (filter & CF_HOST) {
+ allowed |= (c.type() == LOCAL_PORT_TYPE);
+ }
+
+ return allowed;
+}
+
+void BasicPortAllocatorSession::OnPortAllocationComplete(
+ AllocationSequence* seq) {
+ // Send candidate allocation complete signal if all ports are done.
+ MaybeSignalCandidatesAllocationDone();
+}
+
+void BasicPortAllocatorSession::MaybeSignalCandidatesAllocationDone() {
+ // Send signal only if all required AllocationSequence objects
+ // are created.
+ if (!allocation_sequences_created_)
+ return;
+
+ // Check that all port allocation sequences are complete.
+ for (std::vector<AllocationSequence*>::iterator it = sequences_.begin();
+ it != sequences_.end(); ++it) {
+ if ((*it)->state() == AllocationSequence::kRunning)
+ return;
+ }
+
+ // If all allocated ports are in complete state, session must have got all
+ // expected candidates. Session will trigger candidates allocation complete
+ // signal.
+ for (std::vector<PortData>::iterator it = ports_.begin();
+ it != ports_.end(); ++it) {
+ if (!it->complete())
+ return;
+ }
+ LOG(LS_INFO) << "All candidates gathered for " << content_name_ << ":"
+ << component_ << ":" << generation();
+ SignalCandidatesAllocationDone(this);
+}
+
+void BasicPortAllocatorSession::OnPortDestroyed(
+ PortInterface* port) {
+ ASSERT(rtc::Thread::Current() == network_thread_);
+ for (std::vector<PortData>::iterator iter = ports_.begin();
+ iter != ports_.end(); ++iter) {
+ if (port == iter->port()) {
+ ports_.erase(iter);
+ LOG_J(LS_INFO, port) << "Removed port from allocator ("
+ << static_cast<int>(ports_.size()) << " remaining)";
+ return;
+ }
+ }
+ ASSERT(false);
+}
+
+void BasicPortAllocatorSession::OnShake() {
+ LOG(INFO) << ">>>>> SHAKE <<<<< >>>>> SHAKE <<<<< >>>>> SHAKE <<<<<";
+
+ std::vector<Port*> ports;
+ std::vector<Connection*> connections;
+
+ for (size_t i = 0; i < ports_.size(); ++i) {
+ if (ports_[i].ready())
+ ports.push_back(ports_[i].port());
+ }
+
+ for (size_t i = 0; i < ports.size(); ++i) {
+ Port::AddressMap::const_iterator iter;
+ for (iter = ports[i]->connections().begin();
+ iter != ports[i]->connections().end();
+ ++iter) {
+ connections.push_back(iter->second);
+ }
+ }
+
+ LOG(INFO) << ">>>>> Destroying " << ports.size() << " ports and "
+ << connections.size() << " connections";
+
+ for (size_t i = 0; i < connections.size(); ++i)
+ connections[i]->Destroy();
+
+ if (running_ || (ports.size() > 0) || (connections.size() > 0))
+ network_thread_->PostDelayed(ShakeDelay(), this, MSG_SHAKE);
+}
+
+BasicPortAllocatorSession::PortData* BasicPortAllocatorSession::FindPort(
+ Port* port) {
+ for (std::vector<PortData>::iterator it = ports_.begin();
+ it != ports_.end(); ++it) {
+ if (it->port() == port) {
+ return &*it;
+ }
+ }
+ return NULL;
+}
+
+// AllocationSequence
+
+AllocationSequence::AllocationSequence(BasicPortAllocatorSession* session,
+ rtc::Network* network,
+ PortConfiguration* config,
+ uint32 flags)
+ : session_(session),
+ network_(network),
+
+#ifdef USE_WEBRTC_DEV_BRANCH
+ ip_(network->GetBestIP()),
+#else // USE_WEBRTC_DEV_BRANCH
+ ip_(network->ip()),
+#endif // USE_WEBRTC_DEV_BRANCH
+ config_(config),
+ state_(kInit),
+ flags_(flags),
+ udp_socket_(),
+ udp_port_(NULL),
+ phase_(0) {
+}
+
+bool AllocationSequence::Init() {
+ if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET) &&
+ !IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_UFRAG)) {
+ LOG(LS_ERROR) << "Shared socket option can't be set without "
+ << "shared ufrag.";
+ ASSERT(false);
+ return false;
+ }
+
+ if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET)) {
+ udp_socket_.reset(session_->socket_factory()->CreateUdpSocket(
+ rtc::SocketAddress(ip_, 0), session_->allocator()->min_port(),
+ session_->allocator()->max_port()));
+ if (udp_socket_) {
+ udp_socket_->SignalReadPacket.connect(
+ this, &AllocationSequence::OnReadPacket);
+ }
+ // Continuing if |udp_socket_| is NULL, as local TCP and RelayPort using TCP
+ // are next available options to setup a communication channel.
+ }
+ return true;
+}
+
+void AllocationSequence::Clear() {
+ udp_port_ = NULL;
+ turn_ports_.clear();
+}
+
+AllocationSequence::~AllocationSequence() {
+ session_->network_thread()->Clear(this);
+}
+
+void AllocationSequence::DisableEquivalentPhases(rtc::Network* network,
+ PortConfiguration* config, uint32* flags) {
+#ifdef USE_WEBRTC_DEV_BRANCH
+ if (!((network == network_) && (ip_ == network->GetBestIP()))) {
+#else // USE_WEBRTC_DEV_BRANCH
+ if (!((network == network_) && (ip_ == network->ip()))) {
+#endif // USE_WEBRTC_DEV_BRANCH
+ // Different network setup; nothing is equivalent.
+ return;
+ }
+
+ // Else turn off the stuff that we've already got covered.
+
+ // Every config implicitly specifies local, so turn that off right away.
+ *flags |= PORTALLOCATOR_DISABLE_UDP;
+ *flags |= PORTALLOCATOR_DISABLE_TCP;
+
+ if (config_ && config) {
+ if (config_->StunServers() == config->StunServers()) {
+ // Already got this STUN servers covered.
+ *flags |= PORTALLOCATOR_DISABLE_STUN;
+ }
+ if (!config_->relays.empty()) {
+ // Already got relays covered.
+ // NOTE: This will even skip a _different_ set of relay servers if we
+ // were to be given one, but that never happens in our codebase. Should
+ // probably get rid of the list in PortConfiguration and just keep a
+ // single relay server in each one.
+ *flags |= PORTALLOCATOR_DISABLE_RELAY;
+ }
+ }
+}
+
+void AllocationSequence::Start() {
+ state_ = kRunning;
+ session_->network_thread()->Post(this, MSG_ALLOCATION_PHASE);
+}
+
+void AllocationSequence::Stop() {
+ // If the port is completed, don't set it to stopped.
+ if (state_ == kRunning) {
+ state_ = kStopped;
+ session_->network_thread()->Clear(this, MSG_ALLOCATION_PHASE);
+ }
+}
+
+void AllocationSequence::OnMessage(rtc::Message* msg) {
+ ASSERT(rtc::Thread::Current() == session_->network_thread());
+ ASSERT(msg->message_id == MSG_ALLOCATION_PHASE);
+
+ const char* const PHASE_NAMES[kNumPhases] = {
+ "Udp", "Relay", "Tcp", "SslTcp"
+ };
+
+ // Perform all of the phases in the current step.
+ LOG_J(LS_INFO, network_) << "Allocation Phase="
+ << PHASE_NAMES[phase_];
+
+ switch (phase_) {
+ case PHASE_UDP:
+ CreateUDPPorts();
+ CreateStunPorts();
+ EnableProtocol(PROTO_UDP);
+ break;
+
+ case PHASE_RELAY:
+ CreateRelayPorts();
+ break;
+
+ case PHASE_TCP:
+ CreateTCPPorts();
+ EnableProtocol(PROTO_TCP);
+ break;
+
+ case PHASE_SSLTCP:
+ state_ = kCompleted;
+ EnableProtocol(PROTO_SSLTCP);
+ break;
+
+ default:
+ ASSERT(false);
+ }
+
+ if (state() == kRunning) {
+ ++phase_;
+ session_->network_thread()->PostDelayed(
+ session_->allocator()->step_delay(),
+ this, MSG_ALLOCATION_PHASE);
+ } else {
+ // If all phases in AllocationSequence are completed, no allocation
+ // steps needed further. Canceling pending signal.
+ session_->network_thread()->Clear(this, MSG_ALLOCATION_PHASE);
+ SignalPortAllocationComplete(this);
+ }
+}
+
+void AllocationSequence::EnableProtocol(ProtocolType proto) {
+ if (!ProtocolEnabled(proto)) {
+ protocols_.push_back(proto);
+ session_->OnProtocolEnabled(this, proto);
+ }
+}
+
+bool AllocationSequence::ProtocolEnabled(ProtocolType proto) const {
+ for (ProtocolList::const_iterator it = protocols_.begin();
+ it != protocols_.end(); ++it) {
+ if (*it == proto)
+ return true;
+ }
+ return false;
+}
+
+void AllocationSequence::CreateUDPPorts() {
+ if (IsFlagSet(PORTALLOCATOR_DISABLE_UDP)) {
+ LOG(LS_VERBOSE) << "AllocationSequence: UDP ports disabled, skipping.";
+ return;
+ }
+
+ // TODO(mallinath) - Remove UDPPort creating socket after shared socket
+ // is enabled completely.
+ UDPPort* port = NULL;
+ if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET) && udp_socket_) {
+ port = UDPPort::Create(session_->network_thread(),
+ session_->socket_factory(), network_,
+ udp_socket_.get(),
+ session_->username(), session_->password());
+ } else {
+ port = UDPPort::Create(session_->network_thread(),
+ session_->socket_factory(),
+ network_, ip_,
+ session_->allocator()->min_port(),
+ session_->allocator()->max_port(),
+ session_->username(), session_->password());
+ }
+
+ if (port) {
+ // If shared socket is enabled, STUN candidate will be allocated by the
+ // UDPPort.
+ if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET)) {
+ udp_port_ = port;
+
+ // If STUN is not disabled, setting stun server address to port.
+ if (!IsFlagSet(PORTALLOCATOR_DISABLE_STUN)) {
+ // If config has stun_servers, use it to get server reflexive candidate
+ // otherwise use first TURN server which supports UDP.
+ if (config_ && !config_->StunServers().empty()) {
+ LOG(LS_INFO) << "AllocationSequence: UDPPort will be handling the "
+ << "STUN candidate generation.";
+ port->set_server_addresses(config_->StunServers());
+ } else if (config_ &&
+ config_->SupportsProtocol(RELAY_TURN, PROTO_UDP)) {
+ port->set_server_addresses(config_->GetRelayServerAddresses(
+ RELAY_TURN, PROTO_UDP));
+ LOG(LS_INFO) << "AllocationSequence: TURN Server address will be "
+ << " used for generating STUN candidate.";
+ }
+ }
+ }
+
+ session_->AddAllocatedPort(port, this, true);
+ port->SignalDestroyed.connect(this, &AllocationSequence::OnPortDestroyed);
+ }
+}
+
+void AllocationSequence::CreateTCPPorts() {
+ if (IsFlagSet(PORTALLOCATOR_DISABLE_TCP)) {
+ LOG(LS_VERBOSE) << "AllocationSequence: TCP ports disabled, skipping.";
+ return;
+ }
+
+ Port* port = TCPPort::Create(session_->network_thread(),
+ session_->socket_factory(),
+ network_, ip_,
+ session_->allocator()->min_port(),
+ session_->allocator()->max_port(),
+ session_->username(), session_->password(),
+ session_->allocator()->allow_tcp_listen());
+ if (port) {
+ session_->AddAllocatedPort(port, this, true);
+ // Since TCPPort is not created using shared socket, |port| will not be
+ // added to the dequeue.
+ }
+}
+
+void AllocationSequence::CreateStunPorts() {
+ if (IsFlagSet(PORTALLOCATOR_DISABLE_STUN)) {
+ LOG(LS_VERBOSE) << "AllocationSequence: STUN ports disabled, skipping.";
+ return;
+ }
+
+ if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET)) {
+ return;
+ }
+
+ // If BasicPortAllocatorSession::OnAllocate left STUN ports enabled then we
+ // ought to have an address for them here.
+ ASSERT(config_ && !config_->StunServers().empty());
+ if (!(config_ && !config_->StunServers().empty())) {
+ LOG(LS_WARNING)
+ << "AllocationSequence: No STUN server configured, skipping.";
+ return;
+ }
+
+ StunPort* port = StunPort::Create(session_->network_thread(),
+ session_->socket_factory(),
+ network_, ip_,
+ session_->allocator()->min_port(),
+ session_->allocator()->max_port(),
+ session_->username(), session_->password(),
+ config_->StunServers());
+ if (port) {
+ session_->AddAllocatedPort(port, this, true);
+ // Since StunPort is not created using shared socket, |port| will not be
+ // added to the dequeue.
+ }
+}
+
+void AllocationSequence::CreateRelayPorts() {
+ if (IsFlagSet(PORTALLOCATOR_DISABLE_RELAY)) {
+ LOG(LS_VERBOSE) << "AllocationSequence: Relay ports disabled, skipping.";
+ return;
+ }
+
+ // If BasicPortAllocatorSession::OnAllocate left relay ports enabled then we
+ // ought to have a relay list for them here.
+ ASSERT(config_ && !config_->relays.empty());
+ if (!(config_ && !config_->relays.empty())) {
+ LOG(LS_WARNING)
+ << "AllocationSequence: No relay server configured, skipping.";
+ return;
+ }
+
+ PortConfiguration::RelayList::const_iterator relay;
+ for (relay = config_->relays.begin();
+ relay != config_->relays.end(); ++relay) {
+ if (relay->type == RELAY_GTURN) {
+ CreateGturnPort(*relay);
+ } else if (relay->type == RELAY_TURN) {
+ CreateTurnPort(*relay);
+ } else {
+ ASSERT(false);
+ }
+ }
+}
+
+void AllocationSequence::CreateGturnPort(const RelayServerConfig& config) {
+ // TODO(mallinath) - Rename RelayPort to GTurnPort.
+ RelayPort* port = RelayPort::Create(session_->network_thread(),
+ session_->socket_factory(),
+ network_, ip_,
+ session_->allocator()->min_port(),
+ session_->allocator()->max_port(),
+ config_->username, config_->password);
+ if (port) {
+ // Since RelayPort is not created using shared socket, |port| will not be
+ // added to the dequeue.
+ // Note: We must add the allocated port before we add addresses because
+ // the latter will create candidates that need name and preference
+ // settings. However, we also can't prepare the address (normally
+ // done by AddAllocatedPort) until we have these addresses. So we
+ // wait to do that until below.
+ session_->AddAllocatedPort(port, this, false);
+
+ // Add the addresses of this protocol.
+ PortList::const_iterator relay_port;
+ for (relay_port = config.ports.begin();
+ relay_port != config.ports.end();
+ ++relay_port) {
+ port->AddServerAddress(*relay_port);
+ port->AddExternalAddress(*relay_port);
+ }
+ // Start fetching an address for this port.
+ port->PrepareAddress();
+ }
+}
+
+void AllocationSequence::CreateTurnPort(const RelayServerConfig& config) {
+ PortList::const_iterator relay_port;
+ for (relay_port = config.ports.begin();
+ relay_port != config.ports.end(); ++relay_port) {
+ TurnPort* port = NULL;
+ // Shared socket mode must be enabled only for UDP based ports. Hence
+ // don't pass shared socket for ports which will create TCP sockets.
+ // TODO(mallinath) - Enable shared socket mode for TURN ports. Disabled
+ // due to webrtc bug https://code.google.com/p/webrtc/issues/detail?id=3537
+ if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET) &&
+ relay_port->proto == PROTO_UDP) {
+ port = TurnPort::Create(session_->network_thread(),
+ session_->socket_factory(),
+ network_, udp_socket_.get(),
+ session_->username(), session_->password(),
+ *relay_port, config.credentials, config.priority);
+
+ turn_ports_.push_back(port);
+ // Listen to the port destroyed signal, to allow AllocationSequence to
+ // remove entrt from it's map.
+ port->SignalDestroyed.connect(this, &AllocationSequence::OnPortDestroyed);
+ } else {
+ port = TurnPort::Create(session_->network_thread(),
+ session_->socket_factory(),
+ network_, ip_,
+ session_->allocator()->min_port(),
+ session_->allocator()->max_port(),
+ session_->username(),
+ session_->password(),
+ *relay_port, config.credentials, config.priority);
+ }
+ ASSERT(port != NULL);
+ session_->AddAllocatedPort(port, this, true);
+ }
+}
+
+void AllocationSequence::OnReadPacket(
+ rtc::AsyncPacketSocket* socket, const char* data, size_t size,
+ const rtc::SocketAddress& remote_addr,
+ const rtc::PacketTime& packet_time) {
+ ASSERT(socket == udp_socket_.get());
+
+ bool turn_port_found = false;
+
+ // Try to find the TurnPort that matches the remote address. Note that the
+ // message could be a STUN binding response if the TURN server is also used as
+ // a STUN server. We don't want to parse every message here to check if it is
+ // a STUN binding response, so we pass the message to TurnPort regardless of
+ // the message type. The TurnPort will just ignore the message since it will
+ // not find any request by transaction ID.
+ for (std::vector<TurnPort*>::const_iterator it = turn_ports_.begin();
+ it != turn_ports_.end(); ++it) {
+ TurnPort* port = *it;
+ if (port->server_address().address == remote_addr) {
+ port->HandleIncomingPacket(socket, data, size, remote_addr, packet_time);
+ turn_port_found = true;
+ break;
+ }
+ }
+
+ if (udp_port_) {
+ const ServerAddresses& stun_servers = udp_port_->server_addresses();
+
+ // Pass the packet to the UdpPort if there is no matching TurnPort, or if
+ // the TURN server is also a STUN server.
+ if (!turn_port_found ||
+ stun_servers.find(remote_addr) != stun_servers.end()) {
+ udp_port_->HandleIncomingPacket(
+ socket, data, size, remote_addr, packet_time);
+ }
+ }
+}
+
+void AllocationSequence::OnPortDestroyed(PortInterface* port) {
+ if (udp_port_ == port) {
+ udp_port_ = NULL;
+ return;
+ }
+
+ turn_ports_.erase(std::find(turn_ports_.begin(), turn_ports_.end(), port));
+}
+
+// PortConfiguration
+PortConfiguration::PortConfiguration(
+ const rtc::SocketAddress& stun_address,
+ const std::string& username,
+ const std::string& password)
+ : stun_address(stun_address), username(username), password(password) {
+ if (!stun_address.IsNil())
+ stun_servers.insert(stun_address);
+}
+
+PortConfiguration::PortConfiguration(const ServerAddresses& stun_servers,
+ const std::string& username,
+ const std::string& password)
+ : stun_servers(stun_servers),
+ username(username),
+ password(password) {
+ if (!stun_servers.empty())
+ stun_address = *(stun_servers.begin());
+}
+
+ServerAddresses PortConfiguration::StunServers() {
+ if (!stun_address.IsNil() &&
+ stun_servers.find(stun_address) == stun_servers.end()) {
+ stun_servers.insert(stun_address);
+ }
+ return stun_servers;
+}
+
+void PortConfiguration::AddRelay(const RelayServerConfig& config) {
+ relays.push_back(config);
+}
+
+bool PortConfiguration::SupportsProtocol(
+ const RelayServerConfig& relay, ProtocolType type) const {
+ PortList::const_iterator relay_port;
+ for (relay_port = relay.ports.begin();
+ relay_port != relay.ports.end();
+ ++relay_port) {
+ if (relay_port->proto == type)
+ return true;
+ }
+ return false;
+}
+
+bool PortConfiguration::SupportsProtocol(RelayType turn_type,
+ ProtocolType type) const {
+ for (size_t i = 0; i < relays.size(); ++i) {
+ if (relays[i].type == turn_type &&
+ SupportsProtocol(relays[i], type))
+ return true;
+ }
+ return false;
+}
+
+ServerAddresses PortConfiguration::GetRelayServerAddresses(
+ RelayType turn_type, ProtocolType type) const {
+ ServerAddresses servers;
+ for (size_t i = 0; i < relays.size(); ++i) {
+ if (relays[i].type == turn_type && SupportsProtocol(relays[i], type)) {
+ servers.insert(relays[i].ports.front().address);
+ }
+ }
+ return servers;
+}
+
+} // namespace cricket
diff --git a/p2p/client/basicportallocator.h b/p2p/client/basicportallocator.h
new file mode 100644
index 00000000..96468d32
--- /dev/null
+++ b/p2p/client/basicportallocator.h
@@ -0,0 +1,241 @@
+/*
+ * 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 WEBRTC_P2P_CLIENT_BASICPORTALLOCATOR_H_
+#define WEBRTC_P2P_CLIENT_BASICPORTALLOCATOR_H_
+
+#include <string>
+#include <vector>
+
+#include "webrtc/p2p/base/port.h"
+#include "webrtc/p2p/base/portallocator.h"
+#include "webrtc/base/messagequeue.h"
+#include "webrtc/base/network.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/thread.h"
+
+namespace cricket {
+
+struct RelayCredentials {
+ RelayCredentials() {}
+ RelayCredentials(const std::string& username,
+ const std::string& password)
+ : username(username),
+ password(password) {
+ }
+
+ std::string username;
+ std::string password;
+};
+
+typedef std::vector<ProtocolAddress> PortList;
+struct RelayServerConfig {
+ RelayServerConfig(RelayType type) : type(type), priority(0) {}
+
+ RelayType type;
+ PortList ports;
+ RelayCredentials credentials;
+ int priority;
+};
+
+class BasicPortAllocator : public PortAllocator {
+ public:
+ BasicPortAllocator(rtc::NetworkManager* network_manager,
+ rtc::PacketSocketFactory* socket_factory);
+ explicit BasicPortAllocator(rtc::NetworkManager* network_manager);
+ BasicPortAllocator(rtc::NetworkManager* network_manager,
+ rtc::PacketSocketFactory* socket_factory,
+ const ServerAddresses& stun_servers);
+ BasicPortAllocator(rtc::NetworkManager* network_manager,
+ const ServerAddresses& stun_servers,
+ const rtc::SocketAddress& relay_server_udp,
+ const rtc::SocketAddress& relay_server_tcp,
+ const rtc::SocketAddress& relay_server_ssl);
+ virtual ~BasicPortAllocator();
+
+ rtc::NetworkManager* network_manager() { return network_manager_; }
+
+ // If socket_factory() is set to NULL each PortAllocatorSession
+ // creates its own socket factory.
+ rtc::PacketSocketFactory* socket_factory() { return socket_factory_; }
+
+ const ServerAddresses& stun_servers() const {
+ return stun_servers_;
+ }
+
+ const std::vector<RelayServerConfig>& relays() const {
+ return relays_;
+ }
+ virtual void AddRelay(const RelayServerConfig& relay) {
+ relays_.push_back(relay);
+ }
+
+ virtual PortAllocatorSession* CreateSessionInternal(
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd);
+
+ private:
+ void Construct();
+
+ rtc::NetworkManager* network_manager_;
+ rtc::PacketSocketFactory* socket_factory_;
+ const ServerAddresses stun_servers_;
+ std::vector<RelayServerConfig> relays_;
+ bool allow_tcp_listen_;
+};
+
+struct PortConfiguration;
+class AllocationSequence;
+
+class BasicPortAllocatorSession : public PortAllocatorSession,
+ public rtc::MessageHandler {
+ public:
+ BasicPortAllocatorSession(BasicPortAllocator* allocator,
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd);
+ ~BasicPortAllocatorSession();
+
+ virtual BasicPortAllocator* allocator() { return allocator_; }
+ rtc::Thread* network_thread() { return network_thread_; }
+ rtc::PacketSocketFactory* socket_factory() { return socket_factory_; }
+
+ virtual void StartGettingPorts();
+ virtual void StopGettingPorts();
+ virtual bool IsGettingPorts() { return running_; }
+
+ protected:
+ // Starts the process of getting the port configurations.
+ virtual void GetPortConfigurations();
+
+ // Adds a port configuration that is now ready. Once we have one for each
+ // network (or a timeout occurs), we will start allocating ports.
+ virtual void ConfigReady(PortConfiguration* config);
+
+ // MessageHandler. Can be overriden if message IDs do not conflict.
+ virtual void OnMessage(rtc::Message *message);
+
+ private:
+ class PortData {
+ public:
+ PortData() : port_(NULL), sequence_(NULL), state_(STATE_INIT) {}
+ PortData(Port* port, AllocationSequence* seq)
+ : port_(port), sequence_(seq), state_(STATE_INIT) {
+ }
+
+ Port* port() { return port_; }
+ AllocationSequence* sequence() { return sequence_; }
+ bool ready() const { return state_ == STATE_READY; }
+ bool complete() const {
+ // Returns true if candidate allocation has completed one way or another.
+ return ((state_ == STATE_COMPLETE) || (state_ == STATE_ERROR));
+ }
+
+ void set_ready() { ASSERT(state_ == STATE_INIT); state_ = STATE_READY; }
+ void set_complete() {
+ state_ = STATE_COMPLETE;
+ }
+ void set_error() {
+ ASSERT(state_ == STATE_INIT || state_ == STATE_READY);
+ state_ = STATE_ERROR;
+ }
+
+ private:
+ enum State {
+ STATE_INIT, // No candidates allocated yet.
+ STATE_READY, // At least one candidate is ready for process.
+ STATE_COMPLETE, // All candidates allocated and ready for process.
+ STATE_ERROR // Error in gathering candidates.
+ };
+ Port* port_;
+ AllocationSequence* sequence_;
+ State state_;
+ };
+
+ void OnConfigReady(PortConfiguration* config);
+ void OnConfigStop();
+ void AllocatePorts();
+ void OnAllocate();
+ void DoAllocate();
+ void OnNetworksChanged();
+ void OnAllocationSequenceObjectsCreated();
+ void DisableEquivalentPhases(rtc::Network* network,
+ PortConfiguration* config, uint32* flags);
+ void AddAllocatedPort(Port* port, AllocationSequence* seq,
+ bool prepare_address);
+ void OnCandidateReady(Port* port, const Candidate& c);
+ void OnPortComplete(Port* port);
+ void OnPortError(Port* port);
+ void OnProtocolEnabled(AllocationSequence* seq, ProtocolType proto);
+ void OnPortDestroyed(PortInterface* port);
+ void OnShake();
+ void MaybeSignalCandidatesAllocationDone();
+ void OnPortAllocationComplete(AllocationSequence* seq);
+ PortData* FindPort(Port* port);
+
+ bool CheckCandidateFilter(const Candidate& c);
+
+ BasicPortAllocator* allocator_;
+ rtc::Thread* network_thread_;
+ rtc::scoped_ptr<rtc::PacketSocketFactory> owned_socket_factory_;
+ rtc::PacketSocketFactory* socket_factory_;
+ bool allocation_started_;
+ bool network_manager_started_;
+ bool running_; // set when StartGetAllPorts is called
+ bool allocation_sequences_created_;
+ std::vector<PortConfiguration*> configs_;
+ std::vector<AllocationSequence*> sequences_;
+ std::vector<PortData> ports_;
+
+ friend class AllocationSequence;
+};
+
+// Records configuration information useful in creating ports.
+struct PortConfiguration : public rtc::MessageData {
+ // TODO(jiayl): remove |stun_address| when Chrome is updated.
+ rtc::SocketAddress stun_address;
+ ServerAddresses stun_servers;
+ std::string username;
+ std::string password;
+
+ typedef std::vector<RelayServerConfig> RelayList;
+ RelayList relays;
+
+ // TODO(jiayl): remove this ctor when Chrome is updated.
+ PortConfiguration(const rtc::SocketAddress& stun_address,
+ const std::string& username,
+ const std::string& password);
+
+ PortConfiguration(const ServerAddresses& stun_servers,
+ const std::string& username,
+ const std::string& password);
+
+ // TODO(jiayl): remove when |stun_address| is removed.
+ ServerAddresses StunServers();
+
+ // Adds another relay server, with the given ports and modifier, to the list.
+ void AddRelay(const RelayServerConfig& config);
+
+ // Determines whether the given relay server supports the given protocol.
+ bool SupportsProtocol(const RelayServerConfig& relay,
+ ProtocolType type) const;
+ bool SupportsProtocol(RelayType turn_type, ProtocolType type) const;
+ // Helper method returns the server addresses for the matching RelayType and
+ // Protocol type.
+ ServerAddresses GetRelayServerAddresses(
+ RelayType turn_type, ProtocolType type) const;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_CLIENT_BASICPORTALLOCATOR_H_
diff --git a/p2p/client/connectivitychecker.cc b/p2p/client/connectivitychecker.cc
new file mode 100644
index 00000000..6e3598e7
--- /dev/null
+++ b/p2p/client/connectivitychecker.cc
@@ -0,0 +1,573 @@
+/*
+ * 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.
+ */
+
+#include <string>
+
+#include "webrtc/p2p/client/connectivitychecker.h"
+
+#include "webrtc/p2p/base/candidate.h"
+#include "webrtc/p2p/base/common.h"
+#include "webrtc/p2p/base/constants.h"
+#include "webrtc/p2p/base/port.h"
+#include "webrtc/p2p/base/relayport.h"
+#include "webrtc/p2p/base/stunport.h"
+#include "webrtc/base/asynchttprequest.h"
+#include "webrtc/base/autodetectproxy.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/httpcommon-inl.h"
+#include "webrtc/base/httpcommon.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/proxydetect.h"
+#include "webrtc/base/thread.h"
+
+namespace cricket {
+
+static const char kDefaultStunHostname[] = "stun.l.google.com";
+static const int kDefaultStunPort = 19302;
+
+// Default maximum time in milliseconds we will wait for connections.
+static const uint32 kDefaultTimeoutMs = 3000;
+
+enum {
+ MSG_START = 1,
+ MSG_STOP = 2,
+ MSG_TIMEOUT = 3,
+ MSG_SIGNAL_RESULTS = 4
+};
+
+class TestHttpPortAllocator : public HttpPortAllocator {
+ public:
+ TestHttpPortAllocator(rtc::NetworkManager* network_manager,
+ const std::string& user_agent,
+ const std::string& relay_token) :
+ HttpPortAllocator(network_manager, user_agent) {
+ SetRelayToken(relay_token);
+ }
+ PortAllocatorSession* CreateSessionInternal(
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd) {
+ return new TestHttpPortAllocatorSession(this, content_name, component,
+ ice_ufrag, ice_pwd,
+ stun_hosts(), relay_hosts(),
+ relay_token(), user_agent());
+ }
+};
+
+void TestHttpPortAllocatorSession::ConfigReady(PortConfiguration* config) {
+ SignalConfigReady(username(), password(), config, proxy_);
+ delete config;
+}
+
+void TestHttpPortAllocatorSession::OnRequestDone(
+ rtc::SignalThread* data) {
+ rtc::AsyncHttpRequest* request =
+ static_cast<rtc::AsyncHttpRequest*>(data);
+
+ // Tell the checker that the request is complete.
+ SignalRequestDone(request);
+
+ // Pass on the response to super class.
+ HttpPortAllocatorSession::OnRequestDone(data);
+}
+
+ConnectivityChecker::ConnectivityChecker(
+ rtc::Thread* worker,
+ const std::string& jid,
+ const std::string& session_id,
+ const std::string& user_agent,
+ const std::string& relay_token,
+ const std::string& connection)
+ : worker_(worker),
+ jid_(jid),
+ session_id_(session_id),
+ user_agent_(user_agent),
+ relay_token_(relay_token),
+ connection_(connection),
+ proxy_detect_(NULL),
+ timeout_ms_(kDefaultTimeoutMs),
+ stun_address_(kDefaultStunHostname, kDefaultStunPort),
+ started_(false) {
+}
+
+ConnectivityChecker::~ConnectivityChecker() {
+ if (started_) {
+ // We try to clear the TIMEOUT below. But worker may still handle it and
+ // cause SignalCheckDone to happen on main-thread. So we finally clear any
+ // pending SIGNAL_RESULTS.
+ worker_->Clear(this, MSG_TIMEOUT);
+ worker_->Send(this, MSG_STOP);
+ nics_.clear();
+ main_->Clear(this, MSG_SIGNAL_RESULTS);
+ }
+}
+
+bool ConnectivityChecker::Initialize() {
+ network_manager_.reset(CreateNetworkManager());
+ socket_factory_.reset(CreateSocketFactory(worker_));
+ port_allocator_.reset(CreatePortAllocator(network_manager_.get(),
+ user_agent_, relay_token_));
+ uint32 new_allocator_flags = port_allocator_->flags();
+ new_allocator_flags |= cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG;
+ port_allocator_->set_flags(new_allocator_flags);
+ return true;
+}
+
+void ConnectivityChecker::Start() {
+ main_ = rtc::Thread::Current();
+ worker_->Post(this, MSG_START);
+ started_ = true;
+}
+
+void ConnectivityChecker::CleanUp() {
+ ASSERT(worker_ == rtc::Thread::Current());
+ if (proxy_detect_) {
+ proxy_detect_->Release();
+ proxy_detect_ = NULL;
+ }
+
+ for (uint32 i = 0; i < sessions_.size(); ++i) {
+ delete sessions_[i];
+ }
+ sessions_.clear();
+ for (uint32 i = 0; i < ports_.size(); ++i) {
+ delete ports_[i];
+ }
+ ports_.clear();
+}
+
+bool ConnectivityChecker::AddNic(const rtc::IPAddress& ip,
+ const rtc::SocketAddress& proxy_addr) {
+ NicMap::iterator i = nics_.find(NicId(ip, proxy_addr));
+ if (i != nics_.end()) {
+ // Already have it.
+ return false;
+ }
+ uint32 now = rtc::Time();
+ NicInfo info;
+ info.ip = ip;
+ info.proxy_info = GetProxyInfo();
+ info.stun.start_time_ms = now;
+ nics_.insert(std::pair<NicId, NicInfo>(NicId(ip, proxy_addr), info));
+ return true;
+}
+
+void ConnectivityChecker::SetProxyInfo(const rtc::ProxyInfo& proxy_info) {
+ port_allocator_->set_proxy(user_agent_, proxy_info);
+ AllocatePorts();
+}
+
+rtc::ProxyInfo ConnectivityChecker::GetProxyInfo() const {
+ rtc::ProxyInfo proxy_info;
+ if (proxy_detect_) {
+ proxy_info = proxy_detect_->proxy();
+ }
+ return proxy_info;
+}
+
+void ConnectivityChecker::CheckNetworks() {
+ network_manager_->SignalNetworksChanged.connect(
+ this, &ConnectivityChecker::OnNetworksChanged);
+ network_manager_->StartUpdating();
+}
+
+void ConnectivityChecker::OnMessage(rtc::Message *msg) {
+ switch (msg->message_id) {
+ case MSG_START:
+ ASSERT(worker_ == rtc::Thread::Current());
+ worker_->PostDelayed(timeout_ms_, this, MSG_TIMEOUT);
+ CheckNetworks();
+ break;
+ case MSG_STOP:
+ // We're being stopped, free resources.
+ CleanUp();
+ break;
+ case MSG_TIMEOUT:
+ // We need to signal results on the main thread.
+ main_->Post(this, MSG_SIGNAL_RESULTS);
+ break;
+ case MSG_SIGNAL_RESULTS:
+ ASSERT(main_ == rtc::Thread::Current());
+ SignalCheckDone(this);
+ break;
+ default:
+ LOG(LS_ERROR) << "Unknown message: " << msg->message_id;
+ }
+}
+
+void ConnectivityChecker::OnProxyDetect(rtc::SignalThread* thread) {
+ ASSERT(worker_ == rtc::Thread::Current());
+ if (proxy_detect_->proxy().type != rtc::PROXY_NONE) {
+ SetProxyInfo(proxy_detect_->proxy());
+ }
+}
+
+void ConnectivityChecker::OnRequestDone(rtc::AsyncHttpRequest* request) {
+ ASSERT(worker_ == rtc::Thread::Current());
+ // Since we don't know what nic were actually used for the http request,
+ // for now, just use the first one.
+ std::vector<rtc::Network*> networks;
+ network_manager_->GetNetworks(&networks);
+ if (networks.empty()) {
+ LOG(LS_ERROR) << "No networks while registering http start.";
+ return;
+ }
+ rtc::ProxyInfo proxy_info = request->proxy();
+ NicMap::iterator i =
+#ifdef USE_WEBRTC_DEV_BRANCH
+ nics_.find(NicId(networks[0]->GetBestIP(), proxy_info.address));
+#else // USE_WEBRTC_DEV_BRANCH
+ nics_.find(NicId(networks[0]->ip(), proxy_info.address));
+#endif // USE_WEBRTC_DEV_BRANCH
+ if (i != nics_.end()) {
+ int port = request->port();
+ uint32 now = rtc::Time();
+ NicInfo* nic_info = &i->second;
+ if (port == rtc::HTTP_DEFAULT_PORT) {
+ nic_info->http.rtt = now - nic_info->http.start_time_ms;
+ } else if (port == rtc::HTTP_SECURE_PORT) {
+ nic_info->https.rtt = now - nic_info->https.start_time_ms;
+ } else {
+ LOG(LS_ERROR) << "Got response with unknown port: " << port;
+ }
+ } else {
+ LOG(LS_ERROR) << "No nic info found while receiving response.";
+ }
+}
+
+void ConnectivityChecker::OnConfigReady(
+ const std::string& username, const std::string& password,
+ const PortConfiguration* config, const rtc::ProxyInfo& proxy_info) {
+ ASSERT(worker_ == rtc::Thread::Current());
+
+ // Since we send requests on both HTTP and HTTPS we will get two
+ // configs per nic. Results from the second will overwrite the
+ // result from the first.
+ // TODO: Handle multiple pings on one nic.
+ CreateRelayPorts(username, password, config, proxy_info);
+}
+
+void ConnectivityChecker::OnRelayPortComplete(Port* port) {
+ ASSERT(worker_ == rtc::Thread::Current());
+ RelayPort* relay_port = reinterpret_cast<RelayPort*>(port);
+ const ProtocolAddress* address = relay_port->ServerAddress(0);
+#ifdef USE_WEBRTC_DEV_BRANCH
+ rtc::IPAddress ip = port->Network()->GetBestIP();
+#else // USE_WEBRTC_DEV_BRANCH
+ rtc::IPAddress ip = port->Network()->ip();
+#endif // USE_WEBRTC_DEV_BRANCH
+ NicMap::iterator i = nics_.find(NicId(ip, port->proxy().address));
+ if (i != nics_.end()) {
+ // We have it already, add the new information.
+ NicInfo* nic_info = &i->second;
+ ConnectInfo* connect_info = NULL;
+ if (address) {
+ switch (address->proto) {
+ case PROTO_UDP:
+ connect_info = &nic_info->udp;
+ break;
+ case PROTO_TCP:
+ connect_info = &nic_info->tcp;
+ break;
+ case PROTO_SSLTCP:
+ connect_info = &nic_info->ssltcp;
+ break;
+ default:
+ LOG(LS_ERROR) << " relay address with bad protocol added";
+ }
+ if (connect_info) {
+ connect_info->rtt =
+ rtc::TimeSince(connect_info->start_time_ms);
+ }
+ }
+ } else {
+ LOG(LS_ERROR) << " got relay address for non-existing nic";
+ }
+}
+
+void ConnectivityChecker::OnStunPortComplete(Port* port) {
+ ASSERT(worker_ == rtc::Thread::Current());
+ const std::vector<Candidate> candidates = port->Candidates();
+ Candidate c = candidates[0];
+#ifdef USE_WEBRTC_DEV_BRANCH
+ rtc::IPAddress ip = port->Network()->GetBestIP();
+#else // USE_WEBRTC_DEV_BRANCH
+ rtc::IPAddress ip = port->Network()->ip();
+#endif // USE_WEBRTC_DEV_BRANCH
+ NicMap::iterator i = nics_.find(NicId(ip, port->proxy().address));
+ if (i != nics_.end()) {
+ // We have it already, add the new information.
+ uint32 now = rtc::Time();
+ NicInfo* nic_info = &i->second;
+ nic_info->external_address = c.address();
+
+ nic_info->stun_server_addresses =
+ static_cast<StunPort*>(port)->server_addresses();
+ nic_info->stun.rtt = now - nic_info->stun.start_time_ms;
+ } else {
+ LOG(LS_ERROR) << "Got stun address for non-existing nic";
+ }
+}
+
+void ConnectivityChecker::OnStunPortError(Port* port) {
+ ASSERT(worker_ == rtc::Thread::Current());
+ LOG(LS_ERROR) << "Stun address error.";
+#ifdef USE_WEBRTC_DEV_BRANCH
+ rtc::IPAddress ip = port->Network()->GetBestIP();
+#else // USE_WEBRTC_DEV_BRANCH
+ rtc::IPAddress ip = port->Network()->ip();
+#endif // USE_WEBRTC_DEV_BRANCH
+ NicMap::iterator i = nics_.find(NicId(ip, port->proxy().address));
+ if (i != nics_.end()) {
+ // We have it already, add the new information.
+ NicInfo* nic_info = &i->second;
+
+ nic_info->stun_server_addresses =
+ static_cast<StunPort*>(port)->server_addresses();
+ }
+}
+
+void ConnectivityChecker::OnRelayPortError(Port* port) {
+ ASSERT(worker_ == rtc::Thread::Current());
+ LOG(LS_ERROR) << "Relay address error.";
+}
+
+void ConnectivityChecker::OnNetworksChanged() {
+ ASSERT(worker_ == rtc::Thread::Current());
+ std::vector<rtc::Network*> networks;
+ network_manager_->GetNetworks(&networks);
+ if (networks.empty()) {
+ LOG(LS_ERROR) << "Machine has no networks; nothing to do";
+ return;
+ }
+ AllocatePorts();
+}
+
+HttpPortAllocator* ConnectivityChecker::CreatePortAllocator(
+ rtc::NetworkManager* network_manager,
+ const std::string& user_agent,
+ const std::string& relay_token) {
+ return new TestHttpPortAllocator(network_manager, user_agent, relay_token);
+}
+
+StunPort* ConnectivityChecker::CreateStunPort(
+ const std::string& username, const std::string& password,
+ const PortConfiguration* config, rtc::Network* network) {
+ return StunPort::Create(worker_,
+ socket_factory_.get(),
+ network,
+#ifdef USE_WEBRTC_DEV_BRANCH
+ network->GetBestIP(),
+#else // USE_WEBRTC_DEV_BRANCH
+ network->ip(),
+#endif // USE_WEBRTC_DEV_BRANCH
+ 0,
+ 0,
+ username,
+ password,
+ config->stun_servers);
+}
+
+RelayPort* ConnectivityChecker::CreateRelayPort(
+ const std::string& username, const std::string& password,
+ const PortConfiguration* config, rtc::Network* network) {
+ return RelayPort::Create(worker_,
+ socket_factory_.get(),
+ network,
+#ifdef USE_WEBRTC_DEV_BRANCH
+ network->GetBestIP(),
+#else // USE_WEBRTC_DEV_BRANCH
+ network->ip(),
+#endif // USE_WEBRTC_DEV_BRANCH
+ port_allocator_->min_port(),
+ port_allocator_->max_port(),
+ username,
+ password);
+}
+
+void ConnectivityChecker::CreateRelayPorts(
+ const std::string& username, const std::string& password,
+ const PortConfiguration* config, const rtc::ProxyInfo& proxy_info) {
+ PortConfiguration::RelayList::const_iterator relay;
+ std::vector<rtc::Network*> networks;
+ network_manager_->GetNetworks(&networks);
+ if (networks.empty()) {
+ LOG(LS_ERROR) << "Machine has no networks; no relay ports created.";
+ return;
+ }
+ for (relay = config->relays.begin();
+ relay != config->relays.end(); ++relay) {
+ for (uint32 i = 0; i < networks.size(); ++i) {
+ NicMap::iterator iter =
+#ifdef USE_WEBRTC_DEV_BRANCH
+ nics_.find(NicId(networks[i]->GetBestIP(), proxy_info.address));
+#else // USE_WEBRTC_DEV_BRANCH
+ nics_.find(NicId(networks[i]->ip(), proxy_info.address));
+#endif // USE_WEBRTC_DEV_BRANCH
+ if (iter != nics_.end()) {
+ // TODO: Now setting the same start time for all protocols.
+ // This might affect accuracy, but since we are mainly looking for
+ // connect failures or number that stick out, this is good enough.
+ uint32 now = rtc::Time();
+ NicInfo* nic_info = &iter->second;
+ nic_info->udp.start_time_ms = now;
+ nic_info->tcp.start_time_ms = now;
+ nic_info->ssltcp.start_time_ms = now;
+
+ // Add the addresses of this protocol.
+ PortList::const_iterator relay_port;
+ for (relay_port = relay->ports.begin();
+ relay_port != relay->ports.end();
+ ++relay_port) {
+ RelayPort* port = CreateRelayPort(username, password,
+ config, networks[i]);
+ port->AddServerAddress(*relay_port);
+ port->AddExternalAddress(*relay_port);
+
+ nic_info->media_server_address = port->ServerAddress(0)->address;
+
+ // Listen to network events.
+ port->SignalPortComplete.connect(
+ this, &ConnectivityChecker::OnRelayPortComplete);
+ port->SignalPortError.connect(
+ this, &ConnectivityChecker::OnRelayPortError);
+
+ port->set_proxy(user_agent_, proxy_info);
+
+ // Start fetching an address for this port.
+ port->PrepareAddress();
+ ports_.push_back(port);
+ }
+ } else {
+ LOG(LS_ERROR) << "Failed to find nic info when creating relay ports.";
+ }
+ }
+ }
+}
+
+void ConnectivityChecker::AllocatePorts() {
+ const std::string username = rtc::CreateRandomString(ICE_UFRAG_LENGTH);
+ const std::string password = rtc::CreateRandomString(ICE_PWD_LENGTH);
+ ServerAddresses stun_servers;
+ stun_servers.insert(stun_address_);
+ PortConfiguration config(stun_servers, username, password);
+ std::vector<rtc::Network*> networks;
+ network_manager_->GetNetworks(&networks);
+ if (networks.empty()) {
+ LOG(LS_ERROR) << "Machine has no networks; no ports will be allocated";
+ return;
+ }
+ rtc::ProxyInfo proxy_info = GetProxyInfo();
+ bool allocate_relay_ports = false;
+ for (uint32 i = 0; i < networks.size(); ++i) {
+#ifdef USE_WEBRTC_DEV_BRANCH
+ if (AddNic(networks[i]->GetBestIP(), proxy_info.address)) {
+#else // USE_WEBRTC_DEV_BRANCH
+ if (AddNic(networks[i]->ip(), proxy_info.address)) {
+#endif // USE_WEBRTC_DEV_BRANCH
+ Port* port = CreateStunPort(username, password, &config, networks[i]);
+ if (port) {
+
+ // Listen to network events.
+ port->SignalPortComplete.connect(
+ this, &ConnectivityChecker::OnStunPortComplete);
+ port->SignalPortError.connect(
+ this, &ConnectivityChecker::OnStunPortError);
+
+ port->set_proxy(user_agent_, proxy_info);
+ port->PrepareAddress();
+ ports_.push_back(port);
+ allocate_relay_ports = true;
+ }
+ }
+ }
+
+ // If any new ip/proxy combinations were added, send a relay allocate.
+ if (allocate_relay_ports) {
+ AllocateRelayPorts();
+ }
+
+ // Initiate proxy detection.
+ InitiateProxyDetection();
+}
+
+void ConnectivityChecker::InitiateProxyDetection() {
+ // Only start if we haven't been started before.
+ if (!proxy_detect_) {
+ proxy_detect_ = new rtc::AutoDetectProxy(user_agent_);
+ rtc::Url<char> host_url("/", "relay.google.com",
+ rtc::HTTP_DEFAULT_PORT);
+ host_url.set_secure(true);
+ proxy_detect_->set_server_url(host_url.url());
+ proxy_detect_->SignalWorkDone.connect(
+ this, &ConnectivityChecker::OnProxyDetect);
+ proxy_detect_->Start();
+ }
+}
+
+void ConnectivityChecker::AllocateRelayPorts() {
+ // Currently we are using the 'default' nic for http(s) requests.
+ TestHttpPortAllocatorSession* allocator_session =
+ reinterpret_cast<TestHttpPortAllocatorSession*>(
+ port_allocator_->CreateSessionInternal(
+ "connectivity checker test content",
+ ICE_CANDIDATE_COMPONENT_RTP,
+ rtc::CreateRandomString(ICE_UFRAG_LENGTH),
+ rtc::CreateRandomString(ICE_PWD_LENGTH)));
+ allocator_session->set_proxy(port_allocator_->proxy());
+ allocator_session->SignalConfigReady.connect(
+ this, &ConnectivityChecker::OnConfigReady);
+ allocator_session->SignalRequestDone.connect(
+ this, &ConnectivityChecker::OnRequestDone);
+
+ // Try both http and https.
+ RegisterHttpStart(rtc::HTTP_SECURE_PORT);
+ allocator_session->SendSessionRequest("relay.l.google.com",
+ rtc::HTTP_SECURE_PORT);
+ RegisterHttpStart(rtc::HTTP_DEFAULT_PORT);
+ allocator_session->SendSessionRequest("relay.l.google.com",
+ rtc::HTTP_DEFAULT_PORT);
+
+ sessions_.push_back(allocator_session);
+}
+
+void ConnectivityChecker::RegisterHttpStart(int port) {
+ // Since we don't know what nic were actually used for the http request,
+ // for now, just use the first one.
+ std::vector<rtc::Network*> networks;
+ network_manager_->GetNetworks(&networks);
+ if (networks.empty()) {
+ LOG(LS_ERROR) << "No networks while registering http start.";
+ return;
+ }
+ rtc::ProxyInfo proxy_info = GetProxyInfo();
+ NicMap::iterator i =
+#ifdef USE_WEBRTC_DEV_BRANCH
+ nics_.find(NicId(networks[0]->GetBestIP(), proxy_info.address));
+#else // USE_WEBRTC_DEV_BRANCH
+ nics_.find(NicId(networks[0]->ip(), proxy_info.address));
+#endif // USE_WEBRTC_DEV_BRANCH
+ if (i != nics_.end()) {
+ uint32 now = rtc::Time();
+ NicInfo* nic_info = &i->second;
+ if (port == rtc::HTTP_DEFAULT_PORT) {
+ nic_info->http.start_time_ms = now;
+ } else if (port == rtc::HTTP_SECURE_PORT) {
+ nic_info->https.start_time_ms = now;
+ } else {
+ LOG(LS_ERROR) << "Registering start time for unknown port: " << port;
+ }
+ } else {
+ LOG(LS_ERROR) << "Error, no nic info found while registering http start.";
+ }
+}
+
+} // namespace rtc
diff --git a/p2p/client/connectivitychecker.h b/p2p/client/connectivitychecker.h
new file mode 100644
index 00000000..427749e5
--- /dev/null
+++ b/p2p/client/connectivitychecker.h
@@ -0,0 +1,281 @@
+/*
+ * 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 WEBRTC_P2P_CLIENT_CONNECTIVITYCHECKER_H_
+#define WEBRTC_P2P_CLIENT_CONNECTIVITYCHECKER_H_
+
+#include <map>
+#include <string>
+
+#include "webrtc/p2p/base/basicpacketsocketfactory.h"
+#include "webrtc/p2p/client/httpportallocator.h"
+#include "webrtc/base/basictypes.h"
+#include "webrtc/base/messagehandler.h"
+#include "webrtc/base/network.h"
+#include "webrtc/base/proxyinfo.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/sigslot.h"
+#include "webrtc/base/socketaddress.h"
+
+namespace rtc {
+class AsyncHttpRequest;
+class AutoDetectProxy;
+class BasicPacketSocketFactory;
+class NetworkManager;
+class PacketSocketFactory;
+class SignalThread;
+class TestHttpPortAllocatorSession;
+class Thread;
+}
+
+namespace cricket {
+class HttpPortAllocator;
+class Port;
+class PortAllocatorSession;
+struct PortConfiguration;
+class RelayPort;
+class StunPort;
+
+// Contains details about a discovered firewall that are of interest
+// when debugging call failures.
+struct FirewallInfo {
+ std::string brand;
+ std::string model;
+
+ // TODO: List of current port mappings.
+};
+
+// Contains details about a specific connect attempt.
+struct ConnectInfo {
+ ConnectInfo()
+ : rtt(-1), error(0) {}
+ // Time when the connection was initiated. Needed for calculating
+ // the round trip time.
+ uint32 start_time_ms;
+ // Round trip time in milliseconds or -1 for failed connection.
+ int32 rtt;
+ // Error code representing low level errors like socket errors.
+ int error;
+};
+
+// Identifier for a network interface and proxy address pair.
+struct NicId {
+ NicId(const rtc::IPAddress& ip,
+ const rtc::SocketAddress& proxy_address)
+ : ip(ip),
+ proxy_address(proxy_address) {
+ }
+ rtc::IPAddress ip;
+ rtc::SocketAddress proxy_address;
+};
+
+// Comparator implementation identifying unique network interface and
+// proxy address pairs.
+class NicIdComparator {
+ public:
+ int compare(const NicId &first, const NicId &second) const {
+ if (first.ip == second.ip) {
+ // Compare proxy address.
+ if (first.proxy_address == second.proxy_address) {
+ return 0;
+ } else {
+ return first.proxy_address < second.proxy_address? -1 : 1;
+ }
+ }
+ return first.ip < second.ip ? -1 : 1;
+ }
+
+ bool operator()(const NicId &first, const NicId &second) const {
+ return (compare(first, second) < 0);
+ }
+};
+
+// Contains information of a network interface and proxy address pair.
+struct NicInfo {
+ NicInfo() {}
+ rtc::IPAddress ip;
+ rtc::ProxyInfo proxy_info;
+ rtc::SocketAddress external_address;
+ ServerAddresses stun_server_addresses;
+ rtc::SocketAddress media_server_address;
+ ConnectInfo stun;
+ ConnectInfo http;
+ ConnectInfo https;
+ ConnectInfo udp;
+ ConnectInfo tcp;
+ ConnectInfo ssltcp;
+ FirewallInfo firewall;
+};
+
+// Holds the result of the connectivity check.
+class NicMap : public std::map<NicId, NicInfo, NicIdComparator> {
+};
+
+class TestHttpPortAllocatorSession : public HttpPortAllocatorSession {
+ public:
+ TestHttpPortAllocatorSession(
+ HttpPortAllocator* allocator,
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd,
+ const std::vector<rtc::SocketAddress>& stun_hosts,
+ const std::vector<std::string>& relay_hosts,
+ const std::string& relay_token,
+ const std::string& user_agent)
+ : HttpPortAllocatorSession(
+ allocator, content_name, component, ice_ufrag, ice_pwd, stun_hosts,
+ relay_hosts, relay_token, user_agent) {
+ }
+ void set_proxy(const rtc::ProxyInfo& proxy) {
+ proxy_ = proxy;
+ }
+
+ void ConfigReady(PortConfiguration* config);
+
+ void OnRequestDone(rtc::SignalThread* data);
+
+ sigslot::signal4<const std::string&, const std::string&,
+ const PortConfiguration*,
+ const rtc::ProxyInfo&> SignalConfigReady;
+ sigslot::signal1<rtc::AsyncHttpRequest*> SignalRequestDone;
+
+ private:
+ rtc::ProxyInfo proxy_;
+};
+
+// Runs a request/response check on all network interface and proxy
+// address combinations. The check is considered done either when all
+// checks has been successful or when the check times out.
+class ConnectivityChecker
+ : public rtc::MessageHandler, public sigslot::has_slots<> {
+ public:
+ ConnectivityChecker(rtc::Thread* worker,
+ const std::string& jid,
+ const std::string& session_id,
+ const std::string& user_agent,
+ const std::string& relay_token,
+ const std::string& connection);
+ virtual ~ConnectivityChecker();
+
+ // Virtual for gMock.
+ virtual bool Initialize();
+ virtual void Start();
+
+ // MessageHandler implementation.
+ virtual void OnMessage(rtc::Message *msg);
+
+ // Instruct checker to stop and wait until that's done.
+ // Virtual for gMock.
+ virtual void Stop() {
+ worker_->Stop();
+ }
+
+ const NicMap& GetResults() const {
+ return nics_;
+ }
+
+ void set_timeout_ms(uint32 timeout) {
+ timeout_ms_ = timeout;
+ }
+
+ void set_stun_address(const rtc::SocketAddress& stun_address) {
+ stun_address_ = stun_address;
+ }
+
+ const std::string& connection() const {
+ return connection_;
+ }
+
+ const std::string& jid() const {
+ return jid_;
+ }
+
+ const std::string& session_id() const {
+ return session_id_;
+ }
+
+ // Context: Main Thread. Signalled when the connectivity check is complete.
+ sigslot::signal1<ConnectivityChecker*> SignalCheckDone;
+
+ protected:
+ // Can be overridden for test.
+ virtual rtc::NetworkManager* CreateNetworkManager() {
+ return new rtc::BasicNetworkManager();
+ }
+ virtual rtc::BasicPacketSocketFactory* CreateSocketFactory(
+ rtc::Thread* thread) {
+ return new rtc::BasicPacketSocketFactory(thread);
+ }
+ virtual HttpPortAllocator* CreatePortAllocator(
+ rtc::NetworkManager* network_manager,
+ const std::string& user_agent,
+ const std::string& relay_token);
+ virtual StunPort* CreateStunPort(
+ const std::string& username, const std::string& password,
+ const PortConfiguration* config, rtc::Network* network);
+ virtual RelayPort* CreateRelayPort(
+ const std::string& username, const std::string& password,
+ const PortConfiguration* config, rtc::Network* network);
+ virtual void InitiateProxyDetection();
+ virtual void SetProxyInfo(const rtc::ProxyInfo& info);
+ virtual rtc::ProxyInfo GetProxyInfo() const;
+
+ rtc::Thread* worker() {
+ return worker_;
+ }
+
+ private:
+ bool AddNic(const rtc::IPAddress& ip,
+ const rtc::SocketAddress& proxy_address);
+ void AllocatePorts();
+ void AllocateRelayPorts();
+ void CheckNetworks();
+ void CreateRelayPorts(
+ const std::string& username, const std::string& password,
+ const PortConfiguration* config, const rtc::ProxyInfo& proxy_info);
+
+ // Must be called by the worker thread.
+ void CleanUp();
+
+ void OnRequestDone(rtc::AsyncHttpRequest* request);
+ void OnRelayPortComplete(Port* port);
+ void OnStunPortComplete(Port* port);
+ void OnRelayPortError(Port* port);
+ void OnStunPortError(Port* port);
+ void OnNetworksChanged();
+ void OnProxyDetect(rtc::SignalThread* thread);
+ void OnConfigReady(
+ const std::string& username, const std::string& password,
+ const PortConfiguration* config, const rtc::ProxyInfo& proxy);
+ void OnConfigWithProxyReady(const PortConfiguration*);
+ void RegisterHttpStart(int port);
+ rtc::Thread* worker_;
+ std::string jid_;
+ std::string session_id_;
+ std::string user_agent_;
+ std::string relay_token_;
+ std::string connection_;
+ rtc::AutoDetectProxy* proxy_detect_;
+ rtc::scoped_ptr<rtc::NetworkManager> network_manager_;
+ rtc::scoped_ptr<rtc::BasicPacketSocketFactory> socket_factory_;
+ rtc::scoped_ptr<HttpPortAllocator> port_allocator_;
+ NicMap nics_;
+ std::vector<Port*> ports_;
+ std::vector<PortAllocatorSession*> sessions_;
+ uint32 timeout_ms_;
+ rtc::SocketAddress stun_address_;
+ rtc::Thread* main_;
+ bool started_;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_CLIENT_CONNECTIVITYCHECKER_H_
diff --git a/p2p/client/connectivitychecker_unittest.cc b/p2p/client/connectivitychecker_unittest.cc
new file mode 100644
index 00000000..838dc886
--- /dev/null
+++ b/p2p/client/connectivitychecker_unittest.cc
@@ -0,0 +1,375 @@
+/*
+ * 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.
+ */
+
+#include <string>
+
+#include "webrtc/p2p/base/basicpacketsocketfactory.h"
+#include "webrtc/p2p/base/relayport.h"
+#include "webrtc/p2p/base/stunport.h"
+#include "webrtc/p2p/client/connectivitychecker.h"
+#include "webrtc/p2p/client/httpportallocator.h"
+#include "webrtc/base/asynchttprequest.h"
+#include "webrtc/base/fakenetwork.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/socketaddress.h"
+
+namespace cricket {
+
+static const rtc::SocketAddress kClientAddr1("11.11.11.11", 0);
+static const rtc::SocketAddress kClientAddr2("22.22.22.22", 0);
+static const rtc::SocketAddress kExternalAddr("33.33.33.33", 3333);
+static const rtc::SocketAddress kStunAddr("44.44.44.44", 4444);
+static const rtc::SocketAddress kRelayAddr("55.55.55.55", 5555);
+static const rtc::SocketAddress kProxyAddr("66.66.66.66", 6666);
+static const rtc::ProxyType kProxyType = rtc::PROXY_HTTPS;
+static const char kRelayHost[] = "relay.google.com";
+static const char kRelayToken[] =
+ "CAESFwoOb2phQGdvb2dsZS5jb20Q043h47MmGhBTB1rbfIXkhuarDCZe+xF6";
+static const char kBrowserAgent[] = "browser_test";
+static const char kJid[] = "a.b@c";
+static const char kUserName[] = "testuser";
+static const char kPassword[] = "testpassword";
+static const char kMagicCookie[] = "testcookie";
+static const char kRelayUdpPort[] = "4444";
+static const char kRelayTcpPort[] = "5555";
+static const char kRelaySsltcpPort[] = "6666";
+static const char kSessionId[] = "testsession";
+static const char kConnection[] = "testconnection";
+static const int kMinPort = 1000;
+static const int kMaxPort = 2000;
+
+// Fake implementation to mock away real network usage.
+class FakeRelayPort : public RelayPort {
+ public:
+ FakeRelayPort(rtc::Thread* thread,
+ rtc::PacketSocketFactory* factory,
+ rtc::Network* network, const rtc::IPAddress& ip,
+ int min_port, int max_port,
+ const std::string& username, const std::string& password)
+ : RelayPort(thread, factory, network, ip, min_port, max_port,
+ username, password) {
+ }
+
+ // Just signal that we are done.
+ virtual void PrepareAddress() {
+ SignalPortComplete(this);
+ }
+};
+
+// Fake implementation to mock away real network usage.
+class FakeStunPort : public StunPort {
+ public:
+ FakeStunPort(rtc::Thread* thread,
+ rtc::PacketSocketFactory* factory,
+ rtc::Network* network,
+ const rtc::IPAddress& ip,
+ int min_port, int max_port,
+ const std::string& username, const std::string& password,
+ const ServerAddresses& server_addr)
+ : StunPort(thread, factory, network, ip, min_port, max_port,
+ username, password, server_addr) {
+ }
+
+ // Just set external address and signal that we are done.
+ virtual void PrepareAddress() {
+ AddAddress(kExternalAddr, kExternalAddr, rtc::SocketAddress(), "udp", "",
+ STUN_PORT_TYPE, ICE_TYPE_PREFERENCE_SRFLX, 0, true);
+ SignalPortComplete(this);
+ }
+};
+
+// Fake implementation to mock away real network usage by responding
+// to http requests immediately.
+class FakeHttpPortAllocatorSession : public TestHttpPortAllocatorSession {
+ public:
+ FakeHttpPortAllocatorSession(
+ HttpPortAllocator* allocator,
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag, const std::string& ice_pwd,
+ const std::vector<rtc::SocketAddress>& stun_hosts,
+ const std::vector<std::string>& relay_hosts,
+ const std::string& relay_token,
+ const std::string& agent)
+ : TestHttpPortAllocatorSession(allocator,
+ content_name,
+ component,
+ ice_ufrag,
+ ice_pwd,
+ stun_hosts,
+ relay_hosts,
+ relay_token,
+ agent) {
+ }
+ virtual void SendSessionRequest(const std::string& host, int port) {
+ FakeReceiveSessionResponse(host, port);
+ }
+
+ // Pass results to the real implementation.
+ void FakeReceiveSessionResponse(const std::string& host, int port) {
+ rtc::AsyncHttpRequest* response = CreateAsyncHttpResponse(port);
+ TestHttpPortAllocatorSession::OnRequestDone(response);
+ response->Destroy(true);
+ }
+
+ private:
+ // Helper method for creating a response to a relay session request.
+ rtc::AsyncHttpRequest* CreateAsyncHttpResponse(int port) {
+ rtc::AsyncHttpRequest* request =
+ new rtc::AsyncHttpRequest(kBrowserAgent);
+ std::stringstream ss;
+ ss << "username=" << kUserName << std::endl
+ << "password=" << kPassword << std::endl
+ << "magic_cookie=" << kMagicCookie << std::endl
+ << "relay.ip=" << kRelayAddr.ipaddr().ToString() << std::endl
+ << "relay.udp_port=" << kRelayUdpPort << std::endl
+ << "relay.tcp_port=" << kRelayTcpPort << std::endl
+ << "relay.ssltcp_port=" << kRelaySsltcpPort << std::endl;
+ request->response().document.reset(
+ new rtc::MemoryStream(ss.str().c_str()));
+ request->response().set_success();
+ request->set_port(port);
+ request->set_secure(port == rtc::HTTP_SECURE_PORT);
+ return request;
+ }
+};
+
+// Fake implementation for creating fake http sessions.
+class FakeHttpPortAllocator : public HttpPortAllocator {
+ public:
+ FakeHttpPortAllocator(rtc::NetworkManager* network_manager,
+ const std::string& user_agent)
+ : HttpPortAllocator(network_manager, user_agent) {
+ }
+
+ virtual PortAllocatorSession* CreateSessionInternal(
+ const std::string& content_name, int component,
+ const std::string& ice_ufrag, const std::string& ice_pwd) {
+ std::vector<rtc::SocketAddress> stun_hosts;
+ stun_hosts.push_back(kStunAddr);
+ std::vector<std::string> relay_hosts;
+ relay_hosts.push_back(kRelayHost);
+ return new FakeHttpPortAllocatorSession(this,
+ content_name,
+ component,
+ ice_ufrag,
+ ice_pwd,
+ stun_hosts,
+ relay_hosts,
+ kRelayToken,
+ kBrowserAgent);
+ }
+};
+
+class ConnectivityCheckerForTest : public ConnectivityChecker {
+ public:
+ ConnectivityCheckerForTest(rtc::Thread* worker,
+ const std::string& jid,
+ const std::string& session_id,
+ const std::string& user_agent,
+ const std::string& relay_token,
+ const std::string& connection)
+ : ConnectivityChecker(worker,
+ jid,
+ session_id,
+ user_agent,
+ relay_token,
+ connection),
+ proxy_initiated_(false) {
+ }
+
+ rtc::FakeNetworkManager* network_manager() const {
+ return network_manager_;
+ }
+
+ FakeHttpPortAllocator* port_allocator() const {
+ return fake_port_allocator_;
+ }
+
+ protected:
+ // Overridden methods for faking a real network.
+ virtual rtc::NetworkManager* CreateNetworkManager() {
+ network_manager_ = new rtc::FakeNetworkManager();
+ return network_manager_;
+ }
+ virtual rtc::BasicPacketSocketFactory* CreateSocketFactory(
+ rtc::Thread* thread) {
+ // Create socket factory, for simplicity, let it run on the current thread.
+ socket_factory_ =
+ new rtc::BasicPacketSocketFactory(rtc::Thread::Current());
+ return socket_factory_;
+ }
+ virtual HttpPortAllocator* CreatePortAllocator(
+ rtc::NetworkManager* network_manager,
+ const std::string& user_agent,
+ const std::string& relay_token) {
+ fake_port_allocator_ =
+ new FakeHttpPortAllocator(network_manager, user_agent);
+ return fake_port_allocator_;
+ }
+ virtual StunPort* CreateStunPort(
+ const std::string& username, const std::string& password,
+ const PortConfiguration* config, rtc::Network* network) {
+ return new FakeStunPort(worker(),
+ socket_factory_,
+ network,
+#ifdef USE_WEBRTC_DEV_BRANCH
+ network->GetBestIP(),
+#else // USE_WEBRTC_DEV_BRANCH
+ network->ip(),
+#endif // USE_WEBRTC_DEV_BRANCH
+ kMinPort,
+ kMaxPort,
+ username,
+ password,
+ config->stun_servers);
+ }
+ virtual RelayPort* CreateRelayPort(
+ const std::string& username, const std::string& password,
+ const PortConfiguration* config, rtc::Network* network) {
+ return new FakeRelayPort(worker(),
+ socket_factory_,
+ network,
+#ifdef USE_WEBRTC_DEV_BRANCH
+ network->GetBestIP(),
+#else // USE_WEBRTC_DEV_BRANCH
+ network->ip(),
+#endif // USE_WEBRTC_DEV_BRANCH
+ kMinPort,
+ kMaxPort,
+ username,
+ password);
+ }
+ virtual void InitiateProxyDetection() {
+ if (!proxy_initiated_) {
+ proxy_initiated_ = true;
+ proxy_info_.address = kProxyAddr;
+ proxy_info_.type = kProxyType;
+ SetProxyInfo(proxy_info_);
+ }
+ }
+
+ virtual rtc::ProxyInfo GetProxyInfo() const {
+ return proxy_info_;
+ }
+
+ private:
+ rtc::BasicPacketSocketFactory* socket_factory_;
+ FakeHttpPortAllocator* fake_port_allocator_;
+ rtc::FakeNetworkManager* network_manager_;
+ rtc::ProxyInfo proxy_info_;
+ bool proxy_initiated_;
+};
+
+class ConnectivityCheckerTest : public testing::Test {
+ protected:
+ void VerifyNic(const NicInfo& info,
+ const rtc::SocketAddress& local_address) {
+ // Verify that the external address has been set.
+ EXPECT_EQ(kExternalAddr, info.external_address);
+
+ // Verify that the stun server address has been set.
+ EXPECT_EQ(1U, info.stun_server_addresses.size());
+ EXPECT_EQ(kStunAddr, *(info.stun_server_addresses.begin()));
+
+ // Verify that the media server address has been set. Don't care
+ // about port since it is different for different protocols.
+ EXPECT_EQ(kRelayAddr.ipaddr(), info.media_server_address.ipaddr());
+
+ // Verify that local ip matches.
+ EXPECT_EQ(local_address.ipaddr(), info.ip);
+
+ // Verify that we have received responses for our
+ // pings. Unsuccessful ping has rtt value -1, successful >= 0.
+ EXPECT_GE(info.stun.rtt, 0);
+ EXPECT_GE(info.udp.rtt, 0);
+ EXPECT_GE(info.tcp.rtt, 0);
+ EXPECT_GE(info.ssltcp.rtt, 0);
+
+ // If proxy has been set, verify address and type.
+ if (!info.proxy_info.address.IsNil()) {
+ EXPECT_EQ(kProxyAddr, info.proxy_info.address);
+ EXPECT_EQ(kProxyType, info.proxy_info.type);
+ }
+ }
+};
+
+// Tests a configuration with two network interfaces. Verifies that 4
+// combinations of ip/proxy are created and that all protocols are
+// tested on each combination.
+TEST_F(ConnectivityCheckerTest, TestStart) {
+ ConnectivityCheckerForTest connectivity_checker(rtc::Thread::Current(),
+ kJid,
+ kSessionId,
+ kBrowserAgent,
+ kRelayToken,
+ kConnection);
+ connectivity_checker.Initialize();
+ connectivity_checker.set_stun_address(kStunAddr);
+ connectivity_checker.network_manager()->AddInterface(kClientAddr1);
+ connectivity_checker.network_manager()->AddInterface(kClientAddr2);
+
+ connectivity_checker.Start();
+ rtc::Thread::Current()->ProcessMessages(1000);
+
+ NicMap nics = connectivity_checker.GetResults();
+
+ // There should be 4 nics in our map. 2 for each interface added,
+ // one with proxy set and one without.
+ EXPECT_EQ(4U, nics.size());
+
+ // First verify interfaces without proxy.
+ rtc::SocketAddress nilAddress;
+
+ // First lookup the address of the first nic combined with no proxy.
+ NicMap::iterator i = nics.find(NicId(kClientAddr1.ipaddr(), nilAddress));
+ ASSERT(i != nics.end());
+ NicInfo info = i->second;
+ VerifyNic(info, kClientAddr1);
+
+ // Then make sure the second device has been tested without proxy.
+ i = nics.find(NicId(kClientAddr2.ipaddr(), nilAddress));
+ ASSERT(i != nics.end());
+ info = i->second;
+ VerifyNic(info, kClientAddr2);
+
+ // Now verify both interfaces with proxy.
+ i = nics.find(NicId(kClientAddr1.ipaddr(), kProxyAddr));
+ ASSERT(i != nics.end());
+ info = i->second;
+ VerifyNic(info, kClientAddr1);
+
+ i = nics.find(NicId(kClientAddr2.ipaddr(), kProxyAddr));
+ ASSERT(i != nics.end());
+ info = i->second;
+ VerifyNic(info, kClientAddr2);
+};
+
+// Tests that nothing bad happens if thera are no network interfaces
+// available to check.
+TEST_F(ConnectivityCheckerTest, TestStartNoNetwork) {
+ ConnectivityCheckerForTest connectivity_checker(rtc::Thread::Current(),
+ kJid,
+ kSessionId,
+ kBrowserAgent,
+ kRelayToken,
+ kConnection);
+ connectivity_checker.Initialize();
+ connectivity_checker.Start();
+ rtc::Thread::Current()->ProcessMessages(1000);
+
+ NicMap nics = connectivity_checker.GetResults();
+
+ // Verify that no nics where checked.
+ EXPECT_EQ(0U, nics.size());
+}
+
+} // namespace cricket
diff --git a/p2p/client/fakeportallocator.h b/p2p/client/fakeportallocator.h
new file mode 100644
index 00000000..73dae3af
--- /dev/null
+++ b/p2p/client/fakeportallocator.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2010 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_P2P_CLIENT_FAKEPORTALLOCATOR_H_
+#define WEBRTC_P2P_CLIENT_FAKEPORTALLOCATOR_H_
+
+#include <string>
+#include "webrtc/p2p/base/basicpacketsocketfactory.h"
+#include "webrtc/p2p/base/portallocator.h"
+#include "webrtc/p2p/base/udpport.h"
+#include "webrtc/base/scoped_ptr.h"
+
+namespace rtc {
+class SocketFactory;
+class Thread;
+}
+
+namespace cricket {
+
+class FakePortAllocatorSession : public PortAllocatorSession {
+ public:
+ FakePortAllocatorSession(rtc::Thread* worker_thread,
+ rtc::PacketSocketFactory* factory,
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd)
+ : PortAllocatorSession(content_name, component, ice_ufrag, ice_pwd,
+ cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG),
+ worker_thread_(worker_thread),
+ factory_(factory),
+ network_("network", "unittest",
+ rtc::IPAddress(INADDR_LOOPBACK), 8),
+ port_(), running_(false),
+ port_config_count_(0) {
+ network_.AddIP(rtc::IPAddress(INADDR_LOOPBACK));
+ }
+
+ virtual void StartGettingPorts() {
+ if (!port_) {
+ port_.reset(cricket::UDPPort::Create(worker_thread_,
+ factory_,
+ &network_,
+#ifdef USE_WEBRTC_DEV_BRANCH
+ network_.GetBestIP(),
+#else // USE_WEBRTC_DEV_BRANCH
+ network_.ip(),
+#endif // USE_WEBRTC_DEV_BRANCH
+ 0,
+ 0,
+ username(),
+ password()));
+ AddPort(port_.get());
+ }
+ ++port_config_count_;
+ running_ = true;
+ }
+
+ virtual void StopGettingPorts() { running_ = false; }
+ virtual bool IsGettingPorts() { return running_; }
+ int port_config_count() { return port_config_count_; }
+
+ void AddPort(cricket::Port* port) {
+ port->set_component(component_);
+ port->set_generation(0);
+ port->SignalPortComplete.connect(
+ this, &FakePortAllocatorSession::OnPortComplete);
+ port->PrepareAddress();
+ SignalPortReady(this, port);
+ }
+ void OnPortComplete(cricket::Port* port) {
+ SignalCandidatesReady(this, port->Candidates());
+ SignalCandidatesAllocationDone(this);
+ }
+
+ private:
+ rtc::Thread* worker_thread_;
+ rtc::PacketSocketFactory* factory_;
+ rtc::Network network_;
+ rtc::scoped_ptr<cricket::Port> port_;
+ bool running_;
+ int port_config_count_;
+};
+
+class FakePortAllocator : public cricket::PortAllocator {
+ public:
+ FakePortAllocator(rtc::Thread* worker_thread,
+ rtc::PacketSocketFactory* factory)
+ : worker_thread_(worker_thread), factory_(factory) {
+ if (factory_ == NULL) {
+ owned_factory_.reset(new rtc::BasicPacketSocketFactory(
+ worker_thread_));
+ factory_ = owned_factory_.get();
+ }
+ }
+
+ virtual cricket::PortAllocatorSession* CreateSessionInternal(
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd) {
+ return new FakePortAllocatorSession(
+ worker_thread_, factory_, content_name, component, ice_ufrag, ice_pwd);
+ }
+
+ private:
+ rtc::Thread* worker_thread_;
+ rtc::PacketSocketFactory* factory_;
+ rtc::scoped_ptr<rtc::BasicPacketSocketFactory> owned_factory_;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_CLIENT_FAKEPORTALLOCATOR_H_
diff --git a/p2p/client/httpportallocator.cc b/p2p/client/httpportallocator.cc
new file mode 100644
index 00000000..c072da27
--- /dev/null
+++ b/p2p/client/httpportallocator.cc
@@ -0,0 +1,326 @@
+/*
+ * 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 "webrtc/p2p/client/httpportallocator.h"
+
+#include <algorithm>
+#include <map>
+
+#include "webrtc/base/asynchttprequest.h"
+#include "webrtc/base/basicdefs.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/nethelpers.h"
+#include "webrtc/base/signalthread.h"
+#include "webrtc/base/stringencode.h"
+
+namespace {
+
+// Helper routine to remove whitespace from the ends of a string.
+void Trim(std::string& str) {
+ size_t first = str.find_first_not_of(" \t\r\n");
+ if (first == std::string::npos) {
+ str.clear();
+ return;
+ }
+
+ ASSERT(str.find_last_not_of(" \t\r\n") != std::string::npos);
+}
+
+// Parses the lines in the result of the HTTP request that are of the form
+// 'a=b' and returns them in a map.
+typedef std::map<std::string, std::string> StringMap;
+void ParseMap(const std::string& string, StringMap& map) {
+ size_t start_of_line = 0;
+ size_t end_of_line = 0;
+
+ for (;;) { // for each line
+ start_of_line = string.find_first_not_of("\r\n", end_of_line);
+ if (start_of_line == std::string::npos)
+ break;
+
+ end_of_line = string.find_first_of("\r\n", start_of_line);
+ if (end_of_line == std::string::npos) {
+ end_of_line = string.length();
+ }
+
+ size_t equals = string.find('=', start_of_line);
+ if ((equals >= end_of_line) || (equals == std::string::npos))
+ continue;
+
+ std::string key(string, start_of_line, equals - start_of_line);
+ std::string value(string, equals + 1, end_of_line - equals - 1);
+
+ Trim(key);
+ Trim(value);
+
+ if ((key.size() > 0) && (value.size() > 0))
+ map[key] = value;
+ }
+}
+
+} // namespace
+
+namespace cricket {
+
+// HttpPortAllocatorBase
+
+const int HttpPortAllocatorBase::kNumRetries = 5;
+
+const char HttpPortAllocatorBase::kCreateSessionURL[] = "/create_session";
+
+HttpPortAllocatorBase::HttpPortAllocatorBase(
+ rtc::NetworkManager* network_manager,
+ rtc::PacketSocketFactory* socket_factory,
+ const std::string &user_agent)
+ : BasicPortAllocator(network_manager, socket_factory), agent_(user_agent) {
+ relay_hosts_.push_back("relay.google.com");
+ stun_hosts_.push_back(
+ rtc::SocketAddress("stun.l.google.com", 19302));
+}
+
+HttpPortAllocatorBase::HttpPortAllocatorBase(
+ rtc::NetworkManager* network_manager,
+ const std::string &user_agent)
+ : BasicPortAllocator(network_manager), agent_(user_agent) {
+ relay_hosts_.push_back("relay.google.com");
+ stun_hosts_.push_back(
+ rtc::SocketAddress("stun.l.google.com", 19302));
+}
+
+HttpPortAllocatorBase::~HttpPortAllocatorBase() {
+}
+
+// HttpPortAllocatorSessionBase
+
+HttpPortAllocatorSessionBase::HttpPortAllocatorSessionBase(
+ HttpPortAllocatorBase* allocator,
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd,
+ const std::vector<rtc::SocketAddress>& stun_hosts,
+ const std::vector<std::string>& relay_hosts,
+ const std::string& relay_token,
+ const std::string& user_agent)
+ : BasicPortAllocatorSession(allocator, content_name, component,
+ ice_ufrag, ice_pwd),
+ relay_hosts_(relay_hosts), stun_hosts_(stun_hosts),
+ relay_token_(relay_token), agent_(user_agent), attempts_(0) {
+}
+
+HttpPortAllocatorSessionBase::~HttpPortAllocatorSessionBase() {}
+
+void HttpPortAllocatorSessionBase::GetPortConfigurations() {
+ // Creating relay sessions can take time and is done asynchronously.
+ // Creating stun sessions could also take time and could be done aysnc also,
+ // but for now is done here and added to the initial config. Note any later
+ // configs will have unresolved stun ips and will be discarded by the
+ // AllocationSequence.
+ ServerAddresses hosts;
+ for (std::vector<rtc::SocketAddress>::iterator it = stun_hosts_.begin();
+ it != stun_hosts_.end(); ++it) {
+ hosts.insert(*it);
+ }
+
+ PortConfiguration* config = new PortConfiguration(hosts,
+ username(),
+ password());
+ ConfigReady(config);
+ TryCreateRelaySession();
+}
+
+void HttpPortAllocatorSessionBase::TryCreateRelaySession() {
+ if (allocator()->flags() & PORTALLOCATOR_DISABLE_RELAY) {
+ LOG(LS_VERBOSE) << "HttpPortAllocator: Relay ports disabled, skipping.";
+ return;
+ }
+
+ if (attempts_ == HttpPortAllocator::kNumRetries) {
+ LOG(LS_ERROR) << "HttpPortAllocator: maximum number of requests reached; "
+ << "giving up on relay.";
+ return;
+ }
+
+ if (relay_hosts_.size() == 0) {
+ LOG(LS_ERROR) << "HttpPortAllocator: no relay hosts configured.";
+ return;
+ }
+
+ // Choose the next host to try.
+ std::string host = relay_hosts_[attempts_ % relay_hosts_.size()];
+ attempts_++;
+ LOG(LS_INFO) << "HTTPPortAllocator: sending to relay host " << host;
+ if (relay_token_.empty()) {
+ LOG(LS_WARNING) << "No relay auth token found.";
+ }
+
+ SendSessionRequest(host, rtc::HTTP_SECURE_PORT);
+}
+
+std::string HttpPortAllocatorSessionBase::GetSessionRequestUrl() {
+ std::string url = std::string(HttpPortAllocator::kCreateSessionURL);
+ if (allocator()->flags() & PORTALLOCATOR_ENABLE_SHARED_UFRAG) {
+ ASSERT(!username().empty());
+ ASSERT(!password().empty());
+ url = url + "?username=" + rtc::s_url_encode(username()) +
+ "&password=" + rtc::s_url_encode(password());
+ }
+ return url;
+}
+
+void HttpPortAllocatorSessionBase::ReceiveSessionResponse(
+ const std::string& response) {
+
+ StringMap map;
+ ParseMap(response, map);
+
+ if (!username().empty() && map["username"] != username()) {
+ LOG(LS_WARNING) << "Received unexpected username value from relay server.";
+ }
+ if (!password().empty() && map["password"] != password()) {
+ LOG(LS_WARNING) << "Received unexpected password value from relay server.";
+ }
+
+ std::string relay_ip = map["relay.ip"];
+ std::string relay_udp_port = map["relay.udp_port"];
+ std::string relay_tcp_port = map["relay.tcp_port"];
+ std::string relay_ssltcp_port = map["relay.ssltcp_port"];
+
+ ServerAddresses hosts;
+ for (std::vector<rtc::SocketAddress>::iterator it = stun_hosts_.begin();
+ it != stun_hosts_.end(); ++it) {
+ hosts.insert(*it);
+ }
+
+ PortConfiguration* config = new PortConfiguration(hosts,
+ map["username"],
+ map["password"]);
+
+ RelayServerConfig relay_config(RELAY_GTURN);
+ if (!relay_udp_port.empty()) {
+ rtc::SocketAddress address(relay_ip, atoi(relay_udp_port.c_str()));
+ relay_config.ports.push_back(ProtocolAddress(address, PROTO_UDP));
+ }
+ if (!relay_tcp_port.empty()) {
+ rtc::SocketAddress address(relay_ip, atoi(relay_tcp_port.c_str()));
+ relay_config.ports.push_back(ProtocolAddress(address, PROTO_TCP));
+ }
+ if (!relay_ssltcp_port.empty()) {
+ rtc::SocketAddress address(relay_ip, atoi(relay_ssltcp_port.c_str()));
+ relay_config.ports.push_back(ProtocolAddress(address, PROTO_SSLTCP));
+ }
+ config->AddRelay(relay_config);
+ ConfigReady(config);
+}
+
+// HttpPortAllocator
+
+HttpPortAllocator::HttpPortAllocator(
+ rtc::NetworkManager* network_manager,
+ rtc::PacketSocketFactory* socket_factory,
+ const std::string &user_agent)
+ : HttpPortAllocatorBase(network_manager, socket_factory, user_agent) {
+}
+
+HttpPortAllocator::HttpPortAllocator(
+ rtc::NetworkManager* network_manager,
+ const std::string &user_agent)
+ : HttpPortAllocatorBase(network_manager, user_agent) {
+}
+HttpPortAllocator::~HttpPortAllocator() {}
+
+PortAllocatorSession* HttpPortAllocator::CreateSessionInternal(
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag, const std::string& ice_pwd) {
+ return new HttpPortAllocatorSession(this, content_name, component,
+ ice_ufrag, ice_pwd, stun_hosts(),
+ relay_hosts(), relay_token(),
+ user_agent());
+}
+
+// HttpPortAllocatorSession
+
+HttpPortAllocatorSession::HttpPortAllocatorSession(
+ HttpPortAllocator* allocator,
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd,
+ const std::vector<rtc::SocketAddress>& stun_hosts,
+ const std::vector<std::string>& relay_hosts,
+ const std::string& relay,
+ const std::string& agent)
+ : HttpPortAllocatorSessionBase(allocator, content_name, component,
+ ice_ufrag, ice_pwd, stun_hosts,
+ relay_hosts, relay, agent) {
+}
+
+HttpPortAllocatorSession::~HttpPortAllocatorSession() {
+ for (std::list<rtc::AsyncHttpRequest*>::iterator it = requests_.begin();
+ it != requests_.end(); ++it) {
+ (*it)->Destroy(true);
+ }
+}
+
+void HttpPortAllocatorSession::SendSessionRequest(const std::string& host,
+ int port) {
+ // Initiate an HTTP request to create a session through the chosen host.
+ rtc::AsyncHttpRequest* request =
+ new rtc::AsyncHttpRequest(user_agent());
+ request->SignalWorkDone.connect(this,
+ &HttpPortAllocatorSession::OnRequestDone);
+
+ request->set_secure(port == rtc::HTTP_SECURE_PORT);
+ request->set_proxy(allocator()->proxy());
+ request->response().document.reset(new rtc::MemoryStream);
+ request->request().verb = rtc::HV_GET;
+ request->request().path = GetSessionRequestUrl();
+ request->request().addHeader("X-Talk-Google-Relay-Auth", relay_token(), true);
+ request->request().addHeader("X-Stream-Type", "video_rtp", true);
+ request->set_host(host);
+ request->set_port(port);
+ request->Start();
+ request->Release();
+
+ requests_.push_back(request);
+}
+
+void HttpPortAllocatorSession::OnRequestDone(rtc::SignalThread* data) {
+ rtc::AsyncHttpRequest* request =
+ static_cast<rtc::AsyncHttpRequest*>(data);
+
+ // Remove the request from the list of active requests.
+ std::list<rtc::AsyncHttpRequest*>::iterator it =
+ std::find(requests_.begin(), requests_.end(), request);
+ if (it != requests_.end()) {
+ requests_.erase(it);
+ }
+
+ if (request->response().scode != 200) {
+ LOG(LS_WARNING) << "HTTPPortAllocator: request "
+ << " received error " << request->response().scode;
+ TryCreateRelaySession();
+ return;
+ }
+ LOG(LS_INFO) << "HTTPPortAllocator: request succeeded";
+
+ rtc::MemoryStream* stream =
+ static_cast<rtc::MemoryStream*>(request->response().document.get());
+ stream->Rewind();
+ size_t length;
+ stream->GetSize(&length);
+ std::string resp = std::string(stream->GetBuffer(), length);
+ ReceiveSessionResponse(resp);
+}
+
+} // namespace cricket
diff --git a/p2p/client/httpportallocator.h b/p2p/client/httpportallocator.h
new file mode 100644
index 00000000..e2fa7435
--- /dev/null
+++ b/p2p/client/httpportallocator.h
@@ -0,0 +1,173 @@
+/*
+ * 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 WEBRTC_P2P_CLIENT_HTTPPORTALLOCATOR_H_
+#define WEBRTC_P2P_CLIENT_HTTPPORTALLOCATOR_H_
+
+#include <list>
+#include <string>
+#include <vector>
+
+#include "webrtc/p2p/client/basicportallocator.h"
+
+class HttpPortAllocatorTest_TestSessionRequestUrl_Test;
+
+namespace rtc {
+class AsyncHttpRequest;
+class SignalThread;
+}
+
+namespace cricket {
+
+class HttpPortAllocatorBase : public BasicPortAllocator {
+ public:
+ // The number of HTTP requests we should attempt before giving up.
+ static const int kNumRetries;
+
+ // Records the URL that we will GET in order to create a session.
+ static const char kCreateSessionURL[];
+
+ HttpPortAllocatorBase(rtc::NetworkManager* network_manager,
+ const std::string& user_agent);
+ HttpPortAllocatorBase(rtc::NetworkManager* network_manager,
+ rtc::PacketSocketFactory* socket_factory,
+ const std::string& user_agent);
+ virtual ~HttpPortAllocatorBase();
+
+ // CreateSession is defined in BasicPortAllocator but is
+ // redefined here as pure virtual.
+ virtual PortAllocatorSession* CreateSessionInternal(
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd) = 0;
+
+ void SetStunHosts(const std::vector<rtc::SocketAddress>& hosts) {
+ if (!hosts.empty()) {
+ stun_hosts_ = hosts;
+ }
+ }
+ void SetRelayHosts(const std::vector<std::string>& hosts) {
+ if (!hosts.empty()) {
+ relay_hosts_ = hosts;
+ }
+ }
+ void SetRelayToken(const std::string& relay) { relay_token_ = relay; }
+
+ const std::vector<rtc::SocketAddress>& stun_hosts() const {
+ return stun_hosts_;
+ }
+
+ const std::vector<std::string>& relay_hosts() const {
+ return relay_hosts_;
+ }
+
+ const std::string& relay_token() const {
+ return relay_token_;
+ }
+
+ const std::string& user_agent() const {
+ return agent_;
+ }
+
+ private:
+ std::vector<rtc::SocketAddress> stun_hosts_;
+ std::vector<std::string> relay_hosts_;
+ std::string relay_token_;
+ std::string agent_;
+};
+
+class RequestData;
+
+class HttpPortAllocatorSessionBase : public BasicPortAllocatorSession {
+ public:
+ HttpPortAllocatorSessionBase(
+ HttpPortAllocatorBase* allocator,
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd,
+ const std::vector<rtc::SocketAddress>& stun_hosts,
+ const std::vector<std::string>& relay_hosts,
+ const std::string& relay,
+ const std::string& agent);
+ virtual ~HttpPortAllocatorSessionBase();
+
+ const std::string& relay_token() const {
+ return relay_token_;
+ }
+
+ const std::string& user_agent() const {
+ return agent_;
+ }
+
+ virtual void SendSessionRequest(const std::string& host, int port) = 0;
+ virtual void ReceiveSessionResponse(const std::string& response);
+
+ // Made public for testing. Should be protected.
+ std::string GetSessionRequestUrl();
+
+ protected:
+ virtual void GetPortConfigurations();
+ void TryCreateRelaySession();
+ virtual HttpPortAllocatorBase* allocator() {
+ return static_cast<HttpPortAllocatorBase*>(
+ BasicPortAllocatorSession::allocator());
+ }
+
+ private:
+ std::vector<std::string> relay_hosts_;
+ std::vector<rtc::SocketAddress> stun_hosts_;
+ std::string relay_token_;
+ std::string agent_;
+ int attempts_;
+};
+
+class HttpPortAllocator : public HttpPortAllocatorBase {
+ public:
+ HttpPortAllocator(rtc::NetworkManager* network_manager,
+ const std::string& user_agent);
+ HttpPortAllocator(rtc::NetworkManager* network_manager,
+ rtc::PacketSocketFactory* socket_factory,
+ const std::string& user_agent);
+ virtual ~HttpPortAllocator();
+ virtual PortAllocatorSession* CreateSessionInternal(
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag, const std::string& ice_pwd);
+};
+
+class HttpPortAllocatorSession : public HttpPortAllocatorSessionBase {
+ public:
+ HttpPortAllocatorSession(
+ HttpPortAllocator* allocator,
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd,
+ const std::vector<rtc::SocketAddress>& stun_hosts,
+ const std::vector<std::string>& relay_hosts,
+ const std::string& relay,
+ const std::string& agent);
+ virtual ~HttpPortAllocatorSession();
+
+ virtual void SendSessionRequest(const std::string& host, int port);
+
+ protected:
+ // Protected for diagnostics.
+ virtual void OnRequestDone(rtc::SignalThread* request);
+
+ private:
+ std::list<rtc::AsyncHttpRequest*> requests_;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_CLIENT_HTTPPORTALLOCATOR_H_
diff --git a/p2p/client/portallocator_unittest.cc b/p2p/client/portallocator_unittest.cc
new file mode 100644
index 00000000..5dcc8f98
--- /dev/null
+++ b/p2p/client/portallocator_unittest.cc
@@ -0,0 +1,1066 @@
+/*
+ * Copyright 2009 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can 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 "webrtc/p2p/base/basicpacketsocketfactory.h"
+#include "webrtc/p2p/base/constants.h"
+#include "webrtc/p2p/base/p2ptransportchannel.h"
+#include "webrtc/p2p/base/portallocatorsessionproxy.h"
+#include "webrtc/p2p/base/testrelayserver.h"
+#include "webrtc/p2p/base/teststunserver.h"
+#include "webrtc/p2p/base/testturnserver.h"
+#include "webrtc/p2p/client/basicportallocator.h"
+#include "webrtc/p2p/client/httpportallocator.h"
+#include "webrtc/base/fakenetwork.h"
+#include "webrtc/base/firewallsocketserver.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/natserver.h"
+#include "webrtc/base/natsocketfactory.h"
+#include "webrtc/base/network.h"
+#include "webrtc/base/physicalsocketserver.h"
+#include "webrtc/base/socketaddress.h"
+#include "webrtc/base/ssladapter.h"
+#include "webrtc/base/thread.h"
+#include "webrtc/base/virtualsocketserver.h"
+
+using cricket::ServerAddresses;
+using rtc::SocketAddress;
+using rtc::Thread;
+
+static const SocketAddress kClientAddr("11.11.11.11", 0);
+static const SocketAddress kPrivateAddr("192.168.1.11", 0);
+static const SocketAddress kClientIPv6Addr(
+ "2401:fa00:4:1000:be30:5bff:fee5:c3", 0);
+static const SocketAddress kClientAddr2("22.22.22.22", 0);
+static const SocketAddress kNatAddr("77.77.77.77", rtc::NAT_SERVER_PORT);
+static const SocketAddress kRemoteClientAddr("22.22.22.22", 0);
+static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
+static const SocketAddress kRelayUdpIntAddr("99.99.99.2", 5000);
+static const SocketAddress kRelayUdpExtAddr("99.99.99.3", 5001);
+static const SocketAddress kRelayTcpIntAddr("99.99.99.2", 5002);
+static const SocketAddress kRelayTcpExtAddr("99.99.99.3", 5003);
+static const SocketAddress kRelaySslTcpIntAddr("99.99.99.2", 5004);
+static const SocketAddress kRelaySslTcpExtAddr("99.99.99.3", 5005);
+static const SocketAddress kTurnUdpIntAddr("99.99.99.4", 3478);
+static const SocketAddress kTurnTcpIntAddr("99.99.99.5", 3478);
+static const SocketAddress kTurnUdpExtAddr("99.99.99.6", 0);
+
+// Minimum and maximum port for port range tests.
+static const int kMinPort = 10000;
+static const int kMaxPort = 10099;
+
+// Based on ICE_UFRAG_LENGTH
+static const char kIceUfrag0[] = "TESTICEUFRAG0000";
+// Based on ICE_PWD_LENGTH
+static const char kIcePwd0[] = "TESTICEPWD00000000000000";
+
+static const char kContentName[] = "test content";
+
+static const int kDefaultAllocationTimeout = 1000;
+static const char kTurnUsername[] = "test";
+static const char kTurnPassword[] = "test";
+
+namespace cricket {
+
+// Helper for dumping candidates
+std::ostream& operator<<(std::ostream& os, const cricket::Candidate& c) {
+ os << c.ToString();
+ return os;
+}
+
+} // namespace cricket
+
+class PortAllocatorTest : public testing::Test, public sigslot::has_slots<> {
+ public:
+ PortAllocatorTest()
+ : pss_(new rtc::PhysicalSocketServer),
+ vss_(new rtc::VirtualSocketServer(pss_.get())),
+ fss_(new rtc::FirewallSocketServer(vss_.get())),
+ ss_scope_(fss_.get()),
+ nat_factory_(vss_.get(), kNatAddr),
+ nat_socket_factory_(&nat_factory_),
+ stun_server_(cricket::TestStunServer::Create(Thread::Current(),
+ kStunAddr)),
+ relay_server_(Thread::Current(), kRelayUdpIntAddr, kRelayUdpExtAddr,
+ kRelayTcpIntAddr, kRelayTcpExtAddr,
+ kRelaySslTcpIntAddr, kRelaySslTcpExtAddr),
+ turn_server_(Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr),
+ candidate_allocation_done_(false) {
+ cricket::ServerAddresses stun_servers;
+ stun_servers.insert(kStunAddr);
+ // Passing the addresses of GTURN servers will enable GTURN in
+ // Basicportallocator.
+ allocator_.reset(new cricket::BasicPortAllocator(
+ &network_manager_,
+ stun_servers,
+ kRelayUdpIntAddr, kRelayTcpIntAddr, kRelaySslTcpIntAddr));
+ allocator_->set_step_delay(cricket::kMinimumStepDelay);
+ }
+
+ void AddInterface(const SocketAddress& addr) {
+ network_manager_.AddInterface(addr);
+ }
+ bool SetPortRange(int min_port, int max_port) {
+ return allocator_->SetPortRange(min_port, max_port);
+ }
+ void ResetWithNatServer(const rtc::SocketAddress& stun_server) {
+ nat_server_.reset(new rtc::NATServer(
+ rtc::NAT_OPEN_CONE, vss_.get(), kNatAddr, vss_.get(), kNatAddr));
+
+ ServerAddresses stun_servers;
+ stun_servers.insert(stun_server);
+ allocator_.reset(new cricket::BasicPortAllocator(
+ &network_manager_, &nat_socket_factory_, stun_servers));
+ allocator().set_step_delay(cricket::kMinimumStepDelay);
+ }
+
+ // Create a BasicPortAllocator without GTURN and add the TURN servers.
+ void ResetWithTurnServers(const rtc::SocketAddress& udp_turn,
+ const rtc::SocketAddress& tcp_turn) {
+ allocator_.reset(new cricket::BasicPortAllocator(&network_manager_));
+ allocator().set_step_delay(cricket::kMinimumStepDelay);
+ AddTurnServers(udp_turn, tcp_turn);
+ }
+
+ void AddTurnServers(const rtc::SocketAddress& udp_turn,
+ const rtc::SocketAddress& tcp_turn) {
+ cricket::RelayServerConfig relay_server(cricket::RELAY_TURN);
+ cricket::RelayCredentials credentials(kTurnUsername, kTurnPassword);
+ relay_server.credentials = credentials;
+
+ if (!udp_turn.IsNil()) {
+ relay_server.ports.push_back(cricket::ProtocolAddress(
+ kTurnUdpIntAddr, cricket::PROTO_UDP, false));
+ }
+ if (!tcp_turn.IsNil()) {
+ relay_server.ports.push_back(cricket::ProtocolAddress(
+ kTurnTcpIntAddr, cricket::PROTO_TCP, false));
+ }
+ allocator_->AddRelay(relay_server);
+ }
+
+ bool CreateSession(int component) {
+ session_.reset(CreateSession("session", component));
+ if (!session_)
+ return false;
+ return true;
+ }
+
+ bool CreateSession(int component, const std::string& content_name) {
+ session_.reset(CreateSession("session", content_name, component));
+ if (!session_)
+ return false;
+ return true;
+ }
+
+ cricket::PortAllocatorSession* CreateSession(
+ const std::string& sid, int component) {
+ return CreateSession(sid, kContentName, component);
+ }
+
+ cricket::PortAllocatorSession* CreateSession(
+ const std::string& sid, const std::string& content_name, int component) {
+ return CreateSession(sid, content_name, component, kIceUfrag0, kIcePwd0);
+ }
+
+ cricket::PortAllocatorSession* CreateSession(
+ const std::string& sid, const std::string& content_name, int component,
+ const std::string& ice_ufrag, const std::string& ice_pwd) {
+ cricket::PortAllocatorSession* session =
+ allocator_->CreateSession(
+ sid, content_name, component, ice_ufrag, ice_pwd);
+ session->SignalPortReady.connect(this,
+ &PortAllocatorTest::OnPortReady);
+ session->SignalCandidatesReady.connect(this,
+ &PortAllocatorTest::OnCandidatesReady);
+ session->SignalCandidatesAllocationDone.connect(this,
+ &PortAllocatorTest::OnCandidatesAllocationDone);
+ return session;
+ }
+
+ static bool CheckCandidate(const cricket::Candidate& c,
+ int component, const std::string& type,
+ const std::string& proto,
+ const SocketAddress& addr) {
+ return (c.component() == component && c.type() == type &&
+ c.protocol() == proto && c.address().ipaddr() == addr.ipaddr() &&
+ ((addr.port() == 0 && (c.address().port() != 0)) ||
+ (c.address().port() == addr.port())));
+ }
+ static bool CheckPort(const rtc::SocketAddress& addr,
+ int min_port, int max_port) {
+ return (addr.port() >= min_port && addr.port() <= max_port);
+ }
+
+ void OnCandidatesAllocationDone(cricket::PortAllocatorSession* session) {
+ // We should only get this callback once, except in the mux test where
+ // we have multiple port allocation sessions.
+ if (session == session_.get()) {
+ ASSERT_FALSE(candidate_allocation_done_);
+ candidate_allocation_done_ = true;
+ }
+ }
+
+ // Check if all ports allocated have send-buffer size |expected|. If
+ // |expected| == -1, check if GetOptions returns SOCKET_ERROR.
+ void CheckSendBufferSizesOfAllPorts(int expected) {
+ std::vector<cricket::PortInterface*>::iterator it;
+ for (it = ports_.begin(); it < ports_.end(); ++it) {
+ int send_buffer_size;
+ if (expected == -1) {
+ EXPECT_EQ(SOCKET_ERROR,
+ (*it)->GetOption(rtc::Socket::OPT_SNDBUF,
+ &send_buffer_size));
+ } else {
+ EXPECT_EQ(0, (*it)->GetOption(rtc::Socket::OPT_SNDBUF,
+ &send_buffer_size));
+ ASSERT_EQ(expected, send_buffer_size);
+ }
+ }
+ }
+
+ protected:
+ cricket::BasicPortAllocator& allocator() {
+ return *allocator_;
+ }
+
+ void OnPortReady(cricket::PortAllocatorSession* ses,
+ cricket::PortInterface* port) {
+ LOG(LS_INFO) << "OnPortReady: " << port->ToString();
+ ports_.push_back(port);
+ }
+ void OnCandidatesReady(cricket::PortAllocatorSession* ses,
+ const std::vector<cricket::Candidate>& candidates) {
+ for (size_t i = 0; i < candidates.size(); ++i) {
+ LOG(LS_INFO) << "OnCandidatesReady: " << candidates[i].ToString();
+ candidates_.push_back(candidates[i]);
+ }
+ }
+
+ bool HasRelayAddress(const cricket::ProtocolAddress& proto_addr) {
+ for (size_t i = 0; i < allocator_->relays().size(); ++i) {
+ cricket::RelayServerConfig server_config = allocator_->relays()[i];
+ cricket::PortList::const_iterator relay_port;
+ for (relay_port = server_config.ports.begin();
+ relay_port != server_config.ports.end(); ++relay_port) {
+ if (proto_addr.address == relay_port->address &&
+ proto_addr.proto == relay_port->proto)
+ return true;
+ }
+ }
+ return false;
+ }
+
+ rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
+ rtc::scoped_ptr<rtc::VirtualSocketServer> vss_;
+ rtc::scoped_ptr<rtc::FirewallSocketServer> fss_;
+ rtc::SocketServerScope ss_scope_;
+ rtc::scoped_ptr<rtc::NATServer> nat_server_;
+ rtc::NATSocketFactory nat_factory_;
+ rtc::BasicPacketSocketFactory nat_socket_factory_;
+ rtc::scoped_ptr<cricket::TestStunServer> stun_server_;
+ cricket::TestRelayServer relay_server_;
+ cricket::TestTurnServer turn_server_;
+ rtc::FakeNetworkManager network_manager_;
+ rtc::scoped_ptr<cricket::BasicPortAllocator> allocator_;
+ rtc::scoped_ptr<cricket::PortAllocatorSession> session_;
+ std::vector<cricket::PortInterface*> ports_;
+ std::vector<cricket::Candidate> candidates_;
+ bool candidate_allocation_done_;
+};
+
+// Tests that we can init the port allocator and create a session.
+TEST_F(PortAllocatorTest, TestBasic) {
+ EXPECT_EQ(&network_manager_, allocator().network_manager());
+ EXPECT_EQ(kStunAddr, *allocator().stun_servers().begin());
+ ASSERT_EQ(1u, allocator().relays().size());
+ EXPECT_EQ(cricket::RELAY_GTURN, allocator().relays()[0].type);
+ // Empty relay credentials are used for GTURN.
+ EXPECT_TRUE(allocator().relays()[0].credentials.username.empty());
+ EXPECT_TRUE(allocator().relays()[0].credentials.password.empty());
+ EXPECT_TRUE(HasRelayAddress(cricket::ProtocolAddress(
+ kRelayUdpIntAddr, cricket::PROTO_UDP)));
+ EXPECT_TRUE(HasRelayAddress(cricket::ProtocolAddress(
+ kRelayTcpIntAddr, cricket::PROTO_TCP)));
+ EXPECT_TRUE(HasRelayAddress(cricket::ProtocolAddress(
+ kRelaySslTcpIntAddr, cricket::PROTO_SSLTCP)));
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+}
+
+// Tests that we allocator session not trying to allocate ports for every 250ms.
+TEST_F(PortAllocatorTest, TestNoNetworkInterface) {
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+ // Waiting for one second to make sure BasicPortAllocatorSession has not
+ // called OnAllocate multiple times. In old behavior it's called every 250ms.
+ // When there are no network interfaces, each execution of OnAllocate will
+ // result in SignalCandidatesAllocationDone signal.
+ rtc::Thread::Current()->ProcessMessages(1000);
+ EXPECT_TRUE(candidate_allocation_done_);
+ EXPECT_EQ(0U, candidates_.size());
+}
+
+// Tests that we can get all the desired addresses successfully.
+TEST_F(PortAllocatorTest, TestGetAllPortsWithMinimumStepDelay) {
+ AddInterface(kClientAddr);
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+ ASSERT_EQ_WAIT(7U, candidates_.size(), kDefaultAllocationTimeout);
+ EXPECT_EQ(4U, ports_.size());
+ EXPECT_PRED5(CheckCandidate, candidates_[0],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[1],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "stun", "udp", kClientAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[2],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpIntAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[3],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpExtAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[4],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "tcp", kRelayTcpIntAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[5],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp", kClientAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[6],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP,
+ "relay", "ssltcp", kRelaySslTcpIntAddr);
+ EXPECT_TRUE(candidate_allocation_done_);
+}
+
+// Verify candidates with default step delay of 1sec.
+TEST_F(PortAllocatorTest, TestGetAllPortsWithOneSecondStepDelay) {
+ AddInterface(kClientAddr);
+ allocator_->set_step_delay(cricket::kDefaultStepDelay);
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+ ASSERT_EQ_WAIT(2U, candidates_.size(), 1000);
+ EXPECT_EQ(2U, ports_.size());
+ ASSERT_EQ_WAIT(4U, candidates_.size(), 2000);
+ EXPECT_EQ(3U, ports_.size());
+ EXPECT_PRED5(CheckCandidate, candidates_[2],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpIntAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[3],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpExtAddr);
+ ASSERT_EQ_WAIT(6U, candidates_.size(), 1500);
+ EXPECT_PRED5(CheckCandidate, candidates_[4],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "tcp", kRelayTcpIntAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[5],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp", kClientAddr);
+ EXPECT_EQ(4U, ports_.size());
+ ASSERT_EQ_WAIT(7U, candidates_.size(), 2000);
+ EXPECT_PRED5(CheckCandidate, candidates_[6],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP,
+ "relay", "ssltcp", kRelaySslTcpIntAddr);
+ EXPECT_EQ(4U, ports_.size());
+ EXPECT_TRUE(candidate_allocation_done_);
+ // If we Stop gathering now, we shouldn't get a second "done" callback.
+ session_->StopGettingPorts();
+}
+
+TEST_F(PortAllocatorTest, TestSetupVideoRtpPortsWithNormalSendBuffers) {
+ AddInterface(kClientAddr);
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP,
+ cricket::CN_VIDEO));
+ session_->StartGettingPorts();
+ ASSERT_EQ_WAIT(7U, candidates_.size(), kDefaultAllocationTimeout);
+ EXPECT_TRUE(candidate_allocation_done_);
+ // If we Stop gathering now, we shouldn't get a second "done" callback.
+ session_->StopGettingPorts();
+
+ // All ports should have unset send-buffer sizes.
+ CheckSendBufferSizesOfAllPorts(-1);
+}
+
+// Tests that we can get callback after StopGetAllPorts.
+TEST_F(PortAllocatorTest, TestStopGetAllPorts) {
+ AddInterface(kClientAddr);
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+ ASSERT_EQ_WAIT(2U, candidates_.size(), kDefaultAllocationTimeout);
+ EXPECT_EQ(2U, ports_.size());
+ session_->StopGettingPorts();
+ EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
+}
+
+// Test that we restrict client ports appropriately when a port range is set.
+// We check the candidates for udp/stun/tcp ports, and the from address
+// for relay ports.
+TEST_F(PortAllocatorTest, TestGetAllPortsPortRange) {
+ AddInterface(kClientAddr);
+ // Check that an invalid port range fails.
+ EXPECT_FALSE(SetPortRange(kMaxPort, kMinPort));
+ // Check that a null port range succeeds.
+ EXPECT_TRUE(SetPortRange(0, 0));
+ // Check that a valid port range succeeds.
+ EXPECT_TRUE(SetPortRange(kMinPort, kMaxPort));
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+ ASSERT_EQ_WAIT(7U, candidates_.size(), kDefaultAllocationTimeout);
+ EXPECT_EQ(4U, ports_.size());
+ // Check the port number for the UDP port object.
+ EXPECT_PRED3(CheckPort, candidates_[0].address(), kMinPort, kMaxPort);
+ // Check the port number for the STUN port object.
+ EXPECT_PRED3(CheckPort, candidates_[1].address(), kMinPort, kMaxPort);
+ // Check the port number used to connect to the relay server.
+ EXPECT_PRED3(CheckPort, relay_server_.GetConnection(0).source(),
+ kMinPort, kMaxPort);
+ // Check the port number for the TCP port object.
+ EXPECT_PRED3(CheckPort, candidates_[5].address(), kMinPort, kMaxPort);
+ EXPECT_TRUE(candidate_allocation_done_);
+}
+
+// Test that we don't crash or malfunction if we have no network adapters.
+TEST_F(PortAllocatorTest, TestGetAllPortsNoAdapters) {
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+ rtc::Thread::Current()->ProcessMessages(100);
+ // Without network adapter, we should not get any candidate.
+ EXPECT_EQ(0U, candidates_.size());
+ EXPECT_TRUE(candidate_allocation_done_);
+}
+
+// Test that we can get OnCandidatesAllocationDone callback when all the ports
+// are disabled.
+TEST_F(PortAllocatorTest, TestDisableAllPorts) {
+ AddInterface(kClientAddr);
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->set_flags(cricket::PORTALLOCATOR_DISABLE_UDP |
+ cricket::PORTALLOCATOR_DISABLE_STUN |
+ cricket::PORTALLOCATOR_DISABLE_RELAY |
+ cricket::PORTALLOCATOR_DISABLE_TCP);
+ session_->StartGettingPorts();
+ rtc::Thread::Current()->ProcessMessages(100);
+ EXPECT_EQ(0U, candidates_.size());
+ EXPECT_TRUE(candidate_allocation_done_);
+}
+
+// Test that we don't crash or malfunction if we can't create UDP sockets.
+TEST_F(PortAllocatorTest, TestGetAllPortsNoUdpSockets) {
+ AddInterface(kClientAddr);
+ fss_->set_udp_sockets_enabled(false);
+ EXPECT_TRUE(CreateSession(1));
+ session_->StartGettingPorts();
+ ASSERT_EQ_WAIT(5U, candidates_.size(), kDefaultAllocationTimeout);
+ EXPECT_EQ(2U, ports_.size());
+ EXPECT_PRED5(CheckCandidate, candidates_[0],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpIntAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[1],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpExtAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[2],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "tcp", kRelayTcpIntAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[3],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp", kClientAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[4],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP,
+ "relay", "ssltcp", kRelaySslTcpIntAddr);
+ EXPECT_TRUE(candidate_allocation_done_);
+}
+
+// Test that we don't crash or malfunction if we can't create UDP sockets or
+// listen on TCP sockets. We still give out a local TCP address, since
+// apparently this is needed for the remote side to accept our connection.
+TEST_F(PortAllocatorTest, TestGetAllPortsNoUdpSocketsNoTcpListen) {
+ AddInterface(kClientAddr);
+ fss_->set_udp_sockets_enabled(false);
+ fss_->set_tcp_listen_enabled(false);
+ EXPECT_TRUE(CreateSession(1));
+ session_->StartGettingPorts();
+ ASSERT_EQ_WAIT(5U, candidates_.size(), kDefaultAllocationTimeout);
+ EXPECT_EQ(2U, ports_.size());
+ EXPECT_PRED5(CheckCandidate, candidates_[0],
+ 1, "relay", "udp", kRelayUdpIntAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[1],
+ 1, "relay", "udp", kRelayUdpExtAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[2],
+ 1, "relay", "tcp", kRelayTcpIntAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[3],
+ 1, "local", "tcp", kClientAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[4],
+ 1, "relay", "ssltcp", kRelaySslTcpIntAddr);
+ EXPECT_TRUE(candidate_allocation_done_);
+}
+
+// Test that we don't crash or malfunction if we can't create any sockets.
+// TODO: Find a way to exit early here.
+TEST_F(PortAllocatorTest, TestGetAllPortsNoSockets) {
+ AddInterface(kClientAddr);
+ fss_->set_tcp_sockets_enabled(false);
+ fss_->set_udp_sockets_enabled(false);
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+ WAIT(candidates_.size() > 0, 2000);
+ // TODO - Check candidate_allocation_done signal.
+ // In case of Relay, ports creation will succeed but sockets will fail.
+ // There is no error reporting from RelayEntry to handle this failure.
+}
+
+// Testing STUN timeout.
+TEST_F(PortAllocatorTest, TestGetAllPortsNoUdpAllowed) {
+ fss_->AddRule(false, rtc::FP_UDP, rtc::FD_ANY, kClientAddr);
+ AddInterface(kClientAddr);
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+ EXPECT_EQ_WAIT(2U, candidates_.size(), kDefaultAllocationTimeout);
+ EXPECT_EQ(2U, ports_.size());
+ EXPECT_PRED5(CheckCandidate, candidates_[0],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[1],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp", kClientAddr);
+ // RelayPort connection timeout is 3sec. TCP connection with RelayServer
+ // will be tried after 3 seconds.
+ EXPECT_EQ_WAIT(6U, candidates_.size(), 4000);
+ EXPECT_EQ(3U, ports_.size());
+ EXPECT_PRED5(CheckCandidate, candidates_[2],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpIntAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[3],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "tcp", kRelayTcpIntAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[4],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "ssltcp",
+ kRelaySslTcpIntAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[5],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpExtAddr);
+ // Stun Timeout is 9sec.
+ EXPECT_TRUE_WAIT(candidate_allocation_done_, 9000);
+}
+
+TEST_F(PortAllocatorTest, TestCandidatePriorityOfMultipleInterfaces) {
+ AddInterface(kClientAddr);
+ AddInterface(kClientAddr2);
+ // Allocating only host UDP ports. This is done purely for testing
+ // convenience.
+ allocator().set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
+ cricket::PORTALLOCATOR_DISABLE_STUN |
+ cricket::PORTALLOCATOR_DISABLE_RELAY);
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+ EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
+ ASSERT_EQ(2U, candidates_.size());
+ EXPECT_EQ(2U, ports_.size());
+ // Candidates priorities should be different.
+ EXPECT_NE(candidates_[0].priority(), candidates_[1].priority());
+}
+
+// Test to verify ICE restart process.
+TEST_F(PortAllocatorTest, TestGetAllPortsRestarts) {
+ AddInterface(kClientAddr);
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+ EXPECT_EQ_WAIT(7U, candidates_.size(), kDefaultAllocationTimeout);
+ EXPECT_EQ(4U, ports_.size());
+ EXPECT_TRUE(candidate_allocation_done_);
+ // TODO - Extend this to verify ICE restart.
+}
+
+// Test ICE candidate filter mechanism with options Relay/Host/Reflexive.
+// This test also verifies that when the allocator is only allowed to use
+// relay (i.e. IceTransportsType is relay), the raddr is an empty
+// address with the correct family. This is to prevent any local
+// reflective address leakage in the sdp line.
+TEST_F(PortAllocatorTest, TestCandidateFilterWithRelayOnly) {
+ AddInterface(kClientAddr);
+ // GTURN is not configured here.
+ ResetWithTurnServers(kTurnUdpIntAddr, rtc::SocketAddress());
+ allocator().set_candidate_filter(cricket::CF_RELAY);
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+ EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
+ EXPECT_PRED5(CheckCandidate,
+ candidates_[0],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP,
+ "relay",
+ "udp",
+ rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0));
+
+ EXPECT_EQ(1U, candidates_.size());
+ EXPECT_EQ(1U, ports_.size()); // Only Relay port will be in ready state.
+ for (size_t i = 0; i < candidates_.size(); ++i) {
+ EXPECT_EQ(std::string(cricket::RELAY_PORT_TYPE), candidates_[i].type());
+ EXPECT_EQ(
+ candidates_[0].related_address(),
+ rtc::EmptySocketAddressWithFamily(candidates_[0].address().family()));
+ }
+}
+
+TEST_F(PortAllocatorTest, TestCandidateFilterWithHostOnly) {
+ AddInterface(kClientAddr);
+ allocator().set_flags(cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET);
+ allocator().set_candidate_filter(cricket::CF_HOST);
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+ EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
+ EXPECT_EQ(2U, candidates_.size()); // Host UDP/TCP candidates only.
+ EXPECT_EQ(2U, ports_.size()); // UDP/TCP ports only.
+ for (size_t i = 0; i < candidates_.size(); ++i) {
+ EXPECT_EQ(std::string(cricket::LOCAL_PORT_TYPE), candidates_[i].type());
+ }
+}
+
+// Host is behind the NAT.
+TEST_F(PortAllocatorTest, TestCandidateFilterWithReflexiveOnly) {
+ AddInterface(kPrivateAddr);
+ ResetWithNatServer(kStunAddr);
+
+ allocator().set_flags(cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET);
+ allocator().set_candidate_filter(cricket::CF_REFLEXIVE);
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+ EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
+ // Host is behind NAT, no private address will be exposed. Hence only UDP
+ // port with STUN candidate will be sent outside.
+ EXPECT_EQ(1U, candidates_.size()); // Only STUN candidate.
+ EXPECT_EQ(1U, ports_.size()); // Only UDP port will be in ready state.
+ for (size_t i = 0; i < candidates_.size(); ++i) {
+ EXPECT_EQ(std::string(cricket::STUN_PORT_TYPE), candidates_[i].type());
+ EXPECT_EQ(
+ candidates_[0].related_address(),
+ rtc::EmptySocketAddressWithFamily(candidates_[0].address().family()));
+ }
+}
+
+// Host is not behind the NAT.
+TEST_F(PortAllocatorTest, TestCandidateFilterWithReflexiveOnlyAndNoNAT) {
+ AddInterface(kClientAddr);
+ allocator().set_flags(cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET);
+ allocator().set_candidate_filter(cricket::CF_REFLEXIVE);
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+ EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
+ // Host has a public address, both UDP and TCP candidates will be exposed.
+ EXPECT_EQ(2U, candidates_.size()); // Local UDP + TCP candidate.
+ EXPECT_EQ(2U, ports_.size()); // UDP and TCP ports will be in ready state.
+ for (size_t i = 0; i < candidates_.size(); ++i) {
+ EXPECT_EQ(std::string(cricket::LOCAL_PORT_TYPE), candidates_[i].type());
+ }
+}
+
+TEST_F(PortAllocatorTest, TestBasicMuxFeatures) {
+ AddInterface(kClientAddr);
+ allocator().set_flags(cricket::PORTALLOCATOR_ENABLE_BUNDLE);
+ // Session ID - session1.
+ rtc::scoped_ptr<cricket::PortAllocatorSession> session1(
+ CreateSession("session1", cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ rtc::scoped_ptr<cricket::PortAllocatorSession> session2(
+ CreateSession("session1", cricket::ICE_CANDIDATE_COMPONENT_RTCP));
+ session1->StartGettingPorts();
+ session2->StartGettingPorts();
+ // Each session should receive two proxy ports of local and stun.
+ ASSERT_EQ_WAIT(14U, candidates_.size(), kDefaultAllocationTimeout);
+ EXPECT_EQ(8U, ports_.size());
+
+ rtc::scoped_ptr<cricket::PortAllocatorSession> session3(
+ CreateSession("session1", cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session3->StartGettingPorts();
+ // Already allocated candidates and ports will be sent to the newly
+ // allocated proxy session.
+ ASSERT_EQ_WAIT(21U, candidates_.size(), kDefaultAllocationTimeout);
+ EXPECT_EQ(12U, ports_.size());
+}
+
+// This test verifies by changing ice_ufrag and/or ice_pwd
+// will result in different set of candidates when BUNDLE is enabled.
+// If BUNDLE is disabled, CreateSession will always allocate new
+// set of candidates.
+TEST_F(PortAllocatorTest, TestBundleIceRestart) {
+ AddInterface(kClientAddr);
+ allocator().set_flags(cricket::PORTALLOCATOR_ENABLE_BUNDLE);
+ // Session ID - session1.
+ rtc::scoped_ptr<cricket::PortAllocatorSession> session1(
+ CreateSession("session1", kContentName,
+ cricket::ICE_CANDIDATE_COMPONENT_RTP,
+ kIceUfrag0, kIcePwd0));
+ session1->StartGettingPorts();
+ ASSERT_EQ_WAIT(7U, candidates_.size(), kDefaultAllocationTimeout);
+ EXPECT_EQ(4U, ports_.size());
+
+ // Allocate a different session with sid |session1| and different ice_ufrag.
+ rtc::scoped_ptr<cricket::PortAllocatorSession> session2(
+ CreateSession("session1", kContentName,
+ cricket::ICE_CANDIDATE_COMPONENT_RTP,
+ "TestIceUfrag", kIcePwd0));
+ session2->StartGettingPorts();
+ ASSERT_EQ_WAIT(14U, candidates_.size(), kDefaultAllocationTimeout);
+ EXPECT_EQ(8U, ports_.size());
+ // Verifying the candidate address different from previously allocated
+ // address.
+ // Skipping verification of component id and candidate type.
+ EXPECT_NE(candidates_[0].address(), candidates_[7].address());
+ EXPECT_NE(candidates_[1].address(), candidates_[8].address());
+
+ // Allocating a different session with sid |session1| and
+ // different ice_pwd.
+ rtc::scoped_ptr<cricket::PortAllocatorSession> session3(
+ CreateSession("session1", kContentName,
+ cricket::ICE_CANDIDATE_COMPONENT_RTP,
+ kIceUfrag0, "TestIcePwd"));
+ session3->StartGettingPorts();
+ ASSERT_EQ_WAIT(21U, candidates_.size(), kDefaultAllocationTimeout);
+ EXPECT_EQ(12U, ports_.size());
+ // Verifying the candidate address different from previously
+ // allocated address.
+ EXPECT_NE(candidates_[7].address(), candidates_[14].address());
+ EXPECT_NE(candidates_[8].address(), candidates_[15].address());
+
+ // Allocating a session with by changing both ice_ufrag and ice_pwd.
+ rtc::scoped_ptr<cricket::PortAllocatorSession> session4(
+ CreateSession("session1", kContentName,
+ cricket::ICE_CANDIDATE_COMPONENT_RTP,
+ "TestIceUfrag", "TestIcePwd"));
+ session4->StartGettingPorts();
+ ASSERT_EQ_WAIT(28U, candidates_.size(), kDefaultAllocationTimeout);
+ EXPECT_EQ(16U, ports_.size());
+ // Verifying the candidate address different from previously
+ // allocated address.
+ EXPECT_NE(candidates_[14].address(), candidates_[21].address());
+ EXPECT_NE(candidates_[15].address(), candidates_[22].address());
+}
+
+// Test that when the PORTALLOCATOR_ENABLE_SHARED_UFRAG is enabled we got same
+// ufrag and pwd for the collected candidates.
+TEST_F(PortAllocatorTest, TestEnableSharedUfrag) {
+ allocator().set_flags(allocator().flags() |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG);
+ AddInterface(kClientAddr);
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+ ASSERT_EQ_WAIT(7U, candidates_.size(), kDefaultAllocationTimeout);
+ EXPECT_PRED5(CheckCandidate, candidates_[0],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[1],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "stun", "udp", kClientAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[5],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp", kClientAddr);
+ EXPECT_EQ(4U, ports_.size());
+ EXPECT_EQ(kIceUfrag0, candidates_[0].username());
+ EXPECT_EQ(kIceUfrag0, candidates_[1].username());
+ EXPECT_EQ(kIceUfrag0, candidates_[2].username());
+ EXPECT_EQ(kIcePwd0, candidates_[0].password());
+ EXPECT_EQ(kIcePwd0, candidates_[1].password());
+ EXPECT_TRUE(candidate_allocation_done_);
+}
+
+// Test that when the PORTALLOCATOR_ENABLE_SHARED_UFRAG isn't enabled we got
+// different ufrag and pwd for the collected candidates.
+TEST_F(PortAllocatorTest, TestDisableSharedUfrag) {
+ allocator().set_flags(allocator().flags() &
+ ~cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG);
+ AddInterface(kClientAddr);
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+ ASSERT_EQ_WAIT(7U, candidates_.size(), kDefaultAllocationTimeout);
+ EXPECT_PRED5(CheckCandidate, candidates_[0],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[1],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "stun", "udp", kClientAddr);
+ EXPECT_EQ(4U, ports_.size());
+ // Port should generate random ufrag and pwd.
+ EXPECT_NE(kIceUfrag0, candidates_[0].username());
+ EXPECT_NE(kIceUfrag0, candidates_[1].username());
+ EXPECT_NE(candidates_[0].username(), candidates_[1].username());
+ EXPECT_NE(kIcePwd0, candidates_[0].password());
+ EXPECT_NE(kIcePwd0, candidates_[1].password());
+ EXPECT_NE(candidates_[0].password(), candidates_[1].password());
+ EXPECT_TRUE(candidate_allocation_done_);
+}
+
+// Test that when PORTALLOCATOR_ENABLE_SHARED_SOCKET is enabled only one port
+// is allocated for udp and stun. Also verify there is only one candidate
+// (local) if stun candidate is same as local candidate, which will be the case
+// in a public network like the below test.
+TEST_F(PortAllocatorTest, TestSharedSocketWithoutNat) {
+ AddInterface(kClientAddr);
+ allocator_->set_flags(allocator().flags() |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET);
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+ ASSERT_EQ_WAIT(6U, candidates_.size(), kDefaultAllocationTimeout);
+ EXPECT_EQ(3U, ports_.size());
+ EXPECT_PRED5(CheckCandidate, candidates_[0],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
+ EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
+}
+
+// Test that when PORTALLOCATOR_ENABLE_SHARED_SOCKET is enabled only one port
+// is allocated for udp and stun. In this test we should expect both stun and
+// local candidates as client behind a nat.
+TEST_F(PortAllocatorTest, TestSharedSocketWithNat) {
+ AddInterface(kClientAddr);
+ ResetWithNatServer(kStunAddr);
+
+ allocator_->set_flags(allocator().flags() |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET);
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+ ASSERT_EQ_WAIT(3U, candidates_.size(), kDefaultAllocationTimeout);
+ ASSERT_EQ(2U, ports_.size());
+ EXPECT_PRED5(CheckCandidate, candidates_[0],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[1],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "stun", "udp",
+ rtc::SocketAddress(kNatAddr.ipaddr(), 0));
+ EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
+ EXPECT_EQ(3U, candidates_.size());
+}
+
+// Test TURN port in shared socket mode with UDP and TCP TURN server adderesses.
+TEST_F(PortAllocatorTest, TestSharedSocketWithoutNatUsingTurn) {
+ turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
+ AddInterface(kClientAddr);
+ allocator_.reset(new cricket::BasicPortAllocator(&network_manager_));
+
+ AddTurnServers(kTurnUdpIntAddr, kTurnTcpIntAddr);
+
+ allocator_->set_step_delay(cricket::kMinimumStepDelay);
+ allocator_->set_flags(allocator().flags() |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
+ cricket::PORTALLOCATOR_DISABLE_TCP);
+
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+
+ ASSERT_EQ_WAIT(3U, candidates_.size(), kDefaultAllocationTimeout);
+ ASSERT_EQ(3U, ports_.size());
+ EXPECT_PRED5(CheckCandidate, candidates_[0],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[1],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp",
+ rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0));
+ EXPECT_PRED5(CheckCandidate, candidates_[2],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp",
+ rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0));
+ EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
+ EXPECT_EQ(3U, candidates_.size());
+}
+
+// Testing DNS resolve for the TURN server, this will test AllocationSequence
+// handling the unresolved address signal from TurnPort.
+TEST_F(PortAllocatorTest, TestSharedSocketWithServerAddressResolve) {
+ turn_server_.AddInternalSocket(rtc::SocketAddress("127.0.0.1", 3478),
+ cricket::PROTO_UDP);
+ AddInterface(kClientAddr);
+ allocator_.reset(new cricket::BasicPortAllocator(&network_manager_));
+ cricket::RelayServerConfig relay_server(cricket::RELAY_TURN);
+ cricket::RelayCredentials credentials(kTurnUsername, kTurnPassword);
+ relay_server.credentials = credentials;
+ relay_server.ports.push_back(cricket::ProtocolAddress(
+ rtc::SocketAddress("localhost", 3478),
+ cricket::PROTO_UDP, false));
+ allocator_->AddRelay(relay_server);
+
+ allocator_->set_step_delay(cricket::kMinimumStepDelay);
+ allocator_->set_flags(allocator().flags() |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
+ cricket::PORTALLOCATOR_DISABLE_TCP);
+
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+
+ EXPECT_EQ_WAIT(2U, ports_.size(), kDefaultAllocationTimeout);
+}
+
+// Test that when PORTALLOCATOR_ENABLE_SHARED_SOCKET is enabled only one port
+// is allocated for udp/stun/turn. In this test we should expect all local,
+// stun and turn candidates.
+TEST_F(PortAllocatorTest, TestSharedSocketWithNatUsingTurn) {
+ AddInterface(kClientAddr);
+ ResetWithNatServer(kStunAddr);
+
+ AddTurnServers(kTurnUdpIntAddr, rtc::SocketAddress());
+
+ allocator_->set_flags(allocator().flags() |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
+ cricket::PORTALLOCATOR_DISABLE_TCP);
+
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+
+ ASSERT_EQ_WAIT(3U, candidates_.size(), kDefaultAllocationTimeout);
+ ASSERT_EQ(2U, ports_.size());
+ EXPECT_PRED5(CheckCandidate, candidates_[0],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[1],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "stun", "udp",
+ rtc::SocketAddress(kNatAddr.ipaddr(), 0));
+ EXPECT_PRED5(CheckCandidate, candidates_[2],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp",
+ rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0));
+ EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
+ EXPECT_EQ(3U, candidates_.size());
+ // Local port will be created first and then TURN port.
+ EXPECT_EQ(2U, ports_[0]->Candidates().size());
+ EXPECT_EQ(1U, ports_[1]->Candidates().size());
+}
+
+// Test that when PORTALLOCATOR_ENABLE_SHARED_SOCKET is enabled and the TURN
+// server is also used as the STUN server, we should get 'local', 'stun', and
+// 'relay' candidates.
+TEST_F(PortAllocatorTest, TestSharedSocketWithNatUsingTurnAsStun) {
+ AddInterface(kClientAddr);
+ ResetWithNatServer(kTurnUdpIntAddr);
+ AddTurnServers(kTurnUdpIntAddr, rtc::SocketAddress());
+
+ // Must set the step delay to 0 to make sure the relay allocation phase is
+ // started before the STUN candidates are obtained, so that the STUN binding
+ // response is processed when both StunPort and TurnPort exist to reproduce
+ // webrtc issue 3537.
+ allocator_->set_step_delay(0);
+ allocator_->set_flags(allocator().flags() |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
+ cricket::PORTALLOCATOR_DISABLE_TCP);
+
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+
+ ASSERT_EQ_WAIT(3U, candidates_.size(), kDefaultAllocationTimeout);
+ EXPECT_PRED5(CheckCandidate, candidates_[0],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[1],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "stun", "udp",
+ rtc::SocketAddress(kNatAddr.ipaddr(), 0));
+ EXPECT_PRED5(CheckCandidate, candidates_[2],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp",
+ rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0));
+ EXPECT_EQ(candidates_[2].related_address(), candidates_[1].address());
+
+ EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
+ EXPECT_EQ(3U, candidates_.size());
+ // Local port will be created first and then TURN port.
+ EXPECT_EQ(2U, ports_[0]->Candidates().size());
+ EXPECT_EQ(1U, ports_[1]->Candidates().size());
+}
+
+// This test verifies when PORTALLOCATOR_ENABLE_SHARED_SOCKET flag is enabled
+// and fail to generate STUN candidate, local UDP candidate is generated
+// properly.
+TEST_F(PortAllocatorTest, TestSharedSocketNoUdpAllowed) {
+ allocator().set_flags(allocator().flags() |
+ cricket::PORTALLOCATOR_DISABLE_RELAY |
+ cricket::PORTALLOCATOR_DISABLE_TCP |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET);
+ fss_->AddRule(false, rtc::FP_UDP, rtc::FD_ANY, kClientAddr);
+ AddInterface(kClientAddr);
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+ ASSERT_EQ_WAIT(1U, ports_.size(), kDefaultAllocationTimeout);
+ EXPECT_EQ(1U, candidates_.size());
+ EXPECT_PRED5(CheckCandidate, candidates_[0],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
+ // STUN timeout is 9sec. We need to wait to get candidate done signal.
+ EXPECT_TRUE_WAIT(candidate_allocation_done_, 10000);
+ EXPECT_EQ(1U, candidates_.size());
+}
+
+// This test verifies allocator can use IPv6 addresses along with IPv4.
+TEST_F(PortAllocatorTest, TestEnableIPv6Addresses) {
+ allocator().set_flags(allocator().flags() |
+ cricket::PORTALLOCATOR_DISABLE_RELAY |
+ cricket::PORTALLOCATOR_ENABLE_IPV6 |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET);
+ AddInterface(kClientIPv6Addr);
+ AddInterface(kClientAddr);
+ allocator_->set_step_delay(cricket::kMinimumStepDelay);
+ EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ session_->StartGettingPorts();
+ ASSERT_EQ_WAIT(4U, ports_.size(), kDefaultAllocationTimeout);
+ EXPECT_EQ(4U, candidates_.size());
+ EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
+ EXPECT_PRED5(CheckCandidate, candidates_[0],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp",
+ kClientIPv6Addr);
+ EXPECT_PRED5(CheckCandidate, candidates_[1],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp",
+ kClientAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[2],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp",
+ kClientIPv6Addr);
+ EXPECT_PRED5(CheckCandidate, candidates_[3],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp",
+ kClientAddr);
+ EXPECT_EQ(4U, candidates_.size());
+}
+
+// Test that the httpportallocator correctly maintains its lists of stun and
+// relay servers, by never allowing an empty list.
+TEST(HttpPortAllocatorTest, TestHttpPortAllocatorHostLists) {
+ rtc::FakeNetworkManager network_manager;
+ cricket::HttpPortAllocator alloc(&network_manager, "unit test agent");
+ EXPECT_EQ(1U, alloc.relay_hosts().size());
+ EXPECT_EQ(1U, alloc.stun_hosts().size());
+
+ std::vector<std::string> relay_servers;
+ std::vector<rtc::SocketAddress> stun_servers;
+
+ alloc.SetRelayHosts(relay_servers);
+ alloc.SetStunHosts(stun_servers);
+ EXPECT_EQ(1U, alloc.relay_hosts().size());
+ EXPECT_EQ(1U, alloc.stun_hosts().size());
+
+ relay_servers.push_back("1.unittest.corp.google.com");
+ relay_servers.push_back("2.unittest.corp.google.com");
+ stun_servers.push_back(
+ rtc::SocketAddress("1.unittest.corp.google.com", 0));
+ stun_servers.push_back(
+ rtc::SocketAddress("2.unittest.corp.google.com", 0));
+
+ alloc.SetRelayHosts(relay_servers);
+ alloc.SetStunHosts(stun_servers);
+ EXPECT_EQ(2U, alloc.relay_hosts().size());
+ EXPECT_EQ(2U, alloc.stun_hosts().size());
+}
+
+// Test that the HttpPortAllocator uses correct URL to create sessions.
+TEST(HttpPortAllocatorTest, TestSessionRequestUrl) {
+ rtc::FakeNetworkManager network_manager;
+ cricket::HttpPortAllocator alloc(&network_manager, "unit test agent");
+
+ // Disable PORTALLOCATOR_ENABLE_SHARED_UFRAG.
+ alloc.set_flags(alloc.flags() & ~cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG);
+ rtc::scoped_ptr<cricket::HttpPortAllocatorSessionBase> session(
+ static_cast<cricket::HttpPortAllocatorSession*>(
+ alloc.CreateSessionInternal(
+ "test content", 0, kIceUfrag0, kIcePwd0)));
+ std::string url = session->GetSessionRequestUrl();
+ LOG(LS_INFO) << "url: " << url;
+ EXPECT_EQ(std::string(cricket::HttpPortAllocator::kCreateSessionURL), url);
+
+ // Enable PORTALLOCATOR_ENABLE_SHARED_UFRAG.
+ alloc.set_flags(alloc.flags() | cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG);
+ session.reset(static_cast<cricket::HttpPortAllocatorSession*>(
+ alloc.CreateSessionInternal("test content", 0, kIceUfrag0, kIcePwd0)));
+ url = session->GetSessionRequestUrl();
+ LOG(LS_INFO) << "url: " << url;
+ std::vector<std::string> parts;
+ rtc::split(url, '?', &parts);
+ ASSERT_EQ(2U, parts.size());
+
+ std::vector<std::string> args_parts;
+ rtc::split(parts[1], '&', &args_parts);
+
+ std::map<std::string, std::string> args;
+ for (std::vector<std::string>::iterator it = args_parts.begin();
+ it != args_parts.end(); ++it) {
+ std::vector<std::string> parts;
+ rtc::split(*it, '=', &parts);
+ ASSERT_EQ(2U, parts.size());
+ args[rtc::s_url_decode(parts[0])] = rtc::s_url_decode(parts[1]);
+ }
+
+ EXPECT_EQ(kIceUfrag0, args["username"]);
+ EXPECT_EQ(kIcePwd0, args["password"]);
+}
diff --git a/p2p/client/sessionmanagertask.h b/p2p/client/sessionmanagertask.h
new file mode 100644
index 00000000..04d79d48
--- /dev/null
+++ b/p2p/client/sessionmanagertask.h
@@ -0,0 +1,76 @@
+/*
+ * 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 WEBRTC_P2P_CLIENT_SESSIONMANAGERTASK_H_
+#define WEBRTC_P2P_CLIENT_SESSIONMANAGERTASK_H_
+
+#include "webrtc/p2p/base/sessionmanager.h"
+#include "webrtc/p2p/client/sessionsendtask.h"
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+#include "webrtc/libjingle/xmpp/xmpptask.h"
+
+namespace cricket {
+
+// This class handles sending and receiving XMPP messages on behalf of the
+// SessionManager. The sending part is handed over to SessionSendTask.
+
+class SessionManagerTask : public buzz::XmppTask {
+ public:
+ SessionManagerTask(buzz::XmppTaskParentInterface* parent,
+ SessionManager* session_manager)
+ : buzz::XmppTask(parent, buzz::XmppEngine::HL_SINGLE),
+ session_manager_(session_manager) {
+ }
+
+ ~SessionManagerTask() {
+ }
+
+ // Turns on simple support for sending messages, using SessionSendTask.
+ void EnableOutgoingMessages() {
+ session_manager_->SignalOutgoingMessage.connect(
+ this, &SessionManagerTask::OnOutgoingMessage);
+ session_manager_->SignalRequestSignaling.connect(
+ session_manager_, &SessionManager::OnSignalingReady);
+ }
+
+ virtual int ProcessStart() {
+ const buzz::XmlElement *stanza = NextStanza();
+ if (stanza == NULL)
+ return STATE_BLOCKED;
+ session_manager_->OnIncomingMessage(stanza);
+ return STATE_START;
+ }
+
+ protected:
+ virtual bool HandleStanza(const buzz::XmlElement *stanza) {
+ if (!session_manager_->IsSessionMessage(stanza))
+ return false;
+ // Responses are handled by the SessionSendTask that sent the request.
+ //if (stanza->Attr(buzz::QN_TYPE) != buzz::STR_SET)
+ // return false;
+ QueueStanza(stanza);
+ return true;
+ }
+
+ private:
+ void OnOutgoingMessage(SessionManager* manager,
+ const buzz::XmlElement* stanza) {
+ cricket::SessionSendTask* sender =
+ new cricket::SessionSendTask(parent_, session_manager_);
+ sender->Send(stanza);
+ sender->Start();
+ }
+
+ SessionManager* session_manager_;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_CLIENT_SESSIONMANAGERTASK_H_
diff --git a/p2p/client/sessionsendtask.h b/p2p/client/sessionsendtask.h
new file mode 100644
index 00000000..818aa1ad
--- /dev/null
+++ b/p2p/client/sessionsendtask.h
@@ -0,0 +1,128 @@
+/*
+ * 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 WEBRTC_P2P_CLIENT_SESSIONSENDTASK_H_
+#define WEBRTC_P2P_CLIENT_SESSIONSENDTASK_H_
+
+#include "webrtc/p2p/base/sessionmanager.h"
+#include "webrtc/libjingle/xmpp/constants.h"
+#include "webrtc/libjingle/xmpp/xmppclient.h"
+#include "webrtc/libjingle/xmpp/xmppengine.h"
+#include "webrtc/libjingle/xmpp/xmpptask.h"
+#include "webrtc/base/common.h"
+
+namespace cricket {
+
+// The job of this task is to send an IQ stanza out (after stamping it with
+// an ID attribute) and then wait for a response. If not response happens
+// within 5 seconds, it will signal failure on a SessionManager. If an error
+// happens it will also signal failure. If, however, the send succeeds this
+// task will quietly go away.
+
+class SessionSendTask : public buzz::XmppTask {
+ public:
+ SessionSendTask(buzz::XmppTaskParentInterface* parent,
+ SessionManager* session_manager)
+ : buzz::XmppTask(parent, buzz::XmppEngine::HL_SINGLE),
+ session_manager_(session_manager) {
+ set_timeout_seconds(15);
+ session_manager_->SignalDestroyed.connect(
+ this, &SessionSendTask::OnSessionManagerDestroyed);
+ }
+
+ virtual ~SessionSendTask() {
+ SignalDone(this);
+ }
+
+ void Send(const buzz::XmlElement* stanza) {
+ ASSERT(stanza_.get() == NULL);
+
+ // This should be an IQ of type set, result, or error. In the first case,
+ // we supply an ID. In the others, it should be present.
+ ASSERT(stanza->Name() == buzz::QN_IQ);
+ ASSERT(stanza->HasAttr(buzz::QN_TYPE));
+ if (stanza->Attr(buzz::QN_TYPE) == "set") {
+ ASSERT(!stanza->HasAttr(buzz::QN_ID));
+ } else {
+ ASSERT((stanza->Attr(buzz::QN_TYPE) == "result") ||
+ (stanza->Attr(buzz::QN_TYPE) == "error"));
+ ASSERT(stanza->HasAttr(buzz::QN_ID));
+ }
+
+ stanza_.reset(new buzz::XmlElement(*stanza));
+ if (stanza_->HasAttr(buzz::QN_ID)) {
+ set_task_id(stanza_->Attr(buzz::QN_ID));
+ } else {
+ stanza_->SetAttr(buzz::QN_ID, task_id());
+ }
+ }
+
+ void OnSessionManagerDestroyed() {
+ // If the session manager doesn't exist anymore, we should still try to
+ // send the message, but avoid calling back into the SessionManager.
+ session_manager_ = NULL;
+ }
+
+ sigslot::signal1<SessionSendTask *> SignalDone;
+
+ protected:
+ virtual int OnTimeout() {
+ if (session_manager_ != NULL) {
+ session_manager_->OnFailedSend(stanza_.get(), NULL);
+ }
+
+ return XmppTask::OnTimeout();
+ }
+
+ virtual int ProcessStart() {
+ SendStanza(stanza_.get());
+ if (stanza_->Attr(buzz::QN_TYPE) == buzz::STR_SET) {
+ return STATE_RESPONSE;
+ } else {
+ return STATE_DONE;
+ }
+ }
+
+ virtual int ProcessResponse() {
+ const buzz::XmlElement* next = NextStanza();
+ if (next == NULL)
+ return STATE_BLOCKED;
+
+ if (session_manager_ != NULL) {
+ if (next->Attr(buzz::QN_TYPE) == buzz::STR_RESULT) {
+ session_manager_->OnIncomingResponse(stanza_.get(), next);
+ } else {
+ session_manager_->OnFailedSend(stanza_.get(), next);
+ }
+ }
+
+ return STATE_DONE;
+ }
+
+ virtual bool HandleStanza(const buzz::XmlElement *stanza) {
+ if (!MatchResponseIq(stanza,
+ buzz::Jid(stanza_->Attr(buzz::QN_TO)), task_id()))
+ return false;
+ if (stanza->Attr(buzz::QN_TYPE) == buzz::STR_RESULT ||
+ stanza->Attr(buzz::QN_TYPE) == buzz::STR_ERROR) {
+ QueueStanza(stanza);
+ return true;
+ }
+ return false;
+ }
+
+ private:
+ SessionManager *session_manager_;
+ rtc::scoped_ptr<buzz::XmlElement> stanza_;
+};
+
+}
+
+#endif // WEBRTC_P2P_CLIENT_SESSIONSENDTASK_H_
diff --git a/p2p/client/socketmonitor.cc b/p2p/client/socketmonitor.cc
new file mode 100644
index 00000000..5245535b
--- /dev/null
+++ b/p2p/client/socketmonitor.cc
@@ -0,0 +1,97 @@
+/*
+ * 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 "webrtc/p2p/client/socketmonitor.h"
+
+#include "webrtc/base/common.h"
+
+namespace cricket {
+
+enum {
+ MSG_MONITOR_POLL,
+ MSG_MONITOR_START,
+ MSG_MONITOR_STOP,
+ MSG_MONITOR_SIGNAL
+};
+
+SocketMonitor::SocketMonitor(TransportChannel* channel,
+ rtc::Thread* worker_thread,
+ rtc::Thread* monitor_thread) {
+ channel_ = channel;
+ channel_thread_ = worker_thread;
+ monitoring_thread_ = monitor_thread;
+ monitoring_ = false;
+}
+
+SocketMonitor::~SocketMonitor() {
+ channel_thread_->Clear(this);
+ monitoring_thread_->Clear(this);
+}
+
+void SocketMonitor::Start(int milliseconds) {
+ rate_ = milliseconds;
+ if (rate_ < 250)
+ rate_ = 250;
+ channel_thread_->Post(this, MSG_MONITOR_START);
+}
+
+void SocketMonitor::Stop() {
+ channel_thread_->Post(this, MSG_MONITOR_STOP);
+}
+
+void SocketMonitor::OnMessage(rtc::Message *message) {
+ rtc::CritScope cs(&crit_);
+ switch (message->message_id) {
+ case MSG_MONITOR_START:
+ ASSERT(rtc::Thread::Current() == channel_thread_);
+ if (!monitoring_) {
+ monitoring_ = true;
+ PollSocket(true);
+ }
+ break;
+
+ case MSG_MONITOR_STOP:
+ ASSERT(rtc::Thread::Current() == channel_thread_);
+ if (monitoring_) {
+ monitoring_ = false;
+ channel_thread_->Clear(this);
+ }
+ break;
+
+ case MSG_MONITOR_POLL:
+ ASSERT(rtc::Thread::Current() == channel_thread_);
+ PollSocket(true);
+ break;
+
+ case MSG_MONITOR_SIGNAL: {
+ ASSERT(rtc::Thread::Current() == monitoring_thread_);
+ std::vector<ConnectionInfo> infos = connection_infos_;
+ crit_.Leave();
+ SignalUpdate(this, infos);
+ crit_.Enter();
+ break;
+ }
+ }
+}
+
+void SocketMonitor::PollSocket(bool poll) {
+ ASSERT(rtc::Thread::Current() == channel_thread_);
+ rtc::CritScope cs(&crit_);
+
+ // Gather connection infos
+ channel_->GetStats(&connection_infos_);
+
+ // Signal the monitoring thread, start another poll timer
+ monitoring_thread_->Post(this, MSG_MONITOR_SIGNAL);
+ if (poll)
+ channel_thread_->PostDelayed(rate_, this, MSG_MONITOR_POLL);
+}
+
+} // namespace cricket
diff --git a/p2p/client/socketmonitor.h b/p2p/client/socketmonitor.h
new file mode 100644
index 00000000..5c10a4ec
--- /dev/null
+++ b/p2p/client/socketmonitor.h
@@ -0,0 +1,54 @@
+/*
+ * 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 WEBRTC_P2P_CLIENT_SOCKETMONITOR_H_
+#define WEBRTC_P2P_CLIENT_SOCKETMONITOR_H_
+
+#include <vector>
+
+#include "webrtc/p2p/base/transportchannel.h"
+#include "webrtc/base/criticalsection.h"
+#include "webrtc/base/sigslot.h"
+#include "webrtc/base/thread.h"
+
+namespace cricket {
+
+class SocketMonitor : public rtc::MessageHandler,
+ public sigslot::has_slots<> {
+ public:
+ SocketMonitor(TransportChannel* channel,
+ rtc::Thread* worker_thread,
+ rtc::Thread* monitor_thread);
+ ~SocketMonitor();
+
+ void Start(int cms);
+ void Stop();
+
+ rtc::Thread* monitor_thread() { return monitoring_thread_; }
+
+ sigslot::signal2<SocketMonitor*,
+ const std::vector<ConnectionInfo>&> SignalUpdate;
+
+ protected:
+ void OnMessage(rtc::Message* message);
+ void PollSocket(bool poll);
+
+ std::vector<ConnectionInfo> connection_infos_;
+ TransportChannel* channel_;
+ rtc::Thread* channel_thread_;
+ rtc::Thread* monitoring_thread_;
+ rtc::CriticalSection crit_;
+ uint32 rate_;
+ bool monitoring_;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_P2P_CLIENT_SOCKETMONITOR_H_
diff --git a/p2p/p2p.gyp b/p2p/p2p.gyp
new file mode 100644
index 00000000..102e75b5
--- /dev/null
+++ b/p2p/p2p.gyp
@@ -0,0 +1,130 @@
+# 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.
+
+{
+ 'includes': [ '../build/common.gypi', ],
+ 'targets': [
+ {
+ 'target_name': 'rtc_p2p',
+ 'type': 'static_library',
+ 'dependencies': [
+ '<(webrtc_root)/base/base.gyp:webrtc_base',
+ '<(webrtc_root)/libjingle/xmpp/xmpp.gyp:rtc_xmpp',
+ '<(DEPTH)/third_party/expat/expat.gyp:expat',
+ ],
+ 'cflags_cc!': [
+ '-Wnon-virtual-dtor',
+ ],
+ 'export_dependent_settings': [
+ '<(DEPTH)/third_party/expat/expat.gyp:expat',
+ ],
+ 'sources': [
+ 'base/asyncstuntcpsocket.cc',
+ 'base/asyncstuntcpsocket.h',
+ 'base/basicpacketsocketfactory.cc',
+ 'base/basicpacketsocketfactory.h',
+ 'base/candidate.h',
+ 'base/common.h',
+ 'base/constants.cc',
+ 'base/constants.h',
+ 'base/dtlstransportchannel.cc',
+ 'base/dtlstransportchannel.h',
+ 'base/p2ptransport.cc',
+ 'base/p2ptransport.h',
+ 'base/p2ptransportchannel.cc',
+ 'base/p2ptransportchannel.h',
+ 'base/packetsocketfactory.h',
+ 'base/parsing.cc',
+ 'base/parsing.h',
+ 'base/port.cc',
+ 'base/port.h',
+ 'base/portallocator.cc',
+ 'base/portallocator.h',
+ 'base/portallocatorsessionproxy.cc',
+ 'base/portallocatorsessionproxy.h',
+ 'base/portinterface.h',
+ 'base/portproxy.cc',
+ 'base/portproxy.h',
+ 'base/pseudotcp.cc',
+ 'base/pseudotcp.h',
+ 'base/rawtransport.cc',
+ 'base/rawtransport.h',
+ 'base/rawtransportchannel.cc',
+ 'base/rawtransportchannel.h',
+ 'base/relayport.cc',
+ 'base/relayport.h',
+ 'base/relayserver.cc',
+ 'base/relayserver.h',
+ 'base/session.cc',
+ 'base/session.h',
+ 'base/sessionclient.h',
+ 'base/sessiondescription.cc',
+ 'base/sessiondescription.h',
+ 'base/sessionid.h',
+ 'base/sessionmanager.cc',
+ 'base/sessionmanager.h',
+ 'base/sessionmessages.cc',
+ 'base/sessionmessages.h',
+ 'base/stun.cc',
+ 'base/stun.h',
+ 'base/stunport.cc',
+ 'base/stunport.h',
+ 'base/stunrequest.cc',
+ 'base/stunrequest.h',
+ 'base/stunserver.cc',
+ 'base/stunserver.h',
+ 'base/tcpport.cc',
+ 'base/tcpport.h',
+ 'base/transport.cc',
+ 'base/transport.h',
+ 'base/transportchannel.cc',
+ 'base/transportchannel.h',
+ 'base/transportchannelimpl.h',
+ 'base/transportchannelproxy.cc',
+ 'base/transportchannelproxy.h',
+ 'base/transportdescription.cc',
+ 'base/transportdescription.h',
+ 'base/transportdescriptionfactory.cc',
+ 'base/transportdescriptionfactory.h',
+ 'base/transportinfo.h',
+ 'base/turnport.cc',
+ 'base/turnport.h',
+ 'base/turnserver.cc',
+ 'base/turnserver.h',
+ 'base/udpport.h',
+ 'client/autoportallocator.h',
+ 'client/basicportallocator.cc',
+ 'client/basicportallocator.h',
+ 'client/connectivitychecker.cc',
+ 'client/connectivitychecker.h',
+ 'client/httpportallocator.cc',
+ 'client/httpportallocator.h',
+ 'client/sessionmanagertask.h',
+ 'client/sessionsendtask.h',
+ 'client/socketmonitor.cc',
+ 'client/socketmonitor.h',
+ ],
+ 'direct_dependent_settings': {
+ 'cflags_cc!': [
+ '-Wnon-virtual-dtor',
+ ],
+ 'defines': [
+ 'FEATURE_ENABLE_VOICEMAIL',
+ ],
+ },
+ 'conditions': [
+ ['build_with_chromium==0', {
+ 'defines': [
+ 'FEATURE_ENABLE_VOICEMAIL',
+ 'FEATURE_ENABLE_PSTN',
+ ],
+ }],
+ ],
+ }],
+}
+
diff --git a/p2p/p2p_tests.gypi b/p2p/p2p_tests.gypi
new file mode 100644
index 00000000..f9e69594
--- /dev/null
+++ b/p2p/p2p_tests.gypi
@@ -0,0 +1,44 @@
+# 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.
+
+{
+ 'includes': [ '../build/common.gypi', ],
+ 'targets': [
+ {
+ 'target_name': 'rtc_p2p_unittest',
+ 'type': 'none',
+ 'direct_dependent_settings': {
+ 'sources': [
+ 'base/dtlstransportchannel_unittest.cc',
+ 'base/fakesession.h',
+ 'base/p2ptransportchannel_unittest.cc',
+ 'base/port_unittest.cc',
+ 'base/portallocatorsessionproxy_unittest.cc',
+ 'base/pseudotcp_unittest.cc',
+ 'base/relayport_unittest.cc',
+ 'base/relayserver_unittest.cc',
+ 'base/session_unittest.cc',
+ 'base/stun_unittest.cc',
+ 'base/stunport_unittest.cc',
+ 'base/stunrequest_unittest.cc',
+ 'base/stunserver_unittest.cc',
+ 'base/testrelayserver.h',
+ 'base/teststunserver.h',
+ 'base/testturnserver.h',
+ 'base/transport_unittest.cc',
+ 'base/transportdescriptionfactory_unittest.cc',
+ 'base/turnport_unittest.cc',
+ 'client/connectivitychecker_unittest.cc',
+ 'client/fakeportallocator.h',
+ 'client/portallocator_unittest.cc',
+ ],
+ },
+ },
+ ],
+}
+
diff --git a/rtc_unittests.isolate b/rtc_unittests.isolate
index 7bcfc854..6dfe38d4 100644
--- a/rtc_unittests.isolate
+++ b/rtc_unittests.isolate
@@ -12,12 +12,9 @@
'command': [
'<(PRODUCT_DIR)/rtc_unittests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'<(PRODUCT_DIR)/rtc_unittests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_untracked': [
- '<(DEPTH)/tools/swarming_client/',
- ],
},
}],
],
diff --git a/system_wrappers/BUILD.gn b/system_wrappers/BUILD.gn
index c193c28b..c4d21926 100644
--- a/system_wrappers/BUILD.gn
+++ b/system_wrappers/BUILD.gn
@@ -35,6 +35,7 @@ static_library("system_wrappers") {
"interface/file_wrapper.h",
"interface/fix_interlocked_exchange_pointer_win.h",
"interface/logging.h",
+ "interface/metrics.h",
"interface/ref_count.h",
"interface/rtp_to_ntp.h",
"interface/rw_lock_wrapper.h",
@@ -216,6 +217,42 @@ source_set("field_trial_default") {
]
}
+source_set("metrics_default") {
+ sources = [
+ "source/metrics_default.cc",
+ ]
+
+ configs += [ "..:common_config" ]
+ public_configs = [ "..:common_inherited_config" ]
+
+ if (is_clang) {
+ # Suppress warnings from Chrome's Clang plugins.
+ # See http://code.google.com/p/webrtc/issues/detail?id=163 for details.
+ configs -= [ "//build/config/clang:find_bad_constructs" ]
+ }
+
+ deps = [
+ ":system_wrappers",
+ ]
+}
+
+source_set("system_wrappers_default") {
+
+ configs += [ "..:common_config" ]
+ public_configs = [ "..:common_inherited_config" ]
+
+ if (is_clang) {
+ # Suppress warnings from Chrome's Clang plugins.
+ # See http://code.google.com/p/webrtc/issues/detail?id=163 for details.
+ configs -= [ "//build/config/clang:find_bad_constructs" ]
+ }
+
+ deps = [
+ ":field_trial_default",
+ ":metrics_default",
+ ]
+}
+
if (is_android) {
source_set("cpu_features_android") {
sources = [
diff --git a/system_wrappers/interface/metrics.h b/system_wrappers/interface/metrics.h
new file mode 100644
index 00000000..0390140f
--- /dev/null
+++ b/system_wrappers/interface/metrics.h
@@ -0,0 +1,130 @@
+//
+// 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 WEBRTC_SYSTEM_WRAPPERS_INTERFACE_METRICS_H_
+#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_METRICS_H_
+
+#include <string>
+
+#include "webrtc/common_types.h"
+
+// Macros for allowing WebRTC clients (e.g. Chrome) to gather and aggregate
+// statistics.
+//
+// Histogram for counters.
+// RTC_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count);
+//
+// Histogram for enumerators.
+// The boundary should be above the max enumerator sample.
+// RTC_HISTOGRAM_ENUMERATION(name, sample, boundary);
+//
+//
+// The macros use the methods HistogramFactoryGetCounts,
+// HistogramFactoryGetEnumeration and HistogramAdd.
+//
+// Therefore, WebRTC clients must either:
+//
+// - provide implementations of
+// Histogram* webrtc::metrics::HistogramFactoryGetCounts(
+// const std::string& name, int sample, int min, int max,
+// int bucket_count);
+// Histogram* webrtc::metrics::HistogramFactoryGetEnumeration(
+// const std::string& name, int sample, int boundary);
+// void webrtc::metrics::HistogramAdd(
+// Histogram* histogram_pointer, const std::string& name, int sample);
+//
+// - or link with the default implementations (i.e.
+// system_wrappers/source/system_wrappers.gyp:metrics_default).
+//
+//
+// Example usage:
+//
+// RTC_HISTOGRAM_COUNTS("WebRTC.Video.NacksSent", nacks_sent, 1, 100000, 100);
+//
+// enum Types {
+// kTypeX,
+// kTypeY,
+// kBoundary,
+// };
+//
+// RTC_HISTOGRAM_ENUMERATION("WebRTC.Types", kTypeX, kBoundary);
+
+
+// Macros for adding samples to a named histogram.
+//
+// NOTE: this is a temporary solution.
+// The aim is to mimic the behaviour in Chromium's src/base/metrics/histograms.h
+// However as atomics are not supported in webrtc, this is for now a modified
+// and temporary solution. Note that the histogram is constructed/found for
+// each call. Therefore, for now only use this implementation for metrics
+// that do not need to be updated frequently.
+// TODO(asapersson): Change implementation when atomics are supported.
+// Also consider changing string to const char* when switching to atomics.
+
+// Histogram for counters.
+#define RTC_HISTOGRAM_COUNTS_100(name, sample) RTC_HISTOGRAM_COUNTS( \
+ name, sample, 1, 100, 50)
+
+#define RTC_HISTOGRAM_COUNTS_1000(name, sample) RTC_HISTOGRAM_COUNTS( \
+ name, sample, 1, 1000, 50)
+
+#define RTC_HISTOGRAM_COUNTS_10000(name, sample) RTC_HISTOGRAM_COUNTS( \
+ name, sample, 1, 10000, 50)
+
+#define RTC_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count) \
+ RTC_HISTOGRAM_COMMON_BLOCK(name, sample, \
+ webrtc::metrics::HistogramFactoryGetCounts( \
+ name, min, max, bucket_count))
+
+// Histogram for percentage.
+#define RTC_HISTOGRAM_PERCENTAGE(name, sample) \
+ RTC_HISTOGRAM_ENUMERATION(name, sample, 101)
+
+// Histogram for enumerators.
+// |boundary| should be above the max enumerator sample.
+#define RTC_HISTOGRAM_ENUMERATION(name, sample, boundary) \
+ RTC_HISTOGRAM_COMMON_BLOCK(name, sample, \
+ webrtc::metrics::HistogramFactoryGetEnumeration(name, boundary))
+
+#define RTC_HISTOGRAM_COMMON_BLOCK(constant_name, sample, \
+ factory_get_invocation) \
+ do { \
+ webrtc::metrics::Histogram* histogram_pointer = factory_get_invocation; \
+ webrtc::metrics::HistogramAdd(histogram_pointer, constant_name, sample); \
+ } while (0)
+
+
+namespace webrtc {
+namespace metrics {
+
+class Histogram;
+
+// Functions for getting pointer to histogram (constructs or finds the named
+// histogram).
+
+// Get histogram for counters.
+Histogram* HistogramFactoryGetCounts(
+ const std::string& name, int min, int max, int bucket_count);
+
+// Get histogram for enumerators.
+// |boundary| should be above the max enumerator sample.
+Histogram* HistogramFactoryGetEnumeration(
+ const std::string& name, int boundary);
+
+// Function for adding a |sample| to a histogram.
+// |name| can be used to verify that it matches the histogram name.
+void HistogramAdd(
+ Histogram* histogram_pointer, const std::string& name, int sample);
+
+} // namespace metrics
+} // namespace webrtc
+
+#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_METRICS_H_
+
diff --git a/system_wrappers/interface/scoped_ptr.h b/system_wrappers/interface/scoped_ptr.h
index 42bb8a6d..1beca1b8 100644
--- a/system_wrappers/interface/scoped_ptr.h
+++ b/system_wrappers/interface/scoped_ptr.h
@@ -10,10 +10,10 @@
// Borrowed from Chromium's src/base/memory/scoped_ptr.h.
-// Scopers help you manage ownership of a pointer, helping you easily manage the
-// a pointer within a scope, and automatically destroying the pointer at the
-// end of a scope. There are two main classes you will use, which correspond
-// to the operators new/delete and new[]/delete[].
+// Scopers help you manage ownership of a pointer, helping you easily manage a
+// pointer within a scope, and automatically destroying the pointer at the end
+// of a scope. There are two main classes you will use, which correspond to the
+// operators new/delete and new[]/delete[].
//
// Example usage (scoped_ptr<T>):
// {
@@ -66,7 +66,7 @@
// TakesOwnership(ptr.Pass()); // ptr no longer owns Foo("yay").
// scoped_ptr<Foo> ptr2 = CreateFoo(); // ptr2 owns the return Foo.
// scoped_ptr<Foo> ptr3 = // ptr3 now owns what was in ptr2.
-// PassThru(ptr2.Pass()); // ptr2 is correspondingly NULL.
+// PassThru(ptr2.Pass()); // ptr2 is correspondingly nullptr.
// }
//
// Notice that if you do not call Pass() when returning from PassThru(), or
@@ -180,12 +180,23 @@ struct FreeDeleter {
namespace internal {
+template <typename T>
+struct ShouldAbortOnSelfReset {
+ template <typename U>
+ static NoType Test(const typename U::AllowSelfReset*);
+
+ template <typename U>
+ static YesType Test(...);
+
+ static const bool value = sizeof(Test<T>(0)) == sizeof(YesType);
+};
+
// Minimal implementation of the core logic of scoped_ptr, suitable for
// reuse in both scoped_ptr and its specializations.
template <class T, class D>
class scoped_ptr_impl {
public:
- explicit scoped_ptr_impl(T* p) : data_(p) { }
+ explicit scoped_ptr_impl(T* p) : data_(p) {}
// Initializer for deleters that have data parameters.
scoped_ptr_impl(T* p, const D& d) : data_(p, d) {}
@@ -210,7 +221,7 @@ class scoped_ptr_impl {
}
~scoped_ptr_impl() {
- if (data_.ptr != NULL) {
+ if (data_.ptr != nullptr) {
// Not using get_deleter() saves one function call in non-optimized
// builds.
static_cast<D&>(data_)(data_.ptr);
@@ -218,12 +229,12 @@ class scoped_ptr_impl {
}
void reset(T* p) {
- // This is a self-reset, which is no longer allowed: http://crbug.com/162971
- if (p != NULL && p == data_.ptr)
- abort();
+ // This is a self-reset, which is no longer allowed for default deleters:
+ // https://crbug.com/162971
+ assert(!ShouldAbortOnSelfReset<D>::value || p == nullptr || p != data_.ptr);
// Note that running data_.ptr = p can lead to undefined behavior if
- // get_deleter()(get()) deletes this. In order to pevent this, reset()
+ // get_deleter()(get()) deletes this. In order to prevent this, reset()
// should update the stored pointer before deleting its old value.
//
// However, changing reset() to use that behavior may cause current code to
@@ -232,13 +243,13 @@ class scoped_ptr_impl {
// then it will incorrectly dispatch calls to |p| rather than the original
// value of |data_.ptr|.
//
- // During the transition period, set the stored pointer to NULL while
+ // During the transition period, set the stored pointer to nullptr while
// deleting the object. Eventually, this safety check will be removed to
- // prevent the scenario initially described from occuring and
+ // prevent the scenario initially described from occurring and
// http://crbug.com/176091 can be closed.
T* old = data_.ptr;
- data_.ptr = NULL;
- if (old != NULL)
+ data_.ptr = nullptr;
+ if (old != nullptr)
static_cast<D&>(data_)(old);
data_.ptr = p;
}
@@ -259,7 +270,7 @@ class scoped_ptr_impl {
T* release() {
T* old_ptr = data_.ptr;
- data_.ptr = NULL;
+ data_.ptr = nullptr;
return old_ptr;
}
@@ -287,8 +298,8 @@ class scoped_ptr_impl {
// A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T>
// automatically deletes the pointer it holds (if any).
// That is, scoped_ptr<T> owns the T object that it points to.
-// Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object.
-// Also like T*, scoped_ptr<T> is thread-compatible, and once you
+// Like a T*, a scoped_ptr<T> may hold either nullptr or a pointer to a T
+// object. Also like T*, scoped_ptr<T> is thread-compatible, and once you
// dereference it, you get the thread safety guarantees of T.
//
// The size of scoped_ptr is small. On most compilers, when using the
@@ -298,25 +309,33 @@ class scoped_ptr_impl {
//
// Current implementation targets having a strict subset of C++11's
// unique_ptr<> features. Known deficiencies include not supporting move-only
-// deleteres, function pointers as deleters, and deleters with reference
+// deleters, function pointers as deleters, and deleters with reference
// types.
template <class T, class D = webrtc::DefaultDeleter<T> >
class scoped_ptr {
- WEBRTC_MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue)
+ RTC_MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(scoped_ptr)
+
+ // TODO(ajm): If we ever import RefCountedBase, this check needs to be
+ // enabled.
+ //COMPILE_ASSERT(webrtc::internal::IsNotRefCounted<T>::value,
+ // T_is_refcounted_type_and_needs_scoped_refptr);
public:
// The element and deleter types.
typedef T element_type;
typedef D deleter_type;
- // Constructor. Defaults to initializing with NULL.
- scoped_ptr() : impl_(NULL) { }
+ // Constructor. Defaults to initializing with nullptr.
+ scoped_ptr() : impl_(nullptr) {}
// Constructor. Takes ownership of p.
- explicit scoped_ptr(element_type* p) : impl_(p) { }
+ explicit scoped_ptr(element_type* p) : impl_(p) {}
// Constructor. Allows initialization of a stateful deleter.
- scoped_ptr(element_type* p, const D& d) : impl_(p, d) { }
+ scoped_ptr(element_type* p, const D& d) : impl_(p, d) {}
+
+ // Constructor. Allows construction from a nullptr.
+ scoped_ptr(decltype(nullptr)) : impl_(nullptr) {}
// Constructor. Allows construction from a scoped_ptr rvalue for a
// convertible type and deleter.
@@ -329,13 +348,11 @@ class scoped_ptr {
// use of SFINAE. You only need to care about this if you modify the
// implementation of scoped_ptr.
template <typename U, typename V>
- scoped_ptr(scoped_ptr<U, V> other) : impl_(&other.impl_) {
+ scoped_ptr(scoped_ptr<U, V>&& other)
+ : impl_(&other.impl_) {
COMPILE_ASSERT(!webrtc::is_array<U>::value, U_cannot_be_an_array);
}
- // Constructor. Move constructor for C++03 move emulation of this type.
- scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) { }
-
// operator=. Allows assignment from a scoped_ptr rvalue for a convertible
// type and deleter.
//
@@ -347,24 +364,31 @@ class scoped_ptr {
// You only need to care about this if you modify the implementation of
// scoped_ptr.
template <typename U, typename V>
- scoped_ptr& operator=(scoped_ptr<U, V> rhs) {
+ scoped_ptr& operator=(scoped_ptr<U, V>&& rhs) {
COMPILE_ASSERT(!webrtc::is_array<U>::value, U_cannot_be_an_array);
impl_.TakeState(&rhs.impl_);
return *this;
}
+ // operator=. Allows assignment from a nullptr. Deletes the currently owned
+ // object, if any.
+ scoped_ptr& operator=(decltype(nullptr)) {
+ reset();
+ return *this;
+ }
+
// Reset. Deletes the currently owned object, if any.
// Then takes ownership of a new object, if given.
- void reset(element_type* p = NULL) { impl_.reset(p); }
+ void reset(element_type* p = nullptr) { impl_.reset(p); }
// Accessors to get the owned object.
// operator* and operator-> will assert() if there is no current object.
element_type& operator*() const {
- assert(impl_.get() != NULL);
+ assert(impl_.get() != nullptr);
return *impl_.get();
}
element_type* operator->() const {
- assert(impl_.get() != NULL);
+ assert(impl_.get() != nullptr);
return impl_.get();
}
element_type* get() const { return impl_.get(); }
@@ -385,7 +409,9 @@ class scoped_ptr {
scoped_ptr::*Testable;
public:
- operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; }
+ operator Testable() const {
+ return impl_.get() ? &scoped_ptr::impl_ : nullptr;
+ }
// Comparison operators.
// These return whether two scoped_ptr refer to the same object, not just to
@@ -399,25 +425,13 @@ class scoped_ptr {
}
// Release a pointer.
- // The return value is the current pointer held by this object.
- // If this object holds a NULL pointer, the return value is NULL.
- // After this operation, this object will hold a NULL pointer,
- // and will not own the object any more.
+ // The return value is the current pointer held by this object. If this object
+ // holds a nullptr, the return value is nullptr. After this operation, this
+ // object will hold a nullptr, and will not own the object any more.
element_type* release() WARN_UNUSED_RESULT {
return impl_.release();
}
- // C++98 doesn't support functions templates with default parameters which
- // makes it hard to write a PassAs() that understands converting the deleter
- // while preserving simple calling semantics.
- //
- // Until there is a use case for PassAs() with custom deleters, just ignore
- // the custom deleter.
- template <typename PassAsType>
- scoped_ptr<PassAsType> PassAs() {
- return scoped_ptr<PassAsType>(Pass());
- }
-
private:
// Needed to reach into |impl_| in the constructor.
template <typename U, typename V> friend class scoped_ptr;
@@ -436,15 +450,15 @@ class scoped_ptr {
template <class T, class D>
class scoped_ptr<T[], D> {
- WEBRTC_MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue)
+ RTC_MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(scoped_ptr)
public:
// The element and deleter types.
typedef T element_type;
typedef D deleter_type;
- // Constructor. Defaults to initializing with NULL.
- scoped_ptr() : impl_(NULL) { }
+ // Constructor. Defaults to initializing with nullptr.
+ scoped_ptr() : impl_(nullptr) {}
// Constructor. Stores the given array. Note that the argument's type
// must exactly match T*. In particular:
@@ -454,32 +468,39 @@ class scoped_ptr<T[], D> {
// T and the derived types had different sizes access would be
// incorrectly calculated). Deletion is also always undefined
// (C++98 [expr.delete]p3). If you're doing this, fix your code.
- // - it cannot be NULL, because NULL is an integral expression, not a
- // pointer to T. Use the no-argument version instead of explicitly
- // passing NULL.
// - it cannot be const-qualified differently from T per unique_ptr spec
// (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting
// to work around this may use implicit_cast<const T*>().
// However, because of the first bullet in this comment, users MUST
// NOT use implicit_cast<Base*>() to upcast the static type of the array.
- explicit scoped_ptr(element_type* array) : impl_(array) { }
+ explicit scoped_ptr(element_type* array) : impl_(array) {}
- // Constructor. Move constructor for C++03 move emulation of this type.
- scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) { }
+ // Constructor. Allows construction from a nullptr.
+ scoped_ptr(decltype(nullptr)) : impl_(nullptr) {}
- // operator=. Move operator= for C++03 move emulation of this type.
- scoped_ptr& operator=(RValue rhs) {
- impl_.TakeState(&rhs.object->impl_);
+ // Constructor. Allows construction from a scoped_ptr rvalue.
+ scoped_ptr(scoped_ptr&& other) : impl_(&other.impl_) {}
+
+ // operator=. Allows assignment from a scoped_ptr rvalue.
+ scoped_ptr& operator=(scoped_ptr&& rhs) {
+ impl_.TakeState(&rhs.impl_);
+ return *this;
+ }
+
+ // operator=. Allows assignment from a nullptr. Deletes the currently owned
+ // array, if any.
+ scoped_ptr& operator=(decltype(nullptr)) {
+ reset();
return *this;
}
// Reset. Deletes the currently owned array, if any.
// Then takes ownership of a new object, if given.
- void reset(element_type* array = NULL) { impl_.reset(array); }
+ void reset(element_type* array = nullptr) { impl_.reset(array); }
// Accessors to get the owned array.
element_type& operator[](size_t i) const {
- assert(impl_.get() != NULL);
+ assert(impl_.get() != nullptr);
return impl_.get()[i];
}
element_type* get() const { return impl_.get(); }
@@ -495,7 +516,9 @@ class scoped_ptr<T[], D> {
scoped_ptr::*Testable;
public:
- operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; }
+ operator Testable() const {
+ return impl_.get() ? &scoped_ptr::impl_ : nullptr;
+ }
// Comparison operators.
// These return whether two scoped_ptr refer to the same object, not just to
@@ -509,10 +532,9 @@ class scoped_ptr<T[], D> {
}
// Release a pointer.
- // The return value is the current pointer held by this object.
- // If this object holds a NULL pointer, the return value is NULL.
- // After this operation, this object will hold a NULL pointer,
- // and will not own the object any more.
+ // The return value is the current pointer held by this object. If this object
+ // holds a nullptr, the return value is nullptr. After this operation, this
+ // object will hold a nullptr, and will not own the object any more.
element_type* release() WARN_UNUSED_RESULT {
return impl_.release();
}
@@ -547,7 +569,6 @@ class scoped_ptr<T[], D> {
} // namespace webrtc
-// Free functions
template <class T, class D>
void swap(webrtc::scoped_ptr<T, D>& p1, webrtc::scoped_ptr<T, D>& p2) {
p1.swap(p2);
@@ -563,4 +584,12 @@ bool operator!=(T* p1, const webrtc::scoped_ptr<T, D>& p2) {
return p1 != p2.get();
}
+// A function to convert T* into scoped_ptr<T>
+// Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation
+// for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
+template <typename T>
+webrtc::scoped_ptr<T> rtc_make_scoped_ptr(T* ptr) {
+ return webrtc::scoped_ptr<T>(ptr);
+}
+
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_PTR_H_
diff --git a/system_wrappers/interface/scoped_vector.h b/system_wrappers/interface/scoped_vector.h
index 68db3a12..7b8c6788 100644
--- a/system_wrappers/interface/scoped_vector.h
+++ b/system_wrappers/interface/scoped_vector.h
@@ -13,10 +13,9 @@
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_VECTOR_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_VECTOR_H_
-#include <assert.h>
-#include <algorithm>
#include <vector>
+#include "webrtc/base/checks.h"
#include "webrtc/system_wrappers/interface/stl_util.h"
#include "webrtc/system_wrappers/source/move.h"
@@ -26,7 +25,7 @@ namespace webrtc {
// destructor.
template <class T>
class ScopedVector {
- WEBRTC_MOVE_ONLY_TYPE_FOR_CPP_03(ScopedVector, RValue)
+ RTC_MOVE_ONLY_TYPE_FOR_CPP_03(ScopedVector, RValue)
public:
typedef typename std::vector<T*>::allocator_type allocator_type;
@@ -76,7 +75,7 @@ class ScopedVector {
void push_back(T* elem) { v_.push_back(elem); }
void pop_back() {
- assert(!empty());
+ DCHECK(!empty());
delete v_.back();
v_.pop_back();
}
diff --git a/system_wrappers/interface/timestamp_extrapolator.h b/system_wrappers/interface/timestamp_extrapolator.h
index d067198d..b78cf64b 100644
--- a/system_wrappers/interface/timestamp_extrapolator.h
+++ b/system_wrappers/interface/timestamp_extrapolator.h
@@ -31,7 +31,7 @@ private:
bool DelayChangeDetection(double error);
RWLockWrapper* _rwLock;
double _w[2];
- double _P[2][2];
+ double _pP[2][2];
int64_t _startMs;
int64_t _prevMs;
uint32_t _firstTimestamp;
@@ -48,7 +48,7 @@ private:
const double _alarmThreshold;
const double _accDrift;
const double _accMaxError;
- const double _P11;
+ const double _pP11;
};
} // namespace webrtc
diff --git a/system_wrappers/source/cpu_features_android.target.darwin-arm.mk b/system_wrappers/source/cpu_features_android.target.darwin-arm.mk
index 61c917a9..c247f87b 100644
--- a/system_wrappers/source/cpu_features_android.target.darwin-arm.mk
+++ b/system_wrappers/source/cpu_features_android.target.darwin-arm.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -102,6 +104,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -194,11 +197,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -214,6 +219,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/system_wrappers/source/cpu_features_android.target.darwin-arm64.mk b/system_wrappers/source/cpu_features_android.target.darwin-arm64.mk
index 20178186..49b33327 100644
--- a/system_wrappers/source/cpu_features_android.target.darwin-arm64.mk
+++ b/system_wrappers/source/cpu_features_android.target.darwin-arm64.mk
@@ -71,11 +71,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -84,10 +86,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -168,11 +172,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -181,10 +187,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/system_wrappers/source/cpu_features_android.target.darwin-mips.mk b/system_wrappers/source/cpu_features_android.target.darwin-mips.mk
index afbf953a..f4e1bb6c 100644
--- a/system_wrappers/source/cpu_features_android.target.darwin-mips.mk
+++ b/system_wrappers/source/cpu_features_android.target.darwin-mips.mk
@@ -75,11 +75,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -94,6 +96,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -179,11 +182,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -198,6 +203,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/system_wrappers/source/cpu_features_android.target.darwin-mips64.mk b/system_wrappers/source/cpu_features_android.target.darwin-mips64.mk
new file mode 100644
index 00000000..6c25a0ee
--- /dev/null
+++ b/system_wrappers/source/cpu_features_android.target.darwin-mips64.mk
@@ -0,0 +1,262 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_system_wrappers_source_cpu_features_android_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/system_wrappers/source/cpu_features_android.c
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_STATIC_LIBRARIES := \
+ cpufeatures
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_system_wrappers_source_cpu_features_android_gyp
+
+# Alias gyp target name.
+.PHONY: cpu_features_android
+cpu_features_android: third_party_webrtc_system_wrappers_source_cpu_features_android_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/system_wrappers/source/cpu_features_android.target.darwin-x86.mk b/system_wrappers/source/cpu_features_android.target.darwin-x86.mk
index b9b61ef0..c5c4ed6f 100644
--- a/system_wrappers/source/cpu_features_android.target.darwin-x86.mk
+++ b/system_wrappers/source/cpu_features_android.target.darwin-x86.mk
@@ -77,11 +77,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -94,6 +96,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -180,11 +183,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -197,6 +202,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/system_wrappers/source/cpu_features_android.target.darwin-x86_64.mk b/system_wrappers/source/cpu_features_android.target.darwin-x86_64.mk
index cd1b8192..f0ca654d 100644
--- a/system_wrappers/source/cpu_features_android.target.darwin-x86_64.mk
+++ b/system_wrappers/source/cpu_features_android.target.darwin-x86_64.mk
@@ -76,11 +76,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -93,6 +95,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -178,11 +181,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -195,6 +200,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/system_wrappers/source/cpu_features_android.target.linux-arm.mk b/system_wrappers/source/cpu_features_android.target.linux-arm.mk
index 61c917a9..c247f87b 100644
--- a/system_wrappers/source/cpu_features_android.target.linux-arm.mk
+++ b/system_wrappers/source/cpu_features_android.target.linux-arm.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -102,6 +104,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -194,11 +197,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -214,6 +219,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/system_wrappers/source/cpu_features_android.target.linux-arm64.mk b/system_wrappers/source/cpu_features_android.target.linux-arm64.mk
index 20178186..49b33327 100644
--- a/system_wrappers/source/cpu_features_android.target.linux-arm64.mk
+++ b/system_wrappers/source/cpu_features_android.target.linux-arm64.mk
@@ -71,11 +71,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -84,10 +86,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -168,11 +172,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -181,10 +187,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/system_wrappers/source/cpu_features_android.target.linux-mips.mk b/system_wrappers/source/cpu_features_android.target.linux-mips.mk
index afbf953a..f4e1bb6c 100644
--- a/system_wrappers/source/cpu_features_android.target.linux-mips.mk
+++ b/system_wrappers/source/cpu_features_android.target.linux-mips.mk
@@ -75,11 +75,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -94,6 +96,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -179,11 +182,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -198,6 +203,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/system_wrappers/source/cpu_features_android.target.linux-mips64.mk b/system_wrappers/source/cpu_features_android.target.linux-mips64.mk
new file mode 100644
index 00000000..6c25a0ee
--- /dev/null
+++ b/system_wrappers/source/cpu_features_android.target.linux-mips64.mk
@@ -0,0 +1,262 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_system_wrappers_source_cpu_features_android_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/system_wrappers/source/cpu_features_android.c
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_STATIC_LIBRARIES := \
+ cpufeatures
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_system_wrappers_source_cpu_features_android_gyp
+
+# Alias gyp target name.
+.PHONY: cpu_features_android
+cpu_features_android: third_party_webrtc_system_wrappers_source_cpu_features_android_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/system_wrappers/source/cpu_features_android.target.linux-x86.mk b/system_wrappers/source/cpu_features_android.target.linux-x86.mk
index b9b61ef0..c5c4ed6f 100644
--- a/system_wrappers/source/cpu_features_android.target.linux-x86.mk
+++ b/system_wrappers/source/cpu_features_android.target.linux-x86.mk
@@ -77,11 +77,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -94,6 +96,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -180,11 +183,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -197,6 +202,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/system_wrappers/source/cpu_features_android.target.linux-x86_64.mk b/system_wrappers/source/cpu_features_android.target.linux-x86_64.mk
index cd1b8192..f0ca654d 100644
--- a/system_wrappers/source/cpu_features_android.target.linux-x86_64.mk
+++ b/system_wrappers/source/cpu_features_android.target.linux-x86_64.mk
@@ -76,11 +76,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -93,6 +95,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -178,11 +181,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -195,6 +200,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/system_wrappers/source/logging.cc b/system_wrappers/source/logging.cc
index 922a2723..da1c1a57 100644
--- a/system_wrappers/source/logging.cc
+++ b/system_wrappers/source/logging.cc
@@ -55,7 +55,7 @@ bool LogMessage::Loggable(LoggingSeverity sev) {
LogMessage::~LogMessage() {
const std::string& str = print_stream_.str();
- Trace::Add(WebRtcSeverity(severity_), kTraceUndefined, 0, str.c_str());
+ Trace::Add(WebRtcSeverity(severity_), kTraceUndefined, 0, "%s", str.c_str());
}
} // namespace webrtc
diff --git a/system_wrappers/source/metrics_default.cc b/system_wrappers/source/metrics_default.cc
new file mode 100644
index 00000000..af950b4d
--- /dev/null
+++ b/system_wrappers/source/metrics_default.cc
@@ -0,0 +1,29 @@
+// 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 "webrtc/system_wrappers/interface/metrics.h"
+
+// Default implementation of histogram methods for WebRTC clients that do not
+// want to provide their own implementation.
+
+namespace webrtc {
+namespace metrics {
+
+Histogram* HistogramFactoryGetCounts(const std::string& name, int min, int max,
+ int bucket_count) { return NULL; }
+
+Histogram* HistogramFactoryGetEnumeration(const std::string& name,
+ int boundary) { return NULL; }
+
+void HistogramAdd(
+ Histogram* histogram_pointer, const std::string& name, int sample) {}
+
+} // namespace metrics
+} // namespace webrtc
+
diff --git a/system_wrappers/source/move.h b/system_wrappers/source/move.h
index 2e93641f..80aed9a9 100644
--- a/system_wrappers/source/move.h
+++ b/system_wrappers/source/move.h
@@ -10,8 +10,10 @@
// Borrowed from Chromium's src/base/move.h.
-#ifndef WEBRTC_SYSTEM_WRAPPERS_INTEFACE_MOVE_H_
-#define WEBRTC_SYSTEM_WRAPPERS_INTEFACE_MOVE_H_
+#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_MOVE_H_
+#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_MOVE_H_
+
+#include "webrtc/typedefs.h"
// Macro with the boilerplate that makes a type move-only in C++03.
//
@@ -209,7 +211,7 @@
//
// The workaround is to explicitly declare your copy constructor.
//
-#define WEBRTC_MOVE_ONLY_TYPE_FOR_CPP_03(type, rvalue_type) \
+#define RTC_MOVE_ONLY_TYPE_FOR_CPP_03(type, rvalue_type) \
private: \
struct rvalue_type { \
explicit rvalue_type(type* object) : object(object) {} \
@@ -219,8 +221,17 @@
void operator=(type&); \
public: \
operator rvalue_type() { return rvalue_type(this); } \
- type Pass() { return type(rvalue_type(this)); } \
+ type Pass() WARN_UNUSED_RESULT { return type(rvalue_type(this)); } \
+ typedef void MoveOnlyTypeForCPP03; \
+ private:
+
+#define RTC_MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(type) \
+ private: \
+ type(type&); \
+ void operator=(type&); \
+ public: \
+ type&& Pass() WARN_UNUSED_RESULT { return static_cast<type&&>(*this); } \
typedef void MoveOnlyTypeForCPP03; \
private:
-#endif // WEBRTC_SYSTEM_WRAPPERS_INTEFACE_MOVE_H_
+#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_MOVE_H_
diff --git a/system_wrappers/source/system_wrappers.gyp b/system_wrappers/source/system_wrappers.gyp
index 870d88a4..2cdd23de 100644
--- a/system_wrappers/source/system_wrappers.gyp
+++ b/system_wrappers/source/system_wrappers.gyp
@@ -44,6 +44,7 @@
'../interface/fix_interlocked_exchange_pointer_win.h',
'../interface/logcat_trace_context.h',
'../interface/logging.h',
+ '../interface/metrics.h',
'../interface/ref_count.h',
'../interface/rtp_to_ntp.h',
'../interface/rw_lock_wrapper.h',
@@ -204,6 +205,22 @@
'dependencies': [
'system_wrappers',
]
+ }, {
+ 'target_name': 'metrics_default',
+ 'type': 'static_library',
+ 'sources': [
+ 'metrics_default.cc',
+ ],
+ 'dependencies': [
+ 'system_wrappers',
+ ]
+ }, {
+ 'target_name': 'system_wrappers_default',
+ 'type': 'static_library',
+ 'dependencies': [
+ 'field_trial_default',
+ 'metrics_default',
+ ]
},
], # targets
'conditions': [
diff --git a/system_wrappers/source/system_wrappers.target.darwin-arm.mk b/system_wrappers/source/system_wrappers.target.darwin-arm.mk
index 2877b678..410731a6 100644
--- a/system_wrappers/source/system_wrappers.target.darwin-arm.mk
+++ b/system_wrappers/source/system_wrappers.target.darwin-arm.mk
@@ -111,11 +111,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -133,6 +135,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_THREAD_RR' \
'-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -227,11 +230,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -249,6 +254,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_THREAD_RR' \
'-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/system_wrappers/source/system_wrappers.target.darwin-arm64.mk b/system_wrappers/source/system_wrappers.target.darwin-arm64.mk
index 7ad5d7ba..9a13f395 100644
--- a/system_wrappers/source/system_wrappers.target.darwin-arm64.mk
+++ b/system_wrappers/source/system_wrappers.target.darwin-arm64.mk
@@ -100,11 +100,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -113,12 +115,14 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_THREAD_RR' \
'-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -201,11 +205,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -214,12 +220,14 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_THREAD_RR' \
'-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/system_wrappers/source/system_wrappers.target.darwin-mips.mk b/system_wrappers/source/system_wrappers.target.darwin-mips.mk
index 7fcc0841..8739abc9 100644
--- a/system_wrappers/source/system_wrappers.target.darwin-mips.mk
+++ b/system_wrappers/source/system_wrappers.target.darwin-mips.mk
@@ -104,11 +104,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -125,6 +127,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_THREAD_RR' \
'-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -212,11 +215,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -233,6 +238,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_THREAD_RR' \
'-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/system_wrappers/source/system_wrappers.target.darwin-mips64.mk b/system_wrappers/source/system_wrappers.target.darwin-mips64.mk
new file mode 100644
index 00000000..7eeb03d8
--- /dev/null
+++ b/system_wrappers/source/system_wrappers.target.darwin-mips64.mk
@@ -0,0 +1,293 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_system_wrappers_source_system_wrappers_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/system_wrappers/source/aligned_malloc.cc \
+ third_party/webrtc/system_wrappers/source/atomic32_posix.cc \
+ third_party/webrtc/system_wrappers/source/clock.cc \
+ third_party/webrtc/system_wrappers/source/condition_variable.cc \
+ third_party/webrtc/system_wrappers/source/condition_variable_posix.cc \
+ third_party/webrtc/system_wrappers/source/cpu_info.cc \
+ third_party/webrtc/system_wrappers/source/cpu_features.cc \
+ third_party/webrtc/system_wrappers/source/critical_section.cc \
+ third_party/webrtc/system_wrappers/source/critical_section_posix.cc \
+ third_party/webrtc/system_wrappers/source/data_log_c.cc \
+ third_party/webrtc/system_wrappers/source/data_log_no_op.cc \
+ third_party/webrtc/system_wrappers/source/event.cc \
+ third_party/webrtc/system_wrappers/source/event_posix.cc \
+ third_party/webrtc/system_wrappers/source/event_tracer.cc \
+ third_party/webrtc/system_wrappers/source/file_impl.cc \
+ third_party/webrtc/system_wrappers/source/logcat_trace_context.cc \
+ third_party/webrtc/system_wrappers/source/logging.cc \
+ third_party/webrtc/system_wrappers/source/rtp_to_ntp.cc \
+ third_party/webrtc/system_wrappers/source/rw_lock.cc \
+ third_party/webrtc/system_wrappers/source/rw_lock_generic.cc \
+ third_party/webrtc/system_wrappers/source/rw_lock_posix.cc \
+ third_party/webrtc/system_wrappers/source/sleep.cc \
+ third_party/webrtc/system_wrappers/source/sort.cc \
+ third_party/webrtc/system_wrappers/source/tick_util.cc \
+ third_party/webrtc/system_wrappers/source/thread.cc \
+ third_party/webrtc/system_wrappers/source/thread_posix.cc \
+ third_party/webrtc/system_wrappers/source/timestamp_extrapolator.cc \
+ third_party/webrtc/system_wrappers/source/trace_impl.cc \
+ third_party/webrtc/system_wrappers/source/trace_posix.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DWEBRTC_THREAD_RR' \
+ '-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/source/spreadsortlib \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DWEBRTC_THREAD_RR' \
+ '-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/source/spreadsortlib \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_system_wrappers_source_system_wrappers_gyp
+
+# Alias gyp target name.
+.PHONY: system_wrappers
+system_wrappers: third_party_webrtc_system_wrappers_source_system_wrappers_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/system_wrappers/source/system_wrappers.target.darwin-x86.mk b/system_wrappers/source/system_wrappers.target.darwin-x86.mk
index 1515c61b..4e16a4b0 100644
--- a/system_wrappers/source/system_wrappers.target.darwin-x86.mk
+++ b/system_wrappers/source/system_wrappers.target.darwin-x86.mk
@@ -106,11 +106,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -125,6 +127,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_THREAD_RR' \
'-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -213,11 +216,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -232,6 +237,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_THREAD_RR' \
'-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/system_wrappers/source/system_wrappers.target.darwin-x86_64.mk b/system_wrappers/source/system_wrappers.target.darwin-x86_64.mk
index ef734144..3aeeea40 100644
--- a/system_wrappers/source/system_wrappers.target.darwin-x86_64.mk
+++ b/system_wrappers/source/system_wrappers.target.darwin-x86_64.mk
@@ -105,11 +105,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -124,6 +126,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_THREAD_RR' \
'-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -211,11 +214,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -230,6 +235,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_THREAD_RR' \
'-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/system_wrappers/source/system_wrappers.target.linux-arm.mk b/system_wrappers/source/system_wrappers.target.linux-arm.mk
index 2877b678..410731a6 100644
--- a/system_wrappers/source/system_wrappers.target.linux-arm.mk
+++ b/system_wrappers/source/system_wrappers.target.linux-arm.mk
@@ -111,11 +111,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -133,6 +135,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_THREAD_RR' \
'-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -227,11 +230,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -249,6 +254,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_THREAD_RR' \
'-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/system_wrappers/source/system_wrappers.target.linux-arm64.mk b/system_wrappers/source/system_wrappers.target.linux-arm64.mk
index 7ad5d7ba..9a13f395 100644
--- a/system_wrappers/source/system_wrappers.target.linux-arm64.mk
+++ b/system_wrappers/source/system_wrappers.target.linux-arm64.mk
@@ -100,11 +100,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -113,12 +115,14 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_THREAD_RR' \
'-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -201,11 +205,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -214,12 +220,14 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_THREAD_RR' \
'-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/system_wrappers/source/system_wrappers.target.linux-mips.mk b/system_wrappers/source/system_wrappers.target.linux-mips.mk
index 7fcc0841..8739abc9 100644
--- a/system_wrappers/source/system_wrappers.target.linux-mips.mk
+++ b/system_wrappers/source/system_wrappers.target.linux-mips.mk
@@ -104,11 +104,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -125,6 +127,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_THREAD_RR' \
'-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -212,11 +215,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -233,6 +238,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_THREAD_RR' \
'-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/system_wrappers/source/system_wrappers.target.linux-mips64.mk b/system_wrappers/source/system_wrappers.target.linux-mips64.mk
new file mode 100644
index 00000000..7eeb03d8
--- /dev/null
+++ b/system_wrappers/source/system_wrappers.target.linux-mips64.mk
@@ -0,0 +1,293 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_system_wrappers_source_system_wrappers_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/system_wrappers/source/aligned_malloc.cc \
+ third_party/webrtc/system_wrappers/source/atomic32_posix.cc \
+ third_party/webrtc/system_wrappers/source/clock.cc \
+ third_party/webrtc/system_wrappers/source/condition_variable.cc \
+ third_party/webrtc/system_wrappers/source/condition_variable_posix.cc \
+ third_party/webrtc/system_wrappers/source/cpu_info.cc \
+ third_party/webrtc/system_wrappers/source/cpu_features.cc \
+ third_party/webrtc/system_wrappers/source/critical_section.cc \
+ third_party/webrtc/system_wrappers/source/critical_section_posix.cc \
+ third_party/webrtc/system_wrappers/source/data_log_c.cc \
+ third_party/webrtc/system_wrappers/source/data_log_no_op.cc \
+ third_party/webrtc/system_wrappers/source/event.cc \
+ third_party/webrtc/system_wrappers/source/event_posix.cc \
+ third_party/webrtc/system_wrappers/source/event_tracer.cc \
+ third_party/webrtc/system_wrappers/source/file_impl.cc \
+ third_party/webrtc/system_wrappers/source/logcat_trace_context.cc \
+ third_party/webrtc/system_wrappers/source/logging.cc \
+ third_party/webrtc/system_wrappers/source/rtp_to_ntp.cc \
+ third_party/webrtc/system_wrappers/source/rw_lock.cc \
+ third_party/webrtc/system_wrappers/source/rw_lock_generic.cc \
+ third_party/webrtc/system_wrappers/source/rw_lock_posix.cc \
+ third_party/webrtc/system_wrappers/source/sleep.cc \
+ third_party/webrtc/system_wrappers/source/sort.cc \
+ third_party/webrtc/system_wrappers/source/tick_util.cc \
+ third_party/webrtc/system_wrappers/source/thread.cc \
+ third_party/webrtc/system_wrappers/source/thread_posix.cc \
+ third_party/webrtc/system_wrappers/source/timestamp_extrapolator.cc \
+ third_party/webrtc/system_wrappers/source/trace_impl.cc \
+ third_party/webrtc/system_wrappers/source/trace_posix.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DWEBRTC_THREAD_RR' \
+ '-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/source/spreadsortlib \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DWEBRTC_THREAD_RR' \
+ '-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/source/spreadsortlib \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_system_wrappers_source_system_wrappers_gyp
+
+# Alias gyp target name.
+.PHONY: system_wrappers
+system_wrappers: third_party_webrtc_system_wrappers_source_system_wrappers_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/system_wrappers/source/system_wrappers.target.linux-x86.mk b/system_wrappers/source/system_wrappers.target.linux-x86.mk
index 1515c61b..4e16a4b0 100644
--- a/system_wrappers/source/system_wrappers.target.linux-x86.mk
+++ b/system_wrappers/source/system_wrappers.target.linux-x86.mk
@@ -106,11 +106,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -125,6 +127,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_THREAD_RR' \
'-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -213,11 +216,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -232,6 +237,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_THREAD_RR' \
'-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/system_wrappers/source/system_wrappers.target.linux-x86_64.mk b/system_wrappers/source/system_wrappers.target.linux-x86_64.mk
index ef734144..3aeeea40 100644
--- a/system_wrappers/source/system_wrappers.target.linux-x86_64.mk
+++ b/system_wrappers/source/system_wrappers.target.linux-x86_64.mk
@@ -105,11 +105,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -124,6 +126,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_THREAD_RR' \
'-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -211,11 +214,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -230,6 +235,7 @@ MY_DEFS_Release := \
'-DWEBRTC_ANDROID_OPENSLES' \
'-DWEBRTC_THREAD_RR' \
'-DWEBRTC_CLOCK_TYPE_REALTIME' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/system_wrappers/source/system_wrappers_tests.gyp b/system_wrappers/source/system_wrappers_tests.gyp
index f77b985a..18775920 100644
--- a/system_wrappers/source/system_wrappers_tests.gyp
+++ b/system_wrappers/source/system_wrappers_tests.gyp
@@ -80,7 +80,6 @@
],
'includes': [
'../../build/isolate.gypi',
- 'system_wrappers_unittests.isolate',
],
'sources': [
'system_wrappers_unittests.isolate',
diff --git a/system_wrappers/source/system_wrappers_unittests.isolate b/system_wrappers/source/system_wrappers_unittests.isolate
index f5057710..0a56470c 100644
--- a/system_wrappers/source/system_wrappers_unittests.isolate
+++ b/system_wrappers/source/system_wrappers_unittests.isolate
@@ -10,7 +10,7 @@
'conditions': [
['OS=="android"', {
'variables': {
- 'isolate_dependency_untracked': [
+ 'files': [
'<(DEPTH)/data/',
'<(DEPTH)/resources/',
],
@@ -22,13 +22,10 @@
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/system_wrappers_unittests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/system_wrappers_unittests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_untracked': [
- '<(DEPTH)/tools/swarming_client/',
- ],
},
}],
],
diff --git a/system_wrappers/source/timestamp_extrapolator.cc b/system_wrappers/source/timestamp_extrapolator.cc
index afd212b0..f2b70926 100644
--- a/system_wrappers/source/timestamp_extrapolator.cc
+++ b/system_wrappers/source/timestamp_extrapolator.cc
@@ -30,7 +30,7 @@ TimestampExtrapolator::TimestampExtrapolator(int64_t start_ms)
_alarmThreshold(60e3),
_accDrift(6600), // in timestamp ticks, i.e. 15 ms
_accMaxError(7000),
- _P11(1e10) {
+ _pP11(1e10) {
Reset(start_ms);
}
@@ -47,9 +47,9 @@ void TimestampExtrapolator::Reset(int64_t start_ms)
_firstTimestamp = 0;
_w[0] = 90.0;
_w[1] = 0;
- _P[0][0] = 1;
- _P[1][1] = _P11;
- _P[0][1] = _P[1][0] = 0;
+ _pP[0][0] = 1;
+ _pP[1][1] = _pP11;
+ _pP[0][1] = _pP[1][0] = 0;
_firstAfterReset = true;
_prevUnwrappedTimestamp = -1;
_prevWrapTimestamp = -1;
@@ -112,14 +112,14 @@ TimestampExtrapolator::Update(int64_t tMs, uint32_t ts90khz)
// A sudden change of average network delay has been detected.
// Force the filter to adjust its offset parameter by changing
// the offset uncertainty. Don't do this during startup.
- _P[1][1] = _P11;
+ _pP[1][1] = _pP11;
}
//T = [t(k) 1]';
//that = T'*w;
//K = P*T/(lambda + T'*P*T);
double K[2];
- K[0] = _P[0][0] * tMs + _P[0][1];
- K[1] = _P[1][0] * tMs + _P[1][1];
+ K[0] = _pP[0][0] * tMs + _pP[0][1];
+ K[1] = _pP[1][0] * tMs + _pP[1][1];
double TPT = _lambda + tMs * K[0] + K[1];
K[0] /= TPT;
K[1] /= TPT;
@@ -127,12 +127,16 @@ TimestampExtrapolator::Update(int64_t tMs, uint32_t ts90khz)
_w[0] = _w[0] + K[0] * residual;
_w[1] = _w[1] + K[1] * residual;
//P = 1/lambda*(P - K*T'*P);
- double p00 = 1 / _lambda * (_P[0][0] - (K[0] * tMs * _P[0][0] + K[0] * _P[1][0]));
- double p01 = 1 / _lambda * (_P[0][1] - (K[0] * tMs * _P[0][1] + K[0] * _P[1][1]));
- _P[1][0] = 1 / _lambda * (_P[1][0] - (K[1] * tMs * _P[0][0] + K[1] * _P[1][0]));
- _P[1][1] = 1 / _lambda * (_P[1][1] - (K[1] * tMs * _P[0][1] + K[1] * _P[1][1]));
- _P[0][0] = p00;
- _P[0][1] = p01;
+ double p00 = 1 / _lambda *
+ (_pP[0][0] - (K[0] * tMs * _pP[0][0] + K[0] * _pP[1][0]));
+ double p01 = 1 / _lambda *
+ (_pP[0][1] - (K[0] * tMs * _pP[0][1] + K[0] * _pP[1][1]));
+ _pP[1][0] = 1 / _lambda *
+ (_pP[1][0] - (K[1] * tMs * _pP[0][0] + K[1] * _pP[1][0]));
+ _pP[1][1] = 1 / _lambda *
+ (_pP[1][1] - (K[1] * tMs * _pP[0][1] + K[1] * _pP[1][1]));
+ _pP[0][0] = p00;
+ _pP[0][1] = p01;
_prevUnwrappedTimestamp = unwrapped_ts90khz;
if (_packetCount < _startUpFilterDelayInPackets)
{
diff --git a/system_wrappers/source/trace_impl.h b/system_wrappers/source/trace_impl.h
index 9e6e0a2d..5548e984 100644
--- a/system_wrappers/source/trace_impl.h
+++ b/system_wrappers/source/trace_impl.h
@@ -30,7 +30,7 @@ namespace webrtc {
#define WEBRTC_TRACE_MAX_QUEUE 8000
#endif
#define WEBRTC_TRACE_NUM_ARRAY 2
-#define WEBRTC_TRACE_MAX_MESSAGE_SIZE 256
+#define WEBRTC_TRACE_MAX_MESSAGE_SIZE 1024
// Total buffer size is WEBRTC_TRACE_NUM_ARRAY (number of buffer partitions) *
// WEBRTC_TRACE_MAX_QUEUE (number of lines per buffer partition) *
// WEBRTC_TRACE_MAX_MESSAGE_SIZE (number of 1 byte charachters per line) =
diff --git a/test/BUILD.gn b/test/BUILD.gn
index 7bb11a14..db17c31e 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -95,6 +95,7 @@ source_set("test_support_main") {
deps = [
":field_trial",
":test_support",
+ "../system_wrappers:metrics_default",
"//testing/gmock",
"//testing/gtest",
"//third_party/gflags",
diff --git a/test/call_test.cc b/test/call_test.cc
index d49f6e3f..126c7163 100644
--- a/test/call_test.cc
+++ b/test/call_test.cc
@@ -19,6 +19,7 @@ CallTest::CallTest()
send_stream_(NULL),
fake_encoder_(clock_) {
}
+
CallTest::~CallTest() {
}
@@ -98,23 +99,15 @@ void CallTest::CreateSendConfig(size_t num_streams) {
void CallTest::CreateMatchingReceiveConfigs() {
assert(!send_config_.rtp.ssrcs.empty());
assert(receive_configs_.empty());
- assert(fake_decoders_.empty());
+ assert(allocated_decoders_.empty());
VideoReceiveStream::Config config;
- VideoCodec codec =
- test::CreateDecoderVideoCodec(send_config_.encoder_settings);
- config.codecs.push_back(codec);
config.rtp.local_ssrc = kReceiverLocalSsrc;
- if (send_config_.encoder_settings.encoder == &fake_encoder_) {
- config.external_decoders.resize(1);
- config.external_decoders[0].payload_type =
- send_config_.encoder_settings.payload_type;
- }
for (size_t i = 0; i < send_config_.rtp.ssrcs.size(); ++i) {
- if (send_config_.encoder_settings.encoder == &fake_encoder_) {
- FakeDecoder* decoder = new FakeDecoder();
- fake_decoders_.push_back(decoder);
- config.external_decoders[0].decoder = decoder;
- }
+ VideoReceiveStream::Decoder decoder =
+ test::CreateMatchingDecoder(send_config_.encoder_settings);
+ allocated_decoders_.push_back(decoder.decoder);
+ config.decoders.clear();
+ config.decoders.push_back(decoder);
config.rtp.remote_ssrc = send_config_.rtp.ssrcs[i];
receive_configs_.push_back(config);
}
@@ -149,7 +142,7 @@ void CallTest::DestroyStreams() {
for (size_t i = 0; i < receive_streams_.size(); ++i)
receiver_call_->DestroyVideoReceiveStream(receive_streams_[i]);
receive_streams_.clear();
- fake_decoders_.clear();
+ allocated_decoders_.clear();
}
const unsigned int CallTest::kDefaultTimeoutMs = 30 * 1000;
diff --git a/test/call_test.h b/test/call_test.h
index 695fb2ac..b9a091b4 100644
--- a/test/call_test.h
+++ b/test/call_test.h
@@ -74,7 +74,7 @@ class CallTest : public ::testing::Test {
scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer_;
test::FakeEncoder fake_encoder_;
- ScopedVector<test::FakeDecoder> fake_decoders_;
+ ScopedVector<VideoDecoder> allocated_decoders_;
};
class BaseTest : public RtpRtcpObserver {
diff --git a/test/encoder_settings.cc b/test/encoder_settings.cc
index 0eeb0b9f..db064bb8 100644
--- a/test/encoder_settings.cc
+++ b/test/encoder_settings.cc
@@ -12,8 +12,8 @@
#include <assert.h>
#include <string.h>
-#include "webrtc/video_encoder.h"
-#include "webrtc/video_engine/vie_defines.h"
+#include "webrtc/test/fake_decoder.h"
+#include "webrtc/video_decoder.h"
namespace webrtc {
namespace test {
@@ -53,33 +53,17 @@ std::vector<VideoStream> CreateVideoStreams(size_t num_streams) {
return stream_settings;
}
-VideoCodec CreateDecoderVideoCodec(
+VideoReceiveStream::Decoder CreateMatchingDecoder(
const VideoSendStream::Config::EncoderSettings& encoder_settings) {
- VideoCodec codec;
- memset(&codec, 0, sizeof(codec));
-
- codec.plType = encoder_settings.payload_type;
- strcpy(codec.plName, encoder_settings.payload_name.c_str());
+ VideoReceiveStream::Decoder decoder;
+ decoder.payload_type = encoder_settings.payload_type;
+ decoder.payload_name = encoder_settings.payload_name;
if (encoder_settings.payload_name == "VP8") {
- codec.codecType = kVideoCodecVP8;
- } else if (encoder_settings.payload_name == "H264") {
- codec.codecType = kVideoCodecH264;
+ decoder.decoder = VideoDecoder::Create(VideoDecoder::kVp8);
} else {
- codec.codecType = kVideoCodecGeneric;
- }
-
- if (codec.codecType == kVideoCodecVP8) {
- codec.codecSpecific.VP8 = VideoEncoder::GetDefaultVp8Settings();
- } else if (codec.codecType == kVideoCodecH264) {
- codec.codecSpecific.H264 = VideoEncoder::GetDefaultH264Settings();
+ decoder.decoder = new FakeDecoder();
}
-
- codec.width = 320;
- codec.height = 180;
- codec.startBitrate = codec.minBitrate = codec.maxBitrate = 300;
-
- return codec;
+ return decoder;
}
-
} // namespace test
} // namespace webrtc
diff --git a/test/encoder_settings.h b/test/encoder_settings.h
index ea2be977..a44d3661 100644
--- a/test/encoder_settings.h
+++ b/test/encoder_settings.h
@@ -10,13 +10,14 @@
#ifndef WEBRTC_TEST_ENCODER_SETTINGS_H_
#define WEBRTC_TEST_ENCODER_SETTINGS_H_
+#include "webrtc/video_receive_stream.h"
#include "webrtc/video_send_stream.h"
namespace webrtc {
namespace test {
std::vector<VideoStream> CreateVideoStreams(size_t num_streams);
-VideoCodec CreateDecoderVideoCodec(
+VideoReceiveStream::Decoder CreateMatchingDecoder(
const VideoSendStream::Config::EncoderSettings& encoder_settings);
} // namespace test
} // namespace webrtc
diff --git a/test/run_loop.cc b/test/run_loop.cc
index cda1e10c..92f85dd0 100644
--- a/test/run_loop.cc
+++ b/test/run_loop.cc
@@ -16,7 +16,7 @@ namespace test {
void PressEnterToContinue() {
puts(">> Press ENTER to continue...");
- while (getchar() != '\n' && !feof(stdin));
+ while (getc(stdin) != '\n' && !feof(stdin));
}
} // namespace test
} // namespace webrtc
diff --git a/test/test.gyp b/test/test.gyp
index 154ba2cd..5c959b9e 100644
--- a/test/test.gyp
+++ b/test/test.gyp
@@ -53,11 +53,13 @@
],
},
{
- 'target_name': 'rtcp_packet_parser',
+ 'target_name': 'rtp_test_utils',
'type': 'static_library',
'sources': [
'rtcp_packet_parser.cc',
'rtcp_packet_parser.h',
+ 'rtp_file_reader.cc',
+ 'rtp_file_reader.h',
],
'dependencies': [
'<(webrtc_root)/modules/modules.gyp:rtp_rtcp',
@@ -84,6 +86,7 @@
'field_trial',
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
+ '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:metrics_default',
],
},
{
@@ -140,6 +143,7 @@
'<(DEPTH)/testing/gmock.gyp:gmock',
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
+ '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:metrics_default',
],
'sources': [
'run_all_unittests.cc',
@@ -220,7 +224,6 @@
],
'includes': [
'../build/isolate.gypi',
- 'test_support_unittests.isolate',
],
'sources': [
'test_support_unittests.isolate',
diff --git a/test/test_support_unittests.isolate b/test/test_support_unittests.isolate
index 08bd4a4a..c1419e7e 100644
--- a/test/test_support_unittests.isolate
+++ b/test/test_support_unittests.isolate
@@ -9,7 +9,7 @@
'conditions': [
['OS=="android"', {
'variables': {
- 'isolate_dependency_untracked': [
+ 'files': [
'<(DEPTH)/data/',
'<(DEPTH)/resources/',
],
@@ -21,14 +21,11 @@
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/test_support_unittests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'<(DEPTH)/DEPS',
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/test_support_unittests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_untracked': [
- '<(DEPTH)/tools/swarming_client/',
- ],
},
}],
],
diff --git a/test/webrtc_test_common.gyp b/test/webrtc_test_common.gyp
index 477ec0fc..cd076639 100644
--- a/test/webrtc_test_common.gyp
+++ b/test/webrtc_test_common.gyp
@@ -35,8 +35,6 @@
'mock_transport.h',
'null_transport.cc',
'null_transport.h',
- 'rtp_file_reader.cc',
- 'rtp_file_reader.h',
'rtp_rtcp_observer.h',
'run_loop.cc',
'run_loop.h',
@@ -60,10 +58,10 @@
'<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
'<(webrtc_root)/base/base.gyp:rtc_base',
'<(webrtc_root)/modules/modules.gyp:media_file',
- '<(webrtc_root)/modules/modules.gyp:video_capture_module_impl',
'<(webrtc_root)/modules/modules.gyp:video_render_module_impl',
'<(webrtc_root)/test/test.gyp:frame_generator',
'<(webrtc_root)/test/test.gyp:test_support',
+ '<(webrtc_root)/test/test.gyp:rtp_test_utils',
'<(webrtc_root)/webrtc.gyp:webrtc',
],
},
@@ -153,6 +151,7 @@
'webrtc_test_common',
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(DEPTH)/testing/gmock.gyp:gmock',
+ '<(webrtc_root)/modules/modules.gyp:video_capture_module_impl',
'<(webrtc_root)/test/test.gyp:test_support_main',
],
'sources': [
diff --git a/tools/rtcbot/README b/tools/rtcbot/README
index bfa981c5..1f4d7c11 100644
--- a/tools/rtcbot/README
+++ b/tools/rtcbot/README
@@ -17,8 +17,18 @@ access its exposed API. Details are in botmanager.js.
== How to run the test ==
$ cd trunk/webrtc/tool/rtcbot
$ npm install express browserify ws websocket-stream dnode
+ $ mkdir configurations
+ $ cd configurations
+ $ openssl genrsa -out priv.pem 1024
+ $ openssl req -x509 -new -key priv.pem -days 3650 -out cert.crt
+ $ cd trunk/webrtc/tool/rtcbot
$ node main.js "<test_name>"
+* Note:
+ In first time you will use rtcBot you will receive a warning telling
+ you that your connection is not private. Just avoid this warning and
+ click Proceed to localhost (unsafe).
+
== How can I see the list of available tests? ==
$ node main.js
@@ -29,6 +39,10 @@ access its exposed API. Details are in botmanager.js.
$ nvm install 0.10
$ nvm use 0.10
+== Why generating the private key and self signed certificate? ==
+ - Private key and certificate are used for creating HTTPs server in
+ rtcBot for loading the required files on the different types of the bots.
+
== Supported Bot Types ==
- "chrome": chrome on host machine.
- "android-chrome": chrome on android device. Details in "Android" Section.
diff --git a/tools/rtcbot/bot/api.js b/tools/rtcbot/bot/api.js
index b51d49df..7e1a436e 100644
--- a/tools/rtcbot/bot/api.js
+++ b/tools/rtcbot/bot/api.js
@@ -15,7 +15,7 @@ var WebSocketStream = require('websocket-stream');
var Dnode = require('dnode');
function connectToServer(api) {
- var stream = new WebSocketStream("ws://127.0.0.1:8080/");
+ var stream = new WebSocketStream("wss://localhost:8080/");
var dnode = new Dnode(api);
dnode.on('error', function (error) { console.log(error); });
dnode.pipe(stream).pipe(dnode);
diff --git a/tools/rtcbot/bot/browser/bot.js b/tools/rtcbot/bot/browser/bot.js
index 99ff84d6..a5785dfe 100644
--- a/tools/rtcbot/bot/browser/bot.js
+++ b/tools/rtcbot/bot/browser/bot.js
@@ -113,9 +113,28 @@ function getStreamFromIdentifier_(id) {
return null;
};
+function downloadFile(path, onSuccess, onError) {
+ var xhr = new XMLHttpRequest();
+ function onResult() {
+ if (xhr.readyState != 4)
+ return;
+
+ if (xhr.status != 200) {
+ onError("Download request failed!");
+ return;
+ }
+ onSuccess(xhr.responseText);
+ }
+
+ xhr.onreadystatechange = onResult;
+ xhr.open('GET', path, true);
+ xhr.send();
+};
+
connectToServer({
ping: ping,
getUserMedia: getUserMedia,
createPeerConnection: createPeerConnection,
showStream: showStream,
+ downloadFile: downloadFile,
});
diff --git a/tools/rtcbot/botmanager.js b/tools/rtcbot/botmanager.js
index cd88f19f..5b325bd8 100644
--- a/tools/rtcbot/botmanager.js
+++ b/tools/rtcbot/botmanager.js
@@ -8,7 +8,8 @@
//
// botmanager.js module allows a test to spawn bots that expose an RPC API
// to be controlled by tests.
-var http = require('http');
+var https = require('https');
+var fs = require('fs');
var child = require('child_process');
var Browserify = require('browserify');
var Dnode = require('dnode');
@@ -16,7 +17,7 @@ var Express = require('express');
var WebSocketServer = require('ws').Server;
var WebSocketStream = require('websocket-stream');
-// BotManager runs a HttpServer that serves bots assets and and WebSocketServer
+// BotManager runs a HttpsServer that serves bots assets and and WebSocketServer
// that listens to incoming connections. Once a connection is available it
// connects it to bots pending endpoints.
//
@@ -66,7 +67,11 @@ BotManager.prototype = {
this.app_.use('/bot/', Express.static(__dirname + '/bot'));
- this.server_ = http.createServer(this.app_);
+ var options = options = {
+ key: fs.readFileSync('configurations/priv.pem', 'utf8'),
+ cert: fs.readFileSync('configurations/cert.crt', 'utf8')
+ };
+ this.server_ = https.createServer(options, this.app_);
this.webSocketServer_ = new WebSocketServer({ server: this.server_ });
this.webSocketServer_.on('connection', this.onConnection_.bind(this));
@@ -116,7 +121,7 @@ Bot.prototype = {
}
}
-// BrowserBot spawns a process to open "http://localhost:8080/bot/browser".
+// BrowserBot spawns a process to open "https://localhost:8080/bot/browser".
//
// That page once loaded, connects to the websocket server run by BotManager
// and exposes the bot api.
@@ -128,14 +133,14 @@ BrowserBot = function (name, callback) {
BrowserBot.prototype = {
spawnBotProcess_: function () {
this.log('Spawning browser');
- child.exec('google-chrome "http://localhost:8080/bot/browser/"');
+ child.exec('google-chrome "https://localhost:8080/bot/browser/"');
},
__proto__: Bot.prototype
}
// AndroidChromeBot spawns a process to open
-// "http://localhost:8080/bot/browser/" on chrome for Android.
+// "https://localhost:8080/bot/browser/" on chrome for Android.
AndroidChromeBot = function (name, androidDeviceManager, callback) {
Bot.call(this, name, callback);
androidDeviceManager.getNewDevice(function (serialNumber) {
@@ -149,7 +154,7 @@ AndroidChromeBot.prototype = {
this.log('Spawning Android device with serial ' + this.serialNumber_);
var runChrome = 'adb -s ' + this.serialNumber_ + ' shell am start ' +
'-n com.android.chrome/com.google.android.apps.chrome.Main ' +
- '-d http://localhost:8080/bot/browser/';
+ '-d https://localhost:8080/bot/browser/';
child.exec(runChrome, function (error, stdout, stderr) {
if (error) {
this.log(error);
diff --git a/tools/rtcbot/rtcBotReportVisualizer/index.html b/tools/rtcbot/rtcBotReportVisualizer/index.html
new file mode 100644
index 00000000..7ff59fc3
--- /dev/null
+++ b/tools/rtcbot/rtcBotReportVisualizer/index.html
@@ -0,0 +1,14 @@
+<!--
+// 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.
+-->
+<html>
+ <script src="https://www.google.com/jsapi"></script>
+ <script type="text/javascript" src="main.js"></script>
+ <input type="file" onchange="openFiles(event)" multiple>
+</html> \ No newline at end of file
diff --git a/tools/rtcbot/rtcBotReportVisualizer/main.js b/tools/rtcbot/rtcBotReportVisualizer/main.js
new file mode 100644
index 00000000..91b0eec1
--- /dev/null
+++ b/tools/rtcbot/rtcBotReportVisualizer/main.js
@@ -0,0 +1,191 @@
+// 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.
+//
+google.load("visualization", "1", {packages:["corechart"]});
+
+function openFiles(event) {
+ var files = event.target.files;
+ readAndAnalyzeFiles(files)
+}
+
+function readAndAnalyzeFiles(files) {
+ if(!files) {
+ alert("No files have been selected!");
+ return;
+ }
+
+ var reports = [];
+ var filesNames = [];
+ missingFiles = files.length;
+
+ for(var i = 0; i < files.length; i++) {
+ var reader = new FileReader();
+ reader.onload = onReaderLoad.bind(reader, files[i].name);
+ reader.readAsText(files[i]);
+ }
+
+ function onReaderLoad(fileName) {
+ reports.push(JSON.parse(this.result));
+ filesNames.push(fileName);
+
+ missingFiles--;
+ if(missingFiles == 0) {
+ analyzeReports_(reports, filesNames);
+ }
+ }
+}
+
+// TODO(houssainy) take the input stats from the select list or
+// drop down menu in html.
+function analyzeReports_(reports, filesNames) {
+ filesNames.unshift(""); // ned
+
+ // Rtt
+ analyzeRttData(reports, filesNames, "bot1");
+ analyzeRttData(reports, filesNames, "bot2");
+
+ // Send Packets Lost
+ analyzePacketsLostData(reports, filesNames, "bot1");
+ analyzePacketsLostData(reports, filesNames, "bot2");
+
+ // Send bandwidth
+ analyzeData(reports, filesNames, "Available Send Bandwidth-bot1", "bot1",
+ "bweforvideo", "googAvailableSendBandwidth");
+ analyzeData(reports, filesNames, "Available Send Bandwidth-bot2", "bot2",
+ "bweforvideo", "googAvailableSendBandwidth");
+
+ // Receive bandwidth
+ analyzeData(reports, filesNames, "Available Receive Bandwidth-bot1", "bot1",
+ "bweforvideo", "googAvailableReceiveBandwidth");
+ analyzeData(reports, filesNames, "Available Receive Bandwidth-bot2", "bot2",
+ "bweforvideo", "googAvailableReceiveBandwidth");
+
+ drawSeparatorLine();
+}
+
+function analyzeRttData(reports, filesNames, botName) {
+ var outPut = [];
+ outPut.push(filesNames);
+
+ var avergaData = ['Average Rtt x10'];
+ var maxData = ['Max Rtt'];
+
+ var average;
+ var max;
+ for(var index in reports) {
+ average = getStateAverage(reports[index], botName, "Conn-audio-1-0",
+ "googRtt");
+ avergaData.push(average*10);
+
+ max = getStateMax(reports[index], botName, "Conn-audio-1-0",
+ "googRtt");
+ maxData.push(max);
+ }
+ outPut.push(avergaData);
+ outPut.push(maxData);
+
+ drawChart("Rtt-" + botName, outPut);
+}
+
+function analyzePacketsLostData(reports, filesNames, botName) {
+ var outPut = [];
+ outPut.push(filesNames);
+
+ var maxData = ['Max Send PacketsLost'];
+ var max;
+ for(var index in reports) {
+ max = getStateMax(reports[index], botName, "ssrc_[0-9]+_send",
+ "packetsLost");
+ maxData.push(max);
+ }
+ outPut.push(maxData);
+
+ drawChart("Send PacketsLost-" + botName, outPut);
+}
+
+function analyzeData(reports, filesNames, chartName, botName, reportId,
+ statName) {
+ var outPut = [];
+ outPut.push(filesNames);
+
+ var avergaData = ['Average ' + statName];
+ var maxData = ['Max ' + statName];
+
+ var average;
+ var max;
+ for(var index in reports) {
+ average = getStateAverage(reports[index], botName, reportId, statName);
+ avergaData.push(average);
+
+ max = getStateMax(reports[index], botName, reportId, statName);
+ maxData.push(max);
+ }
+ outPut.push(avergaData);
+ outPut.push(maxData);
+
+ drawChart(chartName, outPut);
+}
+
+function getStateAverage(reports, botName, reportId, statName) {
+ var sum = 0;
+ var count = 0;
+
+ for (var index in reports) {
+ var data = reports[index].data;
+ if(index == 0 || !data.hasOwnProperty(botName))
+ continue;
+
+ var stats = data[botName];
+ for (var key in stats) {
+ if(key.search(reportId) != -1) {
+ var value = parseInt(stats[key][statName]);
+ sum += value;
+ count++;
+ }
+ }
+ }
+ return Math.round(sum/count);
+}
+
+function getStateMax(reports, botName, reportId, statName) {
+ var max = -1;
+
+ for (var index in reports) {
+ var data = reports[index].data;
+ if(index == 0 || !data.hasOwnProperty(botName))
+ continue;
+
+ var stats = data[botName];
+ for (var key in stats) {
+ if(key.search(reportId) != -1) {
+ var value = parseInt(stats[key][statName]);
+ max = Math.max(value, max);
+ }
+ }
+ }
+ return max;
+}
+
+function drawChart(title, data) {
+ var dataTable = google.visualization.arrayToDataTable(data);
+
+ var options = {
+ title: title,
+ };
+
+ var div = document.createElement('div');
+ document.body.appendChild(div);
+
+ var chart = new google.visualization.ColumnChart(div);
+ chart.draw(dataTable, options);
+}
+
+function drawSeparatorLine() {
+ var hr = document.createElement('hr');
+ document.body.appendChild(hr);
+}
diff --git a/tools/rtcbot/test/oneWayVideoStreamingWithDownloadingFile.js b/tools/rtcbot/test/oneWayVideoStreamingWithDownloadingFile.js
new file mode 100644
index 00000000..857d838b
--- /dev/null
+++ b/tools/rtcbot/test/oneWayVideoStreamingWithDownloadingFile.js
@@ -0,0 +1,122 @@
+// 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.
+//
+// A unidirectional video and audio flowing test from bot 1 to bot 2,
+// and download a file from a server after 2 seconds of establishing
+// the call.
+//
+// The test succeeds after collecting stats for 10 seconds from both bots
+// and then write these stats to a file.
+//
+// Note: the source of the video and audio stream is getUserMedia().
+//
+function testOneWayVideoWithDownloading(test, bot1, bot2) {
+ var report = test.createStatisticsReport("testOneWayVideoWithDownloading");
+
+ test.wait([
+ createPeerConnection.bind(bot1),
+ createPeerConnection.bind(bot2) ],
+ onPeerConnectionCreated);
+
+ function createPeerConnection(done) {
+ test.createTurnConfig(onTurnConfig.bind(this), test.fail);
+
+ function onTurnConfig(config) {
+ this.createPeerConnection(config, done, test.fail);
+ };
+ }
+
+ function onPeerConnectionCreated(pc1, pc2) {
+ test.log("RTC Peers created.");
+ pc1.addEventListener('addstream', test.fail);
+ pc2.addEventListener('addstream', onAddStream);
+ pc1.addEventListener('icecandidate', onIceCandidate.bind(pc2));
+ pc2.addEventListener('icecandidate', onIceCandidate.bind(pc1));
+
+ bot1.getUserMedia({video:true, audio:true}, onUserMediaSuccess, test.fail);
+
+ function onUserMediaSuccess(stream) {
+ test.log("User has granted access to local media.");
+ pc1.addStream(stream);
+ bot1.showStream(stream.id, true, true);
+
+ createOfferAndAnswer(pc1, pc2);
+ }
+ }
+
+ function onAddStream(event) {
+ test.log("On Add stream.");
+ bot2.showStream(event.stream.id, true, false);
+ }
+
+ function onIceCandidate(event) {
+ if(event.candidate) {
+ test.log(event.candidate.candidate);
+ this.addIceCandidate(event.candidate,
+ onAddIceCandidateSuccess, test.fail);
+ }
+
+ function onAddIceCandidateSuccess() {
+ test.log("Candidate added successfully");
+ }
+ }
+
+ function createOfferAndAnswer(pc1, pc2) {
+ test.log("Creating offer.");
+ pc1.createOffer(gotOffer, test.fail);
+
+ function gotOffer(offer) {
+ test.log("Got offer");
+ pc1.setLocalDescription(offer, onSetSessionDescriptionSuccess, test.fail);
+ pc2.setRemoteDescription(offer, onSetSessionDescriptionSuccess,
+ test.fail);
+ test.log("Creating answer");
+ pc2.createAnswer(gotAnswer, test.fail);
+ }
+
+ function gotAnswer(answer) {
+ test.log("Got answer");
+ pc2.setLocalDescription(answer, onSetSessionDescriptionSuccess,
+ test.fail);
+ pc1.setRemoteDescription(answer, onSetSessionDescriptionSuccess,
+ test.fail);
+ collectStats();
+
+ setTimeout(function() {
+ downloadFile(bot1, "bot1");
+ downloadFile(bot2, "bot2");
+ }, 2000);
+ }
+
+ function onSetSessionDescriptionSuccess() {
+ test.log("Set session description success.");
+ }
+
+ function collectStats() {
+ report.collectStatsFromPeerConnection("bot1", pc1);
+ report.collectStatsFromPeerConnection("bot2", pc2);
+
+ setTimeout(function() {
+ report.finish(test.done);
+ }, 10000);
+ }
+
+ function downloadFile(bot, name) {
+ bot.downloadFile("https://test.webrtc.org/test-download-file/9000KB.data",
+ onDownloadSuccess.bind(null, name), test.fail);
+
+ function onDownloadSuccess(name, data) {
+ test.log( name + " downloaded " +
+ Math.round(data.length/(1024*1024)) + "MB.");
+ }
+ }
+ }
+}
+
+registerBotTest('testOneWayVideoWithDownloading/chrome-chrome',
+ testOneWayVideoWithDownloading, ['chrome', 'chrome']);
diff --git a/tools/rtcbot/test/three_bots_video_conference.js b/tools/rtcbot/test/three_bots_video_conference.js
new file mode 100644
index 00000000..65c3e997
--- /dev/null
+++ b/tools/rtcbot/test/three_bots_video_conference.js
@@ -0,0 +1,135 @@
+// 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.
+//
+// A video conference between 3 bots streaming video and audio between
+// each other.
+// The test succeeds after establishing the call between the three
+// devices.
+//
+// Note: the source of the video and audio stream is getUserMedia().
+function testTwoWayVideoStreaming(test, bot1, bot2, bot3) {
+ var answersCount = 0;
+ var statsCollector;
+
+ test.wait([
+ createBotPeerConnectionsWithLocalStream.bind(bot1),
+ createBotPeerConnectionsWithLocalStream.bind(bot2),
+ createBotPeerConnectionsWithLocalStream.bind(bot3)],
+ onPeerConnectionCreated);
+
+ // done() callback is called with list of peers as argument.
+ function createBotPeerConnectionsWithLocalStream(done) {
+ var peerConnections = [];
+
+ this.getUserMedia({video:true, audio:true},
+ onUserMediaSuccess.bind(this), test.fail);
+
+ function onUserMediaSuccess(stream) {
+ test.log("User has granted access to local media.");
+ this.showStream(stream.id, true, true);
+
+ test.createTurnConfig(onTurnConfig.bind(this), test.fail);
+
+ function onTurnConfig(config) {
+ this.createPeerConnection(config, addStream.bind(this),
+ test.fail);
+ this.createPeerConnection(config, addStream.bind(this),
+ test.fail);
+ }
+
+ function addStream(pc) {
+ pc.addStream(stream);
+ pc.addEventListener('addstream', onAddStream.bind(this));
+
+ peerConnections.push(pc);
+ if(peerConnections.length == 2)
+ done(peerConnections);
+ }
+ }
+ }
+
+ function onPeerConnectionCreated(peerConnections1,
+ peerConnections2, peerConnections3) {
+ test.log("RTC Peers created.");
+
+ // Bot1 and Bot2
+ establichCall(peerConnections1[0], peerConnections2[1]);
+ // Bot2 and Bot3
+ establichCall(peerConnections2[0], peerConnections3[1]);
+ // Bot3 and Bot1
+ establichCall(peerConnections3[0], peerConnections1[1]);
+ }
+
+ function establichCall(pc1, pc2) {
+ pc1.addEventListener('icecandidate', onIceCandidate.bind(pc2));
+ pc2.addEventListener('icecandidate', onIceCandidate.bind(pc1));
+
+ createOfferAndAnswer(pc1, pc2);
+ }
+
+ function onAddStream(event) {
+ test.log("On Add stream.");
+ this.showStream(event.stream.id, true, false);
+ }
+
+ function onIceCandidate(event) {
+ if(event.candidate) {
+ this.addIceCandidate(event.candidate,
+ onAddIceCandidateSuccess, test.fail);
+ };
+
+ function onAddIceCandidateSuccess() {
+ test.log("Candidate added successfully");
+ };
+ }
+
+ function createOfferAndAnswer(pc1, pc2) {
+ test.log("Creating offer.");
+ pc1.createOffer(gotOffer, test.fail);
+
+ function gotOffer(offer) {
+ test.log("Got offer");
+ pc1.setLocalDescription(offer, onSetSessionDescriptionSuccess, test.fail);
+ pc2.setRemoteDescription(offer, onSetSessionDescriptionSuccess,
+ test.fail);
+ test.log("Creating answer");
+ pc2.createAnswer(gotAnswer, test.fail);
+ }
+
+ function gotAnswer(answer) {
+ test.log("Got answer");
+ pc2.setLocalDescription(answer, onSetSessionDescriptionSuccess,
+ test.fail);
+ pc1.setRemoteDescription(answer, onSetSessionDescriptionSuccess,
+ test.fail);
+
+ answersCount++;
+ if(answersCount == 3) {
+ // SetTimeout used because creating the three answers will very fast
+ // and test will success and the vm will be closed before establishing
+ // the calls.
+ setTimeout(function() {
+ test.done();
+ }, 5000);
+ }
+ }
+
+ function onSetSessionDescriptionSuccess() {
+ test.log("Set session description success.");
+ }
+ }
+}
+
+registerBotTest('threeBotsVideoConference/android+android+chrome',
+ testTwoWayVideoStreaming, ['android-chrome', 'android-chrome',
+ 'chrome']);
+registerBotTest('threeBotsVideoConference/chrome-chrome-chrome',
+ testTwoWayVideoStreaming, ['chrome', 'chrome', 'chrome']);
+registerBotTest('threeBotsVideoConference/android-android-android',
+ testTwoWayVideoStreaming, ['android-chrome', 'android-chrome',
+ 'android-chrome']); \ No newline at end of file
diff --git a/tools/rtcbot/test/two_way_video_streaming.js b/tools/rtcbot/test/two_way_video_streaming.js
new file mode 100644
index 00000000..7b02dce4
--- /dev/null
+++ b/tools/rtcbot/test/two_way_video_streaming.js
@@ -0,0 +1,112 @@
+// 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.
+//
+// A two way video and audio flowing test between bot 1 and bot 2.
+// The test succeeds after collecting stats for 10 seconds from both bots
+// and then write these stats to a file.
+//
+// Note: the source of the video and audio stream is getUserMedia().
+function testTwoWayVideoStreaming(test, bot1, bot2) {
+ var report = test.createStatisticsReport("two_way_video_streaming");
+ var statsCollector;
+
+ test.wait([
+ createPeerConnectionWithLocalStream.bind(bot1),
+ createPeerConnectionWithLocalStream.bind(bot2)],
+ onPeerConnectionCreated);
+
+ function createPeerConnectionWithLocalStream(done) {
+ this.getUserMedia({video:true, audio:true},
+ onUserMediaSuccess.bind(this), test.fail);
+
+ function onUserMediaSuccess(stream) {
+ test.log("User has granted access to local media.");
+ test.createTurnConfig(onTurnConfig.bind(this), test.fail);
+
+ function onTurnConfig(config) {
+ this.createPeerConnection(config, addAndShowStream.bind(this),
+ test.fail);
+ };
+
+ function addAndShowStream(pc) {
+ pc.addStream(stream);
+ this.showStream(stream.id, true, true);
+
+ done(pc);
+ }
+ }
+ }
+
+ function onPeerConnectionCreated(pc1, pc2) {
+ test.log("RTC Peers created.");
+ pc1.addEventListener('addstream', onAddStream.bind(bot1));
+ pc2.addEventListener('addstream', onAddStream.bind(bot2));
+ pc1.addEventListener('icecandidate', onIceCandidate.bind(pc2));
+ pc2.addEventListener('icecandidate', onIceCandidate.bind(pc1));
+
+ createOfferAndAnswer(pc1, pc2);
+ }
+
+ function onAddStream(event) {
+ test.log("On Add stream.");
+ this.showStream(event.stream.id, true, false);
+ }
+
+ function onIceCandidate(event) {
+ if(event.candidate) {
+ test.log(event.candidate.candidate);
+ this.addIceCandidate(event.candidate,
+ onAddIceCandidateSuccess, test.fail);
+ };
+
+ function onAddIceCandidateSuccess() {
+ test.log("Candidate added successfully");
+ };
+ }
+
+ function createOfferAndAnswer(pc1, pc2) {
+ test.log("Creating offer.");
+ pc1.createOffer(gotOffer, test.fail);
+
+ function gotOffer(offer) {
+ test.log("Got offer");
+ pc1.setLocalDescription(offer, onSetSessionDescriptionSuccess, test.fail);
+ pc2.setRemoteDescription(offer, onSetSessionDescriptionSuccess,
+ test.fail);
+ test.log("Creating answer");
+ pc2.createAnswer(gotAnswer, test.fail);
+ }
+
+ function gotAnswer(answer) {
+ test.log("Got answer");
+ pc2.setLocalDescription(answer, onSetSessionDescriptionSuccess,
+ test.fail);
+ pc1.setRemoteDescription(answer, onSetSessionDescriptionSuccess,
+ test.fail);
+ collectStats();
+ }
+
+ function onSetSessionDescriptionSuccess() {
+ test.log("Set session description success.");
+ }
+
+ function collectStats() {
+ report.collectStatsFromPeerConnection("bot1", pc1);
+ report.collectStatsFromPeerConnection("bot2", pc2);
+
+ setTimeout(function() {
+ report.finish(test.done);
+ }, 10000);
+ }
+ }
+}
+
+registerBotTest('testTwoWayVideo/android-android',
+ testTwoWayVideoStreaming, ['android-chrome', 'android-chrome']);
+registerBotTest('testTwoWayVideo/chrome-chrome',
+ testTwoWayVideoStreaming, ['chrome', 'chrome']); \ No newline at end of file
diff --git a/tools/rtcbot/test/webrtc_video_streaming.js b/tools/rtcbot/test/webrtc_video_streaming.js
index 60df68ec..6518c20e 100644
--- a/tools/rtcbot/test/webrtc_video_streaming.js
+++ b/tools/rtcbot/test/webrtc_video_streaming.js
@@ -20,7 +20,7 @@ function testOneWayVideo(test, bot1, bot2) {
onPeerConnectionCreated);
function createPeerConnection(done) {
- test.createTurnConfig(onTrunConfig.bind(this), test.fail);
+ test.createTurnConfig(onTurnConfig.bind(this), test.fail);
function onTurnConfig(config) {
this.createPeerConnection(config, done, test.fail);
diff --git a/tools/tools.gyp b/tools/tools.gyp
index 38a19fc8..102ba8ec 100644
--- a/tools/tools.gyp
+++ b/tools/tools.gyp
@@ -91,7 +91,7 @@
'type': 'executable',
'dependencies': [
'<(webrtc_root)/voice_engine/voice_engine.gyp:voice_engine',
- '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default',
+ '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers_default',
],
'sources': [
'force_mic_volume_max/force_mic_volume_max.cc',
@@ -107,7 +107,7 @@
'dependencies': [
'<(webrtc_root)/test/test.gyp:channel_transport',
'<(webrtc_root)/voice_engine/voice_engine.gyp:voice_engine',
- '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default',
+ '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers_default',
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
],
@@ -165,7 +165,6 @@
],
'includes': [
'../build/isolate.gypi',
- 'tools_unittests.isolate',
],
'sources': [
'tools_unittests.isolate',
diff --git a/tools/tools_unittests.isolate b/tools/tools_unittests.isolate
index 18065749..bf1fd019 100644
--- a/tools/tools_unittests.isolate
+++ b/tools/tools_unittests.isolate
@@ -9,7 +9,7 @@
'conditions': [
['OS=="android"', {
'variables': {
- 'isolate_dependency_untracked': [
+ 'files': [
'<(DEPTH)/data/',
'<(DEPTH)/resources/',
],
@@ -21,15 +21,12 @@
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/tools_unittests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'<(DEPTH)/DEPS',
'<(DEPTH)/resources/foreman_cif.yuv',
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/tools_unittests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_untracked': [
- '<(DEPTH)/tools/swarming_client/',
- ],
},
}],
],
diff --git a/video/bitrate_estimator_tests.cc b/video/bitrate_estimator_tests.cc
index cb7c391e..29fb7300 100644
--- a/video/bitrate_estimator_tests.cc
+++ b/video/bitrate_estimator_tests.cc
@@ -151,11 +151,7 @@ class BitrateEstimatorTest : public test::CallTest {
encoder_config_.streams = test::CreateVideoStreams(1);
receive_config_ = VideoReceiveStream::Config();
- assert(receive_config_.codecs.empty());
- VideoCodec codec =
- test::CreateDecoderVideoCodec(send_config_.encoder_settings);
- receive_config_.codecs.push_back(codec);
- // receive_config_.external_decoders will be set by every stream separately.
+ // receive_config_.decoders will be set by every stream separately.
receive_config_.rtp.remote_ssrc = send_config_.rtp.ssrcs[0];
receive_config_.rtp.local_ssrc = kReceiverLocalSsrc;
receive_config_.rtp.extensions.push_back(
@@ -206,12 +202,13 @@ class BitrateEstimatorTest : public test::CallTest {
send_stream_->Start();
frame_generator_capturer_->Start();
- ExternalVideoDecoder decoder;
+ VideoReceiveStream::Decoder decoder;
decoder.decoder = &fake_decoder_;
decoder.payload_type = test_->send_config_.encoder_settings.payload_type;
+ decoder.payload_name = test_->send_config_.encoder_settings.payload_name;
+ test_->receive_config_.decoders.push_back(decoder);
test_->receive_config_.rtp.remote_ssrc = test_->send_config_.rtp.ssrcs[0];
test_->receive_config_.rtp.local_ssrc++;
- test_->receive_config_.external_decoders.push_back(decoder);
receive_stream_ = test_->receiver_call_->CreateVideoReceiveStream(
test_->receive_config_);
receive_stream_->Start();
diff --git a/video/call.cc b/video/call.cc
index f37e5387..fd41d75f 100644
--- a/video/call.cc
+++ b/video/call.cc
@@ -20,6 +20,7 @@
#include "webrtc/config.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
+#include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/rw_lock_wrapper.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
@@ -46,6 +47,17 @@ VideoEncoder* VideoEncoder::Create(VideoEncoder::EncoderType codec_type) {
switch (codec_type) {
case kVp8:
return VP8Encoder::Create();
+ case kVp9:
+ return VP9Encoder::Create();
+ }
+ assert(false);
+ return NULL;
+}
+
+VideoDecoder* VideoDecoder::Create(VideoDecoder::DecoderType codec_type) {
+ switch (codec_type) {
+ case kVp8:
+ return VP8Decoder::Create();
}
assert(false);
return NULL;
diff --git a/video/call_perf_tests.cc b/video/call_perf_tests.cc
index f42e5dd0..9776fb7e 100644
--- a/video/call_perf_tests.cc
+++ b/video/call_perf_tests.cc
@@ -543,9 +543,9 @@ void CallPerfTest::TestMinTransmitBitrate(bool pad_to_min_bitrate) {
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) OVERRIDE {
if (pad_to_min_bitrate_) {
- send_config->rtp.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
+ encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
} else {
- assert(send_config->rtp.min_transmit_bitrate_bps == 0);
+ assert(encoder_config->min_transmit_bitrate_bps == 0);
}
}
@@ -570,4 +570,92 @@ TEST_F(CallPerfTest, NoPadWithoutMinTransmitBitrate) {
TestMinTransmitBitrate(false);
}
+TEST_F(CallPerfTest, KeepsHighBitrateWhenReconfiguringSender) {
+ static const uint32_t kInitialBitrateKbps = 400;
+ static const uint32_t kReconfigureThresholdKbps = 600;
+ static const uint32_t kPermittedReconfiguredBitrateDiffKbps = 100;
+
+ class BitrateObserver : public test::EndToEndTest, public test::FakeEncoder {
+ public:
+ BitrateObserver()
+ : EndToEndTest(kDefaultTimeoutMs),
+ FakeEncoder(Clock::GetRealTimeClock()),
+ time_to_reconfigure_(webrtc::EventWrapper::Create()),
+ encoder_inits_(0) {}
+
+ virtual int32_t InitEncode(const VideoCodec* config,
+ int32_t number_of_cores,
+ uint32_t max_payload_size) OVERRIDE {
+ if (encoder_inits_ == 0) {
+ EXPECT_EQ(kInitialBitrateKbps, config->startBitrate)
+ << "Encoder not initialized at expected bitrate.";
+ }
+ ++encoder_inits_;
+ if (encoder_inits_ == 2) {
+ EXPECT_GE(last_set_bitrate_, kReconfigureThresholdKbps);
+ EXPECT_NEAR(config->startBitrate,
+ last_set_bitrate_,
+ kPermittedReconfiguredBitrateDiffKbps)
+ << "Encoder reconfigured with bitrate too far away from last set.";
+ observation_complete_->Set();
+ }
+ return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
+ }
+
+ virtual int32_t SetRates(uint32_t new_target_bitrate_kbps,
+ uint32_t framerate) OVERRIDE {
+ last_set_bitrate_ = new_target_bitrate_kbps;
+ if (encoder_inits_ == 1 &&
+ new_target_bitrate_kbps > kReconfigureThresholdKbps) {
+ time_to_reconfigure_->Set();
+ }
+ return FakeEncoder::SetRates(new_target_bitrate_kbps, framerate);
+ }
+
+ Call::Config GetSenderCallConfig() OVERRIDE {
+ Call::Config config = EndToEndTest::GetSenderCallConfig();
+ config.stream_start_bitrate_bps = kInitialBitrateKbps * 1000;
+ return config;
+ }
+
+ virtual void ModifyConfigs(
+ VideoSendStream::Config* send_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
+ VideoEncoderConfig* encoder_config) OVERRIDE {
+ send_config->encoder_settings.encoder = this;
+ encoder_config->streams[0].min_bitrate_bps = 50000;
+ encoder_config->streams[0].target_bitrate_bps =
+ encoder_config->streams[0].max_bitrate_bps = 2000000;
+
+ encoder_config_ = *encoder_config;
+ }
+
+ virtual void OnStreamsCreated(
+ VideoSendStream* send_stream,
+ const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE {
+ send_stream_ = send_stream;
+ }
+
+ virtual void PerformTest() OVERRIDE {
+ ASSERT_EQ(kEventSignaled, time_to_reconfigure_->Wait(kDefaultTimeoutMs))
+ << "Timed out before receiving an initial high bitrate.";
+ encoder_config_.streams[0].width *= 2;
+ encoder_config_.streams[0].height *= 2;
+ EXPECT_TRUE(send_stream_->ReconfigureVideoEncoder(encoder_config_));
+ EXPECT_EQ(kEventSignaled, Wait())
+ << "Timed out while waiting for a couple of high bitrate estimates "
+ "after reconfiguring the send stream.";
+ }
+
+ private:
+ scoped_ptr<webrtc::EventWrapper> time_to_reconfigure_;
+ int encoder_inits_;
+ uint32_t last_set_bitrate_;
+ VideoSendStream* send_stream_;
+ VideoEncoderConfig encoder_config_;
+ } test;
+
+ RunBaseTest(&test);
+}
+
} // namespace webrtc
diff --git a/video/end_to_end_tests.cc b/video/end_to_end_tests.cc
index 0e87a033..96249c3c 100644
--- a/video/end_to_end_tests.cc
+++ b/video/end_to_end_tests.cc
@@ -19,6 +19,9 @@
#include "webrtc/call.h"
#include "webrtc/frame_callback.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
+#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
+#include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
+#include "webrtc/modules/video_coding/main/interface/video_coding_defines.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/event_wrapper.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
@@ -222,6 +225,57 @@ TEST_F(EndToEndTest, TransmitsFirstFrame) {
DestroyStreams();
}
+// TODO(marpan): Re-enable this test on the next libvpx roll.
+TEST_F(EndToEndTest, DISABLED_SendsAndReceivesVP9) {
+ class VP9Observer : public test::EndToEndTest, public VideoRenderer {
+ public:
+ VP9Observer()
+ : EndToEndTest(2 * kDefaultTimeoutMs),
+ encoder_(VideoEncoder::Create(VideoEncoder::kVp9)),
+ decoder_(VP9Decoder::Create()),
+ frame_counter_(0) {}
+
+ virtual void PerformTest() OVERRIDE {
+ EXPECT_EQ(kEventSignaled, Wait())
+ << "Timed out while waiting for enough frames to be decoded.";
+ }
+
+ virtual void ModifyConfigs(
+ VideoSendStream::Config* send_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
+ VideoEncoderConfig* encoder_config) OVERRIDE {
+ send_config->encoder_settings.encoder = encoder_.get();
+ send_config->encoder_settings.payload_name = "VP9";
+ send_config->encoder_settings.payload_type = VCM_VP9_PAYLOAD_TYPE;
+ encoder_config->streams[0].min_bitrate_bps = 50000;
+ encoder_config->streams[0].target_bitrate_bps =
+ encoder_config->streams[0].max_bitrate_bps = 2000000;
+
+ (*receive_configs)[0].renderer = this;
+ (*receive_configs)[0].decoders.resize(1);
+ (*receive_configs)[0].decoders[0].payload_type =
+ send_config->encoder_settings.payload_type;
+ (*receive_configs)[0].decoders[0].payload_name =
+ send_config->encoder_settings.payload_name;
+ (*receive_configs)[0].decoders[0].decoder = decoder_.get();
+ }
+
+ virtual void RenderFrame(const I420VideoFrame& video_frame,
+ int time_to_render_ms) OVERRIDE {
+ const int kRequiredFrames = 500;
+ if (++frame_counter_ == kRequiredFrames)
+ observation_complete_->Set();
+ }
+
+ private:
+ scoped_ptr<webrtc::VideoEncoder> encoder_;
+ scoped_ptr<webrtc::VideoDecoder> decoder_;
+ int frame_counter_;
+ } test;
+
+ RunBaseTest(&test);
+}
+
TEST_F(EndToEndTest, SendsAndReceivesH264) {
class H264Observer : public test::EndToEndTest, public VideoRenderer {
public:
@@ -247,14 +301,12 @@ TEST_F(EndToEndTest, SendsAndReceivesH264) {
encoder_config->streams[0].max_bitrate_bps = 2000000;
(*receive_configs)[0].renderer = this;
- VideoCodec codec =
- test::CreateDecoderVideoCodec(send_config->encoder_settings);
- (*receive_configs)[0].codecs.resize(1);
- (*receive_configs)[0].codecs[0] = codec;
- (*receive_configs)[0].external_decoders.resize(1);
- (*receive_configs)[0].external_decoders[0].payload_type =
+ (*receive_configs)[0].decoders.resize(1);
+ (*receive_configs)[0].decoders[0].payload_type =
send_config->encoder_settings.payload_type;
- (*receive_configs)[0].external_decoders[0].decoder = &fake_decoder_;
+ (*receive_configs)[0].decoders[0].payload_name =
+ send_config->encoder_settings.payload_name;
+ (*receive_configs)[0].decoders[0].decoder = &fake_decoder_;
}
virtual void RenderFrame(const I420VideoFrame& video_frame,
@@ -977,6 +1029,7 @@ TEST_F(EndToEndTest, SendsAndReceivesMultipleStreams) {
for (size_t i = 0; i < kNumStreams; ++i)
encoders[i].reset(VideoEncoder::Create(VideoEncoder::kVp8));
+ ScopedVector<VideoDecoder> allocated_decoders;
for (size_t i = 0; i < kNumStreams; ++i) {
uint32_t ssrc = codec_settings[i].ssrc;
int width = codec_settings[i].width;
@@ -1004,9 +1057,10 @@ TEST_F(EndToEndTest, SendsAndReceivesMultipleStreams) {
receive_config.renderer = observers[i];
receive_config.rtp.remote_ssrc = ssrc;
receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
- VideoCodec codec =
- test::CreateDecoderVideoCodec(send_config.encoder_settings);
- receive_config.codecs.push_back(codec);
+ VideoReceiveStream::Decoder decoder =
+ test::CreateMatchingDecoder(send_config.encoder_settings);
+ allocated_decoders.push_back(decoder.decoder);
+ receive_config.decoders.push_back(decoder);
receive_streams[i] =
receiver_call->CreateVideoReceiveStream(receive_config);
receive_streams[i]->Start();
@@ -1653,15 +1707,16 @@ TEST_F(EndToEndTest, DISABLED_RedundantPayloadsTransmittedOnAllSsrcs) {
encoder_config->streams[i].target_bitrate_bps = 15000;
encoder_config->streams[i].max_bitrate_bps = 20000;
}
- // Significantly higher than max bitrates for all video streams -> forcing
- // padding to trigger redundant padding on all RTX SSRCs.
- send_config->rtp.min_transmit_bitrate_bps = 100000;
send_config->rtp.rtx.payload_type = kSendRtxPayloadType;
send_config->rtp.rtx.pad_with_redundant_payloads = true;
for (size_t i = 0; i < kNumSsrcs; ++i)
send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[i]);
+
+ // Significantly higher than max bitrates for all video streams -> forcing
+ // padding to trigger redundant padding on all RTX SSRCs.
+ encoder_config->min_transmit_bitrate_bps = 100000;
}
virtual void PerformTest() OVERRIDE {
@@ -1791,6 +1846,19 @@ void EndToEndTest::TestRtpStatePreservation(bool use_rtx) {
encoder_config_.streams[i].max_bitrate_bps = 20000;
}
+ // Use the same total bitrates when sending a single stream to avoid lowering
+ // the bitrate estimate and requiring a subsequent rampup.
+ VideoEncoderConfig one_stream = encoder_config_;
+ one_stream.streams.resize(1);
+ for (size_t i = 1; i < encoder_config_.streams.size(); ++i) {
+ one_stream.streams.front().min_bitrate_bps +=
+ encoder_config_.streams[i].min_bitrate_bps;
+ one_stream.streams.front().target_bitrate_bps +=
+ encoder_config_.streams[i].target_bitrate_bps;
+ one_stream.streams.front().max_bitrate_bps +=
+ encoder_config_.streams[i].max_bitrate_bps;
+ }
+
CreateMatchingReceiveConfigs();
CreateStreams();
@@ -1807,8 +1875,6 @@ void EndToEndTest::TestRtpStatePreservation(bool use_rtx) {
sender_call_->DestroyVideoSendStream(send_stream_);
// Re-create VideoSendStream with only one stream.
- VideoEncoderConfig one_stream = encoder_config_;
- one_stream.streams.resize(1);
send_stream_ =
sender_call_->CreateVideoSendStream(send_config_, one_stream);
send_stream_->Start();
@@ -2074,4 +2140,39 @@ TEST_F(EndToEndTest, NewReceiveStreamsRespectNetworkDown) {
DestroyStreams();
}
+
+// TODO(pbos): Remove this regression test when VideoEngine is no longer used as
+// a backend. This is to test that we hand channels back properly.
+TEST_F(EndToEndTest, CanCreateAndDestroyManyVideoStreams) {
+ test::NullTransport transport;
+ scoped_ptr<Call> call(Call::Create(Call::Config(&transport)));
+ test::FakeDecoder fake_decoder;
+ test::FakeEncoder fake_encoder(Clock::GetRealTimeClock());
+ for (size_t i = 0; i < 100; ++i) {
+ VideoSendStream::Config send_config;
+ send_config.encoder_settings.encoder = &fake_encoder;
+ send_config.encoder_settings.payload_name = "FAKE";
+ send_config.encoder_settings.payload_type = 123;
+
+ VideoEncoderConfig encoder_config;
+ encoder_config.streams = test::CreateVideoStreams(1);
+ send_config.rtp.ssrcs.push_back(1);
+ VideoSendStream* send_stream =
+ call->CreateVideoSendStream(send_config, encoder_config);
+ call->DestroyVideoSendStream(send_stream);
+
+ VideoReceiveStream::Config receive_config;
+ receive_config.rtp.remote_ssrc = 1;
+ receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
+ VideoReceiveStream::Decoder decoder;
+ decoder.decoder = &fake_decoder;
+ decoder.payload_type = 123;
+ decoder.payload_name = "FAKE";
+ receive_config.decoders.push_back(decoder);
+ VideoReceiveStream* receive_stream =
+ call->CreateVideoReceiveStream(receive_config);
+ call->DestroyVideoReceiveStream(receive_stream);
+ }
+}
+
} // namespace webrtc
diff --git a/video/full_stack.cc b/video/full_stack.cc
index 0c3ea789..25e60eb8 100644
--- a/video/full_stack.cc
+++ b/video/full_stack.cc
@@ -360,8 +360,8 @@ class VideoAnalyzer : public PacketReceiver,
std::map<uint32_t, int64_t> send_times_ GUARDED_BY(crit_);
std::map<uint32_t, int64_t> recv_times_ GUARDED_BY(crit_);
I420VideoFrame* first_send_frame_ GUARDED_BY(crit_);
- double avg_psnr_threshold_ GUARDED_BY(crit_);
- double avg_ssim_threshold_ GUARDED_BY(crit_);
+ const double avg_psnr_threshold_;
+ const double avg_ssim_threshold_;
const scoped_ptr<CriticalSectionWrapper> comparison_lock_;
const scoped_ptr<ThreadWrapper> comparison_thread_;
diff --git a/video/loopback.cc b/video/loopback.cc
index ffc5bcc5..4b49c31e 100644
--- a/video/loopback.cc
+++ b/video/loopback.cc
@@ -22,13 +22,18 @@
#include "webrtc/test/direct_transport.h"
#include "webrtc/test/encoder_settings.h"
#include "webrtc/test/fake_encoder.h"
+#include "webrtc/test/field_trial.h"
#include "webrtc/test/run_loop.h"
#include "webrtc/test/run_test.h"
+#include "webrtc/test/testsupport/trace_to_stderr.h"
#include "webrtc/test/video_capturer.h"
#include "webrtc/test/video_renderer.h"
#include "webrtc/typedefs.h"
namespace webrtc {
+
+static const int kAbsSendTimeExtensionId = 7;
+
namespace flags {
DEFINE_int32(width, 640, "Video width.");
@@ -82,6 +87,16 @@ DEFINE_int32(std_propagation_delay_ms,
int StdPropagationDelayMs() {
return static_cast<int>(FLAGS_std_propagation_delay_ms);
}
+
+DEFINE_bool(logs, false, "print logs to stderr");
+
+DEFINE_string(
+ force_fieldtrials,
+ "",
+ "Field trials control experimental feature code which can be forced. "
+ "E.g. running with --force_fieldtrials=WebRTC-FooFeature/Enable/"
+ " will assign the group Enable to field trial WebRTC-FooFeature. Multiple "
+ "trials are separated by \"/\"");
} // namespace flags
static const uint32_t kSendSsrc = 0x654321;
@@ -91,6 +106,10 @@ static const uint32_t kReceiverLocalSsrc = 0x123456;
static const uint8_t kRtxPayloadType = 96;
void Loopback() {
+ scoped_ptr<test::TraceToStderr> trace_to_stderr_;
+ if (webrtc::flags::FLAGS_logs)
+ trace_to_stderr_.reset(new test::TraceToStderr);
+
scoped_ptr<test::VideoRenderer> local_preview(test::VideoRenderer::Create(
"Local Preview", flags::Width(), flags::Height()));
scoped_ptr<test::VideoRenderer> loopback_video(test::VideoRenderer::Create(
@@ -116,6 +135,8 @@ void Loopback() {
send_config.rtp.rtx.ssrcs.push_back(kSendRtxSsrc);
send_config.rtp.rtx.payload_type = kRtxPayloadType;
send_config.rtp.nack.rtp_history_ms = 1000;
+ send_config.rtp.extensions.push_back(
+ RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId));
send_config.local_renderer = local_preview.get();
scoped_ptr<VideoEncoder> encoder;
@@ -158,10 +179,12 @@ void Loopback() {
receive_config.rtp.nack.rtp_history_ms = 1000;
receive_config.rtp.rtx[kRtxPayloadType].ssrc = kSendRtxSsrc;
receive_config.rtp.rtx[kRtxPayloadType].payload_type = kRtxPayloadType;
+ receive_config.rtp.extensions.push_back(
+ RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId));
receive_config.renderer = loopback_video.get();
- VideoCodec codec =
- test::CreateDecoderVideoCodec(send_config.encoder_settings);
- receive_config.codecs.push_back(codec);
+ VideoReceiveStream::Decoder decoder =
+ test::CreateMatchingDecoder(send_config.encoder_settings);
+ receive_config.decoders.push_back(decoder);
VideoReceiveStream* receive_stream =
call->CreateVideoReceiveStream(receive_config);
@@ -179,6 +202,8 @@ void Loopback() {
call->DestroyVideoReceiveStream(receive_stream);
call->DestroyVideoSendStream(send_stream);
+ delete decoder.decoder;
+
transport.StopSending();
}
} // namespace webrtc
@@ -186,7 +211,8 @@ void Loopback() {
int main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
google::ParseCommandLineFlags(&argc, &argv, true);
-
+ webrtc::test::InitFieldTrialsFromString(
+ webrtc::flags::FLAGS_force_fieldtrials);
webrtc::test::RunTest(webrtc::Loopback);
return 0;
}
diff --git a/video/rampup_tests.cc b/video/rampup_tests.cc
index 96a22763..011ef6af 100644
--- a/video/rampup_tests.cc
+++ b/video/rampup_tests.cc
@@ -154,7 +154,9 @@ bool StreamObserver::SendRtcp(const uint8_t* packet, size_t length) {
return true;
}
-EventTypeWrapper StreamObserver::Wait() { return test_done_->Wait(120 * 1000); }
+EventTypeWrapper StreamObserver::Wait() {
+ return test_done_->Wait(test::CallTest::kLongTimeoutMs);
+}
void StreamObserver::ReportResult(const std::string& measurement,
size_t value,
diff --git a/video/replay.cc b/video/replay.cc
index 3d2689ea..5cfb06f8 100644
--- a/video/replay.cc
+++ b/video/replay.cc
@@ -30,6 +30,7 @@
#include "webrtc/test/video_capturer.h"
#include "webrtc/test/video_renderer.h"
#include "webrtc/typedefs.h"
+#include "webrtc/video_decoder.h"
namespace webrtc {
namespace flags {
@@ -212,8 +213,9 @@ void RtpReplay() {
VideoSendStream::Config::EncoderSettings encoder_settings;
encoder_settings.payload_name = flags::Codec();
encoder_settings.payload_type = flags::PayloadType();
- VideoCodec codec = test::CreateDecoderVideoCodec(encoder_settings);
- receive_config.codecs.push_back(codec);
+ VideoReceiveStream::Decoder decoder =
+ test::CreateMatchingDecoder(encoder_settings);
+ receive_config.decoders.push_back(decoder);
VideoReceiveStream* receive_stream =
call->CreateVideoReceiveStream(receive_config);
@@ -271,6 +273,8 @@ void RtpReplay() {
}
call->DestroyVideoReceiveStream(receive_stream);
+
+ delete decoder.decoder;
}
} // namespace webrtc
diff --git a/video/video_receive_stream.cc b/video/video_receive_stream.cc
index 41a800fa..5b085bb8 100644
--- a/video/video_receive_stream.cc
+++ b/video/video_receive_stream.cc
@@ -19,6 +19,7 @@
#include "webrtc/system_wrappers/interface/clock.h"
#include "webrtc/system_wrappers/interface/logging.h"
#include "webrtc/video/receive_statistics_proxy.h"
+#include "webrtc/video_encoder.h"
#include "webrtc/video_engine/include/vie_base.h"
#include "webrtc/video_engine/include/vie_capture.h"
#include "webrtc/video_engine/include/vie_codec.h"
@@ -31,6 +32,35 @@
namespace webrtc {
namespace internal {
+namespace {
+VideoCodec CreateDecoderVideoCodec(const VideoReceiveStream::Decoder& decoder) {
+ VideoCodec codec;
+ memset(&codec, 0, sizeof(codec));
+
+ codec.plType = decoder.payload_type;
+ strcpy(codec.plName, decoder.payload_name.c_str());
+ if (decoder.payload_name == "VP8") {
+ codec.codecType = kVideoCodecVP8;
+ } else if (decoder.payload_name == "H264") {
+ codec.codecType = kVideoCodecH264;
+ } else {
+ codec.codecType = kVideoCodecGeneric;
+ }
+
+ if (codec.codecType == kVideoCodecVP8) {
+ codec.codecSpecific.VP8 = VideoEncoder::GetDefaultVp8Settings();
+ } else if (codec.codecType == kVideoCodecH264) {
+ codec.codecSpecific.H264 = VideoEncoder::GetDefaultH264Settings();
+ }
+
+ codec.width = 320;
+ codec.height = 180;
+ codec.startBitrate = codec.minBitrate = codec.maxBitrate =
+ Call::Config::kDefaultStartBitrateBps / 1000;
+
+ return codec;
+}
+} // namespace
VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine,
const VideoReceiveStream::Config& config,
@@ -118,15 +148,6 @@ VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine,
}
}
- assert(!config_.codecs.empty());
- for (size_t i = 0; i < config_.codecs.size(); ++i) {
- if (codec_->SetReceiveCodec(channel_, config_.codecs[i]) != 0) {
- // TODO(pbos): Abort gracefully, this can be a runtime error.
- // Factor out to an Init() method.
- abort();
- }
- }
-
stats_proxy_.reset(new ReceiveStatisticsProxy(
config_.rtp.local_ssrc, clock_, rtp_rtcp_, codec_, channel_));
@@ -142,8 +163,9 @@ VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine,
abort();
external_codec_ = ViEExternalCodec::GetInterface(video_engine);
- for (size_t i = 0; i < config_.external_decoders.size(); ++i) {
- const ExternalVideoDecoder& decoder = config_.external_decoders[i];
+ assert(!config_.decoders.empty());
+ for (size_t i = 0; i < config_.decoders.size(); ++i) {
+ const Decoder& decoder = config_.decoders[i];
if (external_codec_->RegisterExternalReceiveCodec(
channel_,
decoder.payload_type,
@@ -153,6 +175,14 @@ VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine,
// TODO(pbos): Abort gracefully? Can this be a runtime error?
abort();
}
+
+ VideoCodec codec = CreateDecoderVideoCodec(decoder);
+
+ if (codec_->SetReceiveCodec(channel_, codec) != 0) {
+ // TODO(pbos): Abort gracefully, this can be a runtime error.
+ // Factor out to an Init() method.
+ abort();
+ }
}
render_ = ViERender::GetInterface(video_engine);
@@ -160,7 +190,7 @@ VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine,
render_->AddRenderCallback(channel_, this);
- if (voice_engine) {
+ if (voice_engine && config_.audio_channel_id != -1) {
video_engine_base_->SetVoiceEngine(voice_engine);
video_engine_base_->ConnectAudioChannel(channel_, config_.audio_channel_id);
}
@@ -183,16 +213,15 @@ VideoReceiveStream::~VideoReceiveStream() {
render_->RemoveRenderer(channel_);
- for (size_t i = 0; i < config_.external_decoders.size(); ++i) {
+ for (size_t i = 0; i < config_.decoders.size(); ++i) {
external_codec_->DeRegisterExternalReceiveCodec(
- channel_, config_.external_decoders[i].payload_type);
+ channel_, config_.decoders[i].payload_type);
}
network_->DeregisterSendTransport(channel_);
video_engine_base_->SetVoiceEngine(NULL);
image_process_->Release();
- video_engine_base_->Release();
external_codec_->Release();
codec_->DeregisterDecoderObserver(channel_);
rtp_rtcp_->DeregisterReceiveChannelRtpStatisticsCallback(channel_,
@@ -203,6 +232,8 @@ VideoReceiveStream::~VideoReceiveStream() {
network_->Release();
render_->Release();
rtp_rtcp_->Release();
+ video_engine_base_->DeleteChannel(channel_);
+ video_engine_base_->Release();
}
void VideoReceiveStream::Start() {
@@ -225,10 +256,6 @@ VideoReceiveStream::Stats VideoReceiveStream::GetStats() const {
return stats_proxy_->GetStats();
}
-void VideoReceiveStream::GetCurrentReceiveCodec(VideoCodec* receive_codec) {
- // TODO(pbos): Implement
-}
-
bool VideoReceiveStream::DeliverRtcp(const uint8_t* packet, size_t length) {
return network_->ReceivedRTCPPacket(
channel_, packet, static_cast<int>(length)) == 0;
diff --git a/video/video_receive_stream.h b/video/video_receive_stream.h
index 68948287..2aa39e23 100644
--- a/video/video_receive_stream.h
+++ b/video/video_receive_stream.h
@@ -53,8 +53,6 @@ class VideoReceiveStream : public webrtc::VideoReceiveStream,
virtual void Stop() OVERRIDE;
virtual Stats GetStats() const OVERRIDE;
- virtual void GetCurrentReceiveCodec(VideoCodec* receive_codec) OVERRIDE;
-
// Overrides I420FrameCallback.
virtual void FrameCallback(I420VideoFrame* video_frame) OVERRIDE;
diff --git a/video/video_send_stream.cc b/video/video_send_stream.cc
index 6e8f2381..28231b00 100644
--- a/video/video_send_stream.cc
+++ b/video/video_send_stream.cc
@@ -66,8 +66,6 @@ std::string VideoSendStream::Config::Rtp::ToString() const {
ss << '}';
ss << ", max_packet_size: " << max_packet_size;
- if (min_transmit_bitrate_bps != 0)
- ss << ", min_transmit_bitrate_bps: " << min_transmit_bitrate_bps;
ss << ", extensions: {";
for (size_t i = 0; i < extensions.size(); ++i) {
@@ -125,6 +123,7 @@ VideoSendStream::VideoSendStream(
suspended_ssrcs_(suspended_ssrcs),
external_codec_(NULL),
channel_(-1),
+ use_default_bitrate_(true),
stats_proxy_(config) {
video_engine_base_ = ViEBase::GetInterface(video_engine);
video_engine_base_->CreateChannel(channel_, base_channel);
@@ -136,10 +135,6 @@ VideoSendStream::VideoSendStream(
assert(config_.rtp.ssrcs.size() > 0);
- assert(config_.rtp.min_transmit_bitrate_bps >= 0);
- rtp_rtcp_->SetMinTransmitBitrate(channel_,
- config_.rtp.min_transmit_bitrate_bps / 1000);
-
for (size_t i = 0; i < config_.rtp.extensions.size(); ++i) {
const std::string& extension = config_.rtp.extensions[i].name;
int id = config_.rtp.extensions[i].id;
@@ -297,6 +292,7 @@ void VideoSendStream::Stop() {
bool VideoSendStream::ReconfigureVideoEncoder(
const VideoEncoderConfig& config) {
+ LOG(LS_INFO) << "(Re)configureVideoEncoder: " << config.ToString();
const std::vector<VideoStream>& streams = config.streams;
assert(!streams.empty());
assert(config_.rtp.ssrcs.size() >= streams.size());
@@ -305,22 +301,32 @@ bool VideoSendStream::ReconfigureVideoEncoder(
memset(&video_codec, 0, sizeof(video_codec));
if (config_.encoder_settings.payload_name == "VP8") {
video_codec.codecType = kVideoCodecVP8;
+ } else if (config_.encoder_settings.payload_name == "VP9") {
+ video_codec.codecType = kVideoCodecVP9;
} else if (config_.encoder_settings.payload_name == "H264") {
video_codec.codecType = kVideoCodecH264;
} else {
video_codec.codecType = kVideoCodecGeneric;
}
+
switch (config.content_type) {
case VideoEncoderConfig::kRealtimeVideo:
video_codec.mode = kRealtimeVideo;
break;
case VideoEncoderConfig::kScreenshare:
video_codec.mode = kScreensharing;
+ if (config.streams.size() == 1 &&
+ config.streams[0].temporal_layer_thresholds_bps.size() == 1) {
+ video_codec.targetBitrate =
+ config.streams[0].temporal_layer_thresholds_bps[0] / 1000;
+ }
break;
}
if (video_codec.codecType == kVideoCodecVP8) {
video_codec.codecSpecific.VP8 = VideoEncoder::GetDefaultVp8Settings();
+ } else if (video_codec.codecType == kVideoCodecVP9) {
+ video_codec.codecSpecific.VP9 = VideoEncoder::GetDefaultVp9Settings();
} else if (video_codec.codecType == kVideoCodecH264) {
video_codec.codecSpecific.H264 = VideoEncoder::GetDefaultH264Settings();
}
@@ -331,7 +337,8 @@ bool VideoSendStream::ReconfigureVideoEncoder(
config.encoder_specific_settings);
}
video_codec.codecSpecific.VP8.numberOfTemporalLayers =
- static_cast<unsigned char>(streams.back().temporal_layers.size());
+ static_cast<unsigned char>(
+ streams.back().temporal_layer_thresholds_bps.size() + 1);
} else {
// TODO(pbos): Support encoder_settings codec-agnostically.
assert(config.encoder_specific_settings == NULL);
@@ -364,8 +371,8 @@ bool VideoSendStream::ReconfigureVideoEncoder(
sim_stream->targetBitrate = streams[i].target_bitrate_bps / 1000;
sim_stream->maxBitrate = streams[i].max_bitrate_bps / 1000;
sim_stream->qpMax = streams[i].max_qp;
- sim_stream->numberOfTemporalLayers =
- static_cast<unsigned char>(streams[i].temporal_layers.size());
+ sim_stream->numberOfTemporalLayers = static_cast<unsigned char>(
+ streams[i].temporal_layer_thresholds_bps.size() + 1);
video_codec.width = std::max(video_codec.width,
static_cast<unsigned short>(streams[i].width));
@@ -378,8 +385,13 @@ bool VideoSendStream::ReconfigureVideoEncoder(
video_codec.qpMax = std::max(video_codec.qpMax,
static_cast<unsigned int>(streams[i].max_qp));
}
+ unsigned int start_bitrate_bps;
+ if (codec_->GetCodecTargetBitrate(channel_, &start_bitrate_bps) != 0 ||
+ use_default_bitrate_) {
+ start_bitrate_bps = start_bitrate_bps_;
+ }
video_codec.startBitrate =
- static_cast<unsigned int>(start_bitrate_bps_) / 1000;
+ static_cast<unsigned int>(start_bitrate_bps) / 1000;
if (video_codec.minBitrate < kViEMinCodecBitrate)
video_codec.minBitrate = kViEMinCodecBitrate;
@@ -398,7 +410,15 @@ bool VideoSendStream::ReconfigureVideoEncoder(
assert(streams[0].max_framerate > 0);
video_codec.maxFramerate = streams[0].max_framerate;
- return codec_->SetSendCodec(channel_, video_codec) == 0;
+ if (codec_->SetSendCodec(channel_, video_codec) != 0)
+ return false;
+
+ assert(config.min_transmit_bitrate_bps >= 0);
+ rtp_rtcp_->SetMinTransmitBitrate(channel_,
+ config.min_transmit_bitrate_bps / 1000);
+
+ use_default_bitrate_ = false;
+ return true;
}
bool VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) {
diff --git a/video/video_send_stream.h b/video/video_send_stream.h
index 8a77852e..f7874308 100644
--- a/video/video_send_stream.h
+++ b/video/video_send_stream.h
@@ -94,6 +94,11 @@ class VideoSendStream : public webrtc::VideoSendStream,
int channel_;
int capture_id_;
+ // Used as a workaround to indicate that we should be using the configured
+ // start bitrate initially, instead of the one reported by VideoEngine (which
+ // defaults to too high).
+ bool use_default_bitrate_;
+
SendStatisticsProxy stats_proxy_;
};
} // namespace internal
diff --git a/video/video_send_stream_tests.cc b/video/video_send_stream_tests.cc
index 6c2fa39f..b863957b 100644
--- a/video/video_send_stream_tests.cc
+++ b/video/video_send_stream_tests.cc
@@ -201,7 +201,7 @@ TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
virtual void PerformTest() OVERRIDE {
EXPECT_EQ(kEventSignaled, Wait())
- << "Timed out while waiting single RTP packet.";
+ << "Timed out while waiting for a single RTP packet.";
}
class DelayedEncoder : public test::FakeEncoder {
@@ -1075,7 +1075,7 @@ TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) OVERRIDE {
- send_config->rtp.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
+ encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
}
virtual void PerformTest() OVERRIDE {
@@ -1440,8 +1440,8 @@ TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
send_config->encoder_settings.payload_name = "VP8";
for (size_t i = 0; i < encoder_config->streams.size(); ++i) {
- encoder_config->streams[i].temporal_layers.resize(
- kNumberOfTemporalLayers);
+ encoder_config->streams[i].temporal_layer_thresholds_bps.resize(
+ kNumberOfTemporalLayers - 1);
}
encoder_config->encoder_specific_settings = &vp8_settings_;
@@ -1550,4 +1550,44 @@ TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
RunBaseTest(&test);
}
+TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
+ static const int kScreencastTargetBitrateKbps = 200;
+ class ScreencastTargetBitrateTest : public test::SendTest,
+ public test::FakeEncoder {
+ public:
+ ScreencastTargetBitrateTest()
+ : SendTest(kDefaultTimeoutMs),
+ test::FakeEncoder(Clock::GetRealTimeClock()) {}
+
+ private:
+ virtual int32_t InitEncode(const VideoCodec* config,
+ int32_t number_of_cores,
+ uint32_t max_payload_size) {
+ EXPECT_EQ(static_cast<unsigned int>(kScreencastTargetBitrateKbps),
+ config->targetBitrate);
+ observation_complete_->Set();
+ return test::FakeEncoder::InitEncode(
+ config, number_of_cores, max_payload_size);
+ }
+ virtual void ModifyConfigs(
+ VideoSendStream::Config* send_config,
+ std::vector<VideoReceiveStream::Config>* receive_configs,
+ VideoEncoderConfig* encoder_config) OVERRIDE {
+ send_config->encoder_settings.encoder = this;
+ EXPECT_EQ(1u, encoder_config->streams.size());
+ EXPECT_TRUE(
+ encoder_config->streams[0].temporal_layer_thresholds_bps.empty());
+ encoder_config->streams[0].temporal_layer_thresholds_bps.push_back(
+ kScreencastTargetBitrateKbps * 1000);
+ encoder_config->content_type = VideoEncoderConfig::kScreenshare;
+ }
+
+ virtual void PerformTest() OVERRIDE {
+ EXPECT_EQ(kEventSignaled, Wait())
+ << "Timed out while waiting for the encoder to be initialized.";
+ }
+ } test;
+
+ RunBaseTest(&test);
+}
} // namespace webrtc
diff --git a/video_decoder.h b/video_decoder.h
new file mode 100644
index 00000000..03a564e3
--- /dev/null
+++ b/video_decoder.h
@@ -0,0 +1,74 @@
+/*
+ * 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 WEBRTC_VIDEO_DECODER_H_
+#define WEBRTC_VIDEO_DECODER_H_
+
+#include <vector>
+
+#include "webrtc/common_types.h"
+#include "webrtc/typedefs.h"
+#include "webrtc/video_frame.h"
+
+namespace webrtc {
+
+class RTPFragmentationHeader;
+// TODO(pbos): Expose these through a public (root) header or change these APIs.
+struct CodecSpecificInfo;
+struct VideoCodec;
+
+class DecodedImageCallback {
+ public:
+ virtual ~DecodedImageCallback() {}
+
+ virtual int32_t Decoded(I420VideoFrame& decodedImage) = 0;
+ virtual int32_t ReceivedDecodedReferenceFrame(const uint64_t pictureId) {
+ return -1;
+ }
+
+ virtual int32_t ReceivedDecodedFrame(const uint64_t pictureId) { return -1; }
+};
+
+class VideoDecoder {
+ public:
+ enum DecoderType {
+ kVp8,
+ };
+
+ static VideoDecoder* Create(DecoderType codec_type);
+
+ virtual ~VideoDecoder() {}
+
+ virtual int32_t InitDecode(const VideoCodec* codecSettings,
+ int32_t numberOfCores) = 0;
+
+ virtual int32_t Decode(const EncodedImage& inputImage,
+ bool missingFrames,
+ const RTPFragmentationHeader* fragmentation,
+ const CodecSpecificInfo* codecSpecificInfo = NULL,
+ int64_t renderTimeMs = -1) = 0;
+
+ virtual int32_t RegisterDecodeCompleteCallback(
+ DecodedImageCallback* callback) = 0;
+
+ virtual int32_t Release() = 0;
+ virtual int32_t Reset() = 0;
+
+ virtual int32_t SetCodecConfigParameters(const uint8_t* /*buffer*/,
+ int32_t /*size*/) {
+ return -1;
+ }
+
+ virtual VideoDecoder* Copy() { return NULL; }
+};
+
+} // namespace webrtc
+
+#endif // WEBRTC_VIDEO_DECODER_H_
diff --git a/video_encoder.h b/video_encoder.h
index cbdf1ef0..2bf52f3c 100644
--- a/video_encoder.h
+++ b/video_encoder.h
@@ -40,28 +40,84 @@ class VideoEncoder {
public:
enum EncoderType {
kVp8,
+ kVp9,
};
static VideoEncoder* Create(EncoderType codec_type);
static VideoCodecVP8 GetDefaultVp8Settings();
+ static VideoCodecVP9 GetDefaultVp9Settings();
static VideoCodecH264 GetDefaultH264Settings();
virtual ~VideoEncoder() {}
+ // Initialize the encoder with the information from the codecSettings
+ //
+ // Input:
+ // - codec_settings : Codec settings
+ // - 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_LEVEL_EXCEEDED
+ // WEBRTC_VIDEO_CODEC_MEMORY
+ // WEBRTC_VIDEO_CODEC_ERROR
virtual int32_t InitEncode(const VideoCodec* codec_settings,
int32_t number_of_cores,
uint32_t max_payload_size) = 0;
+
+ // 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;
- virtual int32_t Release() = 0;
+ // Free encoder memory.
+ // Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise.
+ virtual int32_t Release() = 0;
+ // Encode an I420 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
+ // WEBRTC_VIDEO_CODEC_TIMEOUT
virtual int32_t Encode(const I420VideoFrame& frame,
const CodecSpecificInfo* codec_specific_info,
const std::vector<VideoFrameType>* frame_types) = 0;
+ // Inform the encoder of the new packet loss rate and the round-trip time of
+ // the network.
+ //
+ // Input:
+ // - packet_loss : Fraction lost
+ // (loss rate in percent = 100 * packetLoss / 255)
+ // - rtt : Round-trip time in milliseconds
+ // Return value : WEBRTC_VIDEO_CODEC_OK if OK
+ // <0 - Errors: WEBRTC_VIDEO_CODEC_ERROR
virtual int32_t SetChannelParameters(uint32_t packet_loss, int rtt) = 0;
+
+ // Inform the encoder about the new target bit rate.
+ //
+ // Input:
+ // - bitrate : New target bit rate
+ // - framerate : The target frame rate
+ //
+ // Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise.
virtual int32_t SetRates(uint32_t bitrate, uint32_t framerate) = 0;
virtual int32_t SetPeriodicKeyFrames(bool enable) { return -1; }
diff --git a/video_engine/include/vie_base.h b/video_engine/include/vie_base.h
index a49aba7c..ae80cd78 100644
--- a/video_engine/include/vie_base.h
+++ b/video_engine/include/vie_base.h
@@ -63,6 +63,7 @@ struct CpuOveruseOptions {
bool enable_encode_usage_method;
int low_encode_usage_threshold_percent; // Threshold for triggering underuse.
int high_encode_usage_threshold_percent; // Threshold for triggering overuse.
+ // TODO(asapersson): Remove options, not used.
int low_encode_time_rsd_threshold; // Additional threshold for triggering
// underuse (used in addition to
// threshold above if configured).
@@ -117,6 +118,7 @@ struct CpuOveruseMetrics {
int avg_encode_time_ms; // The average encode time in ms.
int encode_usage_percent; // The average encode time divided by the average
// time difference between incoming captured frames.
+ // TODO(asapersson): Remove metric, not used.
int encode_rsd; // The relative std dev of encode time of frames.
int capture_queue_delay_ms_per_s; // The current time delay between an
// incoming captured frame until the frame
diff --git a/video_engine/overuse_frame_detector.cc b/video_engine/overuse_frame_detector.cc
index 96036132..32b0d255 100644
--- a/video_engine/overuse_frame_detector.cc
+++ b/video_engine/overuse_frame_detector.cc
@@ -212,112 +212,6 @@ class OveruseFrameDetector::SendProcessingUsage {
scoped_ptr<rtc::ExpFilter> filtered_frame_diff_ms_;
};
-// Class for calculating the relative standard deviation of the processing time
-// of frame on the send-side.
-// Currently only used for testing.
-class OveruseFrameDetector::SendProcessingRsd {
- public:
- SendProcessingRsd(Clock* clock)
- : kWeightFactor(0.6f),
- count_(0),
- filtered_rsd_(new rtc::ExpFilter(kWeightFactor)),
- hist_samples_(0),
- hist_sum_(0.0f),
- last_process_time_ms_(clock->TimeInMilliseconds()) {
- Reset();
- }
- ~SendProcessingRsd() {}
-
- void SetOptions(const CpuOveruseOptions& options) {
- options_ = options;
- }
-
- void Reset() {
- count_ = 0;
- filtered_rsd_->Reset(kWeightFactor);
- filtered_rsd_->Apply(1.0f, InitialValue());
- hist_.clear();
- hist_samples_ = 0;
- hist_sum_ = 0.0f;
- }
-
- void AddSample(float processing_ms) {
- int bin = static_cast<int>(processing_ms + 0.5f);
- if (bin <= 0) {
- return;
- }
- ++count_;
- ++hist_[bin];
- ++hist_samples_;
- hist_sum_ += bin;
- }
-
- void Process(int64_t now) {
- if (count_ < static_cast<uint32_t>(options_.min_frame_samples)) {
- // Have not received min number of frames since last reset.
- return;
- }
- const int kMinHistSamples = 20;
- if (hist_samples_ < kMinHistSamples) {
- return;
- }
- const int64_t kMinDiffSinceLastProcessMs = 1000;
- int64_t diff_last_process_ms = now - last_process_time_ms_;
- if (now - last_process_time_ms_ <= kMinDiffSinceLastProcessMs) {
- return;
- }
- last_process_time_ms_ = now;
-
- // Calculate variance (using samples above the mean).
- // Checks for a larger processing time of some frames while there is a small
- // increase in the average time.
- int mean = hist_sum_ / hist_samples_;
- float variance = 0.0f;
- int total_count = 0;
- for (std::map<int,int>::iterator it = hist_.begin();
- it != hist_.end(); ++it) {
- int time = it->first;
- int count = it->second;
- if (time > mean) {
- total_count += count;
- for (int i = 0; i < count; ++i) {
- variance += ((time - mean) * (time - mean));
- }
- }
- }
- variance /= std::max(total_count, 1);
- float cov = sqrt(variance) / mean;
-
- hist_.clear();
- hist_samples_ = 0;
- hist_sum_ = 0.0f;
-
- float exp = static_cast<float>(diff_last_process_ms) / kProcessIntervalMs;
- exp = std::min(exp, kMaxExp);
- filtered_rsd_->Apply(exp, 100.0f * cov);
- }
-
- int Value() const {
- return static_cast<int>(filtered_rsd_->filtered() + 0.5);
- }
-
- private:
- float InitialValue() const {
- // Start in between the underuse and overuse threshold.
- return std::max(((options_.low_encode_time_rsd_threshold +
- options_.high_encode_time_rsd_threshold) / 2.0f), 0.0f);
- }
-
- const float kWeightFactor;
- uint32_t count_; // Number of samples since last reset.
- CpuOveruseOptions options_;
- scoped_ptr<rtc::ExpFilter> filtered_rsd_;
- int hist_samples_;
- float hist_sum_;
- std::map<int, int> hist_; // Histogram of time spent on processing frames.
- int64_t last_process_time_ms_;
-};
-
// Class for calculating the processing time of frames.
class OveruseFrameDetector::FrameQueue {
public:
@@ -439,7 +333,6 @@ OveruseFrameDetector::OveruseFrameDetector(Clock* clock)
num_pixels_(0),
last_encode_sample_ms_(0),
encode_time_(new EncodeTimeAvg()),
- rsd_(new SendProcessingRsd(clock)),
usage_(new SendProcessingUsage()),
frame_queue_(new FrameQueue()),
last_sample_time_ms_(0),
@@ -463,7 +356,6 @@ void OveruseFrameDetector::SetOptions(const CpuOveruseOptions& options) {
options_ = options;
capture_deltas_.SetOptions(options);
usage_->SetOptions(options);
- rsd_->SetOptions(options);
ResetAll(num_pixels_);
}
@@ -487,7 +379,7 @@ void OveruseFrameDetector::GetCpuOveruseMetrics(
CriticalSectionScoped cs(crit_.get());
metrics->capture_jitter_ms = static_cast<int>(capture_deltas_.StdDev() + 0.5);
metrics->avg_encode_time_ms = encode_time_->Value();
- metrics->encode_rsd = rsd_->Value();
+ metrics->encode_rsd = 0;
metrics->encode_usage_percent = usage_->Value();
metrics->capture_queue_delay_ms_per_s = capture_queue_delay_->Value();
}
@@ -515,7 +407,6 @@ void OveruseFrameDetector::ResetAll(int num_pixels) {
num_pixels_ = num_pixels;
capture_deltas_.Reset();
usage_->Reset();
- rsd_->Reset();
frame_queue_->Reset();
capture_queue_delay_->ClearFrames();
last_capture_time_ = 0;
@@ -581,7 +472,6 @@ void OveruseFrameDetector::AddProcessingTime(int elapsed_ms) {
if (last_sample_time_ms_ != 0) {
int64_t diff_ms = now - last_sample_time_ms_;
usage_->AddSample(elapsed_ms, diff_ms);
- rsd_->AddSample(elapsed_ms);
}
last_sample_time_ms_ = now;
}
@@ -599,7 +489,6 @@ int32_t OveruseFrameDetector::Process() {
next_process_time_ = now + kProcessIntervalMs;
++num_process_times_;
- rsd_->Process(now);
capture_queue_delay_->CalculateDelayChange(diff_ms);
if (num_process_times_ <= options_.min_process_count) {
@@ -644,7 +533,6 @@ int32_t OveruseFrameDetector::Process() {
LOG(LS_VERBOSE) << " Frame stats: capture avg: " << capture_deltas_.Mean()
<< " capture stddev " << capture_deltas_.StdDev()
<< " encode usage " << usage_->Value()
- << " encode rsd " << rsd_->Value()
<< " overuse detections " << num_overuse_detections_
<< " rampup delay " << rampup_delay;
return 0;
@@ -656,13 +544,7 @@ bool OveruseFrameDetector::IsOverusing() {
overusing = capture_deltas_.StdDev() >=
options_.high_capture_jitter_threshold_ms;
} else if (options_.enable_encode_usage_method) {
- bool usage_overuse =
- usage_->Value() >= options_.high_encode_usage_threshold_percent;
- bool rsd_overuse = false;
- if (options_.high_encode_time_rsd_threshold > 0) {
- rsd_overuse = (rsd_->Value() >= options_.high_encode_time_rsd_threshold);
- }
- overusing = usage_overuse || rsd_overuse;
+ overusing = usage_->Value() >= options_.high_encode_usage_threshold_percent;
}
if (overusing) {
@@ -683,13 +565,7 @@ bool OveruseFrameDetector::IsUnderusing(int64_t time_now) {
underusing = capture_deltas_.StdDev() <
options_.low_capture_jitter_threshold_ms;
} else if (options_.enable_encode_usage_method) {
- bool usage_underuse =
- usage_->Value() < options_.low_encode_usage_threshold_percent;
- bool rsd_underuse = true;
- if (options_.low_encode_time_rsd_threshold > 0) {
- rsd_underuse = (rsd_->Value() < options_.low_encode_time_rsd_threshold);
- }
- underusing = usage_underuse && rsd_underuse;
+ underusing = usage_->Value() < options_.low_encode_usage_threshold_percent;
}
return underusing;
}
diff --git a/video_engine/overuse_frame_detector.h b/video_engine/overuse_frame_detector.h
index 421e9dec..f90a4f82 100644
--- a/video_engine/overuse_frame_detector.h
+++ b/video_engine/overuse_frame_detector.h
@@ -103,7 +103,6 @@ class OveruseFrameDetector : public Module {
private:
class EncodeTimeAvg;
- class SendProcessingRsd;
class SendProcessingUsage;
class CaptureQueueDelay;
class FrameQueue;
@@ -146,8 +145,6 @@ class OveruseFrameDetector : public Module {
int64_t last_encode_sample_ms_;
scoped_ptr<EncodeTimeAvg> encode_time_;
-
- scoped_ptr<SendProcessingRsd> rsd_;
scoped_ptr<SendProcessingUsage> usage_;
scoped_ptr<FrameQueue> frame_queue_;
int64_t last_sample_time_ms_;
diff --git a/video_engine/overuse_frame_detector_unittest.cc b/video_engine/overuse_frame_detector_unittest.cc
index 553c3512..e2361695 100644
--- a/video_engine/overuse_frame_detector_unittest.cc
+++ b/video_engine/overuse_frame_detector_unittest.cc
@@ -71,12 +71,6 @@ class OveruseFrameDetectorTest : public ::testing::Test {
options_.high_encode_usage_threshold_percent) / 2.0f) + 0.5;
}
- int InitialRsd() {
- return std::max(
- ((options_.low_encode_time_rsd_threshold +
- options_.high_encode_time_rsd_threshold) / 2.0f) + 0.5f, 0.0f);
- }
-
void InsertFramesWithInterval(
size_t num_frames, int interval_ms, int width, int height) {
while (num_frames-- > 0) {
@@ -120,18 +114,6 @@ class OveruseFrameDetectorTest : public ::testing::Test {
}
}
- void TriggerOveruseWithRsd(int num_times) {
- const int kDelayMs1 = 10;
- const int kDelayMs2 = 25;
- for (int i = 0; i < num_times; ++i) {
- InsertAndSendFramesWithInterval(
- 200, kFrameInterval33ms, kWidth, kHeight, kDelayMs1);
- InsertAndSendFramesWithInterval(
- 10, kFrameInterval33ms, kWidth, kHeight, kDelayMs2);
- overuse_detector_->Process();
- }
- }
-
void TriggerUnderuseWithProcessingUsage() {
const int kDelayMs1 = 5;
const int kDelayMs2 = 6;
@@ -160,12 +142,6 @@ class OveruseFrameDetectorTest : public ::testing::Test {
return metrics.encode_usage_percent;
}
- int Rsd() {
- CpuOveruseMetrics metrics;
- overuse_detector_->GetCpuOveruseMetrics(&metrics);
- return metrics.encode_rsd;
- }
-
CpuOveruseOptions options_;
scoped_ptr<SimulatedClock> clock_;
scoped_ptr<MockCpuOveruseObserver> observer_;
@@ -571,73 +547,4 @@ TEST_F(OveruseFrameDetectorTest,
TriggerUnderuseWithProcessingUsage();
}
-TEST_F(OveruseFrameDetectorTest, RsdResetAfterChangingThreshold) {
- EXPECT_EQ(InitialRsd(), Rsd());
- options_.high_encode_time_rsd_threshold = 100;
- overuse_detector_->SetOptions(options_);
- EXPECT_EQ(InitialRsd(), Rsd());
- options_.low_encode_time_rsd_threshold = 20;
- overuse_detector_->SetOptions(options_);
- EXPECT_EQ(InitialRsd(), Rsd());
-}
-
-// enable_encode_usage_method = true;
-// low/high_encode_time_rsd_threshold >= 0
-// UsagePercent() > high_encode_usage_threshold_percent ||
-// Rsd() > high_encode_time_rsd_threshold => overuse.
-// UsagePercent() < low_encode_usage_threshold_percent &&
-// Rsd() < low_encode_time_rsd_threshold => underuse.
-TEST_F(OveruseFrameDetectorTest, TriggerOveruseWithRsd) {
- options_.enable_capture_jitter_method = false;
- options_.enable_encode_usage_method = true;
- options_.high_encode_time_rsd_threshold = 80;
- overuse_detector_->SetOptions(options_);
- // rsd > high, usage < high => overuse
- EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
- TriggerOveruseWithRsd(options_.high_threshold_consecutive_count);
- EXPECT_LT(UsagePercent(), options_.high_encode_usage_threshold_percent);
-}
-
-TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithRsd) {
- options_.enable_capture_jitter_method = false;
- options_.enable_encode_usage_method = true;
- options_.low_encode_time_rsd_threshold = 25;
- options_.high_encode_time_rsd_threshold = 80;
- overuse_detector_->SetOptions(options_);
- // rsd > high, usage < high => overuse
- EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
- TriggerOveruseWithRsd(options_.high_threshold_consecutive_count);
- EXPECT_LT(UsagePercent(), options_.high_encode_usage_threshold_percent);
- // rsd < low, usage < low => underuse
- EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(testing::AtLeast(1));
- TriggerUnderuseWithProcessingUsage();
-}
-
-TEST_F(OveruseFrameDetectorTest, NoUnderuseWithRsd_UsageGtLowThreshold) {
- options_.enable_capture_jitter_method = false;
- options_.enable_encode_usage_method = true;
- options_.low_encode_usage_threshold_percent = 1;
- options_.low_encode_time_rsd_threshold = 25;
- options_.high_encode_time_rsd_threshold = 90;
- overuse_detector_->SetOptions(options_);
- // rsd < low, usage > low => no underuse
- EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0);
- TriggerUnderuseWithProcessingUsage();
- EXPECT_LT(Rsd(), options_.low_encode_time_rsd_threshold);
- EXPECT_GT(UsagePercent(), options_.low_encode_usage_threshold_percent);
-}
-
-TEST_F(OveruseFrameDetectorTest, NoUnderuseWithRsd_RsdGtLowThreshold) {
- options_.enable_capture_jitter_method = false;
- options_.enable_encode_usage_method = true;
- options_.low_encode_usage_threshold_percent = 20;
- options_.low_encode_time_rsd_threshold = 1;
- options_.high_encode_time_rsd_threshold = 90;
- overuse_detector_->SetOptions(options_);
- // rsd > low, usage < low => no underuse
- EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0);
- TriggerUnderuseWithProcessingUsage();
- EXPECT_GT(Rsd(), options_.low_encode_time_rsd_threshold);
- EXPECT_LT(UsagePercent(), options_.low_encode_usage_threshold_percent);
-}
} // namespace webrtc
diff --git a/video_engine/test/auto_test/source/vie_autotest.cc b/video_engine/test/auto_test/source/vie_autotest.cc
index fb1a46f2..41fafaef 100644
--- a/video_engine/test/auto_test/source/vie_autotest.cc
+++ b/video_engine/test/auto_test/source/vie_autotest.cc
@@ -98,6 +98,9 @@ void ViEAutoTest::PrintVideoCodec(const webrtc::VideoCodec videoCodec)
case webrtc::kVideoCodecVP8:
ViETest::Log("\tcodecType: VP8");
break;
+ case webrtc::kVideoCodecVP9:
+ ViETest::Log("\tcodecType: VP9");
+ break;
case webrtc::kVideoCodecI420:
ViETest::Log("\tcodecType: I420");
break;
diff --git a/video_engine/test/auto_test/source/vie_autotest_loopback.cc b/video_engine/test/auto_test/source/vie_autotest_loopback.cc
index 9b8040d9..03a82b4c 100644
--- a/video_engine/test/auto_test/source/vie_autotest_loopback.cc
+++ b/video_engine/test/auto_test/source/vie_autotest_loopback.cc
@@ -158,7 +158,7 @@ int VideoEngineSampleCode(void* window1, void* window2)
printf("Error in scanf()\n");
return -1;
}
- getchar();
+ getc(stdin);
captureIdx = captureIdx - 1; // Compensate for idx start at 1.
#endif
error = ptrViECapture->GetCaptureDevice(captureIdx, deviceName,
@@ -350,7 +350,7 @@ int VideoEngineSampleCode(void* window1, void* window2)
printf("Error in scanf()\n");
return -1;
}
- getchar();
+ getc(stdin);
codecIdx = codecIdx - 1; // Compensate for idx start at 1.
#endif
// VP8 over generic transport gets this special one.
@@ -624,7 +624,7 @@ int VideoEngineSampleCode(void* window1, void* window2)
// Call started
printf("\nLoopback call started\n\n");
printf("Press enter to stop...");
- while ((getchar()) != '\n')
+ while ((getc(stdin)) != '\n')
;
//********************************************************
diff --git a/video_engine/test/auto_test/source/vie_autotest_main.cc b/video_engine/test/auto_test/source/vie_autotest_main.cc
index c688e2ef..16172585 100644
--- a/video_engine/test/auto_test/source/vie_autotest_main.cc
+++ b/video_engine/test/auto_test/source/vie_autotest_main.cc
@@ -106,10 +106,10 @@ int ViEAutoTestMain::AskUserForNumber(int min_allowed, int max_allowed) {
int result;
if (scanf("%d", &result) <= 0) {
ViETest::Log("\nPlease enter a number instead, then hit enter.");
- getchar();
+ getc(stdin);
return kInvalidChoice;
}
- getchar(); // Consume enter key.
+ getc(stdin); // Consume enter key.
if (result < min_allowed || result > max_allowed) {
ViETest::Log("%d-%d are valid choices. Please try again.", min_allowed,
diff --git a/video_engine/test/auto_test/source/vie_autotest_network.cc b/video_engine/test/auto_test/source/vie_autotest_network.cc
index df5b5ef4..1ccac701 100644
--- a/video_engine/test/auto_test/source/vie_autotest_network.cc
+++ b/video_engine/test/auto_test/source/vie_autotest_network.cc
@@ -150,7 +150,7 @@ void ViEAutoTest::ViENetworkExtendedTest()
ViETest::Log("On Win7 and late Vista, you need to right click the "
"exe and choose");
ViETest::Log("\"Run as administrator\"\n");
- getchar();
+ getc(stdin);
}
EXPECT_EQ(0, ViE.network->GetSendToS(
tbChannel.videoChannel, DSCP, useSetSockOpt)); // No ToS set
@@ -390,7 +390,7 @@ void ViEAutoTest::ViENetworkAPITest()
ViETest::Log("On Win7 and late Vista, you need to right click the "
"exe and choose");
ViETest::Log("\"Run as administrator\"\n");
- getchar();
+ getc(stdin);
}
EXPECT_EQ(0, ViE.network->GetSendToS(
tbChannel.videoChannel, DSCP, useSetSockOpt));
diff --git a/video_engine/test/auto_test/source/vie_autotest_record.cc b/video_engine/test/auto_test/source/vie_autotest_record.cc
index 1fb11ad1..89575cee 100644
--- a/video_engine/test/auto_test/source/vie_autotest_record.cc
+++ b/video_engine/test/auto_test/source/vie_autotest_record.cc
@@ -216,7 +216,7 @@ int VideoEngineSampleRecordCode(void* window1, void* window2) {
printf("Error in scanf()\n");
return -1;
}
- getchar();
+ getc(stdin);
captureIdx = captureIdx - 1; // Compensate for idx start at 1.
#endif
error = ptrViECapture->GetCaptureDevice(captureIdx, deviceName,
@@ -441,14 +441,14 @@ int VideoEngineSampleRecordCode(void* window1, void* window2) {
clock_time = webrtc::TickTime::MillisecondTimestamp();
timing << clock_time << std::endl;
}
- char c = getchar();
+ char c = getc(stdin);
fflush(stdin);
while (c != 's') {
if (c == '\n' && enable_labeling == 1) {
clock_time = webrtc::TickTime::MillisecondTimestamp();
timing << clock_time << std::endl;
}
- c = getchar();
+ c = getc(stdin);
}
if (enable_labeling == 1) {
clock_time = webrtc::TickTime::MillisecondTimestamp();
diff --git a/video_engine/test/auto_test/vie_auto_test.gypi b/video_engine/test/auto_test/vie_auto_test.gypi
index a415b3b3..c8886d8f 100644
--- a/video_engine/test/auto_test/vie_auto_test.gypi
+++ b/video_engine/test/auto_test/vie_auto_test.gypi
@@ -13,7 +13,7 @@
'type': 'executable',
'dependencies': [
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
- '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default',
+ '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:metrics_default',
'<(webrtc_root)/modules/modules.gyp:video_capture_module_internal_impl',
'<(webrtc_root)/modules/modules.gyp:video_render_module_internal_impl',
'<(webrtc_root)/voice_engine/voice_engine.gyp:voice_engine',
@@ -137,7 +137,6 @@
],
'includes': [
'../../../build/isolate.gypi',
- 'vie_auto_test.isolate',
],
'sources': [
'vie_auto_test.isolate',
diff --git a/video_engine/test/auto_test/vie_auto_test.isolate b/video_engine/test/auto_test/vie_auto_test.isolate
index 762a7ac5..da09a6e5 100644
--- a/video_engine/test/auto_test/vie_auto_test.isolate
+++ b/video_engine/test/auto_test/vie_auto_test.isolate
@@ -9,7 +9,7 @@
'conditions': [
['OS=="android"', {
'variables': {
- 'isolate_dependency_untracked': [
+ 'files': [
'<(DEPTH)/data/',
'<(DEPTH)/resources/',
],
@@ -21,16 +21,11 @@
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/vie_auto_test<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_touched': [
+ 'files': [
'<(DEPTH)/DEPS',
- ],
- 'isolate_dependency_tracked': [
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/vie_auto_test<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_untracked': [
- '<(DEPTH)/tools/swarming_client/',
- ],
},
}],
],
diff --git a/video_engine/video_engine_core.gypi b/video_engine/video_engine_core.gypi
index fd61043e..2bfc6536 100644
--- a/video_engine/video_engine_core.gypi
+++ b/video_engine/video_engine_core.gypi
@@ -123,7 +123,7 @@
'dependencies': [
'video_engine_core',
'<(webrtc_root)/modules/modules.gyp:video_capture_module_internal_impl',
- '<(webrtc_root)/modules/modules.gyp:video_render_module_internal_impl',
+ '<(webrtc_root)/modules/modules.gyp:video_render_module_internal_impl',
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(DEPTH)/testing/gmock.gyp:gmock',
'<(webrtc_root)/test/test.gyp:test_support_main',
@@ -168,7 +168,6 @@
],
'includes': [
'../build/isolate.gypi',
- 'video_engine_core_unittests.isolate',
],
'sources': [
'video_engine_core_unittests.isolate',
diff --git a/video_engine/video_engine_core.target.darwin-arm.mk b/video_engine/video_engine_core.target.darwin-arm.mk
index 8111c94c..cd60eb0f 100644
--- a/video_engine/video_engine_core.target.darwin-arm.mk
+++ b/video_engine/video_engine_core.target.darwin-arm.mk
@@ -112,11 +112,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -132,6 +134,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -227,11 +230,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -247,6 +252,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/video_engine/video_engine_core.target.darwin-arm64.mk b/video_engine/video_engine_core.target.darwin-arm64.mk
index aefe44bb..1ee5c36b 100644
--- a/video_engine/video_engine_core.target.darwin-arm64.mk
+++ b/video_engine/video_engine_core.target.darwin-arm64.mk
@@ -101,11 +101,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -114,10 +116,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -201,11 +205,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -214,10 +220,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/video_engine/video_engine_core.target.darwin-mips.mk b/video_engine/video_engine_core.target.darwin-mips.mk
index 4a7236f7..6ab77b95 100644
--- a/video_engine/video_engine_core.target.darwin-mips.mk
+++ b/video_engine/video_engine_core.target.darwin-mips.mk
@@ -105,11 +105,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -124,6 +126,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -212,11 +215,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -231,6 +236,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/video_engine/video_engine_core.target.darwin-mips64.mk b/video_engine/video_engine_core.target.darwin-mips64.mk
new file mode 100644
index 00000000..35d9ba5d
--- /dev/null
+++ b/video_engine/video_engine_core.target.darwin-mips64.mk
@@ -0,0 +1,292 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_video_engine_video_engine_core_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/video_engine/call_stats.cc \
+ third_party/webrtc/video_engine/encoder_state_feedback.cc \
+ third_party/webrtc/video_engine/overuse_frame_detector.cc \
+ third_party/webrtc/video_engine/stream_synchronization.cc \
+ third_party/webrtc/video_engine/vie_base_impl.cc \
+ third_party/webrtc/video_engine/vie_capture_impl.cc \
+ third_party/webrtc/video_engine/vie_codec_impl.cc \
+ third_party/webrtc/video_engine/vie_external_codec_impl.cc \
+ third_party/webrtc/video_engine/vie_image_process_impl.cc \
+ third_party/webrtc/video_engine/vie_impl.cc \
+ third_party/webrtc/video_engine/vie_network_impl.cc \
+ third_party/webrtc/video_engine/vie_ref_count.cc \
+ third_party/webrtc/video_engine/vie_render_impl.cc \
+ third_party/webrtc/video_engine/vie_rtp_rtcp_impl.cc \
+ third_party/webrtc/video_engine/vie_shared_data.cc \
+ third_party/webrtc/video_engine/vie_capturer.cc \
+ third_party/webrtc/video_engine/vie_channel.cc \
+ third_party/webrtc/video_engine/vie_channel_group.cc \
+ third_party/webrtc/video_engine/vie_channel_manager.cc \
+ third_party/webrtc/video_engine/vie_encoder.cc \
+ third_party/webrtc/video_engine/vie_file_image.cc \
+ third_party/webrtc/video_engine/vie_frame_provider_base.cc \
+ third_party/webrtc/video_engine/vie_input_manager.cc \
+ third_party/webrtc/video_engine/vie_manager_base.cc \
+ third_party/webrtc/video_engine/vie_receiver.cc \
+ third_party/webrtc/video_engine/vie_remb.cc \
+ third_party/webrtc/video_engine/vie_renderer.cc \
+ third_party/webrtc/video_engine/vie_render_manager.cc \
+ third_party/webrtc/video_engine/vie_sender.cc \
+ third_party/webrtc/video_engine/vie_sync_module.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_video_engine_video_engine_core_gyp
+
+# Alias gyp target name.
+.PHONY: video_engine_core
+video_engine_core: third_party_webrtc_video_engine_video_engine_core_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/video_engine/video_engine_core.target.darwin-x86.mk b/video_engine/video_engine_core.target.darwin-x86.mk
index 56bb12cd..bb960646 100644
--- a/video_engine/video_engine_core.target.darwin-x86.mk
+++ b/video_engine/video_engine_core.target.darwin-x86.mk
@@ -107,11 +107,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -124,6 +126,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -213,11 +216,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -230,6 +235,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/video_engine/video_engine_core.target.darwin-x86_64.mk b/video_engine/video_engine_core.target.darwin-x86_64.mk
index 9fd06489..ea3ccb48 100644
--- a/video_engine/video_engine_core.target.darwin-x86_64.mk
+++ b/video_engine/video_engine_core.target.darwin-x86_64.mk
@@ -106,11 +106,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -123,6 +125,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -211,11 +214,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -228,6 +233,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/video_engine/video_engine_core.target.linux-arm.mk b/video_engine/video_engine_core.target.linux-arm.mk
index 8111c94c..cd60eb0f 100644
--- a/video_engine/video_engine_core.target.linux-arm.mk
+++ b/video_engine/video_engine_core.target.linux-arm.mk
@@ -112,11 +112,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -132,6 +134,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -227,11 +230,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -247,6 +252,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/video_engine/video_engine_core.target.linux-arm64.mk b/video_engine/video_engine_core.target.linux-arm64.mk
index aefe44bb..1ee5c36b 100644
--- a/video_engine/video_engine_core.target.linux-arm64.mk
+++ b/video_engine/video_engine_core.target.linux-arm64.mk
@@ -101,11 +101,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -114,10 +116,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -201,11 +205,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -214,10 +220,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/video_engine/video_engine_core.target.linux-mips.mk b/video_engine/video_engine_core.target.linux-mips.mk
index 4a7236f7..6ab77b95 100644
--- a/video_engine/video_engine_core.target.linux-mips.mk
+++ b/video_engine/video_engine_core.target.linux-mips.mk
@@ -105,11 +105,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -124,6 +126,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -212,11 +215,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -231,6 +236,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/video_engine/video_engine_core.target.linux-mips64.mk b/video_engine/video_engine_core.target.linux-mips64.mk
new file mode 100644
index 00000000..35d9ba5d
--- /dev/null
+++ b/video_engine/video_engine_core.target.linux-mips64.mk
@@ -0,0 +1,292 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_video_engine_video_engine_core_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/video_engine/call_stats.cc \
+ third_party/webrtc/video_engine/encoder_state_feedback.cc \
+ third_party/webrtc/video_engine/overuse_frame_detector.cc \
+ third_party/webrtc/video_engine/stream_synchronization.cc \
+ third_party/webrtc/video_engine/vie_base_impl.cc \
+ third_party/webrtc/video_engine/vie_capture_impl.cc \
+ third_party/webrtc/video_engine/vie_codec_impl.cc \
+ third_party/webrtc/video_engine/vie_external_codec_impl.cc \
+ third_party/webrtc/video_engine/vie_image_process_impl.cc \
+ third_party/webrtc/video_engine/vie_impl.cc \
+ third_party/webrtc/video_engine/vie_network_impl.cc \
+ third_party/webrtc/video_engine/vie_ref_count.cc \
+ third_party/webrtc/video_engine/vie_render_impl.cc \
+ third_party/webrtc/video_engine/vie_rtp_rtcp_impl.cc \
+ third_party/webrtc/video_engine/vie_shared_data.cc \
+ third_party/webrtc/video_engine/vie_capturer.cc \
+ third_party/webrtc/video_engine/vie_channel.cc \
+ third_party/webrtc/video_engine/vie_channel_group.cc \
+ third_party/webrtc/video_engine/vie_channel_manager.cc \
+ third_party/webrtc/video_engine/vie_encoder.cc \
+ third_party/webrtc/video_engine/vie_file_image.cc \
+ third_party/webrtc/video_engine/vie_frame_provider_base.cc \
+ third_party/webrtc/video_engine/vie_input_manager.cc \
+ third_party/webrtc/video_engine/vie_manager_base.cc \
+ third_party/webrtc/video_engine/vie_receiver.cc \
+ third_party/webrtc/video_engine/vie_remb.cc \
+ third_party/webrtc/video_engine/vie_renderer.cc \
+ third_party/webrtc/video_engine/vie_render_manager.cc \
+ third_party/webrtc/video_engine/vie_sender.cc \
+ third_party/webrtc/video_engine/vie_sync_module.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/interface \
+ $(LOCAL_PATH)/third_party/webrtc/common_video/libyuv/include \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_video_engine_video_engine_core_gyp
+
+# Alias gyp target name.
+.PHONY: video_engine_core
+video_engine_core: third_party_webrtc_video_engine_video_engine_core_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/video_engine/video_engine_core.target.linux-x86.mk b/video_engine/video_engine_core.target.linux-x86.mk
index 56bb12cd..bb960646 100644
--- a/video_engine/video_engine_core.target.linux-x86.mk
+++ b/video_engine/video_engine_core.target.linux-x86.mk
@@ -107,11 +107,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -124,6 +126,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -213,11 +216,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -230,6 +235,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/video_engine/video_engine_core.target.linux-x86_64.mk b/video_engine/video_engine_core.target.linux-x86_64.mk
index 9fd06489..ea3ccb48 100644
--- a/video_engine/video_engine_core.target.linux-x86_64.mk
+++ b/video_engine/video_engine_core.target.linux-x86_64.mk
@@ -106,11 +106,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -123,6 +125,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -211,11 +214,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -228,6 +233,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/video_engine/video_engine_core_unittests.isolate b/video_engine/video_engine_core_unittests.isolate
index ec65e739..b95d84c4 100644
--- a/video_engine/video_engine_core_unittests.isolate
+++ b/video_engine/video_engine_core_unittests.isolate
@@ -9,7 +9,7 @@
'conditions': [
['OS=="android"', {
'variables': {
- 'isolate_dependency_untracked': [
+ 'files': [
'<(DEPTH)/data/',
'<(DEPTH)/resources/',
],
@@ -21,13 +21,10 @@
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/video_engine_core_unittests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/video_engine_core_unittests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_untracked': [
- '<(DEPTH)/tools/swarming_client/',
- ],
},
}],
],
diff --git a/video_engine/vie_channel.cc b/video_engine/vie_channel.cc
index bbcb602c..ded21407 100644
--- a/video_engine/vie_channel.cc
+++ b/video_engine/vie_channel.cc
@@ -25,6 +25,7 @@
#include "webrtc/modules/video_render/include/video_render_defines.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/logging.h"
+#include "webrtc/system_wrappers/interface/metrics.h"
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
#include "webrtc/video_engine/call_stats.h"
#include "webrtc/video_engine/include/vie_codec.h"
@@ -147,7 +148,8 @@ ViEChannel::ViEChannel(int32_t channel_id,
sender_(sender),
nack_history_size_sender_(kSendSidePacketHistorySize),
max_nack_reordering_threshold_(kMaxPacketAgeToNack),
- pre_render_callback_(NULL) {
+ pre_render_callback_(NULL),
+ start_ms_(Clock::GetRealTimeClock()->TimeInMilliseconds()) {
RtpRtcp::Configuration configuration;
configuration.id = ViEModuleId(engine_id, channel_id);
configuration.audio = false;
@@ -222,6 +224,7 @@ int32_t ViEChannel::Init() {
}
ViEChannel::~ViEChannel() {
+ UpdateHistograms();
// Make sure we don't get more callbacks from the RTP module.
module_process_thread_.DeRegisterModule(vie_receiver_.GetReceiveStatistics());
module_process_thread_.DeRegisterModule(rtp_rtcp_.get());
@@ -246,6 +249,55 @@ ViEChannel::~ViEChannel() {
VideoCodingModule::Destroy(vcm_);
}
+void ViEChannel::UpdateHistograms() {
+ const float kMinCallLengthInMinutes = 0.5f;
+ float elapsed_minutes =
+ (Clock::GetRealTimeClock()->TimeInMilliseconds() - start_ms_) / 60000.0f;
+ if (elapsed_minutes < kMinCallLengthInMinutes) {
+ return;
+ }
+ RtcpPacketTypeCounter rtcp_sent;
+ RtcpPacketTypeCounter rtcp_received;
+ GetRtcpPacketTypeCounters(&rtcp_sent, &rtcp_received);
+
+ if (sender_) {
+ if (rtcp_received.nack_requests > 0) {
+ RTC_HISTOGRAM_PERCENTAGE(
+ "WebRTC.Video.UniqueNackRequestsReceivedInPercent",
+ rtcp_received.UniqueNackRequestsInPercent());
+ }
+ RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.NackPacketsReceivedPerMinute",
+ rtcp_received.nack_packets / elapsed_minutes);
+ RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FirPacketsReceivedPerMinute",
+ rtcp_received.fir_packets / elapsed_minutes);
+ RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.PliPacketsReceivedPerMinute",
+ rtcp_received.pli_packets / elapsed_minutes);
+ } else if (vie_receiver_.GetRemoteSsrc() > 0) {
+ // Get receive stats if we are receiving packets, i.e. there is a remote
+ // ssrc.
+ if (rtcp_sent.nack_requests > 0) {
+ RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.UniqueNackRequestsSentInPercent",
+ rtcp_sent.UniqueNackRequestsInPercent());
+ }
+ RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.NackPacketsSentPerMinute",
+ rtcp_sent.nack_packets / elapsed_minutes);
+ RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FirPacketsSentPerMinute",
+ rtcp_sent.fir_packets / elapsed_minutes);
+ RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.PliPacketsSentPerMinute",
+ rtcp_sent.pli_packets / elapsed_minutes);
+
+ webrtc::VCMFrameCount frames;
+ if (vcm_->ReceivedFrameCount(frames) == VCM_OK) {
+ uint32_t total_frames = frames.numKeyFrames + frames.numDeltaFrames;
+ if (total_frames > 0) {
+ RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.KeyFramesReceivedInPermille",
+ static_cast<int>((frames.numKeyFrames * 1000.0f / total_frames) +
+ 0.5f));
+ }
+ }
+ }
+}
+
int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
bool new_stream) {
if (!sender_) {
diff --git a/video_engine/vie_channel.h b/video_engine/vie_channel.h
index e55ade79..03279069 100644
--- a/video_engine/vie_channel.h
+++ b/video_engine/vie_channel.h
@@ -383,6 +383,8 @@ class ViEChannel
int GetRequiredNackListSize(int target_delay_ms);
void SetRtxSendStatus(bool enable);
+ void UpdateHistograms();
+
// ViEChannel exposes methods that allow to modify observers and callbacks
// to be modified. Such an API-style is cumbersome to implement and maintain
// at all the levels when comparing to only setting them at construction. As
@@ -499,6 +501,7 @@ class ViEChannel
int nack_history_size_sender_;
int max_nack_reordering_threshold_;
I420FrameCallback* pre_render_callback_;
+ const int64_t start_ms_;
std::map<uint32_t, RTCPReportBlock> prev_report_blocks_;
};
diff --git a/video_engine/vie_channel_group.cc b/video_engine/vie_channel_group.cc
index c6b3f741..9c2d59f0 100644
--- a/video_engine/vie_channel_group.cc
+++ b/video_engine/vie_channel_group.cc
@@ -41,7 +41,7 @@ class WrappingBitrateEstimator : public RemoteBitrateEstimator {
crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
engine_id_(engine_id),
min_bitrate_bps_(config.Get<RemoteBitrateEstimatorMinRate>().min_rate),
- rate_control_type_(kMimdControl),
+ rate_control_type_(kAimdControl),
rbe_(RemoteBitrateEstimatorFactory().Create(observer_,
clock_,
rate_control_type_,
diff --git a/video_engine/vie_codec_impl.cc b/video_engine/vie_codec_impl.cc
index f939a667..0ef039db 100644
--- a/video_engine/vie_codec_impl.cc
+++ b/video_engine/vie_codec_impl.cc
@@ -640,6 +640,8 @@ bool ViECodecImpl::CodecValid(const VideoCodec& video_codec) {
return false;
} else if ((video_codec.codecType == kVideoCodecVP8 &&
strncmp(video_codec.plName, "VP8", 4) == 0) ||
+ (video_codec.codecType == kVideoCodecVP9 &&
+ strncmp(video_codec.plName, "VP9", 4) == 0) ||
(video_codec.codecType == kVideoCodecI420 &&
strncmp(video_codec.plName, "I420", 4) == 0) ||
(video_codec.codecType == kVideoCodecH264 &&
diff --git a/video_engine/vie_encoder.cc b/video_engine/vie_encoder.cc
index 0955066b..3cb0ae70 100644
--- a/video_engine/vie_encoder.cc
+++ b/video_engine/vie_encoder.cc
@@ -26,6 +26,7 @@
#include "webrtc/system_wrappers/interface/clock.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/logging.h"
+#include "webrtc/system_wrappers/interface/metrics.h"
#include "webrtc/system_wrappers/interface/tick_util.h"
#include "webrtc/system_wrappers/interface/trace_event.h"
#include "webrtc/video_engine/include/vie_codec.h"
@@ -109,8 +110,10 @@ class ViEPacedSenderCallback : public PacedSender::Callback {
: owner_(owner) {
}
virtual ~ViEPacedSenderCallback() {}
- virtual bool TimeToSendPacket(uint32_t ssrc, uint16_t sequence_number,
- int64_t capture_time_ms, bool retransmission) {
+ virtual bool TimeToSendPacket(uint32_t ssrc,
+ uint16_t sequence_number,
+ int64_t capture_time_ms,
+ bool retransmission) {
return owner_->TimeToSendPacket(ssrc, sequence_number, capture_time_ms,
retransmission);
}
@@ -154,7 +157,8 @@ ViEEncoder::ViEEncoder(int32_t engine_id,
picture_id_rpsi_(0),
qm_callback_(NULL),
video_suspended_(false),
- pre_encode_callback_(NULL) {
+ pre_encode_callback_(NULL),
+ start_ms_(Clock::GetRealTimeClock()->TimeInMilliseconds()) {
RtpRtcp::Configuration configuration;
configuration.id = ViEModuleId(engine_id_, channel_id_);
configuration.audio = false; // Video.
@@ -162,9 +166,12 @@ ViEEncoder::ViEEncoder(int32_t engine_id,
default_rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(configuration));
bitrate_observer_.reset(new ViEBitrateObserver(this));
pacing_callback_.reset(new ViEPacedSenderCallback(this));
- paced_sender_.reset(
- new PacedSender(Clock::GetRealTimeClock(), pacing_callback_.get(),
- PacedSender::kDefaultInitialPaceKbps, 0));
+ paced_sender_.reset(new PacedSender(
+ Clock::GetRealTimeClock(),
+ pacing_callback_.get(),
+ kDefaultStartBitrateKbps,
+ PacedSender::kDefaultPaceMultiplier * kDefaultStartBitrateKbps,
+ 0));
}
bool ViEEncoder::Init() {
@@ -220,6 +227,7 @@ bool ViEEncoder::Init() {
}
ViEEncoder::~ViEEncoder() {
+ UpdateHistograms();
if (bitrate_controller_) {
bitrate_controller_->RemoveBitrateObserver(bitrate_observer_.get());
}
@@ -232,6 +240,25 @@ ViEEncoder::~ViEEncoder() {
delete qm_callback_;
}
+void ViEEncoder::UpdateHistograms() {
+ const float kMinCallLengthInMinutes = 0.5f;
+ float elapsed_minutes =
+ (Clock::GetRealTimeClock()->TimeInMilliseconds() - start_ms_) / 60000.0f;
+ if (elapsed_minutes < kMinCallLengthInMinutes) {
+ return;
+ }
+ webrtc::VCMFrameCount frames;
+ if (vcm_.SentFrameCount(frames) != VCM_OK) {
+ return;
+ }
+ uint32_t total_frames = frames.numKeyFrames + frames.numDeltaFrames;
+ if (total_frames > 0) {
+ RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.KeyFramesSentInPermille",
+ static_cast<int>(
+ (frames.numKeyFrames * 1000.0f / total_frames) + 0.5f));
+ }
+}
+
int ViEEncoder::Owner() const {
return channel_id_;
}
@@ -368,6 +395,7 @@ int32_t ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec) {
pad_up_to_bitrate_kbps = min_transmit_bitrate_kbps_;
paced_sender_->UpdateBitrate(
+ video_codec.startBitrate,
PacedSender::kDefaultPaceMultiplier * video_codec.startBitrate,
pad_up_to_bitrate_kbps);
@@ -442,9 +470,31 @@ bool ViEEncoder::EncoderPaused() const {
std::max(static_cast<int>(target_delay_ms_ * kEncoderPausePacerMargin),
kMinPacingDelayMs);
}
+ if (paced_sender_->ExpectedQueueTimeMs() >
+ PacedSender::kDefaultMaxQueueLengthMs) {
+ // Too much data in pacer queue, drop frame.
+ return true;
+ }
return !network_is_transmitting_;
}
+void ViEEncoder::TraceFrameDropStart() {
+ // Start trace event only on the first frame after encoder is paused.
+ if (!encoder_paused_and_dropped_frame_) {
+ TRACE_EVENT_ASYNC_BEGIN0("webrtc", "EncoderPaused", this);
+ }
+ encoder_paused_and_dropped_frame_ = true;
+ return;
+}
+
+void ViEEncoder::TraceFrameDropEnd() {
+ // End trace event on first frame after encoder resumes, if frame was dropped.
+ if (encoder_paused_and_dropped_frame_) {
+ TRACE_EVENT_ASYNC_END0("webrtc", "EncoderPaused", this);
+ }
+ encoder_paused_and_dropped_frame_ = false;
+}
+
RtpRtcp* ViEEncoder::SendRtpRtcpModule() {
return default_rtp_rtcp_.get();
}
@@ -461,16 +511,10 @@ void ViEEncoder::DeliverFrame(int id,
CriticalSectionScoped cs(data_cs_.get());
time_of_last_incoming_frame_ms_ = TickTime::MillisecondTimestamp();
if (EncoderPaused()) {
- if (!encoder_paused_and_dropped_frame_) {
- TRACE_EVENT_ASYNC_BEGIN0("webrtc", "EncoderPaused", this);
- }
- encoder_paused_and_dropped_frame_ = true;
+ TraceFrameDropStart();
return;
}
- if (encoder_paused_and_dropped_frame_) {
- TRACE_EVENT_ASYNC_END0("webrtc", "EncoderPaused", this);
- }
- encoder_paused_and_dropped_frame_ = false;
+ TraceFrameDropEnd();
}
// Convert render time, in ms, to RTP timestamp.
@@ -674,15 +718,10 @@ void ViEEncoder::SetSenderBufferingMode(int target_delay_ms) {
// Disable external frame-droppers.
vcm_.EnableFrameDropper(false);
vpm_.EnableTemporalDecimation(false);
- // We don't put any limits on the pacer queue when running in buffered mode
- // since the encoder will be paused if the queue grow too large.
- paced_sender_->set_max_queue_length_ms(-1);
} else {
// Real-time mode - enable frame droppers.
vpm_.EnableTemporalDecimation(true);
vcm_.EnableFrameDropper(true);
- paced_sender_->set_max_queue_length_ms(
- PacedSender::kDefaultMaxQueueLengthMs);
}
}
@@ -885,6 +924,7 @@ void ViEEncoder::OnNetworkChanged(const uint32_t bitrate_bps,
pad_up_to_bitrate_kbps = bitrate_kbps;
paced_sender_->UpdateBitrate(
+ bitrate_kbps,
PacedSender::kDefaultPaceMultiplier * bitrate_kbps,
pad_up_to_bitrate_kbps);
default_rtp_rtcp_->SetTargetSendBitrate(stream_bitrates);
diff --git a/video_engine/vie_encoder.h b/video_engine/vie_encoder.h
index 51c1d016..1e358def 100644
--- a/video_engine/vie_encoder.h
+++ b/video_engine/vie_encoder.h
@@ -192,6 +192,10 @@ class ViEEncoder
int TimeToSendPadding(int bytes);
private:
bool EncoderPaused() const EXCLUSIVE_LOCKS_REQUIRED(data_cs_);
+ void TraceFrameDropStart() EXCLUSIVE_LOCKS_REQUIRED(data_cs_);
+ void TraceFrameDropEnd() EXCLUSIVE_LOCKS_REQUIRED(data_cs_);
+
+ void UpdateHistograms();
int32_t engine_id_;
const int channel_id_;
@@ -235,6 +239,7 @@ class ViEEncoder
QMVideoSettingsCallback* qm_callback_;
bool video_suspended_ GUARDED_BY(data_cs_);
I420FrameCallback* pre_encode_callback_ GUARDED_BY(callback_cs_);
+ const int64_t start_ms_;
};
} // namespace webrtc
diff --git a/video_engine_tests.isolate b/video_engine_tests.isolate
index 40454bd6..fc840829 100644
--- a/video_engine_tests.isolate
+++ b/video_engine_tests.isolate
@@ -9,7 +9,7 @@
'conditions': [
['OS=="android"', {
'variables': {
- 'isolate_dependency_untracked': [
+ 'files': [
'<(DEPTH)/data/',
'<(DEPTH)/resources/',
],
@@ -20,14 +20,11 @@
'command': [
'<(PRODUCT_DIR)/video_engine_tests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'<(DEPTH)/DEPS',
'<(DEPTH)/resources/foreman_cif_short.yuv',
'<(PRODUCT_DIR)/video_engine_tests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_untracked': [
- '<(DEPTH)/tools/swarming_client/',
- ],
},
}],
],
diff --git a/video_receive_stream.h b/video_receive_stream.h
index 4eb5532b..5ab898c7 100644
--- a/video_receive_stream.h
+++ b/video_receive_stream.h
@@ -31,30 +31,38 @@ enum RtcpMode { kRtcpCompound, kRtcpReducedSize };
class VideoDecoder;
-// TODO(mflodman) Move all these settings to VideoDecoder and move the
-// declaration to common_types.h.
-struct ExternalVideoDecoder {
- ExternalVideoDecoder()
- : decoder(NULL), payload_type(0), renderer(false), expected_delay_ms(0) {}
- // The actual decoder.
- VideoDecoder* decoder;
-
- // Received RTP packets with this payload type will be sent to this decoder
- // instance.
- int payload_type;
-
- // 'true' if the decoder handles rendering as well.
- bool renderer;
-
- // The expected delay for decoding and rendering, i.e. the frame will be
- // delivered this many milliseconds, if possible, earlier than the ideal
- // render time.
- // Note: Ignored if 'renderer' is false.
- int expected_delay_ms;
-};
-
class VideoReceiveStream {
public:
+ // TODO(mflodman) Move all these settings to VideoDecoder and move the
+ // declaration to common_types.h.
+ struct Decoder {
+ Decoder()
+ : decoder(NULL),
+ payload_type(0),
+ renderer(false),
+ expected_delay_ms(0) {}
+
+ // The actual decoder instance.
+ VideoDecoder* decoder;
+
+ // Received RTP packets with this payload type will be sent to this decoder
+ // instance.
+ int payload_type;
+
+ // Name of the decoded payload (such as VP8). Maps back to the depacketizer
+ // used to unpack incoming packets.
+ std::string payload_name;
+
+ // 'true' if the decoder handles rendering as well.
+ bool renderer;
+
+ // The expected delay for decoding and rendering, i.e. the frame will be
+ // delivered this many milliseconds, if possible, earlier than the ideal
+ // render time.
+ // Note: Ignored if 'renderer' is false.
+ int expected_delay_ms;
+ };
+
struct Stats : public StreamStats {
Stats()
: network_frame_rate(0),
@@ -77,12 +85,13 @@ class VideoReceiveStream {
Config()
: renderer(NULL),
render_delay_ms(0),
- audio_channel_id(0),
+ audio_channel_id(-1),
pre_decode_callback(NULL),
pre_render_callback(NULL),
target_delay_ms(0) {}
- // Codecs the receive stream can receive.
- std::vector<VideoCodec> codecs;
+
+ // Decoders for every payload that we can receive.
+ std::vector<Decoder> decoders;
// Receive-stream specific RTP settings.
struct Rtp {
@@ -162,10 +171,6 @@ class VideoReceiveStream {
// stream. 'NULL' disables the callback.
I420FrameCallback* pre_render_callback;
- // External video decoders to be used if incoming payload type matches the
- // registered type for an external decoder.
- std::vector<ExternalVideoDecoder> external_decoders;
-
// Target delay in milliseconds. A positive value indicates this stream is
// used for streaming instead of a real-time call.
int target_delay_ms;
@@ -173,10 +178,9 @@ class VideoReceiveStream {
virtual void Start() = 0;
virtual void Stop() = 0;
- virtual Stats GetStats() const = 0;
- // TODO(mflodman) Replace this with callback.
- virtual void GetCurrentReceiveCodec(VideoCodec* receive_codec) = 0;
+ // TODO(pbos): Add info on currently-received codec to Stats.
+ virtual Stats GetStats() const = 0;
protected:
virtual ~VideoReceiveStream() {}
diff --git a/video_send_stream.h b/video_send_stream.h
index dd2bec12..aa5033af 100644
--- a/video_send_stream.h
+++ b/video_send_stream.h
@@ -60,6 +60,7 @@ class VideoSendStream {
struct EncoderSettings {
EncoderSettings() : payload_type(-1), encoder(NULL) {}
+
std::string ToString() const;
std::string payload_name;
@@ -72,9 +73,7 @@ class VideoSendStream {
static const size_t kDefaultMaxPacketSize = 1500 - 40; // TCP over IPv4.
struct Rtp {
- Rtp()
- : max_packet_size(kDefaultMaxPacketSize),
- min_transmit_bitrate_bps(0) {}
+ Rtp() : max_packet_size(kDefaultMaxPacketSize) {}
std::string ToString() const;
std::vector<uint32_t> ssrcs;
@@ -82,11 +81,6 @@ class VideoSendStream {
// Max RTP packet size delivered to send transport from VideoEngine.
size_t max_packet_size;
- // Padding will be used up to this bitrate regardless of the bitrate
- // produced by the encoder. Padding above what's actually produced by the
- // encoder helps maintaining a higher bitrate estimate.
- int min_transmit_bitrate_bps;
-
// RTP header extensions to use for this send stream.
std::vector<RtpExtension> extensions;
diff --git a/voice_engine/utility.cc b/voice_engine/utility.cc
index 561b4ef5..f952d6c5 100644
--- a/voice_engine/utility.cc
+++ b/voice_engine/utility.cc
@@ -22,8 +22,7 @@ namespace webrtc {
namespace voe {
// TODO(ajm): There is significant overlap between RemixAndResample and
-// ConvertToCodecFormat, but if we're to consolidate we should probably make a
-// real converter class.
+// ConvertToCodecFormat. Consolidate using AudioConverter.
void RemixAndResample(const AudioFrame& src_frame,
PushResampler<int16_t>* resampler,
AudioFrame* dst_frame) {
diff --git a/voice_engine/voe_auto_test.isolate b/voice_engine/voe_auto_test.isolate
index 3722b7d7..c13110e7 100644
--- a/voice_engine/voe_auto_test.isolate
+++ b/voice_engine/voe_auto_test.isolate
@@ -9,7 +9,7 @@
'conditions': [
['OS=="android"', {
'variables': {
- 'isolate_dependency_untracked': [
+ 'files': [
'<(DEPTH)/data/',
'<(DEPTH)/resources/',
],
@@ -21,13 +21,10 @@
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/voe_auto_test<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/voe_auto_test<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_untracked': [
- '<(DEPTH)/tools/swarming_client/',
- ],
},
}],
],
diff --git a/voice_engine/voice_engine.gyp b/voice_engine/voice_engine.gyp
index deed467a..83b356d7 100644
--- a/voice_engine/voice_engine.gyp
+++ b/voice_engine/voice_engine.gyp
@@ -148,7 +148,7 @@
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
- '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default',
+ '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers_default',
'<(webrtc_root)/test/test.gyp:channel_transport',
'<(webrtc_root)/test/test.gyp:test_support',
],
@@ -216,7 +216,7 @@
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
- '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default',
+ '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers_default',
'<(webrtc_root)/test/test.gyp:channel_transport',
'<(webrtc_root)/test/test.gyp:test_support',
],
@@ -293,7 +293,6 @@
],
'includes': [
'../build/isolate.gypi',
- 'voice_engine_unittests.isolate',
],
'sources': [
'voice_engine_unittests.isolate',
@@ -307,7 +306,6 @@
],
'includes': [
'../build/isolate.gypi',
- 'voe_auto_test.isolate',
],
'sources': [
'voe_auto_test.isolate',
diff --git a/voice_engine/voice_engine.target.darwin-arm.mk b/voice_engine/voice_engine.target.darwin-arm.mk
index 10a05549..2b86f9c0 100644
--- a/voice_engine/voice_engine.target.darwin-arm.mk
+++ b/voice_engine/voice_engine.target.darwin-arm.mk
@@ -107,11 +107,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -127,6 +129,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -229,11 +232,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -249,6 +254,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/voice_engine/voice_engine.target.darwin-arm64.mk b/voice_engine/voice_engine.target.darwin-arm64.mk
index 6c0fd63f..62897d86 100644
--- a/voice_engine/voice_engine.target.darwin-arm64.mk
+++ b/voice_engine/voice_engine.target.darwin-arm64.mk
@@ -96,11 +96,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -109,10 +111,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -203,11 +207,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -216,10 +222,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/voice_engine/voice_engine.target.darwin-mips.mk b/voice_engine/voice_engine.target.darwin-mips.mk
index c58e6837..1b28efbc 100644
--- a/voice_engine/voice_engine.target.darwin-mips.mk
+++ b/voice_engine/voice_engine.target.darwin-mips.mk
@@ -100,11 +100,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -119,6 +121,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -214,11 +217,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -233,6 +238,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/voice_engine/voice_engine.target.darwin-mips64.mk b/voice_engine/voice_engine.target.darwin-mips64.mk
new file mode 100644
index 00000000..88785765
--- /dev/null
+++ b/voice_engine/voice_engine.target.darwin-mips64.mk
@@ -0,0 +1,301 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_voice_engine_voice_engine_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/voice_engine/channel.cc \
+ third_party/webrtc/voice_engine/channel_manager.cc \
+ third_party/webrtc/voice_engine/dtmf_inband.cc \
+ third_party/webrtc/voice_engine/dtmf_inband_queue.cc \
+ third_party/webrtc/voice_engine/level_indicator.cc \
+ third_party/webrtc/voice_engine/monitor_module.cc \
+ third_party/webrtc/voice_engine/network_predictor.cc \
+ third_party/webrtc/voice_engine/output_mixer.cc \
+ third_party/webrtc/voice_engine/shared_data.cc \
+ third_party/webrtc/voice_engine/statistics.cc \
+ third_party/webrtc/voice_engine/transmit_mixer.cc \
+ third_party/webrtc/voice_engine/utility.cc \
+ third_party/webrtc/voice_engine/voe_audio_processing_impl.cc \
+ third_party/webrtc/voice_engine/voe_base_impl.cc \
+ third_party/webrtc/voice_engine/voe_codec_impl.cc \
+ third_party/webrtc/voice_engine/voe_dtmf_impl.cc \
+ third_party/webrtc/voice_engine/voe_external_media_impl.cc \
+ third_party/webrtc/voice_engine/voe_file_impl.cc \
+ third_party/webrtc/voice_engine/voe_hardware_impl.cc \
+ third_party/webrtc/voice_engine/voe_neteq_stats_impl.cc \
+ third_party/webrtc/voice_engine/voe_network_impl.cc \
+ third_party/webrtc/voice_engine/voe_rtp_rtcp_impl.cc \
+ third_party/webrtc/voice_engine/voe_video_sync_impl.cc \
+ third_party/webrtc/voice_engine/voe_volume_control_impl.cc \
+ third_party/webrtc/voice_engine/voice_engine_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_conference_mixer/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_device/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/media_file/interface \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_conference_mixer/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_device/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/media_file/interface \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_voice_engine_voice_engine_gyp
+
+# Alias gyp target name.
+.PHONY: voice_engine
+voice_engine: third_party_webrtc_voice_engine_voice_engine_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/voice_engine/voice_engine.target.darwin-x86.mk b/voice_engine/voice_engine.target.darwin-x86.mk
index af4c7ad3..3e1bcae7 100644
--- a/voice_engine/voice_engine.target.darwin-x86.mk
+++ b/voice_engine/voice_engine.target.darwin-x86.mk
@@ -102,11 +102,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -119,6 +121,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -215,11 +218,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -232,6 +237,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/voice_engine/voice_engine.target.darwin-x86_64.mk b/voice_engine/voice_engine.target.darwin-x86_64.mk
index 6a78b6b3..55afb796 100644
--- a/voice_engine/voice_engine.target.darwin-x86_64.mk
+++ b/voice_engine/voice_engine.target.darwin-x86_64.mk
@@ -101,11 +101,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -118,6 +120,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -213,11 +216,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -230,6 +235,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/voice_engine/voice_engine.target.linux-arm.mk b/voice_engine/voice_engine.target.linux-arm.mk
index 10a05549..2b86f9c0 100644
--- a/voice_engine/voice_engine.target.linux-arm.mk
+++ b/voice_engine/voice_engine.target.linux-arm.mk
@@ -107,11 +107,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -127,6 +129,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -229,11 +232,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -249,6 +254,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/voice_engine/voice_engine.target.linux-arm64.mk b/voice_engine/voice_engine.target.linux-arm64.mk
index 6c0fd63f..62897d86 100644
--- a/voice_engine/voice_engine.target.linux-arm64.mk
+++ b/voice_engine/voice_engine.target.linux-arm64.mk
@@ -96,11 +96,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -109,10 +111,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -203,11 +207,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -216,10 +222,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/voice_engine/voice_engine.target.linux-mips.mk b/voice_engine/voice_engine.target.linux-mips.mk
index c58e6837..1b28efbc 100644
--- a/voice_engine/voice_engine.target.linux-mips.mk
+++ b/voice_engine/voice_engine.target.linux-mips.mk
@@ -100,11 +100,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -119,6 +121,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -214,11 +217,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -233,6 +238,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/voice_engine/voice_engine.target.linux-mips64.mk b/voice_engine/voice_engine.target.linux-mips64.mk
new file mode 100644
index 00000000..88785765
--- /dev/null
+++ b/voice_engine/voice_engine.target.linux-mips64.mk
@@ -0,0 +1,301 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_voice_engine_voice_engine_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/voice_engine/channel.cc \
+ third_party/webrtc/voice_engine/channel_manager.cc \
+ third_party/webrtc/voice_engine/dtmf_inband.cc \
+ third_party/webrtc/voice_engine/dtmf_inband_queue.cc \
+ third_party/webrtc/voice_engine/level_indicator.cc \
+ third_party/webrtc/voice_engine/monitor_module.cc \
+ third_party/webrtc/voice_engine/network_predictor.cc \
+ third_party/webrtc/voice_engine/output_mixer.cc \
+ third_party/webrtc/voice_engine/shared_data.cc \
+ third_party/webrtc/voice_engine/statistics.cc \
+ third_party/webrtc/voice_engine/transmit_mixer.cc \
+ third_party/webrtc/voice_engine/utility.cc \
+ third_party/webrtc/voice_engine/voe_audio_processing_impl.cc \
+ third_party/webrtc/voice_engine/voe_base_impl.cc \
+ third_party/webrtc/voice_engine/voe_codec_impl.cc \
+ third_party/webrtc/voice_engine/voe_dtmf_impl.cc \
+ third_party/webrtc/voice_engine/voe_external_media_impl.cc \
+ third_party/webrtc/voice_engine/voe_file_impl.cc \
+ third_party/webrtc/voice_engine/voe_hardware_impl.cc \
+ third_party/webrtc/voice_engine/voe_neteq_stats_impl.cc \
+ third_party/webrtc/voice_engine/voe_network_impl.cc \
+ third_party/webrtc/voice_engine/voe_rtp_rtcp_impl.cc \
+ third_party/webrtc/voice_engine/voe_video_sync_impl.cc \
+ third_party/webrtc/voice_engine/voe_volume_control_impl.cc \
+ third_party/webrtc/voice_engine/voice_engine_impl.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_conference_mixer/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_device/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/media_file/interface \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/resampler/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/signal_processing/include \
+ $(LOCAL_PATH)/third_party/webrtc/common_audio/vad/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_coding/main/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/interface \
+ $(LOCAL_PATH)/third_party/webrtc \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_conference_mixer/interface \
+ $(LOCAL_PATH)/third_party/webrtc/modules/audio_device/include \
+ $(LOCAL_PATH)/third_party/webrtc/modules/media_file/interface \
+ $(LOCAL_PATH)/third_party/webrtc/system_wrappers/interface
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_voice_engine_voice_engine_gyp
+
+# Alias gyp target name.
+.PHONY: voice_engine
+voice_engine: third_party_webrtc_voice_engine_voice_engine_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/voice_engine/voice_engine.target.linux-x86.mk b/voice_engine/voice_engine.target.linux-x86.mk
index af4c7ad3..3e1bcae7 100644
--- a/voice_engine/voice_engine.target.linux-x86.mk
+++ b/voice_engine/voice_engine.target.linux-x86.mk
@@ -102,11 +102,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -119,6 +121,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -215,11 +218,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -232,6 +237,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/voice_engine/voice_engine.target.linux-x86_64.mk b/voice_engine/voice_engine.target.linux-x86_64.mk
index 6a78b6b3..55afb796 100644
--- a/voice_engine/voice_engine.target.linux-x86_64.mk
+++ b/voice_engine/voice_engine.target.linux-x86_64.mk
@@ -101,11 +101,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -118,6 +120,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -213,11 +216,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -230,6 +235,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/voice_engine/voice_engine_unittests.isolate b/voice_engine/voice_engine_unittests.isolate
index 02356804..4cd1f907 100644
--- a/voice_engine/voice_engine_unittests.isolate
+++ b/voice_engine/voice_engine_unittests.isolate
@@ -9,7 +9,7 @@
'conditions': [
['OS=="android"', {
'variables': {
- 'isolate_dependency_untracked': [
+ 'files': [
'<(DEPTH)/data/',
'<(DEPTH)/resources/',
],
@@ -21,13 +21,10 @@
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/voice_engine_unittests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'<(DEPTH)/testing/test_env.py',
'<(PRODUCT_DIR)/voice_engine_unittests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_untracked': [
- '<(DEPTH)/tools/swarming_client/',
- ],
},
}],
],
diff --git a/webrtc.gyp b/webrtc.gyp
index bfcec040..f9ed8838 100644
--- a/webrtc.gyp
+++ b/webrtc.gyp
@@ -10,6 +10,8 @@
['include_tests==1', {
'includes': [
'libjingle/xmllite/xmllite_tests.gypi',
+ 'libjingle/xmpp/xmpp_tests.gypi',
+ 'p2p/p2p_tests.gypi',
'sound/sound_tests.gypi',
'webrtc_tests.gypi',
],
@@ -27,11 +29,14 @@
'common_audio/common_audio.gyp:*',
'common_video/common_video.gyp:*',
'libjingle/xmllite/xmllite.gyp:*',
+ 'libjingle/xmpp/xmpp.gyp:*',
'modules/modules.gyp:*',
+ 'p2p/p2p.gyp:*',
'system_wrappers/source/system_wrappers.gyp:*',
'video_engine/video_engine.gyp:*',
'voice_engine/voice_engine.gyp:*',
'<(webrtc_vp8_dir)/vp8.gyp:*',
+ '<(webrtc_vp9_dir)/vp9.gyp:*',
],
},
'targets': [
diff --git a/webrtc.target.darwin-arm.mk b/webrtc.target.darwin-arm.mk
index ce02281b..6395a831 100644
--- a/webrtc.target.darwin-arm.mk
+++ b/webrtc.target.darwin-arm.mk
@@ -89,11 +89,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -109,6 +111,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -201,11 +204,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -221,6 +226,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/webrtc.target.darwin-arm64.mk b/webrtc.target.darwin-arm64.mk
index 6b657972..b14a1ef3 100644
--- a/webrtc.target.darwin-arm64.mk
+++ b/webrtc.target.darwin-arm64.mk
@@ -78,11 +78,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -91,10 +93,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -175,11 +179,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -188,10 +194,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/webrtc.target.darwin-mips.mk b/webrtc.target.darwin-mips.mk
index 21c735f5..06bb28b6 100644
--- a/webrtc.target.darwin-mips.mk
+++ b/webrtc.target.darwin-mips.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -186,11 +189,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -205,6 +210,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/webrtc.target.darwin-mips64.mk b/webrtc.target.darwin-mips64.mk
new file mode 100644
index 00000000..e24144cb
--- /dev/null
+++ b/webrtc.target.darwin-mips64.mk
@@ -0,0 +1,263 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_webrtc_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/video/call.cc \
+ third_party/webrtc/video/encoded_frame_callback_adapter.cc \
+ third_party/webrtc/video/send_statistics_proxy.cc \
+ third_party/webrtc/video/receive_statistics_proxy.cc \
+ third_party/webrtc/video/transport_adapter.cc \
+ third_party/webrtc/video/video_receive_stream.cc \
+ third_party/webrtc/video/video_send_stream.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_webrtc_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc
+webrtc: third_party_webrtc_webrtc_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/webrtc.target.darwin-x86.mk b/webrtc.target.darwin-x86.mk
index ed385335..8365cfa3 100644
--- a/webrtc.target.darwin-x86.mk
+++ b/webrtc.target.darwin-x86.mk
@@ -84,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -187,11 +190,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -204,6 +209,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/webrtc.target.darwin-x86_64.mk b/webrtc.target.darwin-x86_64.mk
index a68c7259..5bdde76a 100644
--- a/webrtc.target.darwin-x86_64.mk
+++ b/webrtc.target.darwin-x86_64.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -185,11 +188,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -202,6 +207,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/webrtc.target.linux-arm.mk b/webrtc.target.linux-arm.mk
index ce02281b..6395a831 100644
--- a/webrtc.target.linux-arm.mk
+++ b/webrtc.target.linux-arm.mk
@@ -89,11 +89,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -109,6 +111,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -201,11 +204,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -221,6 +226,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/webrtc.target.linux-arm64.mk b/webrtc.target.linux-arm64.mk
index 6b657972..b14a1ef3 100644
--- a/webrtc.target.linux-arm64.mk
+++ b/webrtc.target.linux-arm64.mk
@@ -78,11 +78,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -91,10 +93,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -175,11 +179,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -188,10 +194,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/webrtc.target.linux-mips.mk b/webrtc.target.linux-mips.mk
index 21c735f5..06bb28b6 100644
--- a/webrtc.target.linux-mips.mk
+++ b/webrtc.target.linux-mips.mk
@@ -82,11 +82,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -186,11 +189,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -205,6 +210,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/webrtc.target.linux-mips64.mk b/webrtc.target.linux-mips64.mk
new file mode 100644
index 00000000..e24144cb
--- /dev/null
+++ b/webrtc.target.linux-mips64.mk
@@ -0,0 +1,263 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_webrtc_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/video/call.cc \
+ third_party/webrtc/video/encoded_frame_callback_adapter.cc \
+ third_party/webrtc/video/send_statistics_proxy.cc \
+ third_party/webrtc/video/receive_statistics_proxy.cc \
+ third_party/webrtc/video/transport_adapter.cc \
+ third_party/webrtc/video/video_receive_stream.cc \
+ third_party/webrtc/video/video_send_stream.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_webrtc_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc
+webrtc: third_party_webrtc_webrtc_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/webrtc.target.linux-x86.mk b/webrtc.target.linux-x86.mk
index ed385335..8365cfa3 100644
--- a/webrtc.target.linux-x86.mk
+++ b/webrtc.target.linux-x86.mk
@@ -84,11 +84,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -101,6 +103,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -187,11 +190,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -204,6 +209,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/webrtc.target.linux-x86_64.mk b/webrtc.target.linux-x86_64.mk
index a68c7259..5bdde76a 100644
--- a/webrtc.target.linux-x86_64.mk
+++ b/webrtc.target.linux-x86_64.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -100,6 +102,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -185,11 +188,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -202,6 +207,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/webrtc_common.target.darwin-arm.mk b/webrtc_common.target.darwin-arm.mk
index aa34248b..94645388 100644
--- a/webrtc_common.target.darwin-arm.mk
+++ b/webrtc_common.target.darwin-arm.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -103,6 +105,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -195,11 +198,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -215,6 +220,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/webrtc_common.target.darwin-arm64.mk b/webrtc_common.target.darwin-arm64.mk
index 8d6a4cdb..882b81bc 100644
--- a/webrtc_common.target.darwin-arm64.mk
+++ b/webrtc_common.target.darwin-arm64.mk
@@ -72,11 +72,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -85,10 +87,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -169,11 +173,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -182,10 +188,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/webrtc_common.target.darwin-mips.mk b/webrtc_common.target.darwin-mips.mk
index 9b6bc757..9270d93b 100644
--- a/webrtc_common.target.darwin-mips.mk
+++ b/webrtc_common.target.darwin-mips.mk
@@ -76,11 +76,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -95,6 +97,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -180,11 +183,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -199,6 +204,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/webrtc_common.target.darwin-mips64.mk b/webrtc_common.target.darwin-mips64.mk
new file mode 100644
index 00000000..be67b86c
--- /dev/null
+++ b/webrtc_common.target.darwin-mips64.mk
@@ -0,0 +1,257 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_webrtc_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/config.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_webrtc_common_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_common
+webrtc_common: third_party_webrtc_webrtc_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/webrtc_common.target.darwin-x86.mk b/webrtc_common.target.darwin-x86.mk
index 2d7b03bf..3f123a37 100644
--- a/webrtc_common.target.darwin-x86.mk
+++ b/webrtc_common.target.darwin-x86.mk
@@ -78,11 +78,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -95,6 +97,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -181,11 +184,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -198,6 +203,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/webrtc_common.target.darwin-x86_64.mk b/webrtc_common.target.darwin-x86_64.mk
index a89d1ed2..05aebf04 100644
--- a/webrtc_common.target.darwin-x86_64.mk
+++ b/webrtc_common.target.darwin-x86_64.mk
@@ -77,11 +77,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -94,6 +96,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -179,11 +182,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -196,6 +201,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/webrtc_common.target.linux-arm.mk b/webrtc_common.target.linux-arm.mk
index aa34248b..94645388 100644
--- a/webrtc_common.target.linux-arm.mk
+++ b/webrtc_common.target.linux-arm.mk
@@ -83,11 +83,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -103,6 +105,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -195,11 +198,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -215,6 +220,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/webrtc_common.target.linux-arm64.mk b/webrtc_common.target.linux-arm64.mk
index 8d6a4cdb..882b81bc 100644
--- a/webrtc_common.target.linux-arm64.mk
+++ b/webrtc_common.target.linux-arm64.mk
@@ -72,11 +72,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -85,10 +87,12 @@ MY_DEFS_Debug := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -169,11 +173,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -182,10 +188,12 @@ MY_DEFS_Release := \
'-DWEBRTC_MODULE_UTILITY_VIDEO' \
'-DWEBRTC_CHROMIUM_BUILD' \
'-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_ARCH_ARM' \
'-DWEBRTC_POSIX' \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/webrtc_common.target.linux-mips.mk b/webrtc_common.target.linux-mips.mk
index 9b6bc757..9270d93b 100644
--- a/webrtc_common.target.linux-mips.mk
+++ b/webrtc_common.target.linux-mips.mk
@@ -76,11 +76,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -95,6 +97,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -180,11 +183,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -199,6 +204,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/webrtc_common.target.linux-mips64.mk b/webrtc_common.target.linux-mips64.mk
new file mode 100644
index 00000000..be67b86c
--- /dev/null
+++ b/webrtc_common.target.linux-mips64.mk
@@ -0,0 +1,257 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := third_party_webrtc_webrtc_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+LOCAL_SDK_VERSION := 21
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+ third_party/webrtc/config.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -g \
+ -gdwarf-4 \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Debug := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+ '-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+ '-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+ -fstack-protector \
+ --param=ssp-buffer-size=4 \
+ \
+ -fno-strict-aliasing \
+ -Wall \
+ -Wno-unused-parameter \
+ -Wno-missing-field-initializers \
+ -fvisibility=hidden \
+ -pipe \
+ -fPIC \
+ -Wno-unused-local-typedefs \
+ -fno-builtin-cos \
+ -fno-builtin-sin \
+ -fno-builtin-cosf \
+ -fno-builtin-sinf \
+ -ffunction-sections \
+ -funwind-tables \
+ -g \
+ -fstack-protector \
+ -fno-short-enums \
+ -finline-limit=64 \
+ -Wa,--noexecstack \
+ -U_FORTIFY_SOURCE \
+ -Wno-extra \
+ -Wno-ignored-qualifiers \
+ -Wno-type-limits \
+ -Wno-unused-but-set-variable \
+ -Os \
+ -fno-ident \
+ -fdata-sections \
+ -ffunction-sections \
+ -fomit-frame-pointer \
+ -funwind-tables
+
+MY_DEFS_Release := \
+ '-DV8_DEPRECATION_WARNINGS' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DNO_TCMALLOC' \
+ '-DDISABLE_NACL' \
+ '-DCHROMIUM_BUILD' \
+ '-DUSE_LIBJPEG_TURBO=1' \
+ '-DENABLE_WEBRTC=1' \
+ '-DUSE_PROPRIETARY_CODECS' \
+ '-DENABLE_BROWSER_CDMS' \
+ '-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+ '-DDONT_EMBED_BUILD_METADATA' \
+ '-DCLD_VERSION=1' \
+ '-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
+ '-DENABLE_MANAGED_USERS=1' \
+ '-DVIDEO_HOLE=1' \
+ '-DENABLE_LOAD_COMPLETION_HACKS=1' \
+ '-DWEBRTC_RESTRICT_LOGGING' \
+ '-DEXPAT_RELATIVE_PATH' \
+ '-DWEBRTC_MODULE_UTILITY_VIDEO' \
+ '-DWEBRTC_CHROMIUM_BUILD' \
+ '-DLOGGING_INSIDE_WEBRTC' \
+ '-DWEBRTC_POSIX' \
+ '-DWEBRTC_LINUX' \
+ '-DWEBRTC_ANDROID' \
+ '-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
+ '-DUSE_OPENSSL=1' \
+ '-DUSE_OPENSSL_CERTS=1' \
+ '-D__STDC_CONSTANT_MACROS' \
+ '-D__STDC_FORMAT_MACROS' \
+ '-DANDROID' \
+ '-D__GNU_SOURCE=1' \
+ '-DUSE_STLPORT=1' \
+ '-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+ '-DCHROME_BUILD_ID=""' \
+ '-DNDEBUG' \
+ '-DNVALGRIND' \
+ '-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+ '-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+ $(gyp_shared_intermediate_dir) \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/third_party/webrtc/overrides \
+ $(LOCAL_PATH)/third_party
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+ -fno-exceptions \
+ -fno-rtti \
+ -fno-threadsafe-statics \
+ -fvisibility-inlines-hidden \
+ -Wsign-compare \
+ -Wno-uninitialized \
+ -std=gnu++11 \
+ -Wno-narrowing \
+ -Wno-literal-suffix \
+ -Wno-non-virtual-dtor \
+ -Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+### Set directly by aosp_build_settings.
+LOCAL_CLANG := false
+LOCAL_NDK_STL_VARIANT := stlport_static
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: third_party_webrtc_webrtc_common_gyp
+
+# Alias gyp target name.
+.PHONY: webrtc_common
+webrtc_common: third_party_webrtc_webrtc_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/webrtc_common.target.linux-x86.mk b/webrtc_common.target.linux-x86.mk
index 2d7b03bf..3f123a37 100644
--- a/webrtc_common.target.linux-x86.mk
+++ b/webrtc_common.target.linux-x86.mk
@@ -78,11 +78,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -95,6 +97,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -181,11 +184,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -198,6 +203,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/webrtc_common.target.linux-x86_64.mk b/webrtc_common.target.linux-x86_64.mk
index a89d1ed2..05aebf04 100644
--- a/webrtc_common.target.linux-x86_64.mk
+++ b/webrtc_common.target.linux-x86_64.mk
@@ -77,11 +77,13 @@ MY_DEFS_Debug := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -94,6 +96,7 @@ MY_DEFS_Debug := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
@@ -179,11 +182,13 @@ MY_DEFS_Release := \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_BROWSER_CDMS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NOTIFICATIONS' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
- '-DENABLE_EGLIMAGE=1' \
+ '-DDONT_EMBED_BUILD_METADATA' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
+ '-DENABLE_BASIC_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
'-DVIDEO_HOLE=1' \
'-DENABLE_LOAD_COMPLETION_HACKS=1' \
@@ -196,6 +201,7 @@ MY_DEFS_Release := \
'-DWEBRTC_LINUX' \
'-DWEBRTC_ANDROID' \
'-DWEBRTC_ANDROID_OPENSLES' \
+ '-DUSE_LIBPCI=1' \
'-DUSE_OPENSSL=1' \
'-DUSE_OPENSSL_CERTS=1' \
'-D__STDC_CONSTANT_MACROS' \
diff --git a/webrtc_examples.gyp b/webrtc_examples.gyp
index 0c7293f8..4d631100 100644
--- a/webrtc_examples.gyp
+++ b/webrtc_examples.gyp
@@ -18,7 +18,7 @@
'<(DEPTH)/third_party/icu/icu.gyp:icuuc',
'<(webrtc_root)/modules/modules.gyp:video_capture_module_internal_impl',
'<(webrtc_root)/modules/modules.gyp:video_render_module_internal_impl',
- '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default',
+ '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers_default',
'<(webrtc_root)/test/test.gyp:channel_transport',
'<(webrtc_root)/video_engine/video_engine.gyp:video_engine_core',
'<(webrtc_root)/voice_engine/voice_engine.gyp:voice_engine',
diff --git a/webrtc_perf_tests.isolate b/webrtc_perf_tests.isolate
index b39c83df..2c547be5 100644
--- a/webrtc_perf_tests.isolate
+++ b/webrtc_perf_tests.isolate
@@ -9,7 +9,7 @@
'conditions': [
['OS=="android"', {
'variables': {
- 'isolate_dependency_untracked': [
+ 'files': [
'<(DEPTH)/data/',
'<(DEPTH)/resources/',
],
@@ -20,16 +20,13 @@
'command': [
'<(PRODUCT_DIR)/webrtc_perf_tests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'<(DEPTH)/DEPS',
'<(DEPTH)/resources/foreman_cif.yuv',
'<(DEPTH)/resources/paris_qcif.yuv',
'<(DEPTH)/resources/voice_engine/audio_long16.pcm',
'<(PRODUCT_DIR)/webrtc_perf_tests<(EXECUTABLE_SUFFIX)',
],
- 'isolate_dependency_untracked': [
- '<(DEPTH)/tools/swarming_client/',
- ],
},
}],
],
diff --git a/webrtc_tests.gypi b/webrtc_tests.gypi
index cfd5a4b2..dc17e707 100644
--- a/webrtc_tests.gypi
+++ b/webrtc_tests.gypi
@@ -15,8 +15,12 @@
'base/base_tests.gyp:rtc_base_tests_utils',
'base/base_tests.gyp:rtc_base_tests',
'libjingle/xmllite/xmllite.gyp:rtc_xmllite',
+ 'libjingle/xmpp/xmpp.gyp:rtc_xmpp',
+ 'p2p/p2p.gyp:rtc_p2p',
+ 'rtc_p2p_unittest',
'rtc_sound_tests',
'rtc_xmllite_unittest',
+ 'rtc_xmpp_unittest',
'sound/sound.gyp:rtc_sound',
'<(DEPTH)/testing/gtest.gyp:gtest',
],
@@ -52,8 +56,10 @@
'<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
'test/webrtc_test_common.gyp:webrtc_test_common',
'test/webrtc_test_common.gyp:webrtc_test_renderer',
+ '<(webrtc_root)/modules/modules.gyp:video_capture_module_internal_impl',
'<(webrtc_root)/modules/modules.gyp:video_render_module_impl',
- '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default',
+ '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers_default',
+ 'test/test.gyp:test_main',
'webrtc',
],
},
@@ -78,8 +84,9 @@
'<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
'test/webrtc_test_common.gyp:webrtc_test_common',
'test/webrtc_test_common.gyp:webrtc_test_renderer',
+ '<(webrtc_root)/modules/modules.gyp:video_capture_module_impl',
'<(webrtc_root)/modules/modules.gyp:video_render_module_impl',
- '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default',
+ '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers_default',
'webrtc',
],
},
@@ -97,6 +104,7 @@
'dependencies': [
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(webrtc_root)/modules/modules.gyp:rtp_rtcp',
+ '<(webrtc_root)/modules/modules.gyp:video_capture_module_impl',
'<(webrtc_root)/modules/modules.gyp:video_render_module_impl',
'test/metrics.gyp:metrics',
'test/webrtc_test_common.gyp:webrtc_test_common',
@@ -125,6 +133,7 @@
'<(DEPTH)/testing/gtest.gyp:gtest',
'modules/modules.gyp:neteq_test_support', # Needed by neteq_performance_unittest.
'modules/modules.gyp:rtp_rtcp',
+ '<(webrtc_root)/modules/modules.gyp:video_capture_module_impl',
'test/webrtc_test_common.gyp:webrtc_test_common',
'test/test.gyp:test_main',
'webrtc',
@@ -167,7 +176,6 @@
],
'includes': [
'build/isolate.gypi',
- 'rtc_unittests.isolate',
],
'sources': [
'rtc_unittests.isolate',
@@ -181,7 +189,6 @@
],
'includes': [
'build/isolate.gypi',
- 'video_engine_tests.isolate',
],
'sources': [
'video_engine_tests.isolate',
@@ -195,7 +202,6 @@
],
'includes': [
'build/isolate.gypi',
- 'webrtc_perf_tests.isolate',
],
'sources': [
'webrtc_perf_tests.isolate',