Merge m-c to graphics.
authorMorris Tseng <mtseng@mozilla.com>
Thu, 29 Dec 2016 18:26:24 +0800
changeset 342012 b0853f9cf0b1e7fbd54b5e9a57c20d859e8ccc06
parent 342011 2fa9856e4ccf1f0cfe423c82f39df67b275d3b77 (current diff)
parent 327459 143bb4b9249e528e658f6ccc449991794b8675f8 (diff)
child 342013 3bb20d404fc3bcff3663c48c25f4903a1d29ce53
push id31345
push userkwierso@gmail.com
push dateFri, 10 Feb 2017 20:35:09 +0000
treeherdermozilla-central@a288fe35e494 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to graphics.
CLOBBER
dom/base/nsDOMWindowUtils.cpp
dom/ipc/TabChild.cpp
editor/libeditor/SetDocumentTitleTransaction.cpp
editor/libeditor/SetDocumentTitleTransaction.h
editor/libeditor/tests/test_set_document_title_transaction.html
gfx/layers/Layers.h
gfx/layers/client/ClientLayerManager.cpp
gfx/layers/client/ClientLayerManager.h
gfx/layers/ipc/CompositorVsyncScheduler.cpp
gfx/layers/moz.build
layout/painting/nsDisplayList.cpp
media/webrtc/trunk/README
media/webrtc/trunk/webrtc/base/asynchttprequest_unittest.cc
media/webrtc/trunk/webrtc/base/basicdefs.h
media/webrtc/trunk/webrtc/base/cpumonitor.cc
media/webrtc/trunk/webrtc/base/cpumonitor.h
media/webrtc/trunk/webrtc/base/cpumonitor_unittest.cc
media/webrtc/trunk/webrtc/base/fakecpumonitor.h
media/webrtc/trunk/webrtc/base/filelock.cc
media/webrtc/trunk/webrtc/base/filelock.h
media/webrtc/trunk/webrtc/base/filelock_unittest.cc
media/webrtc/trunk/webrtc/base/move.h
media/webrtc/trunk/webrtc/base/nssidentity.cc
media/webrtc/trunk/webrtc/base/nssidentity.h
media/webrtc/trunk/webrtc/base/nssstreamadapter.cc
media/webrtc/trunk/webrtc/base/nssstreamadapter.h
media/webrtc/trunk/webrtc/base/schanneladapter.cc
media/webrtc/trunk/webrtc/base/schanneladapter.h
media/webrtc/trunk/webrtc/base/win32toolhelp.h
media/webrtc/trunk/webrtc/base/win32toolhelp_unittest.cc
media/webrtc/trunk/webrtc/common_video/i420_video_frame.cc
media/webrtc/trunk/webrtc/common_video/interface/i420_buffer_pool.h
media/webrtc/trunk/webrtc/common_video/interface/i420_video_frame.h
media/webrtc/trunk/webrtc/common_video/interface/native_handle.h
media/webrtc/trunk/webrtc/common_video/interface/video_frame_buffer.h
media/webrtc/trunk/webrtc/common_video/interface/video_image.h
media/webrtc/trunk/webrtc/common_video/plane.cc
media/webrtc/trunk/webrtc/common_video/plane.h
media/webrtc/trunk/webrtc/experiments.h
media/webrtc/trunk/webrtc/modules/audio_coding/audio_codec_speed_tests.isolate
media/webrtc/trunk/webrtc/modules/audio_coding/codecs/cng/include/audio_encoder_cng.h
media/webrtc/trunk/webrtc/modules/audio_coding/codecs/cng/include/webrtc_cng.h
media/webrtc/trunk/webrtc/modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h
media/webrtc/trunk/webrtc/modules/audio_coding/codecs/g711/include/g711_interface.h
media/webrtc/trunk/webrtc/modules/audio_coding/codecs/g722/include/audio_encoder_g722.h
media/webrtc/trunk/webrtc/modules/audio_coding/codecs/g722/include/g722_interface.h
media/webrtc/trunk/webrtc/modules/audio_coding/codecs/ilbc/interface/audio_encoder_ilbc.h
media/webrtc/trunk/webrtc/modules/audio_coding/codecs/ilbc/interface/ilbc.h
media/webrtc/trunk/webrtc/modules/audio_coding/codecs/isac/fix/interface/audio_encoder_isacfix.h
media/webrtc/trunk/webrtc/modules/audio_coding/codecs/isac/fix/interface/isacfix.h
media/webrtc/trunk/webrtc/modules/audio_coding/codecs/isac/fix/source/filterbanks_neon.S
media/webrtc/trunk/webrtc/modules/audio_coding/codecs/isac/fix/source/filters_neon.S
media/webrtc/trunk/webrtc/modules/audio_coding/codecs/isac/fix/source/lattice_neon.S
media/webrtc/trunk/webrtc/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model_neon.S
media/webrtc/trunk/webrtc/modules/audio_coding/codecs/isac/fix/source/transform_neon.S
media/webrtc/trunk/webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h
media/webrtc/trunk/webrtc/modules/audio_coding/codecs/isac/main/interface/isac.h
media/webrtc/trunk/webrtc/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h
media/webrtc/trunk/webrtc/modules/audio_coding/codecs/opus/interface/opus_interface.h
media/webrtc/trunk/webrtc/modules/audio_coding/codecs/pcm16b/include/audio_encoder_pcm16b.h
media/webrtc/trunk/webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/OWNERS
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/OWNERS
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_codec_database.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_codec_database.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_common_defs.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_generic_codec_opus_test.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_generic_codec_test.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_neteq_unittest.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_receive_test.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_receive_test.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_receive_test_oldapi.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_receive_test_oldapi.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_receiver.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_receiver.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest_oldapi.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_resampler.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_resampler.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_send_test.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_send_test.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_send_test_oldapi.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/acm_send_test_oldapi.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/audio_coding_module.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/audio_coding_module.gypi
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/audio_coding_module_unittest.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/call_statistics.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/call_statistics.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/call_statistics_unittest.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/codec_manager.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/codec_manager.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/initial_delay_manager.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/initial_delay_manager.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/initial_delay_manager_unittest.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/nack.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/nack.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/acm2/nack_unittest.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/interface/audio_coding_module.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/interface/audio_coding_module_typedefs.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/ACMTest.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/APITest.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/APITest.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/Channel.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/Channel.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/EncodeDecodeTest.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/EncodeDecodeTest.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/PCMFile.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/PCMFile.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/PacketLossTest.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/PacketLossTest.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/RTPFile.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/RTPFile.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/SpatialAudio.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/SpatialAudio.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/TestAllCodecs.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/TestAllCodecs.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/TestRedFec.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/TestRedFec.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/TestStereo.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/TestStereo.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/TestVADDTX.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/TestVADDTX.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/Tester.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/TimedTrace.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/TimedTrace.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/TwoWayCommunication.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/TwoWayCommunication.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/delay_test.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/iSACTest.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/iSACTest.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/initial_delay_unittest.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/insert_packet_with_timing.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/opus_test.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/opus_test.h
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/target_delay_unittest.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/utility.cc
media/webrtc/trunk/webrtc/modules/audio_coding/main/test/utility.h
media/webrtc/trunk/webrtc/modules/audio_coding/neteq/audio_decoder_unittests.isolate
media/webrtc/trunk/webrtc/modules/audio_coding/neteq/interface/neteq.h
media/webrtc/trunk/webrtc/modules/audio_conference_mixer/interface/audio_conference_mixer.h
media/webrtc/trunk/webrtc/modules/audio_conference_mixer/interface/audio_conference_mixer_defines.h
media/webrtc/trunk/webrtc/modules/audio_conference_mixer/source/level_indicator.cc
media/webrtc/trunk/webrtc/modules/audio_conference_mixer/source/level_indicator.h
media/webrtc/trunk/webrtc/modules/audio_device/android/audio_device_utility_android.cc
media/webrtc/trunk/webrtc/modules/audio_device/android/audio_device_utility_android.h
media/webrtc/trunk/webrtc/modules/audio_device/android/audio_manager_jni.cc
media/webrtc/trunk/webrtc/modules/audio_device/android/audio_manager_jni.h
media/webrtc/trunk/webrtc/modules/audio_device/android/fine_audio_buffer.cc
media/webrtc/trunk/webrtc/modules/audio_device/android/fine_audio_buffer.h
media/webrtc/trunk/webrtc/modules/audio_device/android/fine_audio_buffer_unittest.cc
media/webrtc/trunk/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/AudioManagerAndroid.java
media/webrtc/trunk/webrtc/modules/audio_device/android/low_latency_event.h
media/webrtc/trunk/webrtc/modules/audio_device/android/low_latency_event_posix.cc
media/webrtc/trunk/webrtc/modules/audio_device/android/low_latency_event_unittest.cc
media/webrtc/trunk/webrtc/modules/audio_device/android/opensles_input.cc
media/webrtc/trunk/webrtc/modules/audio_device/android/opensles_input.h
media/webrtc/trunk/webrtc/modules/audio_device/android/opensles_output.cc
media/webrtc/trunk/webrtc/modules/audio_device/android/opensles_output.h
media/webrtc/trunk/webrtc/modules/audio_device/android/single_rw_fifo.cc
media/webrtc/trunk/webrtc/modules/audio_device/android/single_rw_fifo.h
media/webrtc/trunk/webrtc/modules/audio_device/android/single_rw_fifo_unittest.cc
media/webrtc/trunk/webrtc/modules/audio_device/audio_device_tests.isolate
media/webrtc/trunk/webrtc/modules/audio_device/audio_device_utility.cc
media/webrtc/trunk/webrtc/modules/audio_device/audio_device_utility.h
media/webrtc/trunk/webrtc/modules/audio_device/dummy/audio_device_utility_dummy.cc
media/webrtc/trunk/webrtc/modules/audio_device/dummy/audio_device_utility_dummy.h
media/webrtc/trunk/webrtc/modules/audio_device/ios/audio_device_utility_ios.cc
media/webrtc/trunk/webrtc/modules/audio_device/ios/audio_device_utility_ios.h
media/webrtc/trunk/webrtc/modules/audio_device/linux/audio_device_utility_linux.cc
media/webrtc/trunk/webrtc/modules/audio_device/linux/audio_device_utility_linux.h
media/webrtc/trunk/webrtc/modules/audio_device/mac/audio_device_utility_mac.cc
media/webrtc/trunk/webrtc/modules/audio_device/mac/audio_device_utility_mac.h
media/webrtc/trunk/webrtc/modules/audio_device/main/interface/audio_device.h
media/webrtc/trunk/webrtc/modules/audio_device/main/source/OWNERS
media/webrtc/trunk/webrtc/modules/audio_device/main/source/audio_device.gypi
media/webrtc/trunk/webrtc/modules/audio_device/opensl/audio_device_opensles.cc
media/webrtc/trunk/webrtc/modules/audio_device/opensl/audio_device_opensles.h
media/webrtc/trunk/webrtc/modules/audio_device/opensl/audio_manager_jni.h
media/webrtc/trunk/webrtc/modules/audio_device/opensl/fine_audio_buffer.cc
media/webrtc/trunk/webrtc/modules/audio_device/opensl/fine_audio_buffer.h
media/webrtc/trunk/webrtc/modules/audio_device/opensl/low_latency_event_posix.cc
media/webrtc/trunk/webrtc/modules/audio_device/opensl/low_latency_event_posix.h
media/webrtc/trunk/webrtc/modules/audio_device/opensl/opensles_common.cc
media/webrtc/trunk/webrtc/modules/audio_device/opensl/opensles_common.h
media/webrtc/trunk/webrtc/modules/audio_device/opensl/opensles_input.cc
media/webrtc/trunk/webrtc/modules/audio_device/opensl/opensles_input.h
media/webrtc/trunk/webrtc/modules/audio_device/opensl/opensles_output.cc
media/webrtc/trunk/webrtc/modules/audio_device/opensl/opensles_output.h
media/webrtc/trunk/webrtc/modules/audio_device/shared/audio_device_utility_shared.cc
media/webrtc/trunk/webrtc/modules/audio_device/shared/audio_device_utility_shared.h
media/webrtc/trunk/webrtc/modules/audio_device/win/audio_device_utility_win.cc
media/webrtc/trunk/webrtc/modules/audio_device/win/audio_device_utility_win.h
media/webrtc/trunk/webrtc/modules/audio_processing/aec/include/echo_cancellation.h
media/webrtc/trunk/webrtc/modules/audio_processing/aecm/include/echo_control_mobile.h
media/webrtc/trunk/webrtc/modules/audio_processing/agc/agc_audio_proc.cc
media/webrtc/trunk/webrtc/modules/audio_processing/agc/agc_audio_proc.h
media/webrtc/trunk/webrtc/modules/audio_processing/agc/agc_audio_proc_internal.h
media/webrtc/trunk/webrtc/modules/audio_processing/agc/agc_audio_proc_unittest.cc
media/webrtc/trunk/webrtc/modules/audio_processing/agc/circular_buffer.cc
media/webrtc/trunk/webrtc/modules/audio_processing/agc/circular_buffer.h
media/webrtc/trunk/webrtc/modules/audio_processing/agc/circular_buffer_unittest.cc
media/webrtc/trunk/webrtc/modules/audio_processing/agc/common.h
media/webrtc/trunk/webrtc/modules/audio_processing/agc/gmm.cc
media/webrtc/trunk/webrtc/modules/audio_processing/agc/gmm.h
media/webrtc/trunk/webrtc/modules/audio_processing/agc/gmm_unittest.cc
media/webrtc/trunk/webrtc/modules/audio_processing/agc/noise_gmm_tables.h
media/webrtc/trunk/webrtc/modules/audio_processing/agc/pitch_based_vad.cc
media/webrtc/trunk/webrtc/modules/audio_processing/agc/pitch_based_vad.h
media/webrtc/trunk/webrtc/modules/audio_processing/agc/pitch_based_vad_unittest.cc
media/webrtc/trunk/webrtc/modules/audio_processing/agc/pitch_internal.cc
media/webrtc/trunk/webrtc/modules/audio_processing/agc/pitch_internal.h
media/webrtc/trunk/webrtc/modules/audio_processing/agc/pitch_internal_unittest.cc
media/webrtc/trunk/webrtc/modules/audio_processing/agc/pole_zero_filter.cc
media/webrtc/trunk/webrtc/modules/audio_processing/agc/pole_zero_filter.h
media/webrtc/trunk/webrtc/modules/audio_processing/agc/pole_zero_filter_unittest.cc
media/webrtc/trunk/webrtc/modules/audio_processing/agc/standalone_vad.cc
media/webrtc/trunk/webrtc/modules/audio_processing/agc/standalone_vad.h
media/webrtc/trunk/webrtc/modules/audio_processing/agc/standalone_vad_unittest.cc
media/webrtc/trunk/webrtc/modules/audio_processing/agc/voice_gmm_tables.h
media/webrtc/trunk/webrtc/modules/audio_processing/beamformer/mock_nonlinear_beamformer.cc
media/webrtc/trunk/webrtc/modules/audio_processing/beamformer/pcm_utils.cc
media/webrtc/trunk/webrtc/modules/audio_processing/beamformer/pcm_utils.h
media/webrtc/trunk/webrtc/modules/audio_processing/ns/include/noise_suppression.h
media/webrtc/trunk/webrtc/modules/audio_processing/ns/include/noise_suppression_x.h
media/webrtc/trunk/webrtc/modules/audio_processing/test/android/apmtest/jni/Application.mk
media/webrtc/trunk/webrtc/modules/bitrate_controller/bitrate_allocator.cc
media/webrtc/trunk/webrtc/modules/bitrate_controller/bitrate_allocator_unittest.cc
media/webrtc/trunk/webrtc/modules/bitrate_controller/include/bitrate_allocator.h
media/webrtc/trunk/webrtc/modules/bitrate_controller/send_time_history.cc
media/webrtc/trunk/webrtc/modules/bitrate_controller/send_time_history.h
media/webrtc/trunk/webrtc/modules/bitrate_controller/send_time_history_unittest.cc
media/webrtc/trunk/webrtc/modules/interface/module.h
media/webrtc/trunk/webrtc/modules/interface/module_common_types.h
media/webrtc/trunk/webrtc/modules/media_file/interface/media_file.h
media/webrtc/trunk/webrtc/modules/media_file/interface/media_file_defines.h
media/webrtc/trunk/webrtc/modules/media_file/source/OWNERS
media/webrtc/trunk/webrtc/modules/media_file/source/media_file_impl.cc
media/webrtc/trunk/webrtc/modules/media_file/source/media_file_impl.h
media/webrtc/trunk/webrtc/modules/media_file/source/media_file_unittest.cc
media/webrtc/trunk/webrtc/modules/media_file/source/media_file_utility.cc
media/webrtc/trunk/webrtc/modules/media_file/source/media_file_utility.h
media/webrtc/trunk/webrtc/modules/pacing/include/mock/mock_paced_sender.h
media/webrtc/trunk/webrtc/modules/pacing/include/paced_sender.h
media/webrtc/trunk/webrtc/modules/pacing/include/packet_router.h
media/webrtc/trunk/webrtc/modules/remote_bitrate_estimator/mimd_rate_control.cc
media/webrtc/trunk/webrtc/modules/remote_bitrate_estimator/mimd_rate_control.h
media/webrtc/trunk/webrtc/modules/remote_bitrate_estimator/remote_rate_control.cc
media/webrtc/trunk/webrtc/modules/remote_bitrate_estimator/remote_rate_control.h
media/webrtc/trunk/webrtc/modules/remote_bitrate_estimator/test/bwe_plot.sh
media/webrtc/trunk/webrtc/modules/rtp_rtcp/interface/fec_receiver.h
media/webrtc/trunk/webrtc/modules/rtp_rtcp/interface/receive_statistics.h
media/webrtc/trunk/webrtc/modules/rtp_rtcp/interface/remote_ntp_time_estimator.h
media/webrtc/trunk/webrtc/modules/rtp_rtcp/interface/rtp_cvo.h
media/webrtc/trunk/webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h
media/webrtc/trunk/webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h
media/webrtc/trunk/webrtc/modules/rtp_rtcp/interface/rtp_receiver.h
media/webrtc/trunk/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h
media/webrtc/trunk/webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h
media/webrtc/trunk/webrtc/modules/rtp_rtcp/test/BWEStandAlone/BWEStandAlone.cc
media/webrtc/trunk/webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.cc
media/webrtc/trunk/webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.h
media/webrtc/trunk/webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestLoadGenerator.cc
media/webrtc/trunk/webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestLoadGenerator.h
media/webrtc/trunk/webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestSenderReceiver.cc
media/webrtc/trunk/webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestSenderReceiver.h
media/webrtc/trunk/webrtc/modules/rtp_rtcp/test/bwe_standalone.gypi
media/webrtc/trunk/webrtc/modules/utility/interface/audio_frame_operations.h
media/webrtc/trunk/webrtc/modules/utility/interface/file_player.h
media/webrtc/trunk/webrtc/modules/utility/interface/file_recorder.h
media/webrtc/trunk/webrtc/modules/utility/interface/helpers_android.h
media/webrtc/trunk/webrtc/modules/utility/interface/mock/mock_process_thread.h
media/webrtc/trunk/webrtc/modules/utility/interface/process_thread.h
media/webrtc/trunk/webrtc/modules/utility/interface/rtp_dump.h
media/webrtc/trunk/webrtc/modules/utility/source/rtp_dump_impl.cc
media/webrtc/trunk/webrtc/modules/utility/source/rtp_dump_impl.h
media/webrtc/trunk/webrtc/modules/video_capture/ensure_initialized.cc
media/webrtc/trunk/webrtc/modules/video_capture/ensure_initialized.h
media/webrtc/trunk/webrtc/modules/video_capture/include/mock/mock_video_capture.h
media/webrtc/trunk/webrtc/modules/video_capture/include/video_capture.h
media/webrtc/trunk/webrtc/modules/video_capture/include/video_capture_defines.h
media/webrtc/trunk/webrtc/modules/video_capture/include/video_capture_factory.h
media/webrtc/trunk/webrtc/modules/video_coding/codecs/i420/main/interface/i420.h
media/webrtc/trunk/webrtc/modules/video_coding/codecs/i420/main/source/OWNERS
media/webrtc/trunk/webrtc/modules/video_coding/codecs/i420/main/source/i420.cc
media/webrtc/trunk/webrtc/modules/video_coding/codecs/i420/main/source/i420.gypi
media/webrtc/trunk/webrtc/modules/video_coding/codecs/vp9/vp9_dummy_impl.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/interface/mock/mock_vcm_callbacks.h
media/webrtc/trunk/webrtc/modules/video_coding/main/interface/video_coding.h
media/webrtc/trunk/webrtc/modules/video_coding/main/interface/video_coding_defines.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/OWNERS
media/webrtc/trunk/webrtc/modules/video_coding/main/source/codec_database.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/codec_database.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/codec_timer.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/codec_timer.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/content_metrics_processing.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/content_metrics_processing.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/decoding_state.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/decoding_state.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/decoding_state_unittest.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/encoded_frame.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/encoded_frame.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/fec_tables_xor.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/frame_buffer.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/frame_buffer.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/generic_decoder.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/generic_decoder.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/generic_encoder.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/generic_encoder.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/inter_frame_delay.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/inter_frame_delay.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/internal_defines.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/jitter_buffer.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/jitter_buffer.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/jitter_buffer_common.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/jitter_buffer_unittest.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/jitter_estimator.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/jitter_estimator.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/jitter_estimator_tests.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/media_opt_util.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/media_opt_util.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/media_optimization.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/media_optimization.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/media_optimization_unittest.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/nack_fec_tables.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/packet.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/packet.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/qm_select.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/qm_select.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/qm_select_data.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/qm_select_unittest.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/receiver.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/receiver.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/receiver_unittest.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/rtt_filter.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/rtt_filter.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/session_info.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/session_info.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/session_info_unittest.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/test/stream_generator.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/test/stream_generator.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/timestamp_map.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/timestamp_map.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/timing.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/timing.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/timing_unittest.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/video_coding_impl.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/video_coding_impl.h
media/webrtc/trunk/webrtc/modules/video_coding/main/source/video_coding_robustness_unittest.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/video_receiver.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/video_receiver_unittest.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/video_sender.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/video_sender_unittest.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/test/plotJitterEstimate.m
media/webrtc/trunk/webrtc/modules/video_coding/main/test/plotReceiveTrace.m
media/webrtc/trunk/webrtc/modules/video_coding/main/test/plotTimingTest.m
media/webrtc/trunk/webrtc/modules/video_coding/main/test/receiver_tests.h
media/webrtc/trunk/webrtc/modules/video_coding/main/test/release_test.h
media/webrtc/trunk/webrtc/modules/video_coding/main/test/rtp_player.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/test/rtp_player.h
media/webrtc/trunk/webrtc/modules/video_coding/main/test/subfigure.m
media/webrtc/trunk/webrtc/modules/video_coding/main/test/test_util.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/test/test_util.h
media/webrtc/trunk/webrtc/modules/video_coding/main/test/tester_main.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/test/vcm_payload_sink_factory.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/test/vcm_payload_sink_factory.h
media/webrtc/trunk/webrtc/modules/video_coding/main/test/video_rtp_play.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/test/video_source.h
media/webrtc/trunk/webrtc/modules/video_coding/utility/include/frame_dropper.h
media/webrtc/trunk/webrtc/modules/video_coding/utility/include/mock/mock_frame_dropper.h
media/webrtc/trunk/webrtc/modules/video_processing/main/interface/video_processing.h
media/webrtc/trunk/webrtc/modules/video_processing/main/interface/video_processing_defines.h
media/webrtc/trunk/webrtc/modules/video_processing/main/source/OWNERS
media/webrtc/trunk/webrtc/modules/video_processing/main/source/brighten.cc
media/webrtc/trunk/webrtc/modules/video_processing/main/source/brighten.h
media/webrtc/trunk/webrtc/modules/video_processing/main/source/brightness_detection.cc
media/webrtc/trunk/webrtc/modules/video_processing/main/source/brightness_detection.h
media/webrtc/trunk/webrtc/modules/video_processing/main/source/color_enhancement.cc
media/webrtc/trunk/webrtc/modules/video_processing/main/source/color_enhancement.h
media/webrtc/trunk/webrtc/modules/video_processing/main/source/color_enhancement_private.h
media/webrtc/trunk/webrtc/modules/video_processing/main/source/content_analysis.cc
media/webrtc/trunk/webrtc/modules/video_processing/main/source/content_analysis.h
media/webrtc/trunk/webrtc/modules/video_processing/main/source/content_analysis_sse2.cc
media/webrtc/trunk/webrtc/modules/video_processing/main/source/deflickering.cc
media/webrtc/trunk/webrtc/modules/video_processing/main/source/deflickering.h
media/webrtc/trunk/webrtc/modules/video_processing/main/source/frame_preprocessor.cc
media/webrtc/trunk/webrtc/modules/video_processing/main/source/frame_preprocessor.h
media/webrtc/trunk/webrtc/modules/video_processing/main/source/spatial_resampler.cc
media/webrtc/trunk/webrtc/modules/video_processing/main/source/spatial_resampler.h
media/webrtc/trunk/webrtc/modules/video_processing/main/source/video_decimator.cc
media/webrtc/trunk/webrtc/modules/video_processing/main/source/video_decimator.h
media/webrtc/trunk/webrtc/modules/video_processing/main/source/video_processing_impl.cc
media/webrtc/trunk/webrtc/modules/video_processing/main/source/video_processing_impl.h
media/webrtc/trunk/webrtc/modules/video_processing/main/test/unit_test/brightness_detection_test.cc
media/webrtc/trunk/webrtc/modules/video_processing/main/test/unit_test/color_enhancement_test.cc
media/webrtc/trunk/webrtc/modules/video_processing/main/test/unit_test/content_metrics_test.cc
media/webrtc/trunk/webrtc/modules/video_processing/main/test/unit_test/createTable.m
media/webrtc/trunk/webrtc/modules/video_processing/main/test/unit_test/deflickering_test.cc
media/webrtc/trunk/webrtc/modules/video_processing/main/test/unit_test/readYUV420file.m
media/webrtc/trunk/webrtc/modules/video_processing/main/test/unit_test/video_processing_unittest.cc
media/webrtc/trunk/webrtc/modules/video_processing/main/test/unit_test/video_processing_unittest.h
media/webrtc/trunk/webrtc/modules/video_processing/main/test/unit_test/writeYUV420file.m
media/webrtc/trunk/webrtc/modules/video_render/include/video_render.h
media/webrtc/trunk/webrtc/modules/video_render/include/video_render_defines.h
media/webrtc/trunk/webrtc/modules/video_render/incoming_video_stream.cc
media/webrtc/trunk/webrtc/modules/video_render/incoming_video_stream.h
media/webrtc/trunk/webrtc/modules/video_render/video_render_frames.cc
media/webrtc/trunk/webrtc/modules/video_render/video_render_frames.h
media/webrtc/trunk/webrtc/modules/video_render/video_render_tests.isolate
media/webrtc/trunk/webrtc/overrides/OWNERS
media/webrtc/trunk/webrtc/overrides/webrtc/base/arraysize.h
media/webrtc/trunk/webrtc/overrides/webrtc/base/basictypes.h
media/webrtc/trunk/webrtc/overrides/webrtc/base/constructormagic.h
media/webrtc/trunk/webrtc/overrides/webrtc/base/diagnostic_logging.h
media/webrtc/trunk/webrtc/overrides/webrtc/base/logging.cc
media/webrtc/trunk/webrtc/overrides/webrtc/base/logging.h
media/webrtc/trunk/webrtc/overrides/webrtc/base/win32socketinit.cc
media/webrtc/trunk/webrtc/p2p/base/fakesession.h
media/webrtc/trunk/webrtc/p2p/base/portallocatorsessionproxy.cc
media/webrtc/trunk/webrtc/p2p/base/portallocatorsessionproxy.h
media/webrtc/trunk/webrtc/p2p/base/portallocatorsessionproxy_unittest.cc
media/webrtc/trunk/webrtc/p2p/base/portproxy.cc
media/webrtc/trunk/webrtc/p2p/base/portproxy.h
media/webrtc/trunk/webrtc/p2p/base/transportchannelproxy.cc
media/webrtc/trunk/webrtc/p2p/base/transportchannelproxy.h
media/webrtc/trunk/webrtc/p2p/client/connectivitychecker.cc
media/webrtc/trunk/webrtc/p2p/client/connectivitychecker.h
media/webrtc/trunk/webrtc/p2p/client/connectivitychecker_unittest.cc
media/webrtc/trunk/webrtc/system_wrappers/interface/aligned_array.h
media/webrtc/trunk/webrtc/system_wrappers/interface/aligned_malloc.h
media/webrtc/trunk/webrtc/system_wrappers/interface/asm_defines.h
media/webrtc/trunk/webrtc/system_wrappers/interface/atomic32.h
media/webrtc/trunk/webrtc/system_wrappers/interface/clock.h
media/webrtc/trunk/webrtc/system_wrappers/interface/compile_assert_c.h
media/webrtc/trunk/webrtc/system_wrappers/interface/condition_variable_wrapper.h
media/webrtc/trunk/webrtc/system_wrappers/interface/cpu_features_wrapper.h
media/webrtc/trunk/webrtc/system_wrappers/interface/cpu_info.h
media/webrtc/trunk/webrtc/system_wrappers/interface/critical_section_wrapper.h
media/webrtc/trunk/webrtc/system_wrappers/interface/data_log.h
media/webrtc/trunk/webrtc/system_wrappers/interface/data_log_c.h
media/webrtc/trunk/webrtc/system_wrappers/interface/data_log_impl.h
media/webrtc/trunk/webrtc/system_wrappers/interface/event_tracer.h
media/webrtc/trunk/webrtc/system_wrappers/interface/event_wrapper.h
media/webrtc/trunk/webrtc/system_wrappers/interface/field_trial.h
media/webrtc/trunk/webrtc/system_wrappers/interface/field_trial_default.h
media/webrtc/trunk/webrtc/system_wrappers/interface/file_wrapper.h
media/webrtc/trunk/webrtc/system_wrappers/interface/fix_interlocked_exchange_pointer_win.h
media/webrtc/trunk/webrtc/system_wrappers/interface/logcat_trace_context.h
media/webrtc/trunk/webrtc/system_wrappers/interface/logging.h
media/webrtc/trunk/webrtc/system_wrappers/interface/metrics.h
media/webrtc/trunk/webrtc/system_wrappers/interface/ref_count.h
media/webrtc/trunk/webrtc/system_wrappers/interface/rtp_to_ntp.h
media/webrtc/trunk/webrtc/system_wrappers/interface/rw_lock_wrapper.h
media/webrtc/trunk/webrtc/system_wrappers/interface/scoped_refptr.h
media/webrtc/trunk/webrtc/system_wrappers/interface/scoped_vector.h
media/webrtc/trunk/webrtc/system_wrappers/interface/sleep.h
media/webrtc/trunk/webrtc/system_wrappers/interface/sort.h
media/webrtc/trunk/webrtc/system_wrappers/interface/static_instance.h
media/webrtc/trunk/webrtc/system_wrappers/interface/stl_util.h
media/webrtc/trunk/webrtc/system_wrappers/interface/stringize_macros.h
media/webrtc/trunk/webrtc/system_wrappers/interface/thread_wrapper.h
media/webrtc/trunk/webrtc/system_wrappers/interface/tick_util.h
media/webrtc/trunk/webrtc/system_wrappers/interface/timestamp_extrapolator.h
media/webrtc/trunk/webrtc/system_wrappers/interface/trace.h
media/webrtc/trunk/webrtc/system_wrappers/interface/trace_event.h
media/webrtc/trunk/webrtc/system_wrappers/interface/utf_util_win.h
media/webrtc/trunk/webrtc/system_wrappers/source/event_posix.cc
media/webrtc/trunk/webrtc/system_wrappers/source/event_posix.h
media/webrtc/trunk/webrtc/system_wrappers/source/event_tracer.cc
media/webrtc/trunk/webrtc/system_wrappers/source/event_tracer_unittest.cc
media/webrtc/trunk/webrtc/system_wrappers/source/event_win.cc
media/webrtc/trunk/webrtc/system_wrappers/source/event_win.h
media/webrtc/trunk/webrtc/system_wrappers/source/thread.cc
media/webrtc/trunk/webrtc/system_wrappers/source/thread_posix.cc
media/webrtc/trunk/webrtc/system_wrappers/source/thread_posix.h
media/webrtc/trunk/webrtc/system_wrappers/source/thread_posix_unittest.cc
media/webrtc/trunk/webrtc/system_wrappers/source/thread_unittest.cc
media/webrtc/trunk/webrtc/system_wrappers/source/thread_win.cc
media/webrtc/trunk/webrtc/system_wrappers/source/thread_win.h
media/webrtc/trunk/webrtc/test/channel_transport/include/channel_transport.h
media/webrtc/trunk/webrtc/test/fake_common.h
media/webrtc/trunk/webrtc/test/testsupport/gtest_disable.h
media/webrtc/trunk/webrtc/tools/agc/agc_manager.cc
media/webrtc/trunk/webrtc/tools/agc/agc_manager.h
media/webrtc/trunk/webrtc/tools/agc/agc_manager_integrationtest.cc
media/webrtc/trunk/webrtc/tools/agc/agc_manager_unittest.cc
media/webrtc/trunk/webrtc/tools/agc/agc_test.cc
media/webrtc/trunk/webrtc/video/bitrate_estimator_tests.cc
media/webrtc/trunk/webrtc/video/call.cc
media/webrtc/trunk/webrtc/video/call_perf_tests.cc
media/webrtc/trunk/webrtc/video/loopback.cc
media/webrtc/trunk/webrtc/video/loopback.h
media/webrtc/trunk/webrtc/video/rampup_tests.cc
media/webrtc/trunk/webrtc/video/rampup_tests.h
media/webrtc/trunk/webrtc/video/transport_adapter.cc
media/webrtc/trunk/webrtc/video/transport_adapter.h
media/webrtc/trunk/webrtc/video_engine/BUILD.gn
media/webrtc/trunk/webrtc/video_engine/OWNERS
media/webrtc/trunk/webrtc/video_engine/call_stats.cc
media/webrtc/trunk/webrtc/video_engine/call_stats.h
media/webrtc/trunk/webrtc/video_engine/call_stats_unittest.cc
media/webrtc/trunk/webrtc/video_engine/encoder_state_feedback.cc
media/webrtc/trunk/webrtc/video_engine/encoder_state_feedback.h
media/webrtc/trunk/webrtc/video_engine/encoder_state_feedback_unittest.cc
media/webrtc/trunk/webrtc/video_engine/include/vie_base.h
media/webrtc/trunk/webrtc/video_engine/include/vie_capture.h
media/webrtc/trunk/webrtc/video_engine/include/vie_codec.h
media/webrtc/trunk/webrtc/video_engine/include/vie_errors.h
media/webrtc/trunk/webrtc/video_engine/include/vie_external_codec.h
media/webrtc/trunk/webrtc/video_engine/include/vie_image_process.h
media/webrtc/trunk/webrtc/video_engine/include/vie_network.h
media/webrtc/trunk/webrtc/video_engine/include/vie_render.h
media/webrtc/trunk/webrtc/video_engine/include/vie_rtp_rtcp.h
media/webrtc/trunk/webrtc/video_engine/mock/mock_vie_frame_provider_base.h
media/webrtc/trunk/webrtc/video_engine/overuse_frame_detector.cc
media/webrtc/trunk/webrtc/video_engine/overuse_frame_detector.h
media/webrtc/trunk/webrtc/video_engine/overuse_frame_detector_unittest.cc
media/webrtc/trunk/webrtc/video_engine/payload_router.cc
media/webrtc/trunk/webrtc/video_engine/payload_router.h
media/webrtc/trunk/webrtc/video_engine/payload_router_unittest.cc
media/webrtc/trunk/webrtc/video_engine/report_block_stats.cc
media/webrtc/trunk/webrtc/video_engine/report_block_stats.h
media/webrtc/trunk/webrtc/video_engine/report_block_stats_unittest.cc
media/webrtc/trunk/webrtc/video_engine/stream_synchronization.cc
media/webrtc/trunk/webrtc/video_engine/stream_synchronization.h
media/webrtc/trunk/webrtc/video_engine/stream_synchronization_unittest.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/OWNERS
media/webrtc/trunk/webrtc/video_engine/test/auto_test/android/.classpath
media/webrtc/trunk/webrtc/video_engine/test/auto_test/android/.project
media/webrtc/trunk/webrtc/video_engine/test/auto_test/android/AndroidManifest.xml
media/webrtc/trunk/webrtc/video_engine/test/auto_test/android/default.properties
media/webrtc/trunk/webrtc/video_engine/test/auto_test/android/gen/org/webrtc/vieautotest/R.java
media/webrtc/trunk/webrtc/video_engine/test/auto_test/android/jni/org_webrtc_vieautotest_vie_autotest.h
media/webrtc/trunk/webrtc/video_engine/test/auto_test/android/jni/vie_autotest_jni.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/android/res/drawable/logo.png
media/webrtc/trunk/webrtc/video_engine/test/auto_test/android/res/layout/main.xml
media/webrtc/trunk/webrtc/video_engine/test/auto_test/android/res/values/strings.xml
media/webrtc/trunk/webrtc/video_engine/test/auto_test/android/src/org/webrtc/vieautotest/ViEAutotest.java
media/webrtc/trunk/webrtc/video_engine/test/auto_test/automated/legacy_fixture.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/automated/legacy_fixture.h
media/webrtc/trunk/webrtc/video_engine/test/auto_test/automated/two_windows_fixture.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/automated/two_windows_fixture.h
media/webrtc/trunk/webrtc/video_engine/test/auto_test/automated/vie_api_integration_test.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/automated/vie_extended_integration_test.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/automated/vie_network_test.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/automated/vie_standard_integration_test.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/automated/vie_video_verification_test.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/interface/vie_autotest.h
media/webrtc/trunk/webrtc/video_engine/test/auto_test/interface/vie_autotest_android.h
media/webrtc/trunk/webrtc/video_engine/test/auto_test/interface/vie_autotest_defines.h
media/webrtc/trunk/webrtc/video_engine/test/auto_test/interface/vie_autotest_linux.h
media/webrtc/trunk/webrtc/video_engine/test/auto_test/interface/vie_autotest_mac_cocoa.h
media/webrtc/trunk/webrtc/video_engine/test/auto_test/interface/vie_autotest_main.h
media/webrtc/trunk/webrtc/video_engine/test/auto_test/interface/vie_autotest_window_manager_interface.h
media/webrtc/trunk/webrtc/video_engine/test/auto_test/interface/vie_autotest_windows.h
media/webrtc/trunk/webrtc/video_engine/test/auto_test/interface/vie_file_based_comparison_tests.h
media/webrtc/trunk/webrtc/video_engine/test/auto_test/interface/vie_window_creator.h
media/webrtc/trunk/webrtc/video_engine/test/auto_test/interface/vie_window_manager_factory.h
media/webrtc/trunk/webrtc/video_engine/test/auto_test/primitives/base_primitives.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/primitives/base_primitives.h
media/webrtc/trunk/webrtc/video_engine/test/auto_test/primitives/choice_helpers.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/primitives/choice_helpers.h
media/webrtc/trunk/webrtc/video_engine/test/auto_test/primitives/choice_helpers_unittest.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/primitives/fake_stdin.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/primitives/fake_stdin.h
media/webrtc/trunk/webrtc/video_engine/test/auto_test/primitives/framedrop_primitives.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/primitives/framedrop_primitives.h
media/webrtc/trunk/webrtc/video_engine/test/auto_test/primitives/framedrop_primitives_unittest.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/primitives/general_primitives.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/primitives/general_primitives.h
media/webrtc/trunk/webrtc/video_engine/test/auto_test/primitives/input_helpers.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/primitives/input_helpers.h
media/webrtc/trunk/webrtc/video_engine/test/auto_test/primitives/input_helpers_unittest.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_autotest.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_autotest_android.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_autotest_base.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_autotest_capture.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_autotest_cocoa_mac.mm
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_autotest_codec.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_autotest_custom_call.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_autotest_image_process.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_autotest_linux.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_autotest_loopback.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_autotest_main.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_autotest_network.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_autotest_record.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_autotest_render.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_autotest_simulcast.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_autotest_win.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_file_based_comparison_tests.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_window_creator.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_window_manager_factory_linux.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_window_manager_factory_mac.mm
media/webrtc/trunk/webrtc/video_engine/test/auto_test/source/vie_window_manager_factory_win.cc
media/webrtc/trunk/webrtc/video_engine/test/auto_test/vie_auto_test.gypi
media/webrtc/trunk/webrtc/video_engine/test/auto_test/vie_auto_test.isolate
media/webrtc/trunk/webrtc/video_engine/test/libvietest/OWNERS
media/webrtc/trunk/webrtc/video_engine/test/libvietest/helpers/vie_fake_camera.cc
media/webrtc/trunk/webrtc/video_engine/test/libvietest/helpers/vie_file_capture_device.cc
media/webrtc/trunk/webrtc/video_engine/test/libvietest/helpers/vie_to_file_renderer.cc
media/webrtc/trunk/webrtc/video_engine/test/libvietest/include/tb_I420_codec.h
media/webrtc/trunk/webrtc/video_engine/test/libvietest/include/tb_capture_device.h
media/webrtc/trunk/webrtc/video_engine/test/libvietest/include/tb_external_transport.h
media/webrtc/trunk/webrtc/video_engine/test/libvietest/include/tb_interfaces.h
media/webrtc/trunk/webrtc/video_engine/test/libvietest/include/tb_video_channel.h
media/webrtc/trunk/webrtc/video_engine/test/libvietest/include/vie_external_render_filter.h
media/webrtc/trunk/webrtc/video_engine/test/libvietest/include/vie_fake_camera.h
media/webrtc/trunk/webrtc/video_engine/test/libvietest/include/vie_file_capture_device.h
media/webrtc/trunk/webrtc/video_engine/test/libvietest/include/vie_to_file_renderer.h
media/webrtc/trunk/webrtc/video_engine/test/libvietest/libvietest.gypi
media/webrtc/trunk/webrtc/video_engine/test/libvietest/testbed/tb_I420_codec.cc
media/webrtc/trunk/webrtc/video_engine/test/libvietest/testbed/tb_capture_device.cc
media/webrtc/trunk/webrtc/video_engine/test/libvietest/testbed/tb_external_transport.cc
media/webrtc/trunk/webrtc/video_engine/test/libvietest/testbed/tb_interfaces.cc
media/webrtc/trunk/webrtc/video_engine/test/libvietest/testbed/tb_video_channel.cc
media/webrtc/trunk/webrtc/video_engine/video_engine.gyp
media/webrtc/trunk/webrtc/video_engine/video_engine_core.gypi
media/webrtc/trunk/webrtc/video_engine/video_engine_core_unittests.isolate
media/webrtc/trunk/webrtc/video_engine/vie_base_impl.cc
media/webrtc/trunk/webrtc/video_engine/vie_base_impl.h
media/webrtc/trunk/webrtc/video_engine/vie_capture_impl.cc
media/webrtc/trunk/webrtc/video_engine/vie_capture_impl.h
media/webrtc/trunk/webrtc/video_engine/vie_capturer.cc
media/webrtc/trunk/webrtc/video_engine/vie_capturer.h
media/webrtc/trunk/webrtc/video_engine/vie_capturer_unittest.cc
media/webrtc/trunk/webrtc/video_engine/vie_channel.cc
media/webrtc/trunk/webrtc/video_engine/vie_channel.h
media/webrtc/trunk/webrtc/video_engine/vie_channel_group.cc
media/webrtc/trunk/webrtc/video_engine/vie_channel_group.h
media/webrtc/trunk/webrtc/video_engine/vie_channel_manager.cc
media/webrtc/trunk/webrtc/video_engine/vie_channel_manager.h
media/webrtc/trunk/webrtc/video_engine/vie_codec_impl.cc
media/webrtc/trunk/webrtc/video_engine/vie_codec_impl.h
media/webrtc/trunk/webrtc/video_engine/vie_codec_unittest.cc
media/webrtc/trunk/webrtc/video_engine/vie_defines.h
media/webrtc/trunk/webrtc/video_engine/vie_encoder.cc
media/webrtc/trunk/webrtc/video_engine/vie_encoder.h
media/webrtc/trunk/webrtc/video_engine/vie_external_codec_impl.cc
media/webrtc/trunk/webrtc/video_engine/vie_external_codec_impl.h
media/webrtc/trunk/webrtc/video_engine/vie_file_image.cc
media/webrtc/trunk/webrtc/video_engine/vie_file_image.h
media/webrtc/trunk/webrtc/video_engine/vie_frame_provider_base.cc
media/webrtc/trunk/webrtc/video_engine/vie_frame_provider_base.h
media/webrtc/trunk/webrtc/video_engine/vie_image_process_impl.cc
media/webrtc/trunk/webrtc/video_engine/vie_image_process_impl.h
media/webrtc/trunk/webrtc/video_engine/vie_impl.cc
media/webrtc/trunk/webrtc/video_engine/vie_impl.h
media/webrtc/trunk/webrtc/video_engine/vie_input_manager.cc
media/webrtc/trunk/webrtc/video_engine/vie_input_manager.h
media/webrtc/trunk/webrtc/video_engine/vie_manager_base.cc
media/webrtc/trunk/webrtc/video_engine/vie_manager_base.h
media/webrtc/trunk/webrtc/video_engine/vie_network_impl.cc
media/webrtc/trunk/webrtc/video_engine/vie_network_impl.h
media/webrtc/trunk/webrtc/video_engine/vie_receiver.cc
media/webrtc/trunk/webrtc/video_engine/vie_receiver.h
media/webrtc/trunk/webrtc/video_engine/vie_ref_count.cc
media/webrtc/trunk/webrtc/video_engine/vie_ref_count.h
media/webrtc/trunk/webrtc/video_engine/vie_remb.cc
media/webrtc/trunk/webrtc/video_engine/vie_remb.h
media/webrtc/trunk/webrtc/video_engine/vie_remb_unittest.cc
media/webrtc/trunk/webrtc/video_engine/vie_render_impl.cc
media/webrtc/trunk/webrtc/video_engine/vie_render_impl.h
media/webrtc/trunk/webrtc/video_engine/vie_render_manager.cc
media/webrtc/trunk/webrtc/video_engine/vie_render_manager.h
media/webrtc/trunk/webrtc/video_engine/vie_renderer.cc
media/webrtc/trunk/webrtc/video_engine/vie_renderer.h
media/webrtc/trunk/webrtc/video_engine/vie_rtp_rtcp_impl.cc
media/webrtc/trunk/webrtc/video_engine/vie_rtp_rtcp_impl.h
media/webrtc/trunk/webrtc/video_engine/vie_sender.cc
media/webrtc/trunk/webrtc/video_engine/vie_sender.h
media/webrtc/trunk/webrtc/video_engine/vie_shared_data.cc
media/webrtc/trunk/webrtc/video_engine/vie_shared_data.h
media/webrtc/trunk/webrtc/video_engine/vie_sync_module.cc
media/webrtc/trunk/webrtc/video_engine/vie_sync_module.h
media/webrtc/trunk/webrtc/voice_engine/include/mock/fake_voe_external_media.h
media/webrtc/trunk/webrtc/voice_engine/include/mock/mock_voe_observer.h
media/webrtc/trunk/webrtc/voice_engine/include/mock/mock_voe_volume_control.h
media/webrtc/trunk/webrtc/voice_engine/test/android/android_test/jni/Application.mk
media/webrtc/trunk/webrtc/voice_engine/test/auto_test/fakes/fake_external_transport.cc
media/webrtc/trunk/webrtc/voice_engine/test/auto_test/fakes/fake_external_transport.h
media/webrtc/trunk/webrtc/voice_engine/test/win_test/Resource.h
media/webrtc/trunk/webrtc/voice_engine/test/win_test/WinTest.aps
media/webrtc/trunk/webrtc/voice_engine/test/win_test/WinTest.cc
media/webrtc/trunk/webrtc/voice_engine/test/win_test/WinTest.h
media/webrtc/trunk/webrtc/voice_engine/test/win_test/WinTest.rc
media/webrtc/trunk/webrtc/voice_engine/test/win_test/WinTestDlg.cc
media/webrtc/trunk/webrtc/voice_engine/test/win_test/WinTestDlg.h
media/webrtc/trunk/webrtc/voice_engine/test/win_test/res/WinTest.ico
media/webrtc/trunk/webrtc/voice_engine/test/win_test/res/WinTest.rc2
media/webrtc/trunk/webrtc/voice_engine/test/win_test/stdafx.cc
media/webrtc/trunk/webrtc/voice_engine/test/win_test/stdafx.h
media/webrtc/trunk/webrtc/webrtc_examples.gyp
modules/libpref/init/all.js
taskcluster/ci/android-test/kind.yml
taskcluster/ci/android-test/test-platforms.yml
taskcluster/ci/android-test/test-sets.yml
taskcluster/ci/android-test/tests.yml
taskcluster/ci/desktop-test/kind.yml
taskcluster/ci/desktop-test/test-platforms.yml
taskcluster/ci/desktop-test/test-sets.yml
taskcluster/ci/desktop-test/tests.yml
taskcluster/ci/test/test-platforms.yml
taskcluster/ci/test/test-sets.yml
taskcluster/taskgraph/transforms/tests/__init__.py
taskcluster/taskgraph/transforms/tests/all_kinds.py
taskcluster/taskgraph/transforms/tests/android_test.py
taskcluster/taskgraph/transforms/tests/desktop_test.py
taskcluster/taskgraph/transforms/tests/make_task_description.py
taskcluster/taskgraph/transforms/tests/test_description.py
widget/cocoa/nsChildView.mm
--- a/.taskcluster.yml
+++ b/.taskcluster.yml
@@ -50,23 +50,16 @@ tasks:
             The task that creates all of the other tasks in the task graph
 
       workerType: "gecko-decision"
       provisionerId: "aws-provisioner-v1"
 
       tags:
         createdForUser: {{owner}}
 
-      scopes:
-        # Bug 1269443: cache scopes, etc. must be listed explicitly
-        - "docker-worker:cache:level-{{level}}-*"
-        - "docker-worker:cache:tooltool-cache"
-        # mozilla-taskcluster will append the appropriate assume:repo:<repo>
-        # scope here.
-
       routes:
         - "index.gecko.v2.{{project}}.latest.firefox.decision"
         - "tc-treeherder.v2.{{project}}.{{revision}}.{{pushlog_id}}"
         - "tc-treeherder-stage.v2.{{project}}.{{revision}}.{{pushlog_id}}"
 
       payload:
         env:
           # checkout-gecko uses these to check out the source; the inputs
--- a/CLOBBER
+++ b/CLOBBER
@@ -17,9 +17,9 @@
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
 # Are you updating CLOBBER because you think it's needed for your WebIDL
 # changes to stick? As of bug 928195, this shouldn't be necessary! Please
 # don't change CLOBBER for WebIDL changes any more.
 
-Bug 1322938 needs a clobber for test_lowDiskSpace.html on Android
+Bug 1250356 Setting CLOBBER out caution landing a huge patchset with gyp changes
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1666,17 +1666,17 @@
     <emItem blockID="i103" id="kdrgun@gmail.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
     <emItem blockID="i1119" id="/^(test3@test.org|test2@test.org|test@test.org|support@mozilla.org)$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i1424" id="/^(jid0-S9kkzfTvEmC985BVmf8ZOzA5nLM@jetpack|jid0-xGZYdxpAkROWMUMfWKINyrXigBA@jetpack|jid1-qps14pkDB6UDvA@jetpack|jid1-Tsr09YnAqIWL0Q@jetpack|shole@ats.ext|voipgrid@jetpack|{38a64ef0-7181-11e3-981f-0800200c9a66}|eochoa@ualberta.ca)$/">
+    <emItem blockID="i1424" id="/^(jid0-S9kkzfTvEmC985BVmf8ZOzA5nLM@jetpack|jid1-qps14pkDB6UDvA@jetpack|jid1-Tsr09YnAqIWL0Q@jetpack|shole@ats.ext|voipgrid@jetpack|{38a64ef0-7181-11e3-981f-0800200c9a66}|eochoa@ualberta.ca)$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i519" id="703db0db-5fe9-44b6-9f53-c6a91a0ad5bd@7314bc82-969e-4d2a-921b-e5edd0b02cf1.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i484" id="plugin@getwebcake.com">
--- a/browser/base/content/sanitize.js
+++ b/browser/base/content/sanitize.js
@@ -152,19 +152,17 @@ Sanitizer.prototype = {
       seenError = true;
       console.error("Error sanitizing " + name, ex);
     };
 
     // Array of objects in form { name, promise }.
     // `name` is the item's name and `promise` may be a promise, if the
     // sanitization is asynchronous, or the function return value, otherwise.
     let handles = [];
-    for (let itemName of itemsToClear) {
-      // Workaround for bug 449811.
-      let name = itemName;
+    for (let name of itemsToClear) {
       let item = this.items[name];
       try {
         // Catch errors here, so later we can just loop through these.
         handles.push({ name,
                        promise: item.clear(range)
                                     .then(() => progress[name] = "cleared",
                                           ex => annotateError(name, ex))
                      });
--- a/browser/components/migration/MigrationUtils.jsm
+++ b/browser/components/migration/MigrationUtils.jsm
@@ -289,31 +289,27 @@ this.MigratorPrototype = {
       let notify = function(aMsg, aItemType) {
         Services.obs.notifyObservers(null, aMsg, aItemType);
       };
 
       for (let resourceType of Object.keys(MigrationUtils._importQuantities)) {
         MigrationUtils._importQuantities[resourceType] = 0;
       }
       notify("Migration:Started");
-      for (let [key, value] of resourcesGroupedByItems) {
-        // Workaround bug 449811.
-        let migrationType = key, itemResources = value;
+      for (let [migrationType, itemResources] of resourcesGroupedByItems) {
 
         notify("Migration:ItemBeforeMigrate", migrationType);
 
         let itemSuccess = false;
         for (let res of itemResources) {
-          // Workaround bug 449811.
-          let resource = res;
-          maybeStartTelemetryStopwatch(migrationType, resource);
+          maybeStartTelemetryStopwatch(migrationType, res);
           let completeDeferred = PromiseUtils.defer();
           let resourceDone = function(aSuccess) {
-            maybeStopTelemetryStopwatch(migrationType, resource);
-            itemResources.delete(resource);
+            maybeStopTelemetryStopwatch(migrationType, res);
+            itemResources.delete(res);
             itemSuccess |= aSuccess;
             if (itemResources.size == 0) {
               notify(itemSuccess ?
                      "Migration:ItemAfterMigrate" : "Migration:ItemError",
                      migrationType);
               resourcesGroupedByItems.delete(migrationType);
               if (resourcesGroupedByItems.size == 0) {
                 collectQuantityTelemetry();
@@ -321,17 +317,17 @@ this.MigratorPrototype = {
               }
             }
             completeDeferred.resolve();
           };
 
           // If migrate throws, an error occurred, and the callback
           // (itemMayBeDone) might haven't been called.
           try {
-            resource.migrate(resourceDone);
+            res.migrate(resourceDone);
           }
           catch (ex) {
             Cu.reportError(ex);
             resourceDone(false);
           }
 
           // Certain resources must be ran sequentially or they could fail,
           // for example bookmarks and history (See bug 1272652).
--- a/browser/components/originattributes/test/browser/browser.ini
+++ b/browser/components/originattributes/test/browser/browser.ini
@@ -64,8 +64,9 @@ support-files =
 [browser_firstPartyIsolation.js]
 [browser_localStorageIsolation.js]
 [browser_blobURLIsolation.js]
 [browser_imageCacheIsolation.js]
 [browser_sharedworker.js]
 [browser_httpauth.js]
 [browser_clientAuth.js]
 [browser_cacheAPI.js]
+[browser_permissions.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/originattributes/test/browser/browser_permissions.js
@@ -0,0 +1,44 @@
+/**
+ * Bug 1282655 - Test if site permissions are universal across origin attributes.
+ *
+ * This test is testing the cookie "permission" for a specific URI.
+ */
+
+const TEST_PAGE = "http://example.net";
+const uri = Services.io.newURI(TEST_PAGE, null, null);
+
+function disableCookies() {
+  Services.cookies.removeAll();
+  Services.perms.add(uri, "cookie", Services.perms.DENY_ACTION);
+}
+
+function ensureCookieNotSet(aBrowser) {
+  ContentTask.spawn(aBrowser, null, function*() {
+    content.document.cookie = "key=value";
+    is(content.document.cookie, "", "Setting/reading cookies should be disabled"
+      + " for this domain for all origin attribute combinations.");
+  });
+}
+
+IsolationTestTools.runTests(TEST_PAGE, ensureCookieNotSet, () => true,
+                            disableCookies);
+
+function enableCookies() {
+  Services.cookies.removeAll();
+  Services.perms.add(uri, "cookie", Services.perms.ALLOW_ACTION);
+}
+
+function ensureCookieSet(aBrowser) {
+  ContentTask.spawn(aBrowser, null, function() {
+    content.document.cookie = "key=value";
+    is(content.document.cookie, "key=value", "Setting/reading cookies should be"
+      + " enabled for this domain for all origin attribute combinations.");
+  });
+}
+
+IsolationTestTools.runTests(TEST_PAGE, ensureCookieSet, () => true,
+                            enableCookies);
+
+registerCleanupFunction(() => {
+    Services.cookies.removeAll();
+});
--- a/browser/components/preferences/in-content/advanced.js
+++ b/browser/components/preferences/in-content/advanced.js
@@ -52,16 +52,21 @@ var gAdvancedPane = {
     }
     this.updateOnScreenKeyboardVisibility();
     this.updateCacheSizeInputField();
     this.updateActualCacheSize();
     this.updateActualAppCacheSize();
 
     if (Services.prefs.getBoolPref("browser.storageManager.enabled")) {
       Services.obs.addObserver(this, "sitedatamanager:sites-updated", false);
+      let unload = () => {
+        window.removeEventListener("unload", unload);
+        Services.obs.removeObserver(this, "sitedatamanager:sites-updated");
+      };
+      window.addEventListener("unload", unload);
       SiteDataManager.updateSites();
       setEventListener("clearSiteDataButton", "command",
                        gAdvancedPane.clearSiteData);
       setEventListener("siteDataSettings", "command",
                        gAdvancedPane.showSiteDataSettings);
     }
 
     setEventListener("layers.acceleration.disabled", "change",
--- a/browser/extensions/formautofill/content/FormAutofillContent.js
+++ b/browser/extensions/formautofill/content/FormAutofillContent.js
@@ -3,18 +3,20 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
  * Form Autofill frame script.
  */
 
 "use strict";
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr, manager: Cm} = Components;
 
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+let {FormAutoCompleteResult} = Cu.import("resource://gre/modules/nsFormAutoCompleteResult.jsm", {});
 
 /**
  * Handles profile autofill for a DOM Form element.
  * @param {HTMLFormElement} form Form that need to be auto filled
  */
 function FormAutofillHandler(form) {
   this.form = form;
   this.fieldDetails = [];
@@ -126,8 +128,115 @@ FormAutofillHandler.prototype = {
         Cu.reportError("Autocomplete tokens mismatched");
         continue;
       }
 
       fieldDetail.element.setUserInput(field.value);
     }
   },
 };
+
+// Register/unregister a constructor as a factory.
+function AutocompleteFactory() {}
+AutocompleteFactory.prototype = {
+  register(targetConstructor) {
+    let proto = targetConstructor.prototype;
+    this._classID = proto.classID;
+
+    let factory = XPCOMUtils._getFactory(targetConstructor);
+    this._factory = factory;
+
+    let registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
+    registrar.registerFactory(proto.classID, proto.classDescription,
+                              proto.contractID, factory);
+
+    if (proto.classID2) {
+      this._classID2 = proto.classID2;
+      registrar.registerFactory(proto.classID2, proto.classDescription,
+                                proto.contractID2, factory);
+    }
+  },
+
+  unregister() {
+    let registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
+    registrar.unregisterFactory(this._classID, this._factory);
+    if (this._classID2) {
+      registrar.unregisterFactory(this._classID2, this._factory);
+    }
+    this._factory = null;
+  },
+};
+
+
+/**
+ * @constructor
+ *
+ * @implements {nsIAutoCompleteSearch}
+ */
+function AutofillProfileAutoCompleteSearch() {
+
+}
+AutofillProfileAutoCompleteSearch.prototype = {
+  classID: Components.ID("4f9f1e4c-7f2c-439e-9c9e-566b68bc187d"),
+  contractID: "@mozilla.org/autocomplete/search;1?name=autofill-profiles",
+  classDescription: "AutofillProfileAutoCompleteSearch",
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompleteSearch]),
+
+  // Begin nsIAutoCompleteSearch implementation
+
+  /**
+   * Searches for a given string and notifies a listener (either synchronously
+   * or asynchronously) of the result
+   *
+   * @param {string} searchString the string to search for
+   * @param {string} searchParam
+   * @param {Object} previousResult a previous result to use for faster searchinig
+   * @param {Object} listener the listener to notify when the search is complete
+   */
+  startSearch(searchString, searchParam, previousResult, listener) {
+    // TODO: These mock data should be replaced by form autofill API
+    let labels = ["Mary", "John"];
+    let values = ["Mary S.", "John S."];
+    let comments = ["123 Sesame Street.", "331 E. Evelyn Avenue"];
+    let result = new FormAutoCompleteResult(searchString,
+                                            Ci.nsIAutoCompleteResult.RESULT_SUCCESS,
+                                            0, "", values, labels,
+                                            comments);
+
+    listener.onSearchResult(this, result);
+  },
+
+  /**
+   * Stops an asynchronous search that is in progress
+   */
+  stopSearch() {
+  },
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([AutofillProfileAutoCompleteSearch]);
+
+// TODO: Remove this lint option once we apply ProfileAutocomplete while
+//       content script initialization.
+/* eslint no-unused-vars: [2, {"vars": "local"}] */
+let ProfileAutocomplete = {
+  _registered: false,
+  _factory: null,
+
+  ensureRegistered() {
+    if (this._registered) {
+      return;
+    }
+
+    this._factory = new AutocompleteFactory();
+    this._factory.register(AutofillProfileAutoCompleteSearch);
+    this._registered = true;
+  },
+
+  ensureUnregistered() {
+    if (!this._registered) {
+      return;
+    }
+
+    this._factory.unregister();
+    this._factory = null;
+    this._registered = false;
+  },
+};
--- a/browser/extensions/shield-recipe-client/test/browser.ini
+++ b/browser/extensions/shield-recipe-client/test/browser.ini
@@ -1,5 +1,6 @@
 [browser_driver_uuids.js]
 [browser_env_expressions.js]
 [browser_EventEmitter.js]
 [browser_Storage.js]
 [browser_Heartbeat.js]
+skip-if = true # bug 1325409
--- a/browser/themes/shared/autocomplete.inc.css
+++ b/browser/themes/shared/autocomplete.inc.css
@@ -43,16 +43,17 @@
   background-color: var(--arrowpanel-dimmed);
   border-bottom: 1px solid var(--panel-separator-color);
   padding-bottom: 4px;
   padding-top: 4px;
 }
 
 #PopupAutoComplete > richlistbox > richlistitem[originaltype="insecureWarning"][selected] {
   background-color: var(--arrowpanel-dimmed-further);
+  color: -moz-DialogText;
 }
 
 #PopupAutoComplete > richlistbox > richlistitem[originaltype="insecureWarning"] > .ac-title {
   color: GrayText;
   font-size: 1em;
 }
 
 #PopupAutoComplete > richlistbox > richlistitem[originaltype="insecureWarning"][selected] > .ac-title {
--- a/build/gyp.mozbuild
+++ b/build/gyp.mozbuild
@@ -34,16 +34,18 @@ gyp_vars.update({
     'build_json': 0,
     'build_icu': 0,
     'build_opus': 0,
     'libyuv_dir': '/media/libyuv',
     'yuv_disable_avx2': 0 if CONFIG['HAVE_X86_AVX2'] else 1,
     # don't use openssl
     'use_openssl': 0,
 
+    'debug': 1 if CONFIG['DEBUG'] else 0,
+
     'use_x11': 1 if CONFIG['MOZ_X11'] else 0,
     'use_glib': 1 if CONFIG['GLIB_LIBS'] else 0,
 
      # turn off mandatory use of NEON and instead use NEON detection
     'arm_neon': 0,
     'arm_neon_optional': 1,
 
     'moz_widget_toolkit_gonk': 0,
--- a/build/moz.configure/util.configure
+++ b/build/moz.configure/util.configure
@@ -135,29 +135,46 @@ normalize_path = normalize_path()
 
 # Locates the given program using which, or returns the given path if it
 # exists.
 # The `paths` parameter may be passed to search the given paths instead of
 # $PATH.
 @imports(_from='which', _import='which')
 @imports(_from='which', _import='WhichError')
 @imports('itertools')
+@imports('sys')
 @imports(_from='os', _import='pathsep')
+@imports(_from='os', _import='environ')
 def find_program(file, paths=None):
+    # The following snippet comes from `which` itself, with a slight
+    # modification to use lowercase extensions, because it's confusing rustup
+    # (on top of making results not really appealing to the eye).
+
+    # Windows has the concept of a list of extensions (PATHEXT env var).
+    if sys.platform.startswith("win"):
+        exts = [e.lower()
+                for e in environ.get("PATHEXT", "").split(pathsep)]
+        # If '.exe' is not in exts then obviously this is Win9x and
+        # or a bogus PATHEXT, then use a reasonable default.
+        if '.exe' not in exts:
+            exts = ['.com', '.exe', '.bat']
+    else:
+        exts = None
+
     try:
         if is_absolute_or_relative(file):
             return normalize_path(which(os.path.basename(file),
-                                        [os.path.dirname(file)]))
+                                        [os.path.dirname(file)], exts=exts))
         if paths:
             if not isinstance(paths, (list, tuple)):
                 die("Paths provided to find_program must be a list of strings, "
                     "not %r", paths)
             paths = list(itertools.chain(
                 *(p.split(pathsep) for p in paths if p)))
-        return normalize_path(which(file, path=paths))
+        return normalize_path(which(file, path=paths, exts=exts))
     except WhichError:
         return None
 
 
 @imports('os')
 @imports('subprocess')
 @imports(_from='mozbuild.configure.util', _import='LineIO')
 @imports(_from='tempfile', _import='mkstemp')
--- a/devtools/client/inspector/inspector.xhtml
+++ b/devtools/client/inspector/inspector.xhtml
@@ -183,17 +183,17 @@
                 </div>
 
                 <div style="display: none">
                   <p id="boxmodel-dummy"></p>
                 </div>
               </div>
             </div>
 
-            <div id="propertyContainer" class="theme-separator" tabindex="0">
+            <div id="propertyContainer" class="theme-separator" tabindex="0" dir="ltr">
             </div>
 
             <div id="computedview-no-results" hidden="" data-localization="content=inspector.noProperties"></div>
           </div>
         </div>
       </div>
 
       <div id="sidebar-panel-fontinspector" class="devtools-monospace theme-sidebar inspector-tabpanel"
--- a/devtools/client/netmonitor/actions/filters.js
+++ b/devtools/client/netmonitor/actions/filters.js
@@ -1,58 +1,58 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const {
-  TOGGLE_FILTER_TYPE,
-  ENABLE_FILTER_TYPE_ONLY,
-  SET_FILTER_TEXT,
+  TOGGLE_REQUEST_FILTER_TYPE,
+  ENABLE_REQUEST_FILTER_TYPE_ONLY,
+  SET_REQUEST_FILTER_TEXT,
 } = require("../constants");
 
 /**
  * Toggle an existing filter type state.
  * If type 'all' is specified, all the other filter types are set to false.
  * Available filter types are defined in filters reducer.
  *
  * @param {string} filter - A filter type is going to be updated
  */
-function toggleFilterType(filter) {
+function toggleRequestFilterType(filter) {
   return {
-    type: TOGGLE_FILTER_TYPE,
+    type: TOGGLE_REQUEST_FILTER_TYPE,
     filter,
   };
 }
 
 /**
  * Enable filter type exclusively.
  * Except filter type is set to true, all the other filter types are set
  * to false.
  * Available filter types are defined in filters reducer.
  *
  * @param {string} filter - A filter type is going to be updated
  */
-function enableFilterTypeOnly(filter) {
+function enableRequestFilterTypeOnly(filter) {
   return {
-    type: ENABLE_FILTER_TYPE_ONLY,
+    type: ENABLE_REQUEST_FILTER_TYPE_ONLY,
     filter,
   };
 }
 
 /**
  * Set filter text.
  *
  * @param {string} text - A filter text is going to be set
  */
-function setFilterText(text) {
+function setRequestFilterText(text) {
   return {
-    type: SET_FILTER_TEXT,
+    type: SET_REQUEST_FILTER_TEXT,
     text,
   };
 }
 
 module.exports = {
-  toggleFilterType,
-  enableFilterTypeOnly,
-  setFilterText,
+  toggleRequestFilterType,
+  enableRequestFilterTypeOnly,
+  setRequestFilterText,
 };
--- a/devtools/client/netmonitor/components/filter-buttons.js
+++ b/devtools/client/netmonitor/components/filter-buttons.js
@@ -7,43 +7,43 @@
 const { DOM, PropTypes } = require("devtools/client/shared/vendor/react");
 const { connect } = require("devtools/client/shared/vendor/react-redux");
 const { L10N } = require("../l10n");
 const Actions = require("../actions/index");
 
 const { button, div } = DOM;
 
 function FilterButtons({
-  filterTypes,
-  triggerFilterType,
+  requestFilterTypes,
+  toggleRequestFilterType,
 }) {
-  const buttons = filterTypes.entrySeq().map(([type, checked]) => {
+  const buttons = requestFilterTypes.entrySeq().map(([type, checked]) => {
     let classList = ["menu-filter-button"];
     checked && classList.push("checked");
 
     return button({
       id: `requests-menu-filter-${type}-button`,
       className: classList.join(" "),
       "data-key": type,
-      onClick: triggerFilterType,
-      onKeyDown: triggerFilterType,
+      onClick: toggleRequestFilterType,
+      onKeyDown: toggleRequestFilterType,
     }, L10N.getStr(`netmonitor.toolbar.filter.${type}`));
   }).toArray();
 
   return div({ id: "requests-menu-filter-buttons" }, buttons);
 }
 
 FilterButtons.propTypes = {
   state: PropTypes.object.isRequired,
-  triggerFilterType: PropTypes.func.iRequired,
+  toggleRequestFilterType: PropTypes.func.iRequired,
 };
 
 module.exports = connect(
-  (state) => ({ filterTypes: state.filters.types }),
+  (state) => ({ requestFilterTypes: state.filters.requestFilterTypes }),
   (dispatch) => ({
-    triggerFilterType: (evt) => {
+    toggleRequestFilterType: (evt) => {
       if (evt.type === "keydown" && (evt.key !== "" || evt.key !== "Enter")) {
         return;
       }
-      dispatch(Actions.toggleFilterType(evt.target.dataset.key));
+      dispatch(Actions.toggleRequestFilterType(evt.target.dataset.key));
     },
   })
 )(FilterButtons);
--- a/devtools/client/netmonitor/components/search-box.js
+++ b/devtools/client/netmonitor/components/search-box.js
@@ -14,12 +14,12 @@ module.exports = connect(
   (state) => ({
     delay: FREETEXT_FILTER_SEARCH_DELAY,
     keyShortcut: L10N.getStr("netmonitor.toolbar.filterFreetext.key"),
     placeholder: L10N.getStr("netmonitor.toolbar.filterFreetext.label"),
     type: "filter",
   }),
   (dispatch) => ({
     onChange: (url) => {
-      dispatch(Actions.setFilterText(url));
+      dispatch(Actions.setRequestFilterText(url));
     },
   })
 )(SearchBox);
--- a/devtools/client/netmonitor/constants.js
+++ b/devtools/client/netmonitor/constants.js
@@ -13,25 +13,25 @@ const general = {
 const actionTypes = {
   ADD_REQUEST: "ADD_REQUEST",
   ADD_TIMING_MARKER: "ADD_TIMING_MARKER",
   BATCH_ACTIONS: "BATCH_ACTIONS",
   BATCH_ENABLE: "BATCH_ENABLE",
   CLEAR_REQUESTS: "CLEAR_REQUESTS",
   CLEAR_TIMING_MARKERS: "CLEAR_TIMING_MARKERS",
   CLONE_SELECTED_REQUEST: "CLONE_SELECTED_REQUEST",
-  ENABLE_FILTER_TYPE_ONLY: "ENABLE_FILTER_TYPE_ONLY",
+  ENABLE_REQUEST_FILTER_TYPE_ONLY: "ENABLE_REQUEST_FILTER_TYPE_ONLY",
   OPEN_SIDEBAR: "OPEN_SIDEBAR",
   OPEN_STATISTICS: "OPEN_STATISTICS",
   PRESELECT_REQUEST: "PRESELECT_REQUEST",
   REMOVE_SELECTED_CUSTOM_REQUEST: "REMOVE_SELECTED_CUSTOM_REQUEST",
   SELECT_REQUEST: "SELECT_REQUEST",
-  SET_FILTER_TEXT: "SET_FILTER_TEXT",
+  SET_REQUEST_FILTER_TEXT: "SET_REQUEST_FILTER_TEXT",
   SORT_BY: "SORT_BY",
-  TOGGLE_FILTER_TYPE: "TOGGLE_FILTER_TYPE",
+  TOGGLE_REQUEST_FILTER_TYPE: "TOGGLE_REQUEST_FILTER_TYPE",
   UPDATE_REQUEST: "UPDATE_REQUEST",
   WATERFALL_RESIZE: "WATERFALL_RESIZE",
 };
 
 // Descriptions for what this frontend is currently doing.
 const ACTIVITY_TYPE = {
   // Standing by and handling requests normally.
   NONE: 0,
--- a/devtools/client/netmonitor/netmonitor-controller.js
+++ b/devtools/client/netmonitor/netmonitor-controller.js
@@ -261,17 +261,17 @@ var NetMonitorController = {
     // Look for the request in the existing ones or wait for it to appear, if
     // the network monitor is still loading.
     let deferred = promise.defer();
     let request = null;
     let inspector = function () {
       request = getDisplayedRequestById(gStore.getState(), requestId);
       if (!request) {
         // Reset filters so that the request is visible.
-        gStore.dispatch(Actions.toggleFilterType("all"));
+        gStore.dispatch(Actions.toggleRequestFilterType("all"));
         request = getDisplayedRequestById(gStore.getState(), requestId);
       }
 
       // If the request was found, select it. Otherwise this function will be
       // called again once new requests arrive.
       if (request) {
         window.off(EVENTS.REQUEST_ADDED, inspector);
         gStore.dispatch(Actions.selectRequest(request.id));
--- a/devtools/client/netmonitor/reducers/filters.js
+++ b/devtools/client/netmonitor/reducers/filters.js
@@ -1,19 +1,19 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const I = require("devtools/client/shared/vendor/immutable");
 const {
-  TOGGLE_FILTER_TYPE,
-  ENABLE_FILTER_TYPE_ONLY,
-  SET_FILTER_TEXT,
+  TOGGLE_REQUEST_FILTER_TYPE,
+  ENABLE_REQUEST_FILTER_TYPE_ONLY,
+  SET_REQUEST_FILTER_TEXT,
 } = require("../constants");
 
 const FilterTypes = I.Record({
   all: false,
   html: false,
   css: false,
   js: false,
   xhr: false,
@@ -21,21 +21,21 @@ const FilterTypes = I.Record({
   images: false,
   media: false,
   flash: false,
   ws: false,
   other: false,
 });
 
 const Filters = I.Record({
-  types: new FilterTypes({ all: true }),
-  text: "",
+  requestFilterTypes: new FilterTypes({ all: true }),
+  requestFilterText: "",
 });
 
-function toggleFilterType(state, action) {
+function toggleRequestFilterType(state, action) {
   let { filter } = action;
   let newState;
 
   // Ignore unknown filter type
   if (!state.has(filter)) {
     return state;
   }
   if (filter === "all") {
@@ -49,33 +49,35 @@ function toggleFilterType(state, action)
 
   if (!newState.includes(true)) {
     newState = new FilterTypes({ all: true });
   }
 
   return newState;
 }
 
-function enableFilterTypeOnly(state, action) {
+function enableRequestFilterTypeOnly(state, action) {
   let { filter } = action;
 
   // Ignore unknown filter type
   if (!state.has(filter)) {
     return state;
   }
 
   return new FilterTypes({ [filter]: true });
 }
 
 function filters(state = new Filters(), action) {
   switch (action.type) {
-    case TOGGLE_FILTER_TYPE:
-      return state.set("types", toggleFilterType(state.types, action));
-    case ENABLE_FILTER_TYPE_ONLY:
-      return state.set("types", enableFilterTypeOnly(state.types, action));
-    case SET_FILTER_TEXT:
-      return state.set("text", action.text);
+    case TOGGLE_REQUEST_FILTER_TYPE:
+      return state.set("requestFilterTypes",
+        toggleRequestFilterType(state.requestFilterTypes, action));
+    case ENABLE_REQUEST_FILTER_TYPE_ONLY:
+      return state.set("requestFilterTypes",
+        enableRequestFilterTypeOnly(state.requestFilterTypes, action));
+    case SET_REQUEST_FILTER_TEXT:
+      return state.set("requestFilterText", action.text);
     default:
       return state;
   }
 }
 
 module.exports = filters;
--- a/devtools/client/netmonitor/requests-menu-view.js
+++ b/devtools/client/netmonitor/requests-menu-view.js
@@ -67,17 +67,17 @@ RequestsMenuView.prototype = {
   initialize: function (store) {
     dumpn("Initializing the RequestsMenuView");
 
     this.store = store;
 
     this.contextMenu = new RequestListContextMenu();
     this.contextMenu.initialize(store);
 
-    Prefs.filters.forEach(type => store.dispatch(Actions.toggleFilterType(type)));
+    Prefs.filters.forEach(type => store.dispatch(Actions.toggleRequestFilterType(type)));
 
     // Watch selection changes
     this.store.subscribe(storeWatcher(
       null,
       () => getSelectedRequest(this.store.getState()),
       (newSelected, oldSelected) => this.onSelectionUpdate(newSelected, oldSelected)
     ));
 
--- a/devtools/client/netmonitor/selectors/filters.js
+++ b/devtools/client/netmonitor/selectors/filters.js
@@ -1,13 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 function getActiveFilters(state) {
-  return state.filters.types.toSeq().filter(checked => checked).keySeq().toArray();
+  return state.filters.requestFilterTypes.toSeq()
+    .filter(checked => checked).keySeq().toArray();
 }
 
 module.exports = {
   getActiveFilters
 };
--- a/devtools/client/netmonitor/selectors/requests.js
+++ b/devtools/client/netmonitor/selectors/requests.js
@@ -19,20 +19,20 @@ function getOrigRequest(requests, req) {
 
   const origId = req.id.replace(/-clone$/, "");
   return requests.find(r => r.id === origId);
 }
 
 const getFilterFn = createSelector(
   state => state.filters,
   filters => r => {
-    const matchesType = filters.types.some((enabled, filter) => {
+    const matchesType = filters.requestFilterTypes.some((enabled, filter) => {
       return enabled && Filters[filter] && Filters[filter](r);
     });
-    return matchesType && isFreetextMatch(r, filters.text);
+    return matchesType && isFreetextMatch(r, filters.requestFilterText);
   }
 );
 
 const getSortFn = createSelector(
   state => state.requests.requests,
   state => state.sort,
   (requests, sort) => {
     let dataSorter = Sorters[sort.type || "waterfall"];
--- a/devtools/client/netmonitor/statistics-view.js
+++ b/devtools/client/netmonitor/statistics-view.js
@@ -166,17 +166,17 @@ StatisticsView.prototype = {
       data: data,
       strings: strings,
       totals: totals,
       sorted: sorted
     });
 
     chart.on("click", (_, item) => {
       // Reset FilterButtons and enable one filter exclusively
-      this.store.dispatch(Actions.enableFilterTypeOnly(item.label));
+      this.store.dispatch(Actions.enableRequestFilterTypeOnly(item.label));
       this.store.dispatch(Actions.openStatistics(false));
     });
 
     container.appendChild(chart.node);
   },
 
   /**
    * Sanitizes the data source used for creating charts, to follow the
--- a/devtools/client/netmonitor/test/browser_net_filter-01.js
+++ b/devtools/client/netmonitor/test/browser_net_filter-01.js
@@ -130,17 +130,17 @@ const EXPECTED_REQUESTS = [
 
 add_task(function* () {
   let Actions = require("devtools/client/netmonitor/actions/index");
 
   let { monitor } = yield initNetMonitor(FILTERING_URL);
   let { gStore } = monitor.panelWin;
 
   function setFreetextFilter(value) {
-    gStore.dispatch(Actions.setFilterText(value));
+    gStore.dispatch(Actions.setRequestFilterText(value));
   }
 
   info("Starting test... ");
 
   let { $, NetMonitorView } = monitor.panelWin;
   let { RequestsMenu } = NetMonitorView;
 
   RequestsMenu.lazyUpdate = false;
--- a/devtools/client/netmonitor/test/browser_net_icon-preview.js
+++ b/devtools/client/netmonitor/test/browser_net_icon-preview.js
@@ -23,17 +23,17 @@ add_task(function* () {
 
   info("Checking the image thumbnail when all items are shown.");
   checkImageThumbnail();
 
   gStore.dispatch(Actions.sortBy("size"));
   info("Checking the image thumbnail when all items are sorted.");
   checkImageThumbnail();
 
-  gStore.dispatch(Actions.toggleFilterType("images"));
+  gStore.dispatch(Actions.toggleRequestFilterType("images"));
   info("Checking the image thumbnail when only images are shown.");
   checkImageThumbnail();
 
   info("Reloading the debuggee and performing all requests again...");
   wait = waitForEvents();
   yield reloadAndPerformRequests();
   yield wait;
 
--- a/devtools/client/netmonitor/test/browser_net_prefs-reload.js
+++ b/devtools/client/netmonitor/test/browser_net_prefs-reload.js
@@ -29,17 +29,17 @@ add_task(function* () {
       // A custom new value to be used for the verified preference.
       newValue: ["html", "css"],
       // Getter used to retrieve the current value from the frontend, in order
       // to verify that the pref was applied properly.
       validateValue: ($) => getActiveFilters(getState()),
       // Predicate used to modify the frontend when setting the new pref value,
       // before trying to validate the changes.
       modifyFrontend: ($, value) => value.forEach(e =>
-        getStore().dispatch(Actions.toggleFilterType(e)))
+        getStore().dispatch(Actions.toggleRequestFilterType(e)))
     },
     networkDetailsWidth: {
       newValue: ~~(Math.random() * 200 + 100),
       validateValue: ($) => ~~$("#details-pane").getAttribute("width"),
       modifyFrontend: ($, value) => $("#details-pane").setAttribute("width", value)
     },
     networkDetailsHeight: {
       newValue: ~~(Math.random() * 300 + 100),
--- a/devtools/client/netmonitor/test/components/filter-buttons.test.js
+++ b/devtools/client/netmonitor/test/components/filter-buttons.test.js
@@ -52,17 +52,17 @@ describe("FilterButtons::enableFilterOnl
   };
 
   const store = configureStore();
   const wrapper = mount(Provider(
     { store },
     FilterButtons()
   ));
 
-  store.dispatch(Actions.enableFilterTypeOnly("xhr"));
+  store.dispatch(Actions.enableRequestFilterTypeOnly("xhr"));
   asExpected(wrapper, expectXHRTypes, `when enableFilterOnly("xhr") is called`);
 });
 
 // integration test with redux store, action, reducer
 describe("FilterButtons::toggleFilter:", () => {
   const expectXHRJSTypes = {
     all: false,
     html: false,
@@ -78,18 +78,18 @@ describe("FilterButtons::toggleFilter:",
   };
 
   const store = configureStore();
   const wrapper = mount(Provider(
     { store },
     FilterButtons()
   ));
 
-  store.dispatch(Actions.toggleFilterType("xhr"));
-  store.dispatch(Actions.toggleFilterType("js"));
+  store.dispatch(Actions.toggleRequestFilterType("xhr"));
+  store.dispatch(Actions.toggleRequestFilterType("js"));
   asExpected(wrapper, expectXHRJSTypes, `when xhr, js is toggled`);
 });
 
 function asExpected(wrapper, expectTypes, description) {
   for (let type of Object.keys(expectTypes)) {
     let checked = expectTypes[type] ? "checked" : "not checked";
     let className = expectTypes[type] ?
         "menu-filter-button checked": "menu-filter-button";
--- a/devtools/client/responsive.html/browser/tunnel.js
+++ b/devtools/client/responsive.html/browser/tunnel.js
@@ -483,23 +483,21 @@ MessageManagerTunnel.prototype = {
     if (!this.inner.frameLoader) {
       return null;
     }
     return this.inner.frameLoader.messageManager;
   },
 
   init() {
     for (let method of this.PASS_THROUGH_METHODS) {
-      // Workaround bug 449811 to ensure a fresh binding each time through the loop
-      let _method = method;
-      this[_method] = (...args) => {
+      this[method] = (...args) => {
         if (!this.outerParentMM) {
           return null;
         }
-        return this.outerParentMM[_method](...args);
+        return this.outerParentMM[method](...args);
       };
     }
 
     for (let name of this.INNER_TO_OUTER_MESSAGES) {
       this.innerParentMM.addMessageListener(name, this);
       this.tunneledMessageNames.add(name);
     }
 
@@ -533,23 +531,21 @@ MessageManagerTunnel.prototype = {
     for (let name of this.tunneledMessageNames) {
       this.innerParentMM.removeMessageListener(name, this);
     }
 
     // Some objects may have cached this tunnel as the messageManager for a frame.  To
     // ensure it keeps working after tunnel close, rewrite the overidden methods as pass
     // through methods.
     for (let method of this.OVERRIDDEN_METHODS) {
-      // Workaround bug 449811 to ensure a fresh binding each time through the loop
-      let _method = method;
-      this[_method] = (...args) => {
+      this[method] = (...args) => {
         if (!this.outerParentMM) {
           return null;
         }
-        return this.outerParentMM[_method](...args);
+        return this.outerParentMM[method](...args);
       };
     }
   },
 
   observe(subject, topic, data) {
     if (topic != "message-manager-close") {
       return;
     }
--- a/devtools/client/webconsole/test/browser_webconsole_netlogging_reset_filter.js
+++ b/devtools/client/webconsole/test/browser_webconsole_netlogging_reset_filter.js
@@ -42,17 +42,17 @@ add_task(function* () {
   let panel = toolbox.getCurrentPanel();
   let selected = panel.panelWin.NetMonitorView.RequestsMenu.selectedItem;
   is(selected.method, htmlRequest.request.method,
      "The correct request is selected");
   is(selected.url, htmlRequest.request.url,
      "The correct request is definitely selected");
 
   // Filter out the HTML request.
-  panel.panelWin.gStore.dispatch(Actions.toggleFilterType("js"));
+  panel.panelWin.gStore.dispatch(Actions.toggleRequestFilterType("js"));
 
   yield toolbox.selectTool("webconsole");
   is(toolbox.currentToolId, "webconsole", "Web console was selected");
   yield hud.ui.openNetworkPanel(htmlRequest.actor);
 
   panel.panelWin.NetMonitorView.RequestsMenu.selectedItem;
   is(selected.method, htmlRequest.request.method,
      "The correct request is selected");
--- a/devtools/server/actors/stylesheets.js
+++ b/devtools/server/actors/stylesheets.js
@@ -436,39 +436,69 @@ var StyleSheetActor = protocol.ActorClas
 
     if (!this.href) {
       // this is an inline <style> sheet
       let content = this.ownerNode.textContent;
       this.text = content;
       return promise.resolve(content);
     }
 
+    return this.fetchStylesheet(this.href).then(({ content }) => {
+      this.text = content;
+      return content;
+    });
+  },
+
+  /**
+   * Fetch a stylesheet at the provided URL. Returns a promise that will resolve the
+   * result of the fetch command.
+   *
+   * @param  {String} href
+   *         The href of the stylesheet to retrieve.
+   * @return {Promise} a promise that resolves with an object with the following members
+   *         on success:
+   *           - content: the document at that URL, as a string,
+   *           - contentType: the content type of the document
+   *         If an error occurs, the promise is rejected with that error.
+   */
+  fetchStylesheet: Task.async(function* (href) {
     let options = {
       loadFromCache: true,
       policy: Ci.nsIContentPolicy.TYPE_INTERNAL_STYLESHEET,
       charset: this._getCSSCharset()
     };
 
     // Bug 1282660 - We use the system principal to load the default internal
     // stylesheets instead of the content principal since such stylesheets
     // require system principal to load. At meanwhile, we strip the loadGroup
     // for preventing the assertion of the userContextId mismatching.
-    // The default internal stylesheets load from the 'resource:' URL.
-    // Bug 1287607, 1291321 - 'chrome' and 'file' protocols should also be handled in the
-    // same way.
-    if (!/^(chrome|file|resource):\/\//.test(this.href)) {
+
+    // chrome|file|resource|moz-extension protocols rely on the system principal.
+    let excludedProtocolsRe = /^(chrome|file|resource|moz-extension):\/\//;
+    if (!excludedProtocolsRe.test(this.href)) {
+      // Stylesheets using other protocols should use the content principal.
       options.window = this.window;
       options.principal = this.document.nodePrincipal;
     }
 
-    return fetch(this.href, options).then(({ content }) => {
-      this.text = content;
-      return content;
-    });
-  },
+    let result;
+    try {
+      result = yield fetch(this.href, options);
+    } catch (e) {
+      // The list of excluded protocols can be missing some protocols, try to use the
+      // system principal if the first fetch failed.
+      console.error(`stylesheets actor: fetch failed for ${this.href},` +
+        ` using system principal instead.`);
+      options.window = undefined;
+      options.principal = undefined;
+      result = yield fetch(this.href, options);
+    }
+
+    return result;
+  }),
 
   /**
    * Protocol method to get the original source (actors) for this
    * stylesheet if it has uses source maps.
    */
   getOriginalSources: function () {
     if (this._originalSources) {
       return promise.resolve(this._originalSources);
--- a/devtools/shared/css/generated/properties-db.js
+++ b/devtools/shared/css/generated/properties-db.js
@@ -2852,16 +2852,17 @@ exports.CSS_PROPERTIES = {
       "-moz-box-direction",
       "-moz-box-flex",
       "-moz-box-ordinal-group",
       "-moz-box-orient",
       "-moz-box-pack",
       "box-shadow",
       "box-sizing",
       "caption-side",
+      "caret-color",
       "clear",
       "clip",
       "clip-path",
       "clip-rule",
       "color",
       "color-adjust",
       "color-interpolation",
       "color-interpolation-filters",
@@ -5256,16 +5257,38 @@ exports.CSS_PROPERTIES = {
       "initial",
       "left",
       "right",
       "top",
       "top-outside",
       "unset"
     ]
   },
+  "caret-color": {
+    "isInherited": true,
+    "subproperties": [
+      "caret-color"
+    ],
+    "supports": [
+      2
+    ],
+    "values": [
+      "COLOR",
+      "auto",
+      "currentColor",
+      "hsl",
+      "hsla",
+      "inherit",
+      "initial",
+      "rgb",
+      "rgba",
+      "transparent",
+      "unset"
+    ]
+  },
   "clear": {
     "isInherited": false,
     "subproperties": [
       "clear"
     ],
     "supports": [],
     "values": [
       "both",
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -2141,27 +2141,30 @@ Element::DispatchClickEvent(nsPresContex
   NS_PRECONDITION(aSourceEvent, "Must have source event");
   NS_PRECONDITION(aStatus, "Null out param?");
 
   WidgetMouseEvent event(aSourceEvent->IsTrusted(), eMouseClick,
                          aSourceEvent->mWidget, WidgetMouseEvent::eReal);
   event.mRefPoint = aSourceEvent->mRefPoint;
   uint32_t clickCount = 1;
   float pressure = 0;
+  uint32_t pointerId = 0; // Use the default value here.
   uint16_t inputSource = 0;
   WidgetMouseEvent* sourceMouseEvent = aSourceEvent->AsMouseEvent();
   if (sourceMouseEvent) {
     clickCount = sourceMouseEvent->mClickCount;
     pressure = sourceMouseEvent->pressure;
+    pointerId = sourceMouseEvent->pointerId;
     inputSource = sourceMouseEvent->inputSource;
   } else if (aSourceEvent->mClass == eKeyboardEventClass) {
     inputSource = nsIDOMMouseEvent::MOZ_SOURCE_KEYBOARD;
   }
   event.pressure = pressure;
   event.mClickCount = clickCount;
+  event.pointerId = pointerId;
   event.inputSource = inputSource;
   event.mModifiers = aSourceEvent->mModifiers;
   if (aExtraEventFlags) {
     // Be careful not to overwrite existing flags!
     event.mFlags.Union(*aExtraEventFlags);
   }
 
   return DispatchEvent(aPresContext, &event, aTarget, aFullDispatch, aStatus);
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -8235,16 +8235,17 @@ nsContentUtils::SendMouseEvent(const nsC
                                float aY,
                                int32_t aButton,
                                int32_t aButtons,
                                int32_t aClickCount,
                                int32_t aModifiers,
                                bool aIgnoreRootScrollFrame,
                                float aPressure,
                                unsigned short aInputSourceArg,
+                               uint32_t aIdentifier,
                                bool aToWindow,
                                bool *aPreventDefault,
                                bool aIsDOMEventSynthesized,
                                bool aIsWidgetEventSynthesized)
 {
   nsPoint offset;
   nsCOMPtr<nsIWidget> widget = GetWidget(aPresShell, &offset);
   if (!widget)
@@ -8282,16 +8283,17 @@ nsContentUtils::SendMouseEvent(const nsC
   }
 
   WidgetMouseEvent event(true, msg, widget,
                          aIsWidgetEventSynthesized ?
                            WidgetMouseEvent::eSynthesized :
                            WidgetMouseEvent::eReal,
                          contextMenuKey ? WidgetMouseEvent::eContextMenuKey :
                                           WidgetMouseEvent::eNormal);
+  event.pointerId = aIdentifier;
   event.mModifiers = GetWidgetModifiers(aModifiers);
   event.button = aButton;
   event.buttons = aButtons != nsIDOMWindowUtils::MOUSE_BUTTONS_NOT_SPECIFIED ?
                   aButtons :
                   msg == eMouseUp ? 0 : GetButtonsFlagForButton(aButton);
   event.pressure = aPressure;
   event.inputSource = aInputSourceArg;
   event.mClickCount = aClickCount;
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -2581,16 +2581,17 @@ public:
                                  float aY,
                                  int32_t aButton,
                                  int32_t aButtons,
                                  int32_t aClickCount,
                                  int32_t aModifiers,
                                  bool aIgnoreRootScrollFrame,
                                  float aPressure,
                                  unsigned short aInputSourceArg,
+                                 uint32_t aIdentifier,
                                  bool aToWindow,
                                  bool *aPreventDefault,
                                  bool aIsDOMEventSynthesized,
                                  bool aIsWidgetEventSynthesized);
 
   static void FirePageShowEvent(nsIDocShellTreeItem* aItem,
                                 mozilla::dom::EventTarget* aChromeEventHandler,
                                 bool aFireIfShowing);
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -637,22 +637,26 @@ nsDOMWindowUtils::SendMouseEvent(const n
                                  int32_t aClickCount,
                                  int32_t aModifiers,
                                  bool aIgnoreRootScrollFrame,
                                  float aPressure,
                                  unsigned short aInputSourceArg,
                                  bool aIsDOMEventSynthesized,
                                  bool aIsWidgetEventSynthesized,
                                  int32_t aButtons,
+                                 uint32_t aIdentifier,
                                  uint8_t aOptionalArgCount,
                                  bool *aPreventDefault)
 {
   return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers,
                               aIgnoreRootScrollFrame, aPressure,
-                              aInputSourceArg, false, aPreventDefault,
+                              aInputSourceArg,
+                              aOptionalArgCount >= 7 ?
+                                aIdentifier : DEFAULT_MOUSE_POINTER_ID,
+                              false, aPreventDefault,
                               aOptionalArgCount >= 4 ?
                                 aIsDOMEventSynthesized : true,
                               aOptionalArgCount >= 5 ?
                                 aIsWidgetEventSynthesized : false,
                               aOptionalArgCount >= 6 ?
                               aButtons : MOUSE_BUTTONS_NOT_SPECIFIED);
 }
 
@@ -664,24 +668,28 @@ nsDOMWindowUtils::SendMouseEventToWindow
                                          int32_t aClickCount,
                                          int32_t aModifiers,
                                          bool aIgnoreRootScrollFrame,
                                          float aPressure,
                                          unsigned short aInputSourceArg,
                                          bool aIsDOMEventSynthesized,
                                          bool aIsWidgetEventSynthesized,
                                          int32_t aButtons,
+                                         uint32_t aIdentifier,
                                          uint8_t aOptionalArgCount)
 {
   PROFILER_LABEL("nsDOMWindowUtils", "SendMouseEventToWindow",
     js::ProfileEntry::Category::EVENTS);
 
   return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers,
                               aIgnoreRootScrollFrame, aPressure,
-                              aInputSourceArg, true, nullptr,
+                              aInputSourceArg,
+                              aOptionalArgCount >= 7 ?
+                                aIdentifier : DEFAULT_MOUSE_POINTER_ID,
+                              true, nullptr,
                               aOptionalArgCount >= 4 ?
                                 aIsDOMEventSynthesized : true,
                               aOptionalArgCount >= 5 ?
                                 aIsWidgetEventSynthesized : false,
                               aOptionalArgCount >= 6 ?
                               aButtons : MOUSE_BUTTONS_NOT_SPECIFIED);
 }
 
@@ -690,27 +698,28 @@ nsDOMWindowUtils::SendMouseEventCommon(c
                                        float aX,
                                        float aY,
                                        int32_t aButton,
                                        int32_t aClickCount,
                                        int32_t aModifiers,
                                        bool aIgnoreRootScrollFrame,
                                        float aPressure,
                                        unsigned short aInputSourceArg,
+                                       uint32_t aPointerId,
                                        bool aToWindow,
                                        bool *aPreventDefault,
                                        bool aIsDOMEventSynthesized,
                                        bool aIsWidgetEventSynthesized,
                                        int32_t aButtons)
 {
   nsCOMPtr<nsIPresShell> presShell = GetPresShell();
   return nsContentUtils::SendMouseEvent(presShell, aType, aX, aY, aButton,
       aButtons, aClickCount, aModifiers, aIgnoreRootScrollFrame, aPressure,
-      aInputSourceArg, aToWindow, aPreventDefault, aIsDOMEventSynthesized,
-      aIsWidgetEventSynthesized);
+      aInputSourceArg, aPointerId, aToWindow, aPreventDefault,
+      aIsDOMEventSynthesized, aIsWidgetEventSynthesized);
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SendPointerEventCommon(const nsAString& aType,
                                          float aX,
                                          float aY,
                                          int32_t aButton,
                                          int32_t aClickCount,
--- a/dom/base/nsDOMWindowUtils.h
+++ b/dom/base/nsDOMWindowUtils.h
@@ -86,16 +86,17 @@ protected:
                                   float aX,
                                   float aY,
                                   int32_t aButton,
                                   int32_t aClickCount,
                                   int32_t aModifiers,
                                   bool aIgnoreRootScrollFrame,
                                   float aPressure,
                                   unsigned short aInputSourceArg,
+                                  uint32_t aIdentifier,
                                   bool aToWindow,
                                   bool *aPreventDefault,
                                   bool aIsDOMEventSynthesized,
                                   bool aIsWidgetEventSynthesized,
                                   int32_t aButtons);
 
   NS_IMETHOD SendPointerEventCommon(const nsAString& aType,
                                     float aX,
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -650,17 +650,17 @@ skip-if = (toolkit == 'android') # Andro
 [test_iframe_referrer.html]
 [test_iframe_referrer_changing.html]
 [test_iframe_referrer_invalid.html]
 [test_Image_constructor.html]
 [test_img_referrer.html]
 [test_innersize_scrollport.html]
 [test_integer_attr_with_leading_zero.html]
 [test_intersectionobservers.html]
-skip-if = true # Track Bug 1320704
+skip-if = (os == "android") # Timing issues
 [test_link_prefetch.html]
 skip-if = !e10s # Track Bug 1281415
 [test_link_stylesheet.html]
 [test_messagemanager_targetchain.html]
 [test_meta_viewport0.html]
 skip-if = (os != 'android')    # meta-viewport tag support is mobile-only
 [test_meta_viewport1.html]
 skip-if = (os != 'android')    # meta-viewport tag support is mobile-only
--- a/dom/canvas/test/captureStream_common.js
+++ b/dom/canvas/test/captureStream_common.js
@@ -141,18 +141,26 @@ CaptureStreamTestHelper.prototype = {
    * Returns a promise that resolves when the top left pixel of |video| matches
    * on all channels. Use |threshold| for fuzzy matching the color on each
    * channel, in the range [0,255].
    */
   waitForPixelColor: function (video, refColor, threshold, infoString) {
     info("Waiting for video " + video.id + " to match [" +
          refColor.data.join(',') + "] - " + refColor.name +
          " (" + infoString + ")");
+    var paintedFrames = video.mozPaintedFrames-1;
     return this.waitForPixel(video, 0, 0,
-                             px => this.isPixel(px, refColor, threshold))
+                             px => { if (paintedFrames != video.mozPaintedFrames) {
+				       info("Frame: " + video.mozPaintedFrames +
+					    " IsPixel ref=" + refColor.data +
+					    " threshold=" + threshold +
+					    " value=" + px);
+				       paintedFrames = video.mozPaintedFrames;
+				     }
+				     return this.isPixel(px, refColor, threshold); })
       .then(() => ok(true, video.id + " " + infoString));
   },
 
   /*
    * Returns a promise that resolves after |timeout| ms of playback or when the
    * top left pixel of |video| becomes |refColor|. The test is failed if the
    * timeout is not reached.
    */
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -4492,16 +4492,17 @@ EventStateManager::FireDragEnterOrExit(n
                                        nsWeakFrame& aTargetFrame)
 {
   nsEventStatus status = nsEventStatus_eIgnore;
   WidgetDragEvent event(aDragEvent->IsTrusted(), aMessage, aDragEvent->mWidget);
   event.mRefPoint = aDragEvent->mRefPoint;
   event.mModifiers = aDragEvent->mModifiers;
   event.buttons = aDragEvent->buttons;
   event.relatedTarget = aRelatedTarget;
+  event.pointerId = aDragEvent->pointerId;
   event.inputSource = aDragEvent->inputSource;
 
   mCurrentTargetContent = aTargetContent;
 
   if (aTargetContent != aRelatedTarget) {
     //XXX This event should still go somewhere!!
     if (aTargetContent) {
       EventDispatcher::Dispatch(aTargetContent, aPresContext, &event,
@@ -4643,16 +4644,17 @@ EventStateManager::InitAndDispatchClickE
   event.mRefPoint = aEvent->mRefPoint;
   event.mClickCount = aEvent->mClickCount;
   event.mModifiers = aEvent->mModifiers;
   event.buttons = aEvent->buttons;
   event.mTime = aEvent->mTime;
   event.mTimeStamp = aEvent->mTimeStamp;
   event.mFlags.mNoContentDispatch = aNoContentDispatch;
   event.button = aEvent->button;
+  event.pointerId = aEvent->pointerId;
   event.inputSource = aEvent->inputSource;
 
   return aPresShell->HandleEventWithTarget(&event, aCurrentTarget,
                                            aMouseTarget, aStatus);
 }
 
 nsresult
 EventStateManager::CheckForAndDispatchClick(WidgetMouseEvent* aEvent,
--- a/dom/events/test/pointerevents/mochitest_support_external.js
+++ b/dom/events/test/pointerevents/mochitest_support_external.js
@@ -30,21 +30,23 @@ function turnOnPointerEvents(callback) {
   SpecialPowers.pushPrefEnv({
     "set": [
       ["dom.w3c_pointer_events.enabled", true],
       ["layout.css.touch_action.enabled", true]
     ]
   }, callback);
 }
 
+var utils = SpecialPowers.Ci.nsIDOMWindowUtils;
+
 // Mouse Event Helper Object
 var MouseEventHelper = (function() {
-  var utils = SpecialPowers.Ci.nsIDOMWindowUtils;
-
   return {
+    MOUSE_ID: utils.DEFAULT_MOUSE_POINTER_ID,
+    PEN_ID:   utils.DEFAULT_PEN_POINTER_ID,
     // State
     // TODO: Separate this to support mouse and pen simultaneously.
     BUTTONS_STATE: utils.MOUSE_BUTTONS_NO_BUTTON,
 
     // Button
     BUTTON_NONE:   -1, // Used by test framework only. (replaced before sending)
     BUTTON_LEFT:   utils.MOUSE_BUTTON_LEFT_BUTTON,
     BUTTON_MIDDLE: utils.MOUSE_BUTTON_MIDDLE_BUTTON,
@@ -81,19 +83,24 @@ var MouseEventHelper = (function() {
 
 // Helper function to send MouseEvent with different parameters
 function sendMouseEvent(int_win, elemId, mouseEventType, params) {
   var elem = int_win.document.getElementById(elemId);
   if(!!elem) {
     var rect = elem.getBoundingClientRect();
     var eventObj = {type: mouseEventType};
 
-    if(params && "inputSource" in params)
-      eventObj.inputSource = params.inputSource;
-
+    // Default to mouse.
+    eventObj.inputSource =
+      (params && "inputSource" in params) ? params.inputSource :
+                                            MouseEvent.MOZ_SOURCE_MOUSE;
+    // Compute pointerId
+    eventObj.id =
+      (eventObj.inputSource === MouseEvent.MOZ_SOURCE_MOUSE) ? MouseEventHelper.MOUSE_ID :
+                                                               MouseEventHelper.PEN_ID;
     // Check or generate a |button| value.
     var isButtonEvent = mouseEventType === "mouseup" ||
                         mouseEventType === "mousedown";
 
     // Set |button| to the default value first.
     eventObj.button = isButtonEvent ? MouseEventHelper.BUTTON_LEFT
                                     : MouseEventHelper.BUTTON_NONE;
 
@@ -136,31 +143,36 @@ function sendMouseEvent(int_win, elemId,
   } else {
     is(!!elem, true, "Document should have element with id: " + elemId);
   }
 }
 
 // Touch Event Helper Object
 var TouchEventHelper = {
   // State
-  // TODO: Support multiple point scenarios.
+  TOUCH_ID: utils.DEFAULT_TOUCH_POINTER_ID,
   TOUCH_STATE: false,
 
   // Utils
   checkExitState: function() {
     ok(!this.TOUCH_STATE, "Mismatched touchstart/touchend caught.");
   }
 }
 
 // Helper function to send TouchEvent with different parameters
+// TODO: Support multiple touch points to test more features such as
+// PointerEvent.isPrimary and pinch-zoom.
 function sendTouchEvent(int_win, elemId, touchEventType, params) {
   var elem = int_win.document.getElementById(elemId);
   if(!!elem) {
     var rect = elem.getBoundingClientRect();
-    var eventObj = {type: touchEventType};
+    var eventObj = {
+      type: touchEventType,
+      id: TouchEventHelper.TOUCH_ID
+    };
 
     // Update touch state
     switch(touchEventType) {
       case "touchstart":
         TouchEventHelper.TOUCH_STATE = true; // Set touch flag.
         break;
       case "touchend":
         TouchEventHelper.TOUCH_STATE = false; // Clear touch flag.
@@ -178,40 +190,50 @@ function sendTouchEvent(int_win, elemId,
     is(!!elem, true, "Document should have element with id: " + elemId);
   }
 }
 
 // Helper function to run Point Event test in a new tab.
 function runTestInNewWindow(aFile) {
   var testURL = location.href.substring(0, location.href.lastIndexOf('/') + 1) + aFile;
   var testWindow = window.open(testURL, "_blank");
+  var testDone = false;
 
   // We start testing when receiving load event. Inject the mochitest helper js
   // to the test case after DOM elements are constructed and before the load
   // event is fired.
   testWindow.addEventListener("DOMContentLoaded", function scriptInjector() {
     testWindow.removeEventListener("DOMContentLoaded", scriptInjector);
     const PARENT_ORIGIN = "http://mochi.test:8888/";
     var e = testWindow.document.createElement('script');
     e.type = 'text/javascript';
     e.src = "mochitest_support_internal.js";
     testWindow.document.getElementsByTagName('head')[0].appendChild(e);
   });
 
   window.addEventListener("message", function(aEvent) {
     switch(aEvent.data.type) {
       case "START":
+        // Update constants
+        MouseEventHelper.MOUSE_ID = aEvent.data.message.mouseId;
+        MouseEventHelper.PEN_ID   = aEvent.data.message.penId;
+        TouchEventHelper.TOUCH_ID = aEvent.data.message.touchId;
+
         turnOnPointerEvents(() => {
           executeTest(testWindow);
         });
         return;
       case "RESULT":
-        ok(aEvent.data.result, aEvent.data.message);
+        // Should not perform checking after SimpleTest.finish().
+        if (!testDone) {
+          ok(aEvent.data.result, aEvent.data.message);
+        }
         return;
       case "FIN":
+        testDone = true;
         MouseEventHelper.checkExitState();
         TouchEventHelper.checkExitState();
         testWindow.close();
         SimpleTest.finish();
         return;
     }
   });
 }
--- a/dom/events/test/pointerevents/mochitest_support_internal.js
+++ b/dom/events/test/pointerevents/mochitest_support_internal.js
@@ -1,43 +1,80 @@
 // This file supports translating W3C tests
 // to tests on auto MochiTest system with minimum changes.
 // Author: Maksim Lebedev <alessarik@gmail.com>
 
 const PARENT_ORIGIN = "http://mochi.test:8888/";
 
+// Since web platform tests don't check pointerId, we have to use some heuristic
+// to test them. and thus pointerIds are send to mochitest_support_external.js
+// before we start sending synthesized widget events. Here, we avoid using
+// default values used in Gecko to insure everything works as expected.
+const POINTER_MOUSE_ID = 7;
+const POINTER_PEN_ID   = 8;
+const POINTER_TOUCH_ID = 9; // Extend for multiple touch points if needed.
+
 // Setup environment.
 addListeners(document.getElementById("target0"));
 addListeners(document.getElementById("target1"));
 
 // Setup communication between mochitest_support_external.js.
 // Function allows to initialize prerequisites before testing
 // and adds some callbacks to support mochitest system.
-add_result_callback((aTestObj) => {
+function resultCallback(aTestObj) {
   var message = aTestObj["name"] + " (";
   message += "Get: " + JSON.stringify(aTestObj["status"]) + ", ";
   message += "Expect: " + JSON.stringify(aTestObj["PASS"]) + ")";
   window.opener.postMessage({type: "RESULT",
                              message: message,
                              result: aTestObj["status"] === aTestObj["PASS"]},
                             PARENT_ORIGIN);
-});
+}
 
+add_result_callback(resultCallback);
 add_completion_callback(() => {
   window.opener.postMessage({type: "FIN"}, PARENT_ORIGIN);
 });
 
 window.addEventListener("load", () => {
-  // Start testing when the document is loaded.
-  window.opener.postMessage({type: "START"}, PARENT_ORIGIN);
+  // Start testing.
+  var startMessage = {
+    type: "START",
+    message: {
+      mouseId: POINTER_MOUSE_ID,
+      penId:   POINTER_PEN_ID,
+      touchId: POINTER_TOUCH_ID
+    }
+  }
+  window.opener.postMessage(startMessage, PARENT_ORIGIN);
 });
 
 function addListeners(elem) {
   if(!elem)
     return;
   var All_Events = ["pointerdown","pointerup","pointercancel","pointermove","pointerover","pointerout",
                     "pointerenter","pointerleave","gotpointercapture","lostpointercapture"];
   All_Events.forEach(function(name) {
     elem.addEventListener(name, function(event) {
       console.log('('+event.type+')-('+event.pointerType+')');
+
+      // Perform checks only for trusted events.
+      if (!event.isTrusted) {
+        return;
+      }
+
+      // Compute the desired event.pointerId from event.pointerType.
+      var pointerId = {
+        mouse: POINTER_MOUSE_ID,
+        pen:   POINTER_PEN_ID,
+        touch: POINTER_TOUCH_ID
+      }[event.pointerType];
+
+      // Compare the pointerId.
+      resultCallback({
+        name:   "Mismatched event.pointerId recieved.",
+        status: event.pointerId,
+        PASS:   pointerId
+      });
+
     }, false);
   });
 }
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -317,32 +317,35 @@ interface nsIDOMWindowUtils : nsISupport
    * @param aPressure touch input pressure: 0.0 -> 1.0
    * @param aInputSourceArg input source, see nsIDOMMouseEvent for values,
    *        defaults to mouse input.
    * @param aIsDOMEventSynthesized controls nsIDOMEvent.isSynthesized value
    *                               that helps identifying test related events,
    *                               defaults to true
    * @param aIsWidgetEventSynthesized controls WidgetMouseEvent.mReason value
    *                                  defaults to false (WidgetMouseEvent::eReal)
+   * @param aIdentifier A unique identifier for the pointer causing the event,
+   *                    defaulting to nsIDOMWindowUtils::DEFAULT_MOUSE_POINTER_ID.
    *
    * returns true if the page called prevent default on this event
    */
   [optional_argc]
   boolean sendMouseEvent(in AString aType,
                          in float aX,
                          in float aY,
                          in long aButton,
                          in long aClickCount,
                          in long aModifiers,
                          [optional] in boolean aIgnoreRootScrollFrame,
                          [optional] in float aPressure,
                          [optional] in unsigned short aInputSourceArg,
                          [optional] in boolean aIsDOMEventSynthesized,
                          [optional] in boolean aIsWidgetEventSynthesized,
-                         [optional] in long aButtons);
+                         [optional] in long aButtons,
+                         [optional] in unsigned long aIdentifier);
 
 
   /** Synthesize a pointer event. The event types supported are:
    *    pointerdown, pointerup, pointermove, pointerover, pointerout
    *
    * Events are sent in coordinates offset by aX and aY from the window.
    *
    * Note that additional events may be fired as a result of this call. For
@@ -367,17 +370,18 @@ interface nsIDOMWindowUtils : nsISupport
    * @param aButton button to synthesize
    * @param aClickCount number of clicks that have been performed
    * @param aModifiers modifiers pressed, using constants defined as MODIFIER_*
    * @param aIgnoreRootScrollFrame whether the event should ignore viewport bounds
    *                           during dispatch
    * @param aPressure touch input pressure: 0.0 -> 1.0
    * @param aInputSourceArg input source, see nsIDOMMouseEvent for values,
    *        defaults to mouse input.
-   * @param aPointerId A unique identifier for the pointer causing the event. default is 0
+   * @param aPointerId A unique identifier for the pointer causing the event,
+   *                   defaulting to nsIDOMWindowUtils::DEFAULT_MOUSE_POINTER_ID.
    * @param aWidth The width (magnitude on the X axis), default is 0
    * @param aHeight The height (magnitude on the Y axis), default is 0
    * @param aTilt The plane angle between the Y-Z plane
    *        and the plane containing both the transducer (e.g. pen stylus) axis and the Y axis. default is 0
    * @param aTiltX The plane angle between the X-Z plane
    *        and the plane containing both the transducer (e.g. pen stylus) axis and the X axis. default is 0
    * @param aIsPrimary  Indicates if the pointer represents the primary pointer of this pointer type.
    * @param aIsSynthesized controls nsIDOMEvent.isSynthesized value
@@ -453,17 +457,18 @@ interface nsIDOMWindowUtils : nsISupport
                               in long aButton,
                               in long aClickCount,
                               in long aModifiers,
                               [optional] in boolean aIgnoreRootScrollFrame,
                               [optional] in float aPressure,
                               [optional] in unsigned short aInputSourceArg,
                               [optional] in boolean aIsDOMEventSynthesized,
                               [optional] in boolean aIsWidgetEventSynthesized,
-                              [optional] in long aButtons);
+                              [optional] in long aButtons,
+                              [optional] in unsigned long aIdentifier);
 
   /** The same as sendPointerEvent but ensures that the event
    *  is dispatched to this DOM window or one of its children.
    */
   [optional_argc]
   void sendPointerEventToWindow(in AString aType,
                                 in float aX,
                                 in float aY,
@@ -1974,16 +1979,21 @@ interface nsIDOMWindowUtils : nsISupport
   readonly attribute int32_t gpuProcessPid;
 
   /**
    * Returns true if the given timeout ID is in the list of tracking
    * timeouts.
    */
   boolean isTimeoutTracking(in unsigned long timeoutId);
 
+  // These consts are only for testing purposes.
+  const long DEFAULT_MOUSE_POINTER_ID = 0;
+  const long DEFAULT_PEN_POINTER_ID   = 1;
+  const long DEFAULT_TOUCH_POINTER_ID = 2;
+
   // Match WidgetMouseEventBase::buttonType.
   const long MOUSE_BUTTON_LEFT_BUTTON   = 0;
   const long MOUSE_BUTTON_MIDDLE_BUTTON = 1;
   const long MOUSE_BUTTON_RIGHT_BUTTON  = 2;
 
   // Match WidgetMouseEventBase::buttonsFlag.
   const long MOUSE_BUTTONS_NO_BUTTON = 0x00;
   const long MOUSE_BUTTONS_LEFT_BUTTON = 0x01;
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -1554,17 +1554,18 @@ TabChild::RecvMouseEvent(const nsString&
                          const float&    aX,
                          const float&    aY,
                          const int32_t&  aButton,
                          const int32_t&  aClickCount,
                          const int32_t&  aModifiers,
                          const bool&     aIgnoreRootScrollFrame)
 {
   APZCCallbackHelper::DispatchMouseEvent(GetPresShell(), aType, CSSPoint(aX, aY),
-      aButton, aClickCount, aModifiers, aIgnoreRootScrollFrame, nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN);
+      aButton, aClickCount, aModifiers, aIgnoreRootScrollFrame,
+      nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN, 0 /* Use the default value here. */);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 TabChild::RecvRealMouseMoveEvent(const WidgetMouseEvent& aEvent,
                                  const ScrollableLayerGuid& aGuid,
                                  const uint64_t& aInputBlockId)
 {
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -481,23 +481,23 @@ public:
 
   State GetState() const override
   {
     return DECODER_STATE_DECODING_FIRSTFRAME;
   }
 
   void HandleAudioDecoded(MediaData* aAudio) override
   {
-    mMaster->Push(aAudio);
+    mMaster->PushAudio(aAudio);
     MaybeFinishDecodeFirstFrame();
   }
 
   void HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) override
   {
-    mMaster->Push(aVideo);
+    mMaster->PushVideo(aVideo);
     MaybeFinishDecodeFirstFrame();
   }
 
   void HandleEndOfStream() override
   {
     MaybeFinishDecodeFirstFrame();
   }
 
@@ -574,23 +574,25 @@ public:
 
   State GetState() const override
   {
     return DECODER_STATE_DECODING;
   }
 
   void HandleAudioDecoded(MediaData* aAudio) override
   {
-    mMaster->Push(aAudio);
+    mMaster->PushAudio(aAudio);
+    mMaster->DispatchDecodeTasksIfNeeded();
     MaybeStopPrerolling();
   }
 
   void HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) override
   {
-    mMaster->Push(aVideo);
+    mMaster->PushVideo(aVideo);
+    mMaster->DispatchDecodeTasksIfNeeded();
     MaybeStopPrerolling();
     CheckSlowDecoding(aDecodeStart);
   }
 
   void HandleEndOfStream() override;
 
   void HandleWaitingForData() override
   {
@@ -862,25 +864,25 @@ public:
   {
     MOZ_ASSERT(!mDoneAudioSeeking || !mDoneVideoSeeking, "Seek shouldn't be finished");
     MOZ_ASSERT(aAudio);
 
     // Video-only seek doesn't reset audio decoder. There might be pending audio
     // requests when AccurateSeekTask::Seek() begins. We will just store the data
     // without checking |mDiscontinuity| or calling DropAudioUpToSeekTarget().
     if (mSeekJob.mTarget->IsVideoOnly()) {
-      mMaster->Push(aAudio);
+      mMaster->PushAudio(aAudio);
       return;
     }
 
     AdjustFastSeekIfNeeded(aAudio);
 
     if (mSeekJob.mTarget->IsFast()) {
       // Non-precise seek; we can stop the seek at the first sample.
-      mMaster->Push(aAudio);
+      mMaster->PushAudio(aAudio);
       mDoneAudioSeeking = true;
     } else {
       nsresult rv = DropAudioUpToSeekTarget(aAudio->As<AudioData>());
       if (NS_FAILED(rv)) {
         mMaster->DecodeError(rv);
         return;
       }
     }
@@ -896,17 +898,17 @@ public:
   {
     MOZ_ASSERT(!mDoneAudioSeeking || !mDoneVideoSeeking, "Seek shouldn't be finished");
     MOZ_ASSERT(aVideo);
 
     AdjustFastSeekIfNeeded(aVideo);
 
     if (mSeekJob.mTarget->IsFast()) {
       // Non-precise seek. We can stop the seek at the first sample.
-      mMaster->Push(aVideo);
+      mMaster->PushVideo(aVideo);
       mDoneVideoSeeking = true;
     } else {
       nsresult rv = DropVideoUpToSeekTarget(aVideo);
       if (NS_FAILED(rv)) {
         mMaster->DecodeError(rv);
         return;
       }
     }
@@ -943,23 +945,23 @@ public:
       return;
     }
 
     if (aError == NS_ERROR_DOM_MEDIA_END_OF_STREAM) {
       if (aType == MediaData::AUDIO_DATA) {
         AudioQueue().Finish();
         mDoneAudioSeeking = true;
       } else {
-        VideoQueue().Finish();
-        mDoneVideoSeeking = true;
         if (mFirstVideoFrameAfterSeek) {
           // Hit the end of stream. Move mFirstVideoFrameAfterSeek into
           // mSeekedVideoData so we have something to display after seeking.
-          mMaster->Push(mFirstVideoFrameAfterSeek);
+          mMaster->PushVideo(mFirstVideoFrameAfterSeek);
         }
+        VideoQueue().Finish();
+        mDoneVideoSeeking = true;
       }
       MaybeFinishSeek();
       return;
     }
 
     // This is a decode error, delegate to the generic error path.
     mMaster->DecodeError(aError);
   }
@@ -1144,17 +1146,17 @@ private:
       // The seek target doesn't lie in the audio block just after the last
       // audio frames we've seen which were before the seek target. This
       // could have been the first audio data we've seen after seek, i.e. the
       // seek terminated after the seek target in the audio stream. Just
       // abort the audio decode-to-target, the state machine will play
       // silence to cover the gap. Typically this happens in poorly muxed
       // files.
       SWARN("Audio not synced after seek, maybe a poorly muxed file?");
-      mMaster->Push(aAudio);
+      mMaster->PushAudio(aAudio);
       mDoneAudioSeeking = true;
       return NS_OK;
     }
 
     // The seek target lies somewhere in this AudioData's frames, strip off
     // any frames which lie before the seek target, so we'll begin playback
     // exactly at the seek target.
     NS_ASSERTION(mSeekJob.mTarget->GetTime().ToMicroseconds() >= aAudio->mTime,
@@ -1190,17 +1192,17 @@ private:
     RefPtr<AudioData> data(new AudioData(aAudio->mOffset,
                                          mSeekJob.mTarget->GetTime().ToMicroseconds(),
                                          duration.value(),
                                          frames,
                                          Move(audioData),
                                          channels,
                                          aAudio->mRate));
     MOZ_ASSERT(AudioQueue().GetSize() == 0, "Should be the 1st sample after seeking");
-    mMaster->Push(data);
+    mMaster->PushAudio(data);
     mDoneAudioSeeking = true;
 
     return NS_OK;
   }
 
   nsresult DropVideoUpToSeekTarget(MediaData* aSample)
   {
     RefPtr<VideoData> video(aSample->As<VideoData>());
@@ -1222,17 +1224,17 @@ private:
         video->UpdateTimestamp(target);
       }
       mFirstVideoFrameAfterSeek = nullptr;
 
       SLOG("DropVideoUpToSeekTarget() found video frame [%lld, %lld] containing target=%lld",
                   video->mTime, video->GetEndTime(), target);
 
       MOZ_ASSERT(VideoQueue().GetSize() == 0, "Should be the 1st sample after seeking");
-      mMaster->Push(video);
+      mMaster->PushVideo(video);
       mDoneVideoSeeking = true;
     }
 
     return NS_OK;
   }
 
   void MaybeFinishSeek()
   {
@@ -1356,27 +1358,27 @@ private:
     // seek is actually performed, the ThenValue of SeekPromise has already
     // been set so that it won't be postponed.
     RefPtr<Runnable> r = mAsyncSeekTask = new AysncNextFrameSeekTask(this);
     OwnerThread()->Dispatch(r.forget());
   }
 
   void HandleAudioDecoded(MediaData* aAudio) override
   {
-    mMaster->Push(aAudio);
+    mMaster->PushAudio(aAudio);
   }
 
   void HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) override
   {
     MOZ_ASSERT(aVideo);
     MOZ_ASSERT(!mSeekJob.mPromise.IsEmpty(), "Seek shouldn't be finished");
     MOZ_ASSERT(NeedMoreVideo());
 
     if (aVideo->mTime > mCurrentTime) {
-      mMaster->Push(aVideo);
+      mMaster->PushVideo(aVideo);
       FinishSeek();
     } else {
       RequestVideoData();
     }
   }
 
   void HandleNotDecoded(MediaData::Type aType, const MediaResult& aError) override
   {
@@ -1545,25 +1547,25 @@ public:
   {
     return DECODER_STATE_BUFFERING;
   }
 
   void HandleAudioDecoded(MediaData* aAudio) override
   {
     // This might be the sample we need to exit buffering.
     // Schedule Step() to check it.
-    mMaster->Push(aAudio);
+    mMaster->PushAudio(aAudio);
     mMaster->ScheduleStateMachine();
   }
 
   void HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) override
   {
     // This might be the sample we need to exit buffering.
     // Schedule Step() to check it.
-    mMaster->Push(aVideo);
+    mMaster->PushVideo(aVideo);
     mMaster->ScheduleStateMachine();
   }
 
   void HandleEndOfStream() override;
 
   void HandleVideoSuspendTimeout() override
   {
     if (mMaster->HasVideo()) {
@@ -2158,16 +2160,17 @@ BufferingState::Step()
     bool isLiveStream = Resource()->IsLiveStream();
     if ((isLiveStream || !mMaster->CanPlayThrough()) &&
         elapsed < TimeDuration::FromSeconds(mBufferingWait * mMaster->mPlaybackRate) &&
         mMaster->HasLowBufferedData(mBufferingWait * USECS_PER_S) &&
         IsExpectingMoreData()) {
       SLOG("Buffering: wait %ds, timeout in %.3lfs",
            mBufferingWait, mBufferingWait - elapsed.ToSeconds());
       mMaster->ScheduleStateMachineIn(USECS_PER_S);
+      mMaster->DispatchDecodeTasksIfNeeded();
       return;
     }
   } else if (mMaster->OutOfDecodedAudio() || mMaster->OutOfDecodedVideo()) {
     MOZ_ASSERT(Reader()->IsWaitForDataSupported(),
                "Don't yet have a strategy for non-heuristic + non-WaitForData");
     mMaster->DispatchDecodeTasksIfNeeded();
     MOZ_ASSERT(mMaster->mMinimizePreroll ||
                !mMaster->OutOfDecodedAudio() ||
@@ -2544,35 +2547,30 @@ MediaDecoderStateMachine::NeedToDecodeAu
 
   return IsAudioDecoding() &&
          mState != DECODER_STATE_SEEKING &&
          ((!mSentFirstFrameLoadedEvent && AudioQueue().GetSize() == 0) ||
           (!mMinimizePreroll && !HaveEnoughDecodedAudio()));
 }
 
 void
-MediaDecoderStateMachine::Push(MediaData* aSample)
+MediaDecoderStateMachine::PushAudio(MediaData* aSample)
 {
   MOZ_ASSERT(OnTaskQueue());
   MOZ_ASSERT(aSample);
-
-  if (aSample->mType == MediaData::AUDIO_DATA) {
-    // TODO: Send aSample to MSG and recalculate readystate before pushing,
-    // otherwise AdvanceFrame may pop the sample before we have a chance
-    // to reach playing.
-    AudioQueue().Push(aSample);
-  } else if (aSample->mType == MediaData::VIDEO_DATA) {
-    // TODO: Send aSample to MSG and recalculate readystate before pushing,
-    // otherwise AdvanceFrame may pop the sample before we have a chance
-    // to reach playing.
-    aSample->As<VideoData>()->mFrameID = ++mCurrentFrameID;
-    VideoQueue().Push(aSample);
-  }
-
-  DispatchDecodeTasksIfNeeded();
+  AudioQueue().Push(aSample);
+}
+
+void
+MediaDecoderStateMachine::PushVideo(MediaData* aSample)
+{
+  MOZ_ASSERT(OnTaskQueue());
+  MOZ_ASSERT(aSample);
+  aSample->As<VideoData>()->mFrameID = ++mCurrentFrameID;
+  VideoQueue().Push(aSample);
 }
 
 void
 MediaDecoderStateMachine::OnAudioPopped(const RefPtr<MediaData>& aSample)
 {
   MOZ_ASSERT(OnTaskQueue());
 
   mPlaybackOffset = std::max(mPlaybackOffset.Ref(), aSample->mOffset);
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -333,17 +333,18 @@ protected:
   virtual ~MediaDecoderStateMachine();
 
   void BufferedRangeUpdated();
 
   void ReaderSuspendedChanged();
 
   // Inserts MediaData* samples into their respective MediaQueues.
   // aSample must not be null.
-  void Push(MediaData* aSample);
+  void PushAudio(MediaData* aSample);
+  void PushVideo(MediaData* aSample);
 
   void OnAudioPopped(const RefPtr<MediaData>& aSample);
   void OnVideoPopped(const RefPtr<MediaData>& aSample);
 
   void AudioAudibleChanged(bool aAudible);
 
   void VolumeChanged();
   void SetPlaybackRate(double aPlaybackRate);
--- a/dom/media/systemservices/CamerasChild.cpp
+++ b/dom/media/systemservices/CamerasChild.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set sw=2 ts=8 et ft=cpp : */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "CamerasChild.h"
 
-#include "webrtc/video_engine/include/vie_capture.h"
 #undef FF
 
 #include "mozilla/Assertions.h"
 #include "mozilla/ipc/BackgroundChild.h"
 #include "mozilla/ipc/PBackgroundChild.h"
 #include "mozilla/Logging.h"
 #include "mozilla/SyncRunnable.h"
 #include "mozilla/WeakPtr.h"
@@ -340,17 +339,17 @@ CamerasChild::EnsureInitialized(CaptureE
   LOG(("Capture Devices: %d", dispatcher.ReturnValue()));
   return dispatcher.ReturnValue();
 }
 
 int
 CamerasChild::GetCaptureCapability(CaptureEngine aCapEngine,
                                    const char* unique_idUTF8,
                                    const unsigned int capability_number,
-                                   webrtc::CaptureCapability& capability)
+                                   webrtc::VideoCaptureCapability& capability)
 {
   LOG(("GetCaptureCapability: %s %d", unique_idUTF8, capability_number));
   nsCString unique_id(unique_idUTF8);
   nsCOMPtr<nsIRunnable> runnable =
     media::NewRunnableFrom([this, aCapEngine, unique_id, capability_number]() -> nsresult {
       if (this->SendGetCaptureCapability(aCapEngine, unique_id, capability_number)) {
         return NS_OK;
       }
@@ -359,17 +358,17 @@ CamerasChild::GetCaptureCapability(Captu
   LockAndDispatch<> dispatcher(this, __func__, runnable);
   if (dispatcher.Success()) {
     capability = mReplyCapability;
   }
   return dispatcher.ReturnValue();
 }
 
 mozilla::ipc::IPCResult
-CamerasChild::RecvReplyGetCaptureCapability(const CaptureCapability& ipcCapability)
+CamerasChild::RecvReplyGetCaptureCapability(const VideoCaptureCapability& ipcCapability)
 {
   LOG((__PRETTY_FUNCTION__));
   MonitorAutoLock monitor(mReplyMonitor);
   mReceivedReply = true;
   mReplySuccess = true;
   mReplyCapability.width = ipcCapability.width();
   mReplyCapability.height = ipcCapability.height();
   mReplyCapability.maxFPS = ipcCapability.maxFPS();
@@ -424,33 +423,33 @@ CamerasChild::RecvReplyGetCaptureDevice(
   monitor.Notify();
   return IPC_OK();
 }
 
 int
 CamerasChild::AllocateCaptureDevice(CaptureEngine aCapEngine,
                                     const char* unique_idUTF8,
                                     const unsigned int unique_idUTF8Length,
-                                    int& capture_id,
+                                    int& aStreamId,
                                     const nsACString& aOrigin)
 {
   LOG((__PRETTY_FUNCTION__));
   nsCString unique_id(unique_idUTF8);
   nsCString origin(aOrigin);
   nsCOMPtr<nsIRunnable> runnable =
     media::NewRunnableFrom([this, aCapEngine, unique_id, origin]() -> nsresult {
       if (this->SendAllocateCaptureDevice(aCapEngine, unique_id, origin)) {
         return NS_OK;
       }
       return NS_ERROR_FAILURE;
     });
   LockAndDispatch<> dispatcher(this, __func__, runnable);
   if (dispatcher.Success()) {
     LOG(("Capture Device allocated: %d", mReplyInteger));
-    capture_id = mReplyInteger;
+    aStreamId = mReplyInteger;
   }
   return dispatcher.ReturnValue();
 }
 
 
 mozilla::ipc::IPCResult
 CamerasChild::RecvReplyAllocateCaptureDevice(const int& numdev)
 {
@@ -476,17 +475,17 @@ CamerasChild::ReleaseCaptureDevice(Captu
       return NS_ERROR_FAILURE;
     });
   LockAndDispatch<> dispatcher(this, __func__, runnable);
   return dispatcher.ReturnValue();
 }
 
 void
 CamerasChild::AddCallback(const CaptureEngine aCapEngine, const int capture_id,
-                          webrtc::ExternalRenderer* render)
+                          FrameRelay* render)
 {
   MutexAutoLock lock(mCallbackMutex);
   CapturerElement ce;
   ce.engine = aCapEngine;
   ce.id = capture_id;
   ce.callback = render;
   mCallbacks.AppendElement(ce);
 }
@@ -502,22 +501,22 @@ CamerasChild::RemoveCallback(const Captu
       break;
     }
   }
 }
 
 int
 CamerasChild::StartCapture(CaptureEngine aCapEngine,
                            const int capture_id,
-                           webrtc::CaptureCapability& webrtcCaps,
-                           webrtc::ExternalRenderer* cb)
+                           webrtc::VideoCaptureCapability& webrtcCaps,
+                           FrameRelay* cb)
 {
   LOG((__PRETTY_FUNCTION__));
   AddCallback(aCapEngine, capture_id, cb);
-  CaptureCapability capCap(webrtcCaps.width,
+  VideoCaptureCapability capCap(webrtcCaps.width,
                            webrtcCaps.height,
                            webrtcCaps.maxFPS,
                            webrtcCaps.expectedCaptureDelay,
                            webrtcCaps.rawType,
                            webrtcCaps.codecType,
                            webrtcCaps.interlaced);
   nsCOMPtr<nsIRunnable> runnable =
     media::NewRunnableFrom([this, aCapEngine, capture_id, capCap]() -> nsresult {
@@ -641,28 +640,22 @@ CamerasChild::ShutdownChild()
   }
   CamerasSingleton::FakeDeviceChangeEventThread() = nullptr;
 }
 
 mozilla::ipc::IPCResult
 CamerasChild::RecvDeliverFrame(const CaptureEngine& capEngine,
                                const int& capId,
                                mozilla::ipc::Shmem&& shmem,
-                               const size_t& size,
-                               const uint32_t& time_stamp,
-                               const int64_t& ntp_time,
-                               const int64_t& render_time)
+                               const VideoFrameProperties & prop)
 {
   MutexAutoLock lock(mCallbackMutex);
   if (Callback(capEngine, capId)) {
     unsigned char* image = shmem.get<unsigned char>();
-    Callback(capEngine, capId)->DeliverFrame(image, size,
-                                             time_stamp,
-                                             ntp_time, render_time,
-                                             nullptr);
+    Callback(capEngine, capId)->DeliverFrame(image, prop);
   } else {
     LOG(("DeliverFrame called with dead callback"));
   }
   SendReleaseFrame(shmem);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
@@ -697,17 +690,17 @@ CamerasChild::SetFakeDeviceChangeEvents(
 mozilla::ipc::IPCResult
 CamerasChild::RecvFrameSizeChange(const CaptureEngine& capEngine,
                                   const int& capId,
                                   const int& w, const int& h)
 {
   LOG((__PRETTY_FUNCTION__));
   MutexAutoLock lock(mCallbackMutex);
   if (Callback(capEngine, capId)) {
-    Callback(capEngine, capId)->FrameSizeChange(w, h, 0);
+    Callback(capEngine, capId)->FrameSizeChange(w, h);
   } else {
     LOG(("Frame size change with dead callback"));
   }
   return IPC_OK();
 }
 
 void
 CamerasChild::ActorDestroy(ActorDestroyReason aWhy)
@@ -741,17 +734,17 @@ CamerasChild::~CamerasChild()
     // get destructed immediately, and should not try to reach
     // the parent.
     ShutdownChild();
   }
 
   MOZ_COUNT_DTOR(CamerasChild);
 }
 
-webrtc::ExternalRenderer* CamerasChild::Callback(CaptureEngine aCapEngine,
+FrameRelay* CamerasChild::Callback(CaptureEngine aCapEngine,
                                                  int capture_id)
 {
   for (unsigned int i = 0; i < mCallbacks.Length(); i++) {
     CapturerElement ce = mCallbacks[i];
     if (ce.engine == aCapEngine && ce.id == capture_id) {
       return ce.callback;
     }
   }
--- a/dom/media/systemservices/CamerasChild.h
+++ b/dom/media/systemservices/CamerasChild.h
@@ -15,33 +15,40 @@
 #include "mozilla/media/DeviceChangeCallback.h"
 #include "mozilla/Mutex.h"
 #include "base/singleton.h"
 #include "nsCOMPtr.h"
 
 // conflicts with #include of scoped_ptr.h
 #undef FF
 #include "webrtc/common.h"
-// Video Engine
-#include "webrtc/video_engine/include/vie_base.h"
-#include "webrtc/video_engine/include/vie_capture.h"
-#include "webrtc/video_engine/include/vie_render.h"
+#include "webrtc/video_renderer.h"
+#include "webrtc/modules/video_capture/video_capture_defines.h"
+
+
 
 namespace mozilla {
 
 namespace ipc {
 class BackgroundChildImpl;
 }
 
 namespace camera {
 
+class FrameRelay {
+public:
+  virtual int DeliverFrame(uint8_t* buffer,
+    const mozilla::camera::VideoFrameProperties& props) = 0;
+  virtual void FrameSizeChange(unsigned int w, unsigned int h) = 0;
+};
+
 struct CapturerElement {
   CaptureEngine engine;
   int id;
-  webrtc::ExternalRenderer* callback;
+  FrameRelay* callback;
 };
 
 // Forward declaration so we can work with pointers to it.
 class CamerasChild;
 // Helper class in impl that we friend.
 template <class T> class LockAndDispatch;
 
 // We emulate the sync webrtc.org API with the help of singleton
@@ -144,79 +151,79 @@ class CamerasChild final : public PCamer
 
 public:
   // We are owned by the PBackground thread only. CamerasSingleton
   // takes a non-owning reference.
   NS_INLINE_DECL_REFCOUNTING(CamerasChild)
 
   // IPC messages recevied, received on the PBackground thread
   // these are the actual callbacks with data
-  virtual mozilla::ipc::IPCResult RecvDeliverFrame(const CaptureEngine&, const int&, mozilla::ipc::Shmem&&,
-                                                   const size_t&, const uint32_t&, const int64_t&,
-                                                   const int64_t&) override;
+  virtual mozilla::ipc::IPCResult RecvDeliverFrame(const CaptureEngine&, const int&,
+                                                   mozilla::ipc::Shmem&&,
+                                                   const VideoFrameProperties & prop) override;
   virtual mozilla::ipc::IPCResult RecvFrameSizeChange(const CaptureEngine&, const int&,
                                                       const int& w, const int& h) override;
 
   virtual mozilla::ipc::IPCResult RecvDeviceChange() override;
   virtual int AddDeviceChangeCallback(DeviceChangeCallback* aCallback) override;
   int SetFakeDeviceChangeEvents();
 
   // these are response messages to our outgoing requests
   virtual mozilla::ipc::IPCResult RecvReplyNumberOfCaptureDevices(const int&) override;
   virtual mozilla::ipc::IPCResult RecvReplyNumberOfCapabilities(const int&) override;
   virtual mozilla::ipc::IPCResult RecvReplyAllocateCaptureDevice(const int&) override;
-  virtual mozilla::ipc::IPCResult RecvReplyGetCaptureCapability(const CaptureCapability& capability) override;
+  virtual mozilla::ipc::IPCResult RecvReplyGetCaptureCapability(const VideoCaptureCapability& capability) override;
   virtual mozilla::ipc::IPCResult RecvReplyGetCaptureDevice(const nsCString& device_name,
                                                             const nsCString& device_id,
                                                             const bool& scary) override;
   virtual mozilla::ipc::IPCResult RecvReplyFailure(void) override;
   virtual mozilla::ipc::IPCResult RecvReplySuccess(void) override;
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
   // the webrtc.org ViECapture calls are mirrored here, but with access
   // to a specific PCameras instance to communicate over. These also
   // run on the MediaManager thread
   int NumberOfCaptureDevices(CaptureEngine aCapEngine);
   int NumberOfCapabilities(CaptureEngine aCapEngine,
                            const char* deviceUniqueIdUTF8);
   int ReleaseCaptureDevice(CaptureEngine aCapEngine,
                            const int capture_id);
   int StartCapture(CaptureEngine aCapEngine,
-                   const int capture_id, webrtc::CaptureCapability& capability,
-                   webrtc::ExternalRenderer* func);
+                   const int capture_id, webrtc::VideoCaptureCapability& capability,
+                   FrameRelay* func);
   int StopCapture(CaptureEngine aCapEngine, const int capture_id);
   int AllocateCaptureDevice(CaptureEngine aCapEngine,
                             const char* unique_idUTF8,
                             const unsigned int unique_idUTF8Length,
                             int& capture_id,
                             const nsACString& aOrigin);
   int GetCaptureCapability(CaptureEngine aCapEngine,
                            const char* unique_idUTF8,
                            const unsigned int capability_number,
-                           webrtc::CaptureCapability& capability);
+                           webrtc::VideoCaptureCapability& capability);
   int GetCaptureDevice(CaptureEngine aCapEngine,
                        unsigned int list_number, char* device_nameUTF8,
                        const unsigned int device_nameUTF8Length,
                        char* unique_idUTF8,
                        const unsigned int unique_idUTF8Length,
                        bool* scary = nullptr);
   void ShutdownAll();
   int EnsureInitialized(CaptureEngine aCapEngine);
 
-  webrtc::ExternalRenderer* Callback(CaptureEngine aCapEngine, int capture_id);
+  FrameRelay* Callback(CaptureEngine aCapEngine, int capture_id);
 
 private:
   CamerasChild();
   ~CamerasChild();
   // Dispatch a Runnable to the PCamerasParent, by executing it on the
   // decidecated Cameras IPC/PBackground thread.
   bool DispatchToParent(nsIRunnable* aRunnable,
                         MonitorAutoLock& aMonitor);
   void AddCallback(const CaptureEngine aCapEngine, const int capture_id,
-                   webrtc::ExternalRenderer* render);
+                   FrameRelay* render);
   void RemoveCallback(const CaptureEngine aCapEngine, const int capture_id);
   void ShutdownParent();
   void ShutdownChild();
 
   nsTArray<CapturerElement> mCallbacks;
   // Protects the callback arrays
   Mutex mCallbackMutex;
 
@@ -233,17 +240,17 @@ private:
   Mutex mRequestMutex;
   // Hold to wait for an async response to our calls
   Monitor mReplyMonitor;
   // Async response valid?
   bool mReceivedReply;
   // Async responses data contents;
   bool mReplySuccess;
   int mReplyInteger;
-  webrtc::CaptureCapability mReplyCapability;
+  webrtc::VideoCaptureCapability mReplyCapability;
   nsCString mReplyDeviceName;
   nsCString mReplyDeviceID;
   bool mReplyScary;
 };
 
 } // namespace camera
 } // namespace mozilla
 
--- a/dom/media/systemservices/CamerasParent.cpp
+++ b/dom/media/systemservices/CamerasParent.cpp
@@ -2,16 +2,17 @@
 /* vim: set sw=2 ts=8 et ft=cpp : */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "CamerasParent.h"
 #include "MediaEngine.h"
 #include "MediaUtils.h"
+#include "VideoFrameUtils.h"
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Unused.h"
 #include "mozilla/Services.h"
 #include "mozilla/Logging.h"
 #include "mozilla/ipc/BackgroundParent.h"
 #include "mozilla/ipc/PBackgroundParent.h"
 #include "mozilla/Preferences.h"
@@ -23,34 +24,36 @@
 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
 
 #if defined(_WIN32)
 #include <process.h>
 #define getpid() _getpid()
 #endif
 
 #undef LOG
+#undef LOG_VERBOSE
 #undef LOG_ENABLED
 mozilla::LazyLogModule gCamerasParentLog("CamerasParent");
 #define LOG(args) MOZ_LOG(gCamerasParentLog, mozilla::LogLevel::Debug, args)
+#define LOG_VERBOSE(args) MOZ_LOG(gCamerasParentLog, mozilla::LogLevel::Verbose, args)
 #define LOG_ENABLED() MOZ_LOG_TEST(gCamerasParentLog, mozilla::LogLevel::Debug)
 
 namespace mozilla {
 namespace camera {
 
 // 3 threads are involved in this code:
 // - the main thread for some setups, and occassionally for video capture setup
 //   calls that don't work correctly elsewhere.
 // - the IPC thread on which PBackground is running and which receives and
 //   sends messages
 // - a thread which will execute the actual (possibly slow) camera access
 //   called "VideoCapture". On Windows this is a thread with an event loop
 //   suitable for UI access.
 
-void InputObserver::DeviceChange() {
+void InputObserver::OnDeviceChange() {
   LOG((__PRETTY_FUNCTION__));
   MOZ_ASSERT(mParent);
 
   RefPtr<nsIRunnable> ipc_runnable =
     media::NewRunnableFrom([this]() -> nsresult {
       if (mParent->IsShuttingDown()) {
         return NS_ERROR_FAILURE;
       }
@@ -58,122 +61,67 @@ void InputObserver::DeviceChange() {
       return NS_OK;
     });
 
   nsIThread* thread = mParent->GetBackgroundThread();
   MOZ_ASSERT(thread != nullptr);
   thread->Dispatch(ipc_runnable, NS_DISPATCH_NORMAL);
 };
 
-class FrameSizeChangeRunnable : public Runnable {
+class DeliverFrameRunnable : public ::mozilla::Runnable {
 public:
-  FrameSizeChangeRunnable(CamerasParent *aParent, CaptureEngine capEngine,
-                          int cap_id, unsigned int aWidth, unsigned int aHeight)
-    : mParent(aParent), mCapEngine(capEngine), mCapId(cap_id),
-      mWidth(aWidth), mHeight(aHeight) {}
+  DeliverFrameRunnable(CamerasParent *aParent, CaptureEngine aEngine,
+      uint32_t aStreamId, const webrtc::VideoFrame& aFrame,
+      const VideoFrameProperties& aProperties)
+      : mParent(aParent), mCapEngine(aEngine), mStreamId(aStreamId),
+      mProperties(aProperties)
+  {
+    // No ShmemBuffer (of the right size) was available, so make an
+    // extra buffer here.  We have no idea when we are going to run and
+    // it will be potentially long after the webrtc frame callback has
+    // returned, so the copy needs to be no later than here.
+    // We will need to copy this back into a Shmem later on so we prefer
+    // using ShmemBuffers to avoid the extra copy.
+    mAlternateBuffer.reset(new unsigned char[aProperties.bufferSize()]);
+    VideoFrameUtils::CopyVideoFrameBuffers(mAlternateBuffer.get(),
+                                           aProperties.bufferSize(), aFrame);
+  }
+
+  DeliverFrameRunnable(CamerasParent* aParent, CaptureEngine aEngine,
+      uint32_t aStreamId, ShmemBuffer aBuffer, VideoFrameProperties& aProperties)
+      : mParent(aParent), mCapEngine(aEngine), mStreamId(aStreamId),
+      mBuffer(Move(aBuffer)), mProperties(aProperties)
+  {};
 
   NS_IMETHOD Run() override {
     if (mParent->IsShuttingDown()) {
       // Communication channel is being torn down
-      LOG(("FrameSizeChangeRunnable is active without active Child"));
       mResult = 0;
       return NS_OK;
     }
-    if (!mParent->SendFrameSizeChange(mCapEngine, mCapId, mWidth, mHeight)) {
+    if (!mParent->DeliverFrameOverIPC(mCapEngine, mStreamId, Move(mBuffer),
+                                      mAlternateBuffer.get(), mProperties)) {
       mResult = -1;
     } else {
       mResult = 0;
     }
     return NS_OK;
   }
 
   int GetResult() {
     return mResult;
   }
 
 private:
   RefPtr<CamerasParent> mParent;
   CaptureEngine mCapEngine;
-  int mCapId;
-  unsigned int mWidth;
-  unsigned int mHeight;
-  int mResult;
-};
-
-int
-CallbackHelper::FrameSizeChange(unsigned int w, unsigned int h,
-                                unsigned int streams)
-{
-  LOG(("CallbackHelper Video FrameSizeChange: %ux%u", w, h));
-  RefPtr<FrameSizeChangeRunnable> runnable =
-    new FrameSizeChangeRunnable(mParent, mCapEngine, mCapturerId, w, h);
-  MOZ_ASSERT(mParent);
-  nsIThread * thread = mParent->GetBackgroundThread();
-  MOZ_ASSERT(thread != nullptr);
-  thread->Dispatch(runnable, NS_DISPATCH_NORMAL);
-  return 0;
-}
-
-class DeliverFrameRunnable : public Runnable {
-public:
-  DeliverFrameRunnable(CamerasParent *aParent,
-                       CaptureEngine engine,
-                       int cap_id,
-                       ShmemBuffer buffer,
-                       unsigned char* altbuffer,
-                       size_t size,
-                       uint32_t time_stamp,
-                       int64_t ntp_time,
-                       int64_t render_time)
-    : mParent(aParent), mCapEngine(engine), mCapId(cap_id), mBuffer(Move(buffer)),
-      mSize(size), mTimeStamp(time_stamp), mNtpTime(ntp_time),
-      mRenderTime(render_time) {
-    // No ShmemBuffer (of the right size) was available, so make an
-    // extra buffer here.  We have no idea when we are going to run and
-    // it will be potentially long after the webrtc frame callback has
-    // returned, so the copy needs to be no later than here.
-    // We will need to copy this back into a Shmem later on so we prefer
-    // using ShmemBuffers to avoid the extra copy.
-    if (altbuffer != nullptr) {
-      mAlternateBuffer.reset(new unsigned char[size]);
-      memcpy(mAlternateBuffer.get(), altbuffer, size);
-    }
-  };
-
-  NS_IMETHOD Run() override {
-    if (mParent->IsShuttingDown()) {
-      // Communication channel is being torn down
-      mResult = 0;
-      return NS_OK;
-    }
-    if (!mParent->DeliverFrameOverIPC(mCapEngine, mCapId,
-                                      Move(mBuffer), mAlternateBuffer.get(),
-                                      mSize, mTimeStamp,
-                                      mNtpTime, mRenderTime)) {
-      mResult = -1;
-    } else {
-      mResult = 0;
-    }
-    return NS_OK;
-  }
-
-  int GetResult() {
-    return mResult;
-  }
-
-private:
-  RefPtr<CamerasParent> mParent;
-  CaptureEngine mCapEngine;
-  int mCapId;
+  uint32_t mStreamId;
   ShmemBuffer mBuffer;
   mozilla::UniquePtr<unsigned char[]> mAlternateBuffer;
-  size_t mSize;
-  uint32_t mTimeStamp;
-  int64_t mNtpTime;
-  int64_t mRenderTime;
+  VideoFrameProperties mProperties;
   int mResult;
 };
 
 NS_IMPL_ISUPPORTS(CamerasParent, nsIObserver)
 
 NS_IMETHODIMP
 CamerasParent::Observe(nsISupports *aSubject,
                        const char *aTopic,
@@ -253,128 +201,128 @@ CamerasParent::StopVideoCapture()
       });
     if (NS_FAILED(NS_DispatchToMainThread(threadShutdown))) {
       LOG(("Could not dispatch VideoCaptureThread destruction"));
     }
   }
 }
 
 int
-CamerasParent::DeliverFrameOverIPC(CaptureEngine cap_engine,
-                                   int cap_id,
-                                   ShmemBuffer buffer,
-                                   unsigned char* altbuffer,
-                                   size_t size,
-                                   uint32_t time_stamp,
-                                   int64_t ntp_time,
-                                   int64_t render_time)
+CamerasParent::DeliverFrameOverIPC(CaptureEngine capEng,
+                          uint32_t aStreamId,
+                          ShmemBuffer buffer,
+                          unsigned char* altbuffer,
+                          VideoFrameProperties& aProps)
 {
   // No ShmemBuffers were available, so construct one now of the right size
   // and copy into it. That is an extra copy, but we expect this to be
   // the exceptional case, because we just assured the next call *will* have a
   // buffer of the right size.
   if (altbuffer != nullptr) {
     // Get a shared memory buffer from the pool, at least size big
-    ShmemBuffer shMemBuff = mShmemPool.Get(this, size);
+    ShmemBuffer shMemBuff = mShmemPool.Get(this, aProps.bufferSize());
 
     if (!shMemBuff.Valid()) {
       LOG(("No usable Video shmem in DeliverFrame (out of buffers?)"));
       // We can skip this frame if we run out of buffers, it's not a real error.
       return 0;
     }
 
     // get() and Size() check for proper alignment of the segment
-    memcpy(shMemBuff.GetBytes(), altbuffer, size);
+    memcpy(shMemBuff.GetBytes(), altbuffer, aProps.bufferSize());
 
-    if (!SendDeliverFrame(cap_engine, cap_id,
-                          shMemBuff.Get(), size,
-                          time_stamp, ntp_time, render_time)) {
+    if (!SendDeliverFrame(capEng, aStreamId,
+                          shMemBuff.Get(), aProps)) {
       return -1;
     }
   } else {
     MOZ_ASSERT(buffer.Valid());
     // ShmemBuffer was available, we're all good. A single copy happened
     // in the original webrtc callback.
-    if (!SendDeliverFrame(cap_engine, cap_id,
-                          buffer.Get(), size,
-                          time_stamp, ntp_time, render_time)) {
+    if (!SendDeliverFrame(capEng, aStreamId,
+                          buffer.Get(), aProps)) {
       return -1;
     }
   }
 
   return 0;
 }
 
 ShmemBuffer
 CamerasParent::GetBuffer(size_t aSize)
 {
   return mShmemPool.GetIfAvailable(aSize);
 }
 
-int
-CallbackHelper::DeliverFrame(unsigned char* buffer,
-                             size_t size,
-                             uint32_t time_stamp,
-                             int64_t ntp_time,
-                             int64_t render_time,
-                             void *handle)
+int32_t
+CallbackHelper::RenderFrame(uint32_t aStreamId, const webrtc::VideoFrame& aVideoFrame)
 {
+  LOG_VERBOSE((__PRETTY_FUNCTION__));
+  RefPtr<DeliverFrameRunnable> runnable = nullptr;
+  // Get frame properties
+  camera::VideoFrameProperties properties;
+  VideoFrameUtils::InitFrameBufferProperties(aVideoFrame, properties);
   // Get a shared memory buffer to copy the frame data into
-  ShmemBuffer shMemBuffer = mParent->GetBuffer(size);
+  ShmemBuffer shMemBuffer = mParent->GetBuffer(properties.bufferSize());
   if (!shMemBuffer.Valid()) {
     // Either we ran out of buffers or they're not the right size yet
     LOG(("Correctly sized Video shmem not available in DeliverFrame"));
     // We will do the copy into a(n extra) temporary buffer inside
     // the DeliverFrameRunnable constructor.
   } else {
     // Shared memory buffers of the right size are available, do the copy here.
-    memcpy(shMemBuffer.GetBytes(), buffer, size);
-    // Mark the original buffer as cleared.
-    buffer = nullptr;
+    VideoFrameUtils::CopyVideoFrameBuffers(shMemBuffer.GetBytes(),
+                                           properties.bufferSize(), aVideoFrame);
+    runnable = new DeliverFrameRunnable(mParent, mCapEngine, mStreamId,
+                                        Move(shMemBuffer), properties);
   }
-  RefPtr<DeliverFrameRunnable> runnable =
-    new DeliverFrameRunnable(mParent, mCapEngine, mCapturerId,
-                             Move(shMemBuffer), buffer, size, time_stamp,
-                             ntp_time, render_time);
+  if (!runnable.get()) {
+    runnable = new DeliverFrameRunnable(mParent, mCapEngine, mStreamId,
+                                        aVideoFrame, properties);
+  }
   MOZ_ASSERT(mParent);
   nsIThread* thread = mParent->GetBackgroundThread();
   MOZ_ASSERT(thread != nullptr);
   thread->Dispatch(runnable, NS_DISPATCH_NORMAL);
   return 0;
 }
-// XXX!!! FIX THIS -- we should move to pure DeliverI420Frame
-int
-CallbackHelper::DeliverI420Frame(const webrtc::I420VideoFrame& webrtc_frame)
+
+void
+CallbackHelper::OnIncomingCapturedFrame(const int32_t id, const webrtc::VideoFrame& aVideoFrame)
 {
-  return DeliverFrame(const_cast<uint8_t*>(webrtc_frame.buffer(webrtc::kYPlane)),
-                      CalcBufferSize(webrtc::kI420, webrtc_frame.width(), webrtc_frame.height()),
-                      webrtc_frame.timestamp(),
-                      webrtc_frame.ntp_time_ms(),
-                      webrtc_frame.render_time_ms(),
-                      (void*) webrtc_frame.native_handle());
+ LOG_VERBOSE((__PRETTY_FUNCTION__));
+ RenderFrame(id,aVideoFrame);
+}
+
+void
+CallbackHelper::OnCaptureDelayChanged(const int32_t id, const int32_t delay)
+{
+  LOG((__PRETTY_FUNCTION__));
 }
 
 mozilla::ipc::IPCResult
 CamerasParent::RecvReleaseFrame(mozilla::ipc::Shmem&& s) {
   mShmemPool.Put(ShmemBuffer(s));
   return IPC_OK();
 }
 
 bool
 CamerasParent::SetupEngine(CaptureEngine aCapEngine)
 {
+  LOG((__PRETTY_FUNCTION__));
   MOZ_ASSERT(mVideoCaptureThread->thread_id() == PlatformThread::CurrentId());
-  EngineHelper *helper = &mEngines[aCapEngine];
+  RefPtr<mozilla::camera::VideoEngine>* engine = &mEngines[aCapEngine];
 
   // Already initialized
-  if (helper->mEngine) {
+  if (engine->get()) {
     return true;
   }
 
   webrtc::CaptureDeviceInfo *captureDeviceInfo = nullptr;
+  UniquePtr<webrtc::Config> config(new webrtc::Config);
 
   switch (aCapEngine) {
   case ScreenEngine:
     captureDeviceInfo =
       new webrtc::CaptureDeviceInfo(webrtc::CaptureDeviceType::Screen);
     break;
   case BrowserEngine:
     captureDeviceInfo =
@@ -393,54 +341,29 @@ CamerasParent::SetupEngine(CaptureEngine
       new webrtc::CaptureDeviceInfo(webrtc::CaptureDeviceType::Camera);
     break;
   default:
     LOG(("Invalid webrtc Video engine"));
     MOZ_CRASH();
     break;
   }
 
-  helper->mConfig.Set<webrtc::CaptureDeviceInfo>(captureDeviceInfo);
-  helper->mEngine = webrtc::VideoEngine::Create(helper->mConfig);
+  config->Set<webrtc::CaptureDeviceInfo>(captureDeviceInfo);
+  *engine = mozilla::camera::VideoEngine::Create(UniquePtr<const webrtc::Config>(config.release()));
 
-  if (!helper->mEngine) {
+  if (!engine->get()) {
     LOG(("VideoEngine::Create failed"));
     return false;
   }
 
-  helper->mPtrViEBase = webrtc::ViEBase::GetInterface(helper->mEngine);
-  if (!helper->mPtrViEBase) {
-    LOG(("ViEBase::GetInterface failed"));
-    return false;
-  }
-
-  if (helper->mPtrViEBase->Init() < 0) {
-    LOG(("ViEBase::Init failed"));
-    return false;
-  }
-
-  helper->mPtrViECapture = webrtc::ViECapture::GetInterface(helper->mEngine);
-  if (!helper->mPtrViECapture) {
-    LOG(("ViECapture::GetInterface failed"));
-    return false;
-  }
-
-  InputObserver** observer = mObservers.AppendElement(
-          new InputObserver(this));
-
-#ifdef DEBUG
-  MOZ_ASSERT(0 == helper->mPtrViECapture->RegisterInputObserver(*observer));
-#else
-  helper->mPtrViECapture->RegisterInputObserver(*observer);
-#endif
-
-  helper->mPtrViERender = webrtc::ViERender::GetInterface(helper->mEngine);
-  if (!helper->mPtrViERender) {
-    LOG(("ViERender::GetInterface failed"));
-    return false;
+  InputObserver** observer = mObservers.AppendElement(new InputObserver(this));
+  auto device_info = engine->get()->GetOrCreateVideoCaptureDeviceInfo();
+  MOZ_ASSERT(device_info);
+  if (device_info) {
+    device_info->RegisterVideoInputFeedBack(**observer);
   }
 
   return true;
 }
 
 void
 CamerasParent::CloseEngines()
 {
@@ -448,92 +371,81 @@ CamerasParent::CloseEngines()
   if (!mWebRTCAlive) {
     return;
   }
   MOZ_ASSERT(mVideoCaptureThread->thread_id() == PlatformThread::CurrentId());
 
   // Stop the callers
   while (mCallbacks.Length()) {
     auto capEngine = mCallbacks[0]->mCapEngine;
-    auto capNum = mCallbacks[0]->mCapturerId;
-    LOG(("Forcing shutdown of engine %d, capturer %d", capEngine, capNum));
-    StopCapture(capEngine, capNum);
-    Unused << ReleaseCaptureDevice(capEngine, capNum);
+    auto streamNum = mCallbacks[0]->mStreamId;
+    LOG(("Forcing shutdown of engine %d, capturer %d", capEngine, streamNum));
+    StopCapture(capEngine, streamNum);
+    Unused << ReleaseCaptureDevice(capEngine, streamNum);
   }
 
   for (int i = 0; i < CaptureEngine::MaxEngine; i++) {
-    if (mEngines[i].mEngineIsRunning) {
-      LOG(("Being closed down while engine %d is running!", i));
-    }
-    if (mEngines[i].mPtrViERender) {
-      mEngines[i].mPtrViERender->Release();
-      mEngines[i].mPtrViERender = nullptr;
-    }
-    if (mEngines[i].mPtrViECapture) {
-#ifdef DEBUG
-      MOZ_ASSERT(0 == mEngines[i].mPtrViECapture->DeregisterInputObserver());
-#else
-      mEngines[i].mPtrViECapture->DeregisterInputObserver();
-#endif
+    if (auto engine = mEngines[i].get() ){
+      if (engine->IsRunning()) {
+        LOG(("Being closed down while engine %d is running!", i));
+      }
 
-      mEngines[i].mPtrViECapture->Release();
-        mEngines[i].mPtrViECapture = nullptr;
-    }
-    if(mEngines[i].mPtrViEBase) {
-      mEngines[i].mPtrViEBase->Release();
-      mEngines[i].mPtrViEBase = nullptr;
-    }
-    if (mEngines[i].mEngine) {
-      mEngines[i].mEngine->SetTraceCallback(nullptr);
-      webrtc::VideoEngine::Delete(mEngines[i].mEngine);
-      mEngines[i].mEngine = nullptr;
+      auto device_info = engine->GetOrCreateVideoCaptureDeviceInfo();
+      MOZ_ASSERT(device_info);
+      if (device_info) {
+        device_info->DeRegisterVideoInputFeedBack();
+      }
+      mozilla::camera::VideoEngine::Delete(engine);
+      mEngines[i] = nullptr;
     }
   }
 
   for (InputObserver* observer : mObservers) {
     delete observer;
   }
   mObservers.Clear();
 
   mWebRTCAlive = false;
 }
 
-bool
+VideoEngine *
 CamerasParent::EnsureInitialized(int aEngine)
 {
-  LOG((__PRETTY_FUNCTION__));
+  LOG_VERBOSE((__PRETTY_FUNCTION__));
   // We're shutting down, don't try to do new WebRTC ops.
   if (!mWebRTCAlive) {
-    return false;
+    return nullptr;
   }
   CaptureEngine capEngine = static_cast<CaptureEngine>(aEngine);
   if (!SetupEngine(capEngine)) {
     LOG(("CamerasParent failed to initialize engine"));
-    return false;
+    return nullptr;
   }
 
-  return true;
+  return mEngines[aEngine];
 }
 
 // Dispatch the runnable to do the camera operation on the
 // specific Cameras thread, preventing us from blocking, and
 // chain a runnable to send back the result on the IPC thread.
 // It would be nice to get rid of the code duplication here,
 // perhaps via Promises.
 mozilla::ipc::IPCResult
 CamerasParent::RecvNumberOfCaptureDevices(const CaptureEngine& aCapEngine)
 {
   LOG((__PRETTY_FUNCTION__));
-
+  LOG(("CaptureEngine=%d", aCapEngine));
   RefPtr<CamerasParent> self(this);
   RefPtr<Runnable> webrtc_runnable =
     media::NewRunnableFrom([self, aCapEngine]() -> nsresult {
       int num = -1;
-      if (self->EnsureInitialized(aCapEngine)) {
-        num = self->mEngines[aCapEngine].mPtrViECapture->NumberOfCaptureDevices();
+      if (auto engine = self->EnsureInitialized(aCapEngine)) {
+        if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()) {
+          num = devInfo->NumberOfDevices();
+        }
       }
       RefPtr<nsIRunnable> ipc_runnable =
         media::NewRunnableFrom([self, num]() -> nsresult {
           if (self->IsShuttingDown()) {
             return NS_ERROR_FAILURE;
           }
           if (num < 0) {
             LOG(("RecvNumberOfCaptureDevices couldn't find devices"));
@@ -590,21 +502,20 @@ CamerasParent::RecvNumberOfCapabilities(
 {
   LOG((__PRETTY_FUNCTION__));
   LOG(("Getting caps for %s", unique_id.get()));
 
   RefPtr<CamerasParent> self(this);
   RefPtr<Runnable> webrtc_runnable =
     media::NewRunnableFrom([self, unique_id, aCapEngine]() -> nsresult {
       int num = -1;
-      if (self->EnsureInitialized(aCapEngine)) {
-        num =
-          self->mEngines[aCapEngine].mPtrViECapture->NumberOfCapabilities(
-            unique_id.get(),
-            MediaEngineSource::kMaxUniqueIdLength);
+      if (auto engine = self->EnsureInitialized(aCapEngine)) {
+        if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()) {
+          num = devInfo->NumberOfCapabilities(unique_id.get());
+        }
       }
       RefPtr<nsIRunnable> ipc_runnable =
         media::NewRunnableFrom([self, num]() -> nsresult {
           if (self->IsShuttingDown()) {
             return NS_ERROR_FAILURE;
           }
           if (num < 0) {
             LOG(("RecvNumberOfCapabilities couldn't find capabilities"));
@@ -629,28 +540,29 @@ CamerasParent::RecvGetCaptureCapability(
                                         const int& num)
 {
   LOG((__PRETTY_FUNCTION__));
   LOG(("RecvGetCaptureCapability: %s %d", unique_id.get(), num));
 
   RefPtr<CamerasParent> self(this);
   RefPtr<Runnable> webrtc_runnable =
     media::NewRunnableFrom([self, unique_id, aCapEngine, num]() -> nsresult {
-      webrtc::CaptureCapability webrtcCaps;
+      webrtc::VideoCaptureCapability webrtcCaps;
       int error = -1;
-      if (self->EnsureInitialized(aCapEngine)) {
-        error = self->mEngines[aCapEngine].mPtrViECapture->GetCaptureCapability(
-          unique_id.get(), MediaEngineSource::kMaxUniqueIdLength, num, webrtcCaps);
+      if (auto engine = self->EnsureInitialized(aCapEngine)) {
+        if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()){
+          error = devInfo->GetCapability(unique_id.get(), num, webrtcCaps);
+        }
       }
       RefPtr<nsIRunnable> ipc_runnable =
         media::NewRunnableFrom([self, webrtcCaps, error]() -> nsresult {
           if (self->IsShuttingDown()) {
             return NS_ERROR_FAILURE;
           }
-          CaptureCapability capCap(webrtcCaps.width,
+          VideoCaptureCapability capCap(webrtcCaps.width,
                                    webrtcCaps.height,
                                    webrtcCaps.maxFPS,
                                    webrtcCaps.expectedCaptureDelay,
                                    webrtcCaps.rawType,
                                    webrtcCaps.codecType,
                                    webrtcCaps.interlaced);
           LOG(("Capability: %u %u %u %u %d %d",
                webrtcCaps.width,
@@ -681,25 +593,25 @@ CamerasParent::RecvGetCaptureDevice(cons
 
   RefPtr<CamerasParent> self(this);
   RefPtr<Runnable> webrtc_runnable =
     media::NewRunnableFrom([self, aCapEngine, aListNumber]() -> nsresult {
       char deviceName[MediaEngineSource::kMaxDeviceNameLength];
       char deviceUniqueId[MediaEngineSource::kMaxUniqueIdLength];
       nsCString name;
       nsCString uniqueId;
-      int devicePid = 0;
+      pid_t devicePid = 0;
       int error = -1;
-      if (self->EnsureInitialized(aCapEngine)) {
-          error = self->mEngines[aCapEngine].mPtrViECapture->GetCaptureDevice(aListNumber,
-                                                                              deviceName,
-                                                                              sizeof(deviceName),
-                                                                              deviceUniqueId,
-                                                                              sizeof(deviceUniqueId),
-                                                                              &devicePid);
+      if (auto engine = self->EnsureInitialized(aCapEngine)) {
+        if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()) {
+          error = devInfo->GetDeviceName(aListNumber, deviceName, sizeof(deviceName),
+                                         deviceUniqueId, sizeof(deviceUniqueId),
+                                         nullptr, 0,
+                                         &devicePid);
+        }
       }
       if (!error) {
         name.Assign(deviceName);
         uniqueId.Assign(deviceUniqueId);
       }
       RefPtr<nsIRunnable> ipc_runnable =
         media::NewRunnableFrom([self, error, name, uniqueId, devicePid]() {
           if (self->IsShuttingDown()) {
@@ -805,18 +717,27 @@ CamerasParent::RecvAllocateCaptureDevice
       // After retrieving the permission (or not) on the main thread,
       // bounce to the WebRTC thread to allocate the device (or not),
       // then bounce back to the IPC thread for the reply to content.
       RefPtr<Runnable> webrtc_runnable =
       media::NewRunnableFrom([self, allowed, aCapEngine, unique_id]() -> nsresult {
         int numdev = -1;
         int error = -1;
         if (allowed && self->EnsureInitialized(aCapEngine)) {
-          error = self->mEngines[aCapEngine].mPtrViECapture->AllocateCaptureDevice(
-                    unique_id.get(), MediaEngineSource::kMaxUniqueIdLength, numdev);
+          auto engine = self->mEngines[aCapEngine].get();
+          engine->CreateVideoCapture(numdev, unique_id.get());
+          engine->WithEntry(numdev, [&error](VideoEngine::CaptureEntry& cap) {
+            if (cap.VideoCapture()) {
+              if (!cap.VideoRenderer()) {
+                LOG(("VideoEngine::VideoRenderer() failed"));
+              } else {
+                error = 0;
+              }
+            }
+          });
         }
         RefPtr<nsIRunnable> ipc_runnable =
           media::NewRunnableFrom([self, numdev, error]() -> nsresult {
             if (self->IsShuttingDown()) {
               return NS_ERROR_FAILURE;
             }
             if (error) {
               Unused << self->SendReplyFailure();
@@ -837,18 +758,18 @@ CamerasParent::RecvAllocateCaptureDevice
   return IPC_OK();
 }
 
 int
 CamerasParent::ReleaseCaptureDevice(const CaptureEngine& aCapEngine,
                                     const int& capnum)
 {
   int error = -1;
-  if (EnsureInitialized(aCapEngine)) {
-    error = mEngines[aCapEngine].mPtrViECapture->ReleaseCaptureDevice(capnum);
+  if (auto engine = EnsureInitialized(aCapEngine)) {
+    error = engine->ReleaseVideoCapture(capnum);
   }
   return error;
 }
 
 mozilla::ipc::IPCResult
 CamerasParent::RecvReleaseCaptureDevice(const CaptureEngine& aCapEngine,
                                         const int& numdev)
 {
@@ -880,54 +801,58 @@ CamerasParent::RecvReleaseCaptureDevice(
     });
   DispatchToVideoCaptureThread(webrtc_runnable);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 CamerasParent::RecvStartCapture(const CaptureEngine& aCapEngine,
                                 const int& capnum,
-                                const CaptureCapability& ipcCaps)
+                                const VideoCaptureCapability& ipcCaps)
 {
   LOG((__PRETTY_FUNCTION__));
 
   RefPtr<CamerasParent> self(this);
   RefPtr<Runnable> webrtc_runnable =
     media::NewRunnableFrom([self, aCapEngine, capnum, ipcCaps]() -> nsresult {
+      LOG((__PRETTY_FUNCTION__));
       CallbackHelper** cbh;
-      webrtc::ExternalRenderer* render;
-      EngineHelper* helper = nullptr;
+      webrtc::VideoRenderCallback* render;
+      VideoEngine* engine = nullptr;
       int error = -1;
       if (self->EnsureInitialized(aCapEngine)) {
         cbh = self->mCallbacks.AppendElement(
           new CallbackHelper(static_cast<CaptureEngine>(aCapEngine), capnum, self));
-        render = static_cast<webrtc::ExternalRenderer*>(*cbh);
+        render = static_cast<webrtc::VideoRenderCallback*>(*cbh);
 
-        helper = &self->mEngines[aCapEngine];
-        error =
-          helper->mPtrViERender->AddRenderer(capnum, webrtc::kVideoI420, render);
-        if (!error) {
-          error = helper->mPtrViERender->StartRender(capnum);
-        }
+        engine = self->mEngines[aCapEngine];
+        engine->WithEntry(capnum, [capnum, &render, &engine, &error, &ipcCaps, &cbh](VideoEngine::CaptureEntry& cap) {
+          cap.VideoRenderer()->AddIncomingRenderStream(capnum,0, 0., 0., 1., 1.);
+          error = cap.VideoRenderer()->AddExternalRenderCallback(capnum, render);
+          if (!error) {
+            error = cap.VideoRenderer()->StartRender(capnum);
+          }
 
-        webrtc::CaptureCapability capability;
-        capability.width = ipcCaps.width();
-        capability.height = ipcCaps.height();
-        capability.maxFPS = ipcCaps.maxFPS();
-        capability.expectedCaptureDelay = ipcCaps.expectedCaptureDelay();
-        capability.rawType = static_cast<webrtc::RawVideoType>(ipcCaps.rawType());
-        capability.codecType = static_cast<webrtc::VideoCodecType>(ipcCaps.codecType());
-        capability.interlaced = ipcCaps.interlaced();
+          webrtc::VideoCaptureCapability capability;
+          capability.width = ipcCaps.width();
+          capability.height = ipcCaps.height();
+          capability.maxFPS = ipcCaps.maxFPS();
+          capability.expectedCaptureDelay = ipcCaps.expectedCaptureDelay();
+          capability.rawType = static_cast<webrtc::RawVideoType>(ipcCaps.rawType());
+          capability.codecType = static_cast<webrtc::VideoCodecType>(ipcCaps.codecType());
+          capability.interlaced = ipcCaps.interlaced();
 
-        if (!error) {
-          error = helper->mPtrViECapture->StartCapture(capnum, capability);
-        }
-        if (!error) {
-          helper->mEngineIsRunning = true;
-        }
+          if (!error) {
+            error = cap.VideoCapture()->StartCapture(capability);
+          }
+          if (!error) {
+            engine->Startup();
+            cap.VideoCapture()->RegisterCaptureDataCallback(*static_cast<webrtc::VideoCaptureDataCallback*>(*cbh));
+          }
+        });
       }
       RefPtr<nsIRunnable> ipc_runnable =
         media::NewRunnableFrom([self, error]() -> nsresult {
           if (self->IsShuttingDown()) {
             return NS_ERROR_FAILURE;
           }
           if (!error) {
             Unused << self->SendReplySuccess();
@@ -943,30 +868,37 @@ CamerasParent::RecvStartCapture(const Ca
   DispatchToVideoCaptureThread(webrtc_runnable);
   return IPC_OK();
 }
 
 void
 CamerasParent::StopCapture(const CaptureEngine& aCapEngine,
                            const int& capnum)
 {
-  if (EnsureInitialized(aCapEngine)) {
-    mEngines[aCapEngine].mPtrViECapture->StopCapture(capnum);
-    mEngines[aCapEngine].mPtrViERender->StopRender(capnum);
-    mEngines[aCapEngine].mPtrViERender->RemoveRenderer(capnum);
-    mEngines[aCapEngine].mEngineIsRunning = false;
-
-    for (size_t i = 0; i < mCallbacks.Length(); i++) {
-      if (mCallbacks[i]->mCapEngine == aCapEngine
-          && mCallbacks[i]->mCapturerId == capnum) {
-        delete mCallbacks[i];
-        mCallbacks.RemoveElementAt(i);
+  if (auto engine = EnsureInitialized(aCapEngine)) {
+    engine->WithEntry(capnum,[capnum](VideoEngine::CaptureEntry& cap){
+      if (cap.VideoCapture()) {
+        cap.VideoCapture()->StopCapture();
+        cap.VideoCapture()->DeRegisterCaptureDataCallback();
+      }
+      if (cap.VideoRenderer()) {
+        cap.VideoRenderer()->StopRender(capnum);
+      }
+    });
+    // we're removing elements, iterate backwards
+    for (size_t i = mCallbacks.Length(); i > 0; i--) {
+      if (mCallbacks[i-1]->mCapEngine == aCapEngine
+          && mCallbacks[i-1]->mStreamId == (uint32_t) capnum) {
+        delete mCallbacks[i-1];
+        mCallbacks.RemoveElementAt(i-1);
         break;
       }
     }
+    engine->RemoveRenderer(capnum);
+    engine->Shutdown();
   }
 }
 
 mozilla::ipc::IPCResult
 CamerasParent::RecvStopCapture(const CaptureEngine& aCapEngine,
                                const int& capnum)
 {
   LOG((__PRETTY_FUNCTION__));
@@ -1084,17 +1016,17 @@ CamerasParent::~CamerasParent()
   LOG(("~CamerasParent: %p", this));
 
 #ifdef DEBUG
   // Verify we have shut down the webrtc engines, this is
   // supposed to happen in ActorDestroy.
   // That runnable takes a ref to us, so it must have finished
   // by the time we get here.
   for (int i = 0; i < CaptureEngine::MaxEngine; i++) {
-    MOZ_ASSERT(!mEngines[i].mEngine);
+    MOZ_ASSERT(!mEngines[i]);
   }
 #endif
 }
 
 already_AddRefed<CamerasParent>
 CamerasParent::Create() {
   mozilla::ipc::AssertIsOnBackgroundThread();
   RefPtr<CamerasParent> camerasParent = new CamerasParent();
--- a/dom/media/systemservices/CamerasParent.h
+++ b/dom/media/systemservices/CamerasParent.h
@@ -3,90 +3,75 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_CamerasParent_h
 #define mozilla_CamerasParent_h
 
 #include "nsIObserver.h"
+#include "VideoEngine.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/camera/PCamerasParent.h"
 #include "mozilla/ipc/Shmem.h"
 #include "mozilla/ShmemPool.h"
 #include "mozilla/Atomics.h"
+#include "webrtc/modules/video_capture/video_capture.h"
+#include "webrtc/modules/video_render/video_render_impl.h"
+#include "webrtc/modules/video_capture/video_capture_defines.h"
+#include "webrtc/common_video/include/incoming_video_stream.h"
 
 // conflicts with #include of scoped_ptr.h
 #undef FF
 #include "webrtc/common.h"
-// Video Engine
-#include "webrtc/video_engine/include/vie_base.h"
-#include "webrtc/video_engine/include/vie_capture.h"
-#include "webrtc/video_engine/include/vie_render.h"
+
 #include "CamerasChild.h"
 
 #include "base/thread.h"
 
 namespace mozilla {
 namespace camera {
 
 class CamerasParent;
 
-class CallbackHelper : public webrtc::ExternalRenderer
+class CallbackHelper :
+  public webrtc::VideoRenderCallback,
+  public webrtc::VideoCaptureDataCallback
 {
 public:
-  CallbackHelper(CaptureEngine aCapEng, int aCapId, CamerasParent *aParent)
-    : mCapEngine(aCapEng), mCapturerId(aCapId), mParent(aParent) {};
+  CallbackHelper(CaptureEngine aCapEng, uint32_t aStreamId, CamerasParent *aParent)
+    : mCapEngine(aCapEng), mStreamId(aStreamId), mParent(aParent) {};
 
   // ViEExternalRenderer implementation. These callbacks end up
   // running on the VideoCapture thread.
-  virtual int FrameSizeChange(unsigned int w, unsigned int h,
-                              unsigned int streams) override;
-  virtual int DeliverFrame(unsigned char* buffer,
-                           size_t size,
-                           uint32_t time_stamp,
-                           int64_t ntp_time,
-                           int64_t render_time,
-                           void *handle) override;
-  virtual int DeliverI420Frame(const webrtc::I420VideoFrame& webrtc_frame) override;
-  virtual bool IsTextureSupported() override { return false; };
+  virtual int32_t RenderFrame(const uint32_t aStreamId, const webrtc::VideoFrame& video_frame) override;
+
+  // From  VideoCaptureCallback
+  virtual void OnIncomingCapturedFrame(const int32_t id, const webrtc::VideoFrame& videoFrame) override;
+  virtual void OnCaptureDelayChanged(const int32_t id, const int32_t delay) override;
+
+	// TODO(@@NG) This is now part of webrtc::VideoRenderer, not in the webrtc::VideoRenderCallback
+	// virtual bool IsTextureSupported() const override { return false; };
+	//
+	// virtual bool SmoothsRenderedFrames() const override { return false; }
 
   friend CamerasParent;
 
 private:
   CaptureEngine mCapEngine;
-  int mCapturerId;
+  uint32_t mStreamId;
   CamerasParent *mParent;
 };
 
-class EngineHelper
-{
-public:
-  EngineHelper() :
-    mEngine(nullptr), mPtrViEBase(nullptr), mPtrViECapture(nullptr),
-    mPtrViERender(nullptr), mEngineIsRunning(false) {};
-
-  webrtc::VideoEngine *mEngine;
-  webrtc::ViEBase *mPtrViEBase;
-  webrtc::ViECapture *mPtrViECapture;
-  webrtc::ViERender *mPtrViERender;
-
-  // The webrtc code keeps a reference to this one.
-  webrtc::Config mConfig;
-
-  // Engine alive
-  bool mEngineIsRunning;
-};
-
-class InputObserver :  public webrtc::ViEInputObserver
+class InputObserver :  public webrtc::VideoInputFeedBack
 {
 public:
   explicit InputObserver(CamerasParent* aParent)
     : mParent(aParent) {};
-  virtual void DeviceChange();
+  virtual void OnDeviceChange();
 
   friend CamerasParent;
 
 private:
   RefPtr<CamerasParent> mParent;
 };
 
 class CamerasParent :  public PCamerasParent,
@@ -105,58 +90,55 @@ public:
                                                            const int&) override;
   virtual mozilla::ipc::IPCResult RecvNumberOfCaptureDevices(const CaptureEngine&) override;
   virtual mozilla::ipc::IPCResult RecvNumberOfCapabilities(const CaptureEngine&,
                                                            const nsCString&) override;
   virtual mozilla::ipc::IPCResult RecvGetCaptureCapability(const CaptureEngine&, const nsCString&,
                                                            const int&) override;
   virtual mozilla::ipc::IPCResult RecvGetCaptureDevice(const CaptureEngine&, const int&) override;
   virtual mozilla::ipc::IPCResult RecvStartCapture(const CaptureEngine&, const int&,
-                                                   const CaptureCapability&) override;
+                                                   const VideoCaptureCapability&) override;
   virtual mozilla::ipc::IPCResult RecvStopCapture(const CaptureEngine&, const int&) override;
   virtual mozilla::ipc::IPCResult RecvReleaseFrame(mozilla::ipc::Shmem&&) override;
   virtual mozilla::ipc::IPCResult RecvAllDone() override;
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
   virtual mozilla::ipc::IPCResult RecvEnsureInitialized(const CaptureEngine&) override;
 
   nsIThread* GetBackgroundThread() { return mPBackgroundThread; };
   bool IsShuttingDown() { return !mChildIsAlive
                               ||  mDestroyed
                               || !mWebRTCAlive; };
   ShmemBuffer GetBuffer(size_t aSize);
 
   // helper to forward to the PBackground thread
   int DeliverFrameOverIPC(CaptureEngine capEng,
-                          int cap_id,
+                          uint32_t aStreamId,
                           ShmemBuffer buffer,
                           unsigned char* altbuffer,
-                          size_t size,
-                          uint32_t time_stamp,
-                          int64_t ntp_time,
-                          int64_t render_time);
+                          VideoFrameProperties& aProps);
 
 
   CamerasParent();
 
 protected:
   virtual ~CamerasParent();
 
   // We use these helpers for shutdown and for the respective IPC commands.
   void StopCapture(const CaptureEngine& aCapEngine, const int& capnum);
   int ReleaseCaptureDevice(const CaptureEngine& aCapEngine, const int& capnum);
 
   bool SetupEngine(CaptureEngine aCapEngine);
-  bool EnsureInitialized(int aEngine);
+  VideoEngine* EnsureInitialized(int aEngine);
   void CloseEngines();
   void StopIPC();
   void StopVideoCapture();
   // Can't take already_AddRefed because it can fail in stupid ways.
   nsresult DispatchToVideoCaptureThread(Runnable* event);
 
-  EngineHelper mEngines[CaptureEngine::MaxEngine];
+  RefPtr<VideoEngine> mEngines[CaptureEngine::MaxEngine];
   nsTArray<CallbackHelper*> mCallbacks;
 
   // image buffers
   mozilla::ShmemPool mShmemPool;
 
   // PBackground parent thread
   nsCOMPtr<nsIThread> mPBackgroundThread;
 
--- a/dom/media/systemservices/LoadManager.h
+++ b/dom/media/systemservices/LoadManager.h
@@ -9,18 +9,18 @@
 #include "LoadMonitor.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Services.h"
 #include "nsTArray.h"
 #include "nsIObserver.h"
 
 #include "webrtc/common_types.h"
-#include "webrtc/video_engine/include/vie_base.h"
-
+#include "webrtc/call.h"
+#include "webrtc/video/overuse_frame_detector.h"
 extern mozilla::LazyLogModule gLoadManagerLog;
 
 namespace mozilla {
 
 class LoadManagerSingleton : public LoadNotificationCallback,
                              public webrtc::CPULoadStateCallbackInvoker,
                              public webrtc::CpuOveruseObserver,
                              public nsIObserver
@@ -72,39 +72,40 @@ private:
     int mAveragingMeasurements;
     float mHighLoadThreshold;
     float mLowLoadThreshold;
 
     static StaticRefPtr<LoadManagerSingleton> sSingleton;
 };
 
 class LoadManager final : public webrtc::CPULoadStateCallbackInvoker,
-                          public webrtc::CpuOveruseObserver
+                          public webrtc::LoadObserver
 {
 public:
     explicit LoadManager(LoadManagerSingleton* aManager)
         : mManager(aManager)
     {}
     ~LoadManager() {}
 
     void AddObserver(webrtc::CPULoadStateObserver * aObserver) override
     {
         mManager->AddObserver(aObserver);
     }
     void RemoveObserver(webrtc::CPULoadStateObserver * aObserver) override
     {
         mManager->RemoveObserver(aObserver);
     }
-    void OveruseDetected() override
+
+    void OnLoadUpdate(webrtc::LoadObserver::Load load_state) override
     {
-        mManager->OveruseDetected();
-    }
-    void NormalUsage() override
-    {
-        mManager->NormalUsage();
+        if (load_state == webrtc::LoadObserver::kOveruse) {
+            mManager->OveruseDetected();
+        } else if (load_state == webrtc::LoadObserver::kUnderuse) {
+            mManager->NormalUsage();
+        }
     }
 
 private:
     RefPtr<LoadManagerSingleton> mManager;
 };
 
 } //namespace
 
--- a/dom/media/systemservices/PCameras.ipdl
+++ b/dom/media/systemservices/PCameras.ipdl
@@ -5,57 +5,84 @@
 include protocol PContent;
 include protocol PBackground;
 
 using mozilla::camera::CaptureEngine from "mozilla/media/CamerasTypes.h";
 
 namespace mozilla {
 namespace camera {
 
-struct CaptureCapability
+// IPC analog for webrtc::VideoCaptureCapability
+struct VideoCaptureCapability
 {
   int width;
   int height;
   int maxFPS;
   int expectedCaptureDelay;
   int rawType;
   int codecType;
   bool interlaced;
 };
 
+
+// IPC analog for webrtc::VideoFrame
+// the described buffer is transported seperately in a Shmem
+// See VideoFrameUtils.h
+struct VideoFrameProperties
+{
+  // Size of image data within the ShMem,
+  // the ShMem is at least this large
+  size_t bufferSize;
+  // From webrtc::VideoFrame
+  uint32_t timeStamp;
+  int64_t ntpTimeMs;
+  int64_t renderTimeMs;
+  // See webrtc/**/rotation.h
+  int rotation;
+  int yAllocatedSize;
+  int uAllocatedSize;
+  int vAllocatedSize;
+  // From webrtc::VideoFrameBuffer
+  int width;
+  int height;
+  int yStride;
+  int uStride;
+  int vStride;
+};
+
 async protocol PCameras
 {
   manager PBackground;
 
 child:
   async FrameSizeChange(CaptureEngine capEngine, int cap_id, int w, int h);
   // transfers ownership of |buffer| from parent to child
-  async DeliverFrame(CaptureEngine capEngine, int cap_id,
-                     Shmem buffer, size_t size, uint32_t time_stamp,
-                     int64_t ntp_time, int64_t render_time);
+  async DeliverFrame(CaptureEngine capEngine, int streamId,
+                     Shmem buffer, VideoFrameProperties props);
   async DeviceChange();
   async ReplyNumberOfCaptureDevices(int numdev);
   async ReplyNumberOfCapabilities(int numdev);
   async ReplyAllocateCaptureDevice(int numdev);
-  async ReplyGetCaptureCapability(CaptureCapability cap);
+  async ReplyGetCaptureCapability(VideoCaptureCapability cap);
   async ReplyGetCaptureDevice(nsCString device_name, nsCString device_id, bool scary);
   async ReplyFailure();
   async ReplySuccess();
   async __delete__();
 
 parent:
   async NumberOfCaptureDevices(CaptureEngine engine);
   async NumberOfCapabilities(CaptureEngine engine, nsCString deviceUniqueIdUTF8);
 
-  async GetCaptureCapability(CaptureEngine engine, nsCString unique_idUTF8, int capability_number);
+  async GetCaptureCapability(CaptureEngine engine, nsCString unique_idUTF8,
+                             int capability_number);
   async GetCaptureDevice(CaptureEngine engine, int num);
 
   async AllocateCaptureDevice(CaptureEngine engine, nsCString unique_idUTF8, nsCString origin);
   async ReleaseCaptureDevice(CaptureEngine engine, int numdev);
-  async StartCapture(CaptureEngine engine, int numdev, CaptureCapability capability);
+  async StartCapture(CaptureEngine engine, int numdev, VideoCaptureCapability capability);
   async StopCapture(CaptureEngine engine, int numdev);
   // transfers frame back
   async ReleaseFrame(Shmem s);
 
   // Ask parent to delete us
   async AllDone();
   // setup camera engine
   async EnsureInitialized(CaptureEngine engine);
--- a/dom/media/systemservices/ShmemPool.cpp
+++ b/dom/media/systemservices/ShmemPool.cpp
@@ -35,17 +35,17 @@ mozilla::ShmemBuffer ShmemPool::GetIfAva
 
   if (!res.mInitialized) {
     LOG(("No free preallocated Shmem"));
     return ShmemBuffer();
   }
 
   MOZ_ASSERT(res.mShmem.IsWritable(), "Pool in Shmem is not writable?");
 
-  if (res.mShmem.Size<char>() < aSize) {
+  if (res.mShmem.Size<uint8_t>() < aSize) {
     LOG(("Free Shmem but not of the right size"));
     return ShmemBuffer();
   }
 
   mPoolFree--;
 #ifdef DEBUG
   size_t poolUse = mShmemPool.Length() - mPoolFree;
   if (poolUse > mMaxPoolUse) {
@@ -60,17 +60,17 @@ void ShmemPool::Put(ShmemBuffer&& aShmem
 {
   MutexAutoLock lock(mMutex);
   MOZ_ASSERT(mPoolFree < mShmemPool.Length());
   mShmemPool[mPoolFree] = Move(aShmem);
   mPoolFree++;
 #ifdef DEBUG
   size_t poolUse = mShmemPool.Length() - mPoolFree;
   if (poolUse > 0) {
-    LOG(("ShmemPool usage reduced to %d buffers", poolUse));
+    LOG_VERBOSE(("ShmemPool usage reduced to %d buffers", poolUse));
   }
 #endif
 }
 
 ShmemPool::~ShmemPool()
 {
 #ifdef DEBUG
   for (size_t i = 0; i < mShmemPool.Length(); i++) {
--- a/dom/media/systemservices/ShmemPool.h
+++ b/dom/media/systemservices/ShmemPool.h
@@ -43,18 +43,18 @@ public:
   // No copies allowed
   ShmemBuffer(const ShmemBuffer&) = delete;
   ShmemBuffer& operator=(const ShmemBuffer&) = delete;
 
   bool Valid() {
     return mInitialized;
   }
 
-  char* GetBytes() {
-    return mShmem.get<char>();
+  uint8_t * GetBytes() {
+    return mShmem.get<uint8_t>();
   }
 
   mozilla::ipc::Shmem& Get() {
     return mShmem;
   }
 
 private:
   friend class ShmemPool;
new file mode 100644
--- /dev/null
+++ b/dom/media/systemservices/VideoEngine.cpp
@@ -0,0 +1,185 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et ft=cpp : */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "VideoEngine.h"
+#include "webrtc/video_engine/browser_capture_impl.h"
+#ifdef WEBRTC_ANDROID
+#include "webrtc/modules/video_capture/video_capture.h"
+#ifdef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
+#include "webrtc/modules/video_render/video_render.h"
+#endif
+#endif
+
+
+namespace mozilla {
+namespace camera {
+
+#undef LOG
+#undef LOG_ENABLED
+mozilla::LazyLogModule gVideoEngineLog("VideoEngine");
+#define LOG(args) MOZ_LOG(gVideoEngineLog, mozilla::LogLevel::Debug, args)
+#define LOG_ENABLED() MOZ_LOG_TEST(gVideoEngineLog, mozilla::LogLevel::Debug)
+
+int VideoEngine::sId = 0;
+
+#if defined(ANDROID)
+int VideoEngine::SetAndroidObjects(JavaVM* javaVM) {
+  LOG((__PRETTY_FUNCTION__));
+
+  if (webrtc::SetCaptureAndroidVM(javaVM) != 0) {
+    LOG(("Could not set capture Android VM"));
+    return -1;
+  }
+#ifdef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
+  if (webrtc::SetRenderAndroidVM(javaVM) != 0) {
+    LOG(("Could not set render Android VM"));
+    return -1;
+  }
+#endif
+  return 0;
+}
+#endif
+
+void
+VideoEngine::CreateVideoCapture(int32_t& id, const char* deviceUniqueIdUTF8) {
+  LOG((__PRETTY_FUNCTION__));
+  id = GenerateId();
+  LOG(("CaptureDeviceInfo.type=%s id=%d",mCaptureDevInfo.TypeName(),id));
+  CaptureEntry entry = {-1,nullptr,nullptr};
+
+  if (mCaptureDevInfo.type == webrtc::CaptureDeviceType::Camera) {
+    entry = CaptureEntry(id,
+		         webrtc::VideoCaptureFactory::Create(id, deviceUniqueIdUTF8),
+                         nullptr);
+  } else {
+#ifndef WEBRTC_ANDROID
+    entry = CaptureEntry(
+	      id,
+	      webrtc::DesktopCaptureImpl::Create(id, deviceUniqueIdUTF8, mCaptureDevInfo.type),
+              nullptr);
+#else
+    MOZ_ASSERT("CreateVideoCapture NO DESKTOP CAPTURE IMPL ON ANDROID" == nullptr);
+#endif
+  }
+  mCaps.emplace(id,std::move(entry));
+}
+
+int
+VideoEngine::ReleaseVideoCapture(const int32_t id) {
+  bool found = false;
+  WithEntry(id, [&found](CaptureEntry& cap) {
+         cap.mVideoCaptureModule = nullptr;
+        found = true;
+   });
+  return found ? 0 : (-1);
+}
+
+std::shared_ptr<webrtc::VideoCaptureModule::DeviceInfo>
+VideoEngine::GetOrCreateVideoCaptureDeviceInfo() {
+  if (mDeviceInfo) {
+    return mDeviceInfo;
+  }
+  switch (mCaptureDevInfo.type) {
+    case webrtc::CaptureDeviceType::Camera: {
+      mDeviceInfo.reset(webrtc::VideoCaptureFactory::CreateDeviceInfo(0));
+      break;
+    }
+    case webrtc::CaptureDeviceType::Browser: {
+      mDeviceInfo.reset(webrtc::BrowserDeviceInfoImpl::CreateDeviceInfo());
+      break;
+    }
+    // Window, Application, and Screen types are handled by DesktopCapture
+    case webrtc::CaptureDeviceType::Window:
+    case webrtc::CaptureDeviceType::Application:
+    case webrtc::CaptureDeviceType::Screen: {
+#if !defined(WEBRTC_ANDROID) && !defined(WEBRTC_IOS)
+      mDeviceInfo.reset(webrtc::DesktopCaptureImpl::CreateDeviceInfo(mId,mCaptureDevInfo.type));
+#else
+      MOZ_ASSERT("GetVideoCaptureDeviceInfo NO DESKTOP CAPTURE IMPL ON ANDROID" == nullptr);
+      mDeviceInfo.reset();
+#endif
+      break;
+    }
+  }
+  return mDeviceInfo;
+}
+
+void
+VideoEngine::RemoveRenderer(int capnum) {
+  WithEntry(capnum, [](CaptureEntry& cap) {
+    cap.mVideoRender = nullptr;
+  });
+}
+
+const UniquePtr<const webrtc::Config>&
+VideoEngine::GetConfiguration() {
+  return mConfig;
+}
+
+RefPtr<VideoEngine> VideoEngine::Create(UniquePtr<const webrtc::Config>&& aConfig) {
+  LOG((__PRETTY_FUNCTION__));
+  LOG(("Creating new VideoEngine with CaptureDeviceType %s",
+       aConfig->Get<webrtc::CaptureDeviceInfo>().TypeName()));
+  RefPtr<VideoEngine> engine(new VideoEngine(std::move(aConfig)));
+  return engine;
+}
+
+VideoEngine::CaptureEntry::CaptureEntry(int32_t aCapnum,
+                                        rtc::scoped_refptr<webrtc::VideoCaptureModule> aCapture,
+                                        webrtc::VideoRender * aRenderer):
+    mCapnum(aCapnum),
+    mVideoCaptureModule(aCapture),
+    mVideoRender(aRenderer)
+{}
+
+rtc::scoped_refptr<webrtc::VideoCaptureModule>
+VideoEngine::CaptureEntry::VideoCapture() {
+  return mVideoCaptureModule;
+}
+
+const UniquePtr<webrtc::VideoRender>&
+VideoEngine::CaptureEntry::VideoRenderer() {
+  if (!mVideoRender) {
+     MOZ_ASSERT(mCapnum != -1);
+     // Create a VideoRender on demand
+     mVideoRender = UniquePtr<webrtc::VideoRender>(
+         webrtc::VideoRender::CreateVideoRender(mCapnum,nullptr,false,webrtc::kRenderExternal));
+   }
+  return mVideoRender;
+}
+
+int32_t
+VideoEngine::CaptureEntry::Capnum() const {
+  return mCapnum;
+}
+
+bool VideoEngine::WithEntry(const int32_t entryCapnum,
+			    const std::function<void(CaptureEntry &entry)>&& fn) {
+  auto it = mCaps.find(entryCapnum);
+  if (it == mCaps.end()) {
+    return false;
+  }
+  fn(it->second);
+  return true;
+}
+
+int32_t
+VideoEngine::GenerateId() {
+  // XXX Something better than this (a map perhaps, or a simple boolean TArray, given
+  // the number in-use is O(1) normally!)
+  return mId = sId++;
+}
+
+VideoEngine::VideoEngine(UniquePtr<const webrtc::Config>&& aConfig):
+  mCaptureDevInfo(aConfig->Get<webrtc::CaptureDeviceInfo>()),
+  mDeviceInfo(nullptr),
+  mConfig(std::move(aConfig))
+{
+  LOG((__PRETTY_FUNCTION__));
+}
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/dom/media/systemservices/VideoEngine.h
@@ -0,0 +1,104 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et ft=cpp : */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_VideoEngine_h
+#define mozilla_VideoEngine_h
+
+#include "MediaEngine.h"
+#include "VideoFrameUtils.h"
+#include "mozilla/media/MediaUtils.h"
+#include "webrtc/common.h"
+#include "webrtc/modules/video_capture/video_capture_impl.h"
+#include "webrtc/modules/video_render/video_render.h"
+#include "webrtc/modules/video_capture/video_capture_defines.h"
+#include "webrtc/modules/video_capture/video_capture_factory.h"
+#include "webrtc/video_engine/desktop_capture_impl.h"
+#include <memory>
+#include <functional>
+
+namespace mozilla {
+namespace camera {
+
+// Historically the video engine was part of webrtc
+// it was removed (and reimplemented in Talk)
+class VideoEngine
+{
+private:
+  virtual ~VideoEngine (){};
+
+public:
+  VideoEngine (){};
+  NS_INLINE_DECL_REFCOUNTING(VideoEngine)
+
+  static RefPtr<VideoEngine> Create(UniquePtr<const webrtc::Config>&& aConfig);
+#if defined(ANDROID)
+  static int SetAndroidObjects(JavaVM* javaVM);
+#endif
+  void CreateVideoCapture(int32_t& id, const char* deviceUniqueIdUTF8);
+
+  int ReleaseVideoCapture(const int32_t id);
+
+  // VideoEngine is responsible for any cleanup in its modules
+  static void Delete(VideoEngine * engine) { }
+
+  /** Returns or creates a new new DeviceInfo.
+  *   It is cached to prevent repeated lengthy polling for "realness"
+  *   of the hardware devices.  This could be handled in a more elegant
+  *   way in the future.
+  *   @return on failure the shared_ptr will be null, otherwise it will contain a DeviceInfo.
+  *   @see bug 1305212 https://bugzilla.mozilla.org/show_bug.cgi?id=1305212
+  */
+  std::shared_ptr<webrtc::VideoCaptureModule::DeviceInfo> GetOrCreateVideoCaptureDeviceInfo();
+
+  void RemoveRenderer(int capnum);
+
+  const UniquePtr<const webrtc::Config>& GetConfiguration();
+
+  void Startup() {
+    mIsRunning = true;
+  }
+
+  void Shutdown() {
+    mIsRunning = false;
+  }
+
+  bool IsRunning() const {
+    return mIsRunning;
+  }
+
+  class CaptureEntry {
+  public:
+    CaptureEntry(int32_t aCapnum,
+                 rtc::scoped_refptr<webrtc::VideoCaptureModule> aCapture,
+                 webrtc::VideoRender* aRenderer);
+    int32_t Capnum() const;
+    rtc::scoped_refptr<webrtc::VideoCaptureModule> VideoCapture();
+    const UniquePtr<webrtc::VideoRender> & VideoRenderer();
+  private:
+    int32_t mCapnum;
+    rtc::scoped_refptr<webrtc::VideoCaptureModule> mVideoCaptureModule;
+    UniquePtr<webrtc::VideoRender> mVideoRender;
+    friend class VideoEngine;
+  };
+
+  // Returns true iff an entry for capnum exists
+  bool WithEntry(const int32_t entryCapnum, const std::function<void(CaptureEntry &entry)>&& fn);
+
+private:
+  explicit VideoEngine(UniquePtr<const webrtc::Config>&& aConfig);
+  bool mIsRunning;
+  int32_t mId;
+  webrtc::CaptureDeviceInfo mCaptureDevInfo;
+  std::shared_ptr<webrtc::VideoCaptureModule::DeviceInfo> mDeviceInfo;
+  UniquePtr<const webrtc::Config> mConfig;
+  std::map<int32_t, CaptureEntry> mCaps;
+
+  int32_t GenerateId();
+  static int32_t sId;
+};
+}
+}
+#endif
new file mode 100644
--- /dev/null
+++ b/dom/media/systemservices/VideoFrameUtils.cpp
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et ft=cpp : */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "VideoFrameUtils.h"
+#include "webrtc/video_frame.h"
+#include "mozilla/ShmemPool.h"
+
+namespace mozilla {
+
+size_t
+VideoFrameUtils::TotalRequiredBufferSize(
+                  const webrtc::VideoFrame& aVideoFrame)
+{
+  static const webrtc::PlaneType kPlanes[] =
+                  {webrtc::kYPlane, webrtc::kUPlane, webrtc::kVPlane};
+  if (aVideoFrame.IsZeroSize()) {
+    return 0;
+  }
+
+  size_t sum = 0;
+  for (auto plane : kPlanes) {
+    sum += aVideoFrame.allocated_size(plane);
+  }
+  return sum;
+}
+
+void VideoFrameUtils::InitFrameBufferProperties(
+                  const webrtc::VideoFrame& aVideoFrame,
+                  camera::VideoFrameProperties& aDestProps)
+{
+  // The VideoFrameBuffer image data stored in the accompanying buffer
+  // the buffer is at least this size of larger.
+  aDestProps.bufferSize() = TotalRequiredBufferSize(aVideoFrame);
+
+  aDestProps.timeStamp() = aVideoFrame.timestamp();
+  aDestProps.ntpTimeMs() = aVideoFrame.ntp_time_ms();
+  aDestProps.renderTimeMs() = aVideoFrame.render_time_ms();
+
+  aDestProps.rotation() = aVideoFrame.rotation();
+
+  aDestProps.yAllocatedSize() = aVideoFrame.allocated_size(webrtc::kYPlane);
+  aDestProps.uAllocatedSize() = aVideoFrame.allocated_size(webrtc::kYPlane);
+  aDestProps.vAllocatedSize() = aVideoFrame.allocated_size(webrtc::kYPlane);
+
+  aDestProps.width() = aVideoFrame.width();
+  aDestProps.height() = aVideoFrame.height();
+
+  aDestProps.yStride() = aVideoFrame.stride(webrtc::kYPlane);
+  aDestProps.uStride() = aVideoFrame.stride(webrtc::kUPlane);
+  aDestProps.vStride() = aVideoFrame.stride(webrtc::kVPlane);
+}
+
+void VideoFrameUtils::CopyVideoFrameBuffers(uint8_t* aDestBuffer,
+                       const size_t aDestBufferSize,
+                       const webrtc::VideoFrame& aFrame)
+{
+  static const webrtc::PlaneType planes[] = {webrtc::kYPlane, webrtc::kUPlane, webrtc::kVPlane};
+
+  size_t aggregateSize = TotalRequiredBufferSize(aFrame);
+
+  MOZ_ASSERT(aDestBufferSize >= aggregateSize);
+
+  // If planes are ordered YUV and contiguous then do a single copy
+  if ((aFrame.buffer(webrtc::kYPlane) != nullptr)
+    // Check that the three planes are ordered
+    && (aFrame.buffer(webrtc::kYPlane) < aFrame.buffer(webrtc::kUPlane))
+    && (aFrame.buffer(webrtc::kUPlane) < aFrame.buffer(webrtc::kVPlane))
+    //  Check that the last plane ends at firstPlane[totalsize]
+    && (&aFrame.buffer(webrtc::kYPlane)[aggregateSize] == &aFrame.buffer(webrtc::kVPlane)[aFrame.allocated_size(webrtc::kVPlane)]))
+  {
+    memcpy(aDestBuffer,aFrame.buffer(webrtc::kYPlane),aggregateSize);
+    return;
+  }
+
+  // Copy each plane
+  size_t offset = 0;
+  for (auto plane: planes) {
+    memcpy(&aDestBuffer[offset], aFrame.buffer(plane), aFrame.allocated_size(plane));
+    offset += aFrame.allocated_size(plane);
+  }
+}
+
+void VideoFrameUtils::CopyVideoFrameBuffers(ShmemBuffer& aDestShmem,
+                        const webrtc::VideoFrame& aVideoFrame)
+{
+  CopyVideoFrameBuffers(aDestShmem.Get().get<uint8_t>(), aDestShmem.Get().Size<uint8_t>(), aVideoFrame);
+}
+
+}
new file mode 100644
--- /dev/null
+++ b/dom/media/systemservices/VideoFrameUtils.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et ft=cpp : */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_VideoFrameUtil_h
+#define mozilla_VideoFrameUtil_h
+
+#include "mozilla/camera/PCameras.h"
+
+namespace webrtc {
+  class VideoFrame;
+}
+
+namespace mozilla
+{
+  class ShmemBuffer;
+
+// Util methods for working with webrtc::VideoFrame(s) and
+// the IPC classes that are used to deliver their contents to the
+// MediaEnginge
+
+class VideoFrameUtils {
+public:
+
+  // Returns the total number of bytes necessary to copy a VideoFrame's buffer
+  // across all planes.
+  static size_t TotalRequiredBufferSize(const webrtc::VideoFrame & frame);
+
+  // Initializes a camera::VideoFrameProperties from a VideoFrameBuffer
+  static void InitFrameBufferProperties(const webrtc::VideoFrame& aVideoFrame,
+                camera::VideoFrameProperties & aDestProperties);
+
+  // Copies the buffers out of a VideoFrameBuffer into a buffer.
+  // Attempts to make as few memcopies as possible.
+  static void CopyVideoFrameBuffers(uint8_t * aDestBuffer,
+                         const size_t aDestBufferSize,
+                         const webrtc::VideoFrame & aVideoFrame);
+
+  // Copies the buffers in a VideoFrameBuffer into a Shmem
+  // returns the eno from the underlying memcpy.
+  static void CopyVideoFrameBuffers(ShmemBuffer & aDestShmem,
+                         const webrtc::VideoFrame & aVideoFrame);
+
+
+};
+
+} /* namespace mozilla */
+
+#endif
--- a/dom/media/systemservices/moz.build
+++ b/dom/media/systemservices/moz.build
@@ -1,39 +1,46 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 if CONFIG['MOZ_WEBRTC']:
     EXPORTS += [
         'CamerasChild.h',
         'CamerasParent.h',
         'LoadManager.h',
         'LoadManagerFactory.h',
         'LoadMonitor.h',
+        'VideoEngine.h',
+        'VideoFrameUtils.h'
     ]
     UNIFIED_SOURCES += [
         'CamerasChild.cpp',
         'CamerasParent.cpp',
         'LoadManager.cpp',
         'LoadManagerFactory.cpp',
         'LoadMonitor.cpp',
         'ShmemPool.cpp',
+        'VideoEngine.cpp',
+        'VideoFrameUtils.cpp'
     ]
     LOCAL_INCLUDES += [
         '/media/webrtc/signaling',
         '/media/webrtc/trunk',
     ]
 if CONFIG['OS_TARGET'] == 'WINNT':
     DEFINES['WEBRTC_WIN'] = True
 else:
     DEFINES['WEBRTC_POSIX'] = True
 
+if CONFIG['OS_TARGET'] == 'Android':
+    DEFINES['WEBRTC_ANDROID'] = True
+
 
 if CONFIG['OS_TARGET'] == 'Android':
     EXPORTS += [
         'OpenSLESProvider.h'
     ]
     UNIFIED_SOURCES += [
         'OpenSLESProvider.cpp',
     ]
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -35,17 +35,16 @@ skip-if = android_version == '18' # andr
 [test_dataChannel_basicVideo.html]
 skip-if = android_version == '18' # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_dataChannel_bug1013809.html]
 skip-if = android_version == '18' # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_dataChannel_noOffer.html]
 [test_enumerateDevices.html]
 [test_ondevicechange.html]
 skip-if = os == 'android'
-[test_getUserMedia_active_autoplay.html]
 [test_getUserMedia_audioCapture.html]
 skip-if = android_version == '18' # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_getUserMedia_addTrackRemoveTrack.html]
 skip-if = android_version == '18' # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_getUserMedia_addtrack_removetrack_events.html]
 [test_getUserMedia_basicAudio.html]
 [test_getUserMedia_basicVideo.html]
 [test_getUserMedia_basicVideo_playAfterLoadedmetadata.html]
@@ -93,17 +92,17 @@ skip-if = android_version == '18' # andr
 skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_peerConnection_basicAudioNATSrflx.html]
 skip-if = toolkit == 'android' # websockets don't work on android (bug 1266217)
 [test_peerConnection_basicAudioNATRelay.html]
 skip-if = toolkit == 'android' # websockets don't work on android (bug 1266217)
 [test_peerConnection_basicAudioNATRelayTCP.html]
 skip-if = toolkit == 'android' # websockets don't work on android (bug 1266217)
 [test_peerConnection_basicAudioRequireEOC.html]
-skip-if = (android_version == '18' && debug) # android(Bug 1189784, timeouts on 4.3 emulator)
+skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_peerConnection_basicAudioPcmaPcmuOnly.html]
 skip-if = android_version == '18'
 [test_peerConnection_basicAudioDynamicPtMissingRtpmap.html]
 skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_peerConnection_basicAudioVideo.html]
 skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_peerConnection_basicAudioVideoCombined.html]
 skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
@@ -121,17 +120,17 @@ skip-if = toolkit == 'android' # no scre
 [test_peerConnection_basicWindowshare.html]
 # frequent timeouts/crashes on e10s (bug 1048455)
 skip-if = toolkit == 'android' # no screenshare on android
 [test_peerConnection_basicH264Video.html]
 skip-if = os == 'android' # bug 1043403
 [test_peerConnection_bug822674.html]
 [test_peerConnection_bug825703.html]
 [test_peerConnection_bug827843.html]
-skip-if = (android_version == '18' && debug) # android(Bug 1189784, timeouts on 4.3 emulator)
+skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_peerConnection_bug834153.html]
 [test_peerConnection_bug1013809.html]
 skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_peerConnection_bug1042791.html]
 skip-if = os == 'android' # bug 1043403
 [test_peerConnection_bug1064223.html]
 [test_peerConnection_capturedVideo.html]
 tags=capturestream
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -1414,36 +1414,72 @@ PeerConnectionWrapper.prototype = {
    * Wait for RTP packet flow for the given MediaStreamTrack.
    *
    * @param {object} track
    *        A MediaStreamTrack to wait for data flow on.
    * @returns {Promise}
    *        A promise that resolves when media is flowing.
    */
   waitForRtpFlow(track) {
-    var hasFlow = stats => {
-      var rtp = stats.get([...stats.keys()].find(key =>
+    var hasFlow = (stats, retries) => {
+      info("Checking for stats in " + JSON.stringify(stats) + " for " + track.kind
+        + " track " + track.id + ", retry number " + retries);
+      var rtp = stats.get([...Object.keys(stats)].find(key =>
         !stats.get(key).isRemote && stats.get(key).type.endsWith("boundrtp")));
-      ok(rtp, "Should have RTP stats for track " + track.id);
       if (!rtp) {
+
         return false;
       }
+      info("Should have RTP stats for track " + track.id);
+      info("RTP stats: "+JSON.stringify(rtp));
       var nrPackets = rtp[rtp.type == "outboundrtp" ? "packetsSent"
                                                     : "packetsReceived"];
       info("Track " + track.id + " has " + nrPackets + " " +
            rtp.type + " RTP packets.");
       return nrPackets > 0;
     };
 
-    info("Checking RTP packet flow for track " + track.id);
+    // Time between stats checks
+    var retryInterval = 500;
+    // Timeout in ms
+    var timeoutInterval = 30000;
+    // Check hasFlow at a reasonable interval
+    var checkStats = new Promise((resolve, reject)=>{
+      var retries = 0;
+      var timer = setInterval(()=>{
+        this._pc.getStats(track).then(stats=>{
+          if (hasFlow(stats, retries)) {
+            clearInterval(timer);
+            ok(true, "RTP flowing for " + track.kind + " track " + track.id);
+            resolve();
+          }
+          retries = retries + 1;
+          // This is not accurate but it will tear down
+          // the timer eventually and probably not
+          // before timeoutInterval has elapsed.
+          if ((retries * retryInterval) > timeoutInterval) {
+            clearInterval(timer);
+          }
+        });
+      }, retryInterval);
+    });
 
-    var retry = (delay) => this._pc.getStats(track)
-      .then(stats => hasFlow(stats)? ok(true, "RTP flowing for track " + track.id) :
-            wait(delay).then(retry(1000)));
-    return retry(200);
+    info("Checking RTP packet flow for track " + track.id);
+    var retry = Promise.race([checkStats.then(new Promise((resolve, reject)=>{
+        info("checkStats completed for " + track.kind + " track " + track.id);
+        resolve();
+      })),
+      new Promise((accept,reject)=>wait(timeoutInterval).then(()=>{
+        info("Timeout checking for stats for track " + track.id + " after " + timeoutInterval + "ms");
+        reject("Timeout checking for stats for " + track.kind
+          + " track " + track.id + " after " + timeoutInterval + "ms");
+      })
+    )]);
+
+    return retry;
   },
 
   /**
    * Wait for presence of video flow on all media elements and rtp flow on
    * all sending and receiving track involved in this test.
    *
    * @returns {Promise}
    *        A promise that resolves when media flows for all elements and tracks
@@ -1535,17 +1571,19 @@ PeerConnectionWrapper.prototype = {
     var counters = {};
     for (let [key, res] of stats) {
       // validate stats
       ok(res.id == key, "Coherent stats id");
       var nowish = Date.now() + 1000;        // TODO: clock drift observed
       var minimum = this.whenCreated - 1000; // on Windows XP (Bug 979649)
       if (isWinXP) {
         todo(false, "Can't reliably test rtcp timestamps on WinXP (Bug 979649)");
-      } else if (!twoMachines) {
+
+      } else if (false) { // Bug 1325430 - timestamps aren't working properly in update 49
+	// else if (!twoMachines) {
         // Bug 1225729: On android, sometimes the first RTCP of the first
         // test run gets this value, likely because no RTP has been sent yet.
         if (res.timestamp != 2085978496000) {
           ok(res.timestamp >= minimum,
              "Valid " + (res.isRemote? "rtcp" : "rtp") + " timestamp " +
                  res.timestamp + " >= " + minimum + " (" +
                  (res.timestamp - minimum) + " ms)");
           ok(res.timestamp <= nowish,
@@ -1583,18 +1621,27 @@ PeerConnectionWrapper.prototype = {
             var rem = stats[res.remoteId];
             ok(rem.isRemote, "Remote is rtcp");
             ok(rem.remoteId == res.id, "Remote backlink match");
             if(res.type == "outboundrtp") {
               ok(rem.type == "inboundrtp", "Rtcp is inbound");
               ok(rem.packetsReceived !== undefined, "Rtcp packetsReceived");
               ok(rem.packetsLost !== undefined, "Rtcp packetsLost");
               ok(rem.bytesReceived >= rem.packetsReceived, "Rtcp bytesReceived");
-              if (!this.disableRtpCountChecking) {
-                ok(rem.packetsReceived <= res.packetsSent, "No more than sent packets");
+	       if (false) { // Bug 1325430 if (!this.disableRtpCountChecking) {
+	       // no guarantee which one is newer!
+	       // Note: this must change when we add a timestamp field to remote RTCP reports
+	       // and make rem.timestamp be the reception time
+		if (res.timestamp >= rem.timestamp) {
+                 ok(rem.packetsReceived <= res.packetsSent, "No more than sent packets");
+		 } else {
+                  info("REVERSED timestamps: rec:" +
+		     rem.packetsReceived + " time:" + rem.timestamp + " sent:" + res.packetsSent + " time:" + res.timestamp);
+		 }
+		// Else we may have received more than outdated Rtcp packetsSent
                 ok(rem.bytesReceived <= res.bytesSent, "No more than sent bytes");
               }
               ok(rem.jitter !== undefined, "Rtcp jitter");
               ok(rem.mozRtt !== undefined, "Rtcp rtt");
               ok(rem.mozRtt >= 0, "Rtcp rtt " + rem.mozRtt + " >= 0");
               ok(rem.mozRtt < 60000, "Rtcp rtt " + rem.mozRtt + " < 1 min");
             } else {
               ok(rem.type == "outboundrtp", "Rtcp is outbound");
--- a/dom/media/tests/mochitest/test_peerConnection_captureStream_canvas_2d.html
+++ b/dom/media/tests/mochitest/test_peerConnection_captureStream_canvas_2d.html
@@ -41,16 +41,28 @@ runNetworkTest(() => {
                                  "pcRemote's remote should become green");
     },
     function PC_LOCAL_DRAW_LOCAL_RED() {
       // After requesting a frame it will be captured at the time of next render.
       // Next render will happen at next stable state, at the earliest,
       // i.e., this order of `requestFrame(); draw();` should work.
       stream.requestFrame();
       h.drawColor(canvas, h.red);
+      var i = 0;
+      return setInterval(function() {
+        try {
+          info("draw " + i ? "green" : "red");
+          h.drawColor(canvas, i ? h.green : h.red);
+          i = 1 - i;
+          stream.requestFrame();
+        } catch (e) {
+          // ignore; stream might have shut down, and we don't bother clearing
+          // the setInterval.
+        }
+      }, 500);
     },
     function PC_REMOTE_WAIT_FOR_REMOTE_RED() {
       return h.waitForPixelColor(mediaElement, h.red, 128,
                                  "pcRemote's remote should become red");
     }
   ]);
   test.run();
 });
--- a/dom/media/tests/mochitest/test_peerConnection_captureStream_canvas_webgl.html
+++ b/dom/media/tests/mochitest/test_peerConnection_captureStream_canvas_webgl.html
@@ -47,17 +47,17 @@ runNetworkTest(() => {
 
   test.setMediaConstraints([{video: true}], []);
   test.chain.replace("PC_LOCAL_GUM", [
     function WEBGL_SETUP(test) {
       var program = WebGLUtil.createProgramByIds(gl, 'v-shader', 'f-shader');
 
       if (!program) {
         ok(false, "Program should link");
-        return Promise.reject();
+        return Promise.reject("Program should link");
       }
       gl.useProgram(program);
 
       var uColorLocation = gl.getUniformLocation(program, "uColor");
       h.setFragmentColorLocation(uColorLocation);
 
       var squareBuffer = gl.createBuffer();
       gl.bindBuffer(gl.ARRAY_BUFFER, squareBuffer);
@@ -95,16 +95,26 @@ runNetworkTest(() => {
     function REQUEST_FRAME(test) {
       // After requesting a frame it will be captured at the time of next render.
       // Next render will happen at next stable state, at the earliest,
       // i.e., this order of `requestFrame(); draw();` should work.
       test.pcLocal.canvasStream.requestFrame();
     },
     function DRAW_LOCAL_RED() {
       h.drawColor(canvas, h.red);
+      return setInterval(function() {
+        try {
+          info("draw");
+          h.drawColor(canvas, h.red);
+          test.pcLocal.canvasStream.requestFrame();
+        } catch (e) {
+          // ignore; stream might have shut down, and we don't bother clearing
+          // the setInterval.
+        }
+      }, 500);
     },
     function WAIT_FOR_REMOTE_RED() {
       return h.waitForPixelColor(vremote, h.red, 128,
                                  "pcRemote's remote should become red");
     }
   ]);
   test.run();
 });
--- a/dom/media/tests/mochitest/test_peerConnection_multiple_captureStream_canvas_2d.html
+++ b/dom/media/tests/mochitest/test_peerConnection_multiple_captureStream_canvas_2d.html
@@ -67,25 +67,48 @@ runNetworkTest(() => {
                                      "pcRemote's remote1 should become blue")
                ])
              ]);
     },
     function DRAW_LOCAL1_RED() {
       // After requesting a frame it will be captured at the time of next render.
       // Next render will happen at next stable state, at the earliest,
       // i.e., this order of `requestFrame(); draw();` should work.
+      h.drawColor(canvas1, h.red);
       stream1.requestFrame();
-      h.drawColor(canvas1, h.red);
+      var i = 0;
+      return setInterval(function() {
+        try {
+          info("draw " + i ? "green" : "red");
+          h.drawColor(canvas1, i ? h.green : h.red);
+          i = 1 - i;
+          stream1.requestFrame();
+        } catch (e) {
+          // ignore; stream might have shut down, and we don't bother clearing
+          // the setInterval.
+        }
+      }, 500);
     },
     function DRAW_LOCAL2_RED() {
       // After requesting a frame it will be captured at the time of next render.
       // Next render will happen at next stable state, at the earliest,
       // i.e., this order of `requestFrame(); draw();` should work.
+      h.drawColor(canvas2, h.red);
       stream2.requestFrame();
-      h.drawColor(canvas2, h.red);
+      return setInterval(function() {
+        try {
+          info("draw");
+          h.drawColor(canvas2, i ? h.green : h.red);
+          i = 1 - i;
+          stream2.requestFrame();
+        } catch (e) {
+          // ignore; stream might have shut down, and we don't bother clearing
+          // the setInterval.
+        }
+      }, 500);
     },
     function WAIT_FOR_REMOTE1_RED() {
       return h.waitForPixelColor(vremote1, h.red, 128,
                                  "pcRemote's remote1 should become red");
     },
     function WAIT_FOR_REMOTE2_RED() {
       return h.waitForPixelColor(vremote2, h.red, 128,
                                  "pcRemote's remote2 should become red");
--- a/dom/media/tests/mochitest/test_peerConnection_simulcastOffer.html
+++ b/dom/media/tests/mochitest/test_peerConnection_simulcastOffer.html
@@ -55,17 +55,18 @@
       ]);
 
       test.chain.insertAfter('PC_LOCAL_GET_ANSWER', [
         function PC_LOCAL_ADD_RIDS_TO_ANSWER(test) {
           test._remote_answer.sdp = sdputils.transferSimulcastProperties(
             test.originalOffer.sdp, test._remote_answer.sdp);
           info("Answer with RIDs: " + JSON.stringify(test._remote_answer));
           ok(test._remote_answer.sdp.match(/a=simulcast:/), "Modified answer has simulcast");
-          ok(test._remote_answer.sdp.match(/a=rid:/), "Modified answer has rid");
+          ok(test._remote_answer.sdp.match(/a=rid:foo/), "Modified answer has rid foo");
+          ok(test._remote_answer.sdp.match(/a=rid:bar/), "Modified answer has rid bar");
         }
       ]);
 
       test.chain.insertAfter('PC_REMOTE_WAIT_FOR_MEDIA_FLOW',[
         function PC_REMOTE_SET_RTP_FIRST_RID(test) {
           // Cause pcRemote to filter out everything but the first SSRC. This
           // lets only one of the simulcast streams through.
           selectRecvSsrc(test.pcRemote, 0);
@@ -80,39 +81,27 @@
         },
         function PC_REMOTE_CHECK_SIZE_1() {
           var vlocal = test.pcLocal.localMediaElements[0];
           var vremote = test.pcRemote.remoteMediaElements[0];
           ok(vlocal, "Should have local video element for pcLocal");
           ok(vremote, "Should have remote video element for pcRemote");
           ok(vlocal.videoWidth > 0, "source width is positive");
           ok(vlocal.videoHeight > 0, "source height is positive");
-          is(vremote.videoWidth, vlocal.videoWidth, "sink is same width as source");
-          is(vremote.videoHeight, vlocal.videoHeight, "sink is same height as source");
+          is(vremote.videoWidth, vlocal.videoWidth / 2, "sink is same width as source");
+          is(vremote.videoHeight, vlocal.videoHeight / 2, "sink is same height as source");
         },
         function PC_REMOTE_SET_RTP_SECOND_RID(test) {
           // Now, cause pcRemote to filter out everything but the second SSRC.
           // This lets only the other simulcast stream through.
           selectRecvSsrc(test.pcRemote, 1);
         },
         function PC_REMOTE_WAIT_FOR_SECOND_MEDIA_FLOW(test) {
           return test.pcRemote.waitForMediaFlow();
         },
-        function PC_REMOTE_WAIT_FOR_FRAMES_2() {
-          var vremote = test.pcRemote.remoteMediaElements[0];
-          ok(vremote, "Should have remote video element for pcRemote");
-          return helper.waitForFrames(vremote);
-        },
-        // For some reason, even though we're getting a 25x25 stream, sometimes
-        // the resolution isn't updated on the video element on the first frame.
-        function PC_REMOTE_WAIT_FOR_FRAMES_3() {
-          var vremote = test.pcRemote.remoteMediaElements[0];
-          ok(vremote, "Should have remote video element for pcRemote");
-          return helper.waitForFrames(vremote);
-        },
         function PC_REMOTE_CHECK_SIZE_2() {
           var vlocal = test.pcLocal.localMediaElements[0];
           var vremote = test.pcRemote.remoteMediaElements[0];
           ok(vlocal, "Should have local video element for pcLocal");
           ok(vremote, "Should have remote video element for pcRemote");
           ok(vlocal.videoWidth > 0, "source width is positive");
           ok(vlocal.videoHeight > 0, "source height is positive");
           is(vremote.videoWidth, vlocal.videoWidth / 2, "sink is 1/2 width of source");
--- a/dom/media/tests/mochitest/test_peerConnection_verifyVideoAfterRenegotiation.html
+++ b/dom/media/tests/mochitest/test_peerConnection_verifyVideoAfterRenegotiation.html
@@ -46,16 +46,28 @@ runNetworkTest(() => {
                                  "pcRemote's remote should become green");
     },
     function DRAW_LOCAL_RED() {
       // After requesting a frame it will be captured at the time of next render.
       // Next render will happen at next stable state, at the earliest,
       // i.e., this order of `requestFrame(); draw();` should work.
       stream1.requestFrame();
       h1.drawColor(canvas1, h1.red);
+      var i = 0;
+      return setInterval(function() {
+        try {
+          info("draw " + i ? "green" : "red");
+          h1.drawColor(canvas1, i ? h1.green : h1.red);
+          i = 1 - i;
+          stream1.requestFrame();
+        } catch (e) {
+          // ignore; stream might have shut down, and we don't bother clearing
+          // the setInterval.
+        }
+      }, 500);
     },
     function WAIT_FOR_REMOTE_RED() {
       return h1.waitForPixelColor(vremote1, h1.red, 128,
                                  "pcRemote's remote should become red");
     }
   ]);
 
   addRenegotiation(test.chain,
--- a/dom/media/webrtc/MediaEngineCameraVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineCameraVideoSource.cpp
@@ -392,27 +392,9 @@ MediaEngineCameraVideoSource::GetUUID() 
 
 void
 MediaEngineCameraVideoSource::SetDirectListeners(bool aHasDirectListeners)
 {
   LOG((__FUNCTION__));
   mHasDirectListeners = aHasDirectListeners;
 }
 
-bool operator == (const webrtc::CaptureCapability& a,
-                  const webrtc::CaptureCapability& b)
-{
-  return a.width == b.width &&
-         a.height == b.height &&
-         a.maxFPS == b.maxFPS &&
-         a.rawType == b.rawType &&
-         a.codecType == b.codecType &&
-         a.expectedCaptureDelay == b.expectedCaptureDelay &&
-         a.interlaced == b.interlaced;
-};
-
-bool operator != (const webrtc::CaptureCapability& a,
-                  const webrtc::CaptureCapability& b)
-{
-  return !(a == b);
-}
-
 } // namespace mozilla
--- a/dom/media/webrtc/MediaEngineCameraVideoSource.h
+++ b/dom/media/webrtc/MediaEngineCameraVideoSource.h
@@ -6,25 +6,28 @@
 #define MediaEngineCameraVideoSource_h
 
 #include "MediaEngine.h"
 
 #include "nsDirectoryServiceDefs.h"
 
 // conflicts with #include of scoped_ptr.h
 #undef FF
-#include "webrtc/video_engine/include/vie_capture.h"