Merge m-c to fx-team. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 11 Jul 2014 16:43:23 -0400
changeset 215691 e2cda132334e4339405bf7307acce4ce0b5da412
parent 215690 b1fe950c22890fd97363db5c7b56c41abef09492 (current diff)
parent 215545 84bd8d9f4256c3130c1a8ff4d26fc2215056fd7a (diff)
child 215692 b4c300eceeff7a5cdd3b7907e0e84dcb7e28c51d
push id515
push userraliiev@mozilla.com
push dateMon, 06 Oct 2014 12:51:51 +0000
treeherdermozilla-release@267c7a481bef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone33.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 fx-team. a=merge
content/media/gmp/gmp-api/gmp-video-errors.h
security/manager/ssl/tests/gtest/Makefile.in
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,23 +14,23 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="0d616942c300d9fb142483210f1dda9096c9a9fc">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="2580a49ddeb99f4bdaaae6716ea99c9547cb6d9f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="40cac290f0a3253d31242d7f50b1d2ddd2f47cda"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9ff55cd0aefea23e4c60e5844c155c6ebc2e632b"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="bf9aaf39dd5a6491925a022db167c460f8207d34"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="ee6e7320bb83409ebd4685fbd87a8ae033704182"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="aebf432f334ec0b48eb358569b9dfbfbead48017"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
   <project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/>
   <project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/>
   <project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
   <project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="52a1a862a8bac319652b8f82d9541ba40bfa45ce"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,20 +12,20 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="cc67f31dc638c0b7edba3cf7e3d87cadf0ed52bf">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="2580a49ddeb99f4bdaaae6716ea99c9547cb6d9f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="40cac290f0a3253d31242d7f50b1d2ddd2f47cda"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9ff55cd0aefea23e4c60e5844c155c6ebc2e632b"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="ee6e7320bb83409ebd4685fbd87a8ae033704182"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="aebf432f334ec0b48eb358569b9dfbfbead48017"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="276ce45e78b09c4a4ee643646f691d22804754c1">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="2580a49ddeb99f4bdaaae6716ea99c9547cb6d9f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="40cac290f0a3253d31242d7f50b1d2ddd2f47cda"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9ff55cd0aefea23e4c60e5844c155c6ebc2e632b"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="ee6e7320bb83409ebd4685fbd87a8ae033704182"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="aebf432f334ec0b48eb358569b9dfbfbead48017"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="1950e4760fa14688b83cdbb5acaa1af9f82ef434"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="ac6eb97a37035c09fb5ede0852f0881e9aadf9ad"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="737f591c5f95477148d26602c7be56cbea0cdeb9"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="51da9b1981be481b92a59a826d4d78dc73d0989a"/>
   <project name="device/common" path="device/common" revision="798a3664597e6041985feab9aef42e98d458bc3d"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,23 +14,23 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="0d616942c300d9fb142483210f1dda9096c9a9fc">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="2580a49ddeb99f4bdaaae6716ea99c9547cb6d9f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="40cac290f0a3253d31242d7f50b1d2ddd2f47cda"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9ff55cd0aefea23e4c60e5844c155c6ebc2e632b"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="bf9aaf39dd5a6491925a022db167c460f8207d34"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="ee6e7320bb83409ebd4685fbd87a8ae033704182"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="aebf432f334ec0b48eb358569b9dfbfbead48017"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
   <project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/>
   <project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/>
   <project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
   <project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="52a1a862a8bac319652b8f82d9541ba40bfa45ce"/>
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -12,20 +12,20 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="cc67f31dc638c0b7edba3cf7e3d87cadf0ed52bf">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="2580a49ddeb99f4bdaaae6716ea99c9547cb6d9f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="40cac290f0a3253d31242d7f50b1d2ddd2f47cda"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9ff55cd0aefea23e4c60e5844c155c6ebc2e632b"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="ee6e7320bb83409ebd4685fbd87a8ae033704182"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="aebf432f334ec0b48eb358569b9dfbfbead48017"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="e95b4ce22c825da44d14299e1190ea39a5260bde"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
         "git_revision": "", 
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "ccd8b59df6230fc0eb5d47e9c617e58ddb4673dd", 
+    "revision": "f705a3f96020c7d7aa5ec63bf3417db29e1ab2a2", 
     "repo_path": "/integration/gaia-central"
 }
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -12,22 +12,22 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="0d616942c300d9fb142483210f1dda9096c9a9fc">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="2580a49ddeb99f4bdaaae6716ea99c9547cb6d9f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="40cac290f0a3253d31242d7f50b1d2ddd2f47cda"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9ff55cd0aefea23e4c60e5844c155c6ebc2e632b"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="ee6e7320bb83409ebd4685fbd87a8ae033704182"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="aebf432f334ec0b48eb358569b9dfbfbead48017"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="746bc48f34f5060f90801925dcdd964030c1ab6d"/>
   <project name="platform/development" path="development" revision="2460485184bc8535440bb63876d4e63ec1b4770c"/>
   <project name="device/common" path="device/common" revision="0dcc1e03659db33b77392529466f9eb685cdd3c7"/>
   <project name="device/sample" path="device/sample" revision="68b1cb978a20806176123b959cb05d4fa8adaea4"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="0d616942c300d9fb142483210f1dda9096c9a9fc">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="2580a49ddeb99f4bdaaae6716ea99c9547cb6d9f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="40cac290f0a3253d31242d7f50b1d2ddd2f47cda"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9ff55cd0aefea23e4c60e5844c155c6ebc2e632b"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,20 +12,20 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="cc67f31dc638c0b7edba3cf7e3d87cadf0ed52bf">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="2580a49ddeb99f4bdaaae6716ea99c9547cb6d9f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="40cac290f0a3253d31242d7f50b1d2ddd2f47cda"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9ff55cd0aefea23e4c60e5844c155c6ebc2e632b"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="ee6e7320bb83409ebd4685fbd87a8ae033704182"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="aebf432f334ec0b48eb358569b9dfbfbead48017"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -12,22 +12,22 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="0d616942c300d9fb142483210f1dda9096c9a9fc">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="2580a49ddeb99f4bdaaae6716ea99c9547cb6d9f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="40cac290f0a3253d31242d7f50b1d2ddd2f47cda"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9ff55cd0aefea23e4c60e5844c155c6ebc2e632b"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="ee6e7320bb83409ebd4685fbd87a8ae033704182"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="aebf432f334ec0b48eb358569b9dfbfbead48017"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="e0a9ac010df3afaa47ba107192c05ac8b5516435"/>
   <project name="platform/development" path="development" revision="a384622f5fcb1d2bebb9102591ff7ae91fe8ed2d"/>
   <project name="device/common" path="device/common" revision="7c65ea240157763b8ded6154a17d3c033167afb7"/>
   <project name="device/sample" path="device/sample" revision="c328f3d4409db801628861baa8d279fb8855892f"/>
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,2227 +1,2313 @@
 <?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1404245815000">
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1405034316000">
   <emItems>
       <emItem  blockID="i454" id="sqlmoz@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                                <versionRange  minVersion="0" maxVersion="*" severity="3">
+                                                                <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i58" id="webmaster@buzzzzvideos.info">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
-      <emItem  blockID="i402" id="{99079a25-328f-4bd4-be04-00955acaa0a7}">
-                        <versionRange  minVersion="0.1" maxVersion="4.3.1.00" severity="1">
+      <emItem  blockID="i652" id="garg_sms@yahoo.in">
+                        <versionRange  minVersion="67.9" maxVersion="67.9" severity="3">
                     </versionRange>
-                                <versionRange  minVersion="0" maxVersion="*" severity="1">
-                    </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i71" id="youtube@2youtube.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i404" id="{a9bb9fa0-4122-4c75-bd9a-bc27db3f9155}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i8" id="{B13721C7-F507-4982-B2E5-502A71474FED}">
                         <versionRange  minVersion=" " severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i107" os="WINNT" id="{ABDE892B-13A8-4d1b-88E6-365A6E755758}">
                         <versionRange  minVersion="0" maxVersion="15.0.5" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i88" id="anttoolbar@ant.com">
                         <versionRange  minVersion="2.4.6.4" maxVersion="2.4.6.4" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i484" id="plugin@getwebcake.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
-      <emItem  blockID="i433" id="{c95a4e8e-816d-4655-8c79-d736da1adb6d}">
-                        <versionRange  minVersion="0" maxVersion="*" severity="1">
+      <emItem  blockID="i640" id="jid0-l9BxpNUhx1UUgRfKigWzSfrZqAc@jetpack">
+                        <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i65" id="activity@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i527" id="/^({bfec236d-e122-4102-864f-f5f19d897f5e}|{3f842035-47f4-4f10-846b-6199b07f09b8}|{92ed4bbd-83f2-4c70-bb4e-f8d3716143fe})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i535" id="/^ext@WebexpEnhancedV1alpha[0-9]+\.net$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i105" id="{95ff02bc-ffc6-45f0-a5c8-619b8226a9de}">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i626" id="{20AD702C-661E-4534-8CE9-BA4EC9AD6ECC}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i20" id="{AB2CE124-6272-4b12-94A9-7303C7397BD1}">
                         <versionRange  minVersion="0.1" maxVersion="5.2.0.7164" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i506" id="/^ext@bettersurfplus/">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i400" id="{dd6b651f-dfb9-4142-b0bd-09912ad22674}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i488" id="jid1-4P0kohSJxU1qGg@jetpack">
                         <versionRange  minVersion="1.2.50" maxVersion="1.2.50" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i578" id="jid1-XLjasWL55iEE1Q@jetpack">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
+              </prefs>
+    </emItem>
+      <emItem  blockID="i660" id="youplayer@addons.mozilla.org">
+                        <versionRange  minVersion="79.9.8" maxVersion="208.0.1" severity="3">
+                    </versionRange>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i529" id="/^(torntv@torntv\.com|trtv3@trtv\.com|torntv2@torntv\.com|e2fd07a6-e282-4f2e-8965-85565fcb6384@b69158e6-3c3b-476c-9d98-ae5838c5b707\.com)$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i486" id="xz123@ya456.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i392" id="{EEE6C361-6118-11DC-9C72-001320C79847}">
                         <versionRange  minVersion="0" maxVersion="1.7.999" severity="1">
                     </versionRange>
-                                <versionRange  minVersion="0" maxVersion="*" severity="1">
+                                                                <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i406" id="{bf7380fa-e3b4-4db2-af3e-9d8783a45bfc}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i4" id="{4B3803EA-5230-4DC3-A7FC-33638F3D3542}">
                         <versionRange  minVersion="1.2" maxVersion="1.2">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="3.0a1" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i492" id="{af95cc15-3b9b-45ae-8d9b-98d08eda3111}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i24" id="{6E19037A-12E3-4295-8915-ED48BC341614}">
                         <versionRange  minVersion="0.1" maxVersion="1.3.328.4" severity="1">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="3.7a1pre" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i64" id="royal@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i72" os="WINNT" id="{4ED1F68A-5463-4931-9384-8FFF5ED91D92}">
                         <versionRange  minVersion="3.4.1" maxVersion="3.4.1.194" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i100" id="{394DCBA4-1F92-4f8e-8EC9-8D2CB90CB69B}">
                         <versionRange  minVersion="2.5.0" maxVersion="2.5.0" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i77" id="{fa277cfc-1d75-4949-a1f9-4ac8e41b2dfd}">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i40" id="{28387537-e3f9-4ed7-860c-11e69af4a8a0}">
                         <versionRange  minVersion="0.1" maxVersion="4.3.1.00" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i491" id="{515b2424-5911-40bd-8a2c-bdb20286d8f5}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i498" id="hoverst@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i127" id="plugin@youtubeplayer.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i430" id="1chtw@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i78" id="socialnetworktools@mozilla.doslash.org">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i238" id="/^pink@.*\.info$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="18.0" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i516" id="/^({3f3cddf8-f74d-430c-bd19-d2c9147aed3d}|{515b2424-5911-40bd-8a2c-bdb20286d8f5}|{17464f93-137e-4646-a0c6-0dc13faf0113}|{d1b5aad5-d1ae-4b20-88b1-feeaeb4c1ebc}|{aad50c91-b136-49d9-8b30-0e8d3ead63d0})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i630" id="webbooster@iminent.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
                   <pref>browser.startup.homepage</pref>
                   <pref>browser.search.defaultenginename</pref>
               </prefs>
     </emItem>
       <emItem  blockID="i174" id="info@thebflix.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i478" id="{7e8a1050-cf67-4575-92df-dcc60e7d952d}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i582" id="discoverypro@discoverypro.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i172" id="info@bflix.info">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i93" id="{68b8676b-99a5-46d1-b390-22411d8bcd61}">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i596" id="{b99c8534-7800-48fa-bd71-519a46cdc7e1}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i140" id="mozillahmpg@mozilla.org">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i500" id="{2aab351c-ad56-444c-b935-38bffe18ad26}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i494" id="/^({e9df9360-97f8-4690-afe6-996c80790da4}|{687578b9-7132-4a7a-80e4-30ee31099e03}|{46a3135d-3683-48cf-b94c-82655cbc0e8a}|{49c795c2-604a-4d18-aeb1-b3eba27e5ea2}|{7473b6bd-4691-4744-a82b-7854eb3d70b6}|{96f454ea-9d38-474f-b504-56193e00c1a5})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i467" id="plugin@analytic-s.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i47" id="youtube@youtube2.com">
-                          <prefs>
+                                                          <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i360" id="ytd@mybrowserbar.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i5" id="support@daemon-tools.cc">
                         <versionRange  minVersion=" " maxVersion="1.0.0.5">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i436" id="/(\{7aeae561-714b-45f6-ace3-4a8aed6e227b\})|(\{01e86e69-a2f8-48a0-b068-83869bdba3d0\})|(\{77f5fe49-12e3-4cf5-abb4-d993a0164d9e\})/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i97" id="support3_en@adobe122.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i342" id="lbmsrvfvxcblvpane@lpaezhjez.org">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i481" id="{B40794A0-7477-4335-95C5-8CB9BBC5C4A5}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                                <versionRange  minVersion="0" maxVersion="*" severity="3">
+                                                                <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                                <versionRange  minVersion="0" maxVersion="*" severity="3">
+                                                                <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i11" id="yslow@yahoo-inc.com">
                         <versionRange  minVersion="2.0.5" maxVersion="2.0.5">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="3.5.7" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i62" id="jid0-EcdqvFOgWLKHNJPuqAnawlykCGZ@jetpack">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i624" id="/^({b95faac1-a3d7-4d69-8943-ddd5a487d966}|{ecce0073-a837-45a2-95b9-600420505f7e}|{2713b394-286f-4d7c-89ea-4174eeab9f5a}|{da7a20cf-bef4-4342-ad78-0240fdf87055})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i472" id="linksicle@linksicle.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i99" id="pfzPXmnzQRXX6@2iABkVe.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i66" id="youtubeer@youtuber.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i438" id="{02edb56b-9b33-435b-b7df-b2843273a694}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i450" id="{dff137ae-1ffd-11e3-8277-b8ac6f996f26}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i521" id="/^({66b103a7-d772-4fcd-ace4-16f79a9056e0}|{6926c7f7-6006-42d1-b046-eba1b3010315}|{72cabc40-64b2-46ed-8648-26d831761150}|{73ee2cf2-7b76-4c49-b659-c3d8cf30825d}|{ca6446a5-73d5-4c35-8aa1-c71dc1024a18}|{5373a31d-9410-45e2-b299-4f61428f0be4})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i499" id="{babb9931-ad56-444c-b935-38bffe18ad26}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i356" id="{341f4dac-1966-47ff-aacf-0ce175f1498a}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i101" id="{3a12052a-66ef-49db-8c39-e5b0bd5c83fa}">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i111" os="WINNT" id="{C3949AC2-4B17-43ee-B4F1-D26B9D42404D}">
                         <versionRange  minVersion="0" maxVersion="15.0.5" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i136" id="Adobe@flash.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i543" id="{badea1ae-72ed-4f6a-8c37-4db9a4ac7bc9}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i447" id="{B18B1E5C-4D81-11E1-9C00-AFEB4824019B}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i519" id="703db0db-5fe9-44b6-9f53-c6a91a0ad5bd@7314bc82-969e-4d2a-921b-e5edd0b02cf1.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i537" id="rally_toolbar_ff@bulletmedia.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i526" id="/^({83a8ce1b-683c-4784-b86d-9eb601b59f38}|{ef1feedd-d8da-4930-96f1-0a1a598375c6}|{79ff1aae-701f-4ca5-aea3-74b3eac6f01b}|{8a184644-a171-4b05-bc9a-28d75ffc9505}|{bc09c55d-0375-4dcc-836e-0e3c8addfbda}|{cef81415-2059-4dd5-9829-1aef3cf27f4f})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i532" id="249911bc-d1bd-4d66-8c17-df533609e6d8@c76f3de9-939e-4922-b73c-5d7a3139375d.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i258" id="helperbar@helperbar.com">
                         <versionRange  minVersion="0" maxVersion="1.0" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i98" id="youtubeeing@youtuberie.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i515" id="/^({bf9194c2-b86d-4ebc-9b53-1c08b6ff779e}|{61a83e16-7198-49c6-8874-3e4e8faeb4f3}|{f0af464e-5167-45cf-9cf0-66b396d1918c}|{5d9968c3-101c-4944-ba71-72d77393322d}|{01e86e69-a2f8-48a0-b068-83869bdba3d0})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i549" id="/^firefox@(albrechto|swiftbrowse|springsmart|storimbo|squirrelweb|betterbrowse|lizardlink|rolimno|browsebeyond|clingclang|weblayers|kasimos|higher-aurum|xaven|bomlabio)\.(com?|net|org|info|biz)$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i168" id="flashX@adobe.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i39" id="{c2d64ff7-0ab8-4263-89c9-ea3b0f8f050c}">
                         <versionRange  minVersion="0.1" maxVersion="4.3.1.00" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i42" id="{D19CA586-DD6C-4a0a-96F8-14644F340D60}">
                         <versionRange  minVersion="0.1" maxVersion="14.4.0" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i449" id="gystqfr@ylgga.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i502" id="{df6bb2ec-333b-4267-8c4f-3f27dc8c6e07}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                                <versionRange  minVersion="0" maxVersion="*" severity="3">
+                                                                <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i142" id="{a3a5c777-f583-4fef-9380-ab4add1bc2a8}">
                         <versionRange  minVersion="2.0.3" maxVersion="2.0.3">
                     </versionRange>
-                                <versionRange  minVersion="4.2" maxVersion="4.2" severity="3">
+                                                                <versionRange  minVersion="4.2" maxVersion="4.2" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i306" id="{ADFA33FD-16F5-4355-8504-DF4D664CFE10}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
-      <emItem  blockID="i632" id="jid1-4vUehhSALFNqCw@jetpack">
+      <emItem  blockID="i634" id="jid1-4vUehhSALFNqCw@jetpack">
                         <versionRange  minVersion="100.7" maxVersion="100.7" severity="3">
                     </versionRange>
-                    <prefs>
+                                                                <versionRange  minVersion="99.7" maxVersion="99.7" severity="3">
+                    </versionRange>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i63" id="youtube@youtuber.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i398" id="{377e5d4d-77e5-476a-8716-7e70a9272da0}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i18" id="msntoolbar@msn.com">
                         <versionRange  minVersion=" " maxVersion="6.*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i358" id="lfind@nijadsoft.net">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i628" id="ffxtlbr@iminent.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
                   <pref>browser.startup.homepage</pref>
                   <pref>browser.search.defaultenginename</pref>
               </prefs>
     </emItem>
       <emItem  blockID="i228" id="crossriderapp5060@crossrider.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i465" id="trtv3@trtv.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i554" id="lightningnewtab@gmail.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i550" id="colmer@yopmail.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i618" id="toolbar@ask.com">
                         <versionRange  minVersion="3.15.5" maxVersion="3.15.5.*" severity="1">
                     </versionRange>
-                                <versionRange  minVersion="3.15.8" maxVersion="3.15.8.*" severity="1">
+                                                                <versionRange  minVersion="3.15.8" maxVersion="3.15.8.*" severity="1">
                     </versionRange>
-                                <versionRange  minVersion="3.15.10" maxVersion="3.15.11.*" severity="1">
+                                                                <versionRange  minVersion="3.15.10" maxVersion="3.15.11.*" severity="1">
                     </versionRange>
-                                <versionRange  minVersion="3.15.13" maxVersion="3.15.13.*" severity="1">
+                                                                <versionRange  minVersion="3.15.13" maxVersion="3.15.13.*" severity="1">
                     </versionRange>
-                                <versionRange  minVersion="3.15.18" maxVersion="3.15.20.*" severity="1">
+                                                                <versionRange  minVersion="3.15.18" maxVersion="3.15.20.*" severity="1">
                     </versionRange>
-                                <versionRange  minVersion="3.15.22" maxVersion="3.15.22.*" severity="1">
+                                                                <versionRange  minVersion="3.15.22" maxVersion="3.15.22.*" severity="1">
                     </versionRange>
-                                <versionRange  minVersion="3.15.24" maxVersion="3.15.24.*" severity="1">
+                                                                <versionRange  minVersion="3.15.24" maxVersion="3.15.24.*" severity="1">
                     </versionRange>
-                                <versionRange  minVersion="3.15.26" maxVersion="3.15.26.*" severity="1">
+                                                                <versionRange  minVersion="3.15.26" maxVersion="3.15.26.*" severity="1">
                     </versionRange>
-                                <versionRange  minVersion="3.15.28" maxVersion="3.15.28.*" severity="1">
+                                                                <versionRange  minVersion="3.15.28" maxVersion="3.15.28.*" severity="1">
                     </versionRange>
-                                <versionRange  minVersion="3.15.31" maxVersion="3.15.31.*" severity="1">
+                                                                <versionRange  minVersion="3.15.31" maxVersion="3.15.31.*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i75" os="Darwin,Linux" id="firebug@software.joehewitt.com">
                         <versionRange  minVersion="1.9.0" maxVersion="1.9.0" severity="1">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="9.0a1" maxVersion="9.*" />
                           </targetApplication>
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i514" id="/^(67314b39-24e6-4f05-99f3-3f88c7cddd17@6c5fa560-13a3-4d42-8e90-53d9930111f9\.com|ffxtlbr@visualbee\.com|{7aeae561-714b-45f6-ace3-4a8aed6e227b}|{7093ee04-f2e4-4637-a667-0f730797b3a0}|{53c4024f-5a2e-4f2a-b33e-e8784d730938})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i348" id="{13c9f1f9-2322-4d5c-81df-6d4bf8476ba4}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i338" id="{1FD91A9C-410C-4090-BBCC-55D3450EF433}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i364" id="{FE1DEEEA-DB6D-44b8-83F0-34FC0F9D1052}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i59" id="ghostviewer@youtube2.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i222" id="dealcabby@jetpack">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i51" id="admin@youtubeplayer.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
+              </prefs>
+    </emItem>
+      <emItem  blockID="i433" id="{c95a4e8e-816d-4655-8c79-d736da1adb6d}">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
+                    </versionRange>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i352" id="vpyekkifgv@vpyekkifgv.org">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i466" id="afext@anchorfree.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
+              </prefs>
+    </emItem>
+      <emItem  blockID="i650" id="jid1-qj0w91o64N7Eeg@jetpack">
+                        <versionRange  minVersion="39.5.1" maxVersion="47.0.4" severity="3">
+                    </versionRange>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i468" id="05dd836e-2cbd-4204-9ff3-2f8a8665967d@a8876730-fb0c-4057-a2fc-f9c09d438e81.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i522" id="/^({976cd962-e0ca-4337-aea7-d93fae63a79c}|{525ba996-1ce4-4677-91c5-9fc4ead2d245}|{91659dab-9117-42d1-a09f-13ec28037717}|{c1211069-1163-4ba8-b8b3-32fc724766be})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
+              </prefs>
+    </emItem>
+      <emItem  blockID="i642" id="{bee6eb20-01e0-ebd1-da83-080329fb9a3a}">
+                        <versionRange  minVersion="40.10.1" maxVersion="44.10.1" severity="3">
+                    </versionRange>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i479" id="mbrsepone@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
-      <emItem  blockID="i620" id="{21EAF666-26B3-4A3C-ABD0-CA2F5A326744}">
-                        <versionRange  minVersion="0" maxVersion="*" severity="3">
+      <emItem  blockID="i666" id="wecarereminder@bryan">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
+              </prefs>
+    </emItem>
+      <emItem  blockID="i646" id="{e1aaa9f8-4500-47f1-9a0a-b02bd60e4076}">
+                        <versionRange  minVersion="178.7.0" maxVersion="178.7.0" severity="3">
+                    </versionRange>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i552" id="jid0-O6MIff3eO5dIGf5Tcv8RsJDKxrs@jetpack">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i256" id="/^[0-9a-f]+@[0-9a-f]+\.info/">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i584" id="{52b0f3db-f988-4788-b9dc-861d016f4487}">
                         <versionRange  minVersion="0" maxVersion="0.1.9999999" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i370" id="happylyrics@hpyproductions.net">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i440" id="{2d069a16-fca1-4e81-81ea-5d5086dcbd0c}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i396" id="/@(ft|putlocker|clickmovie|m2k|sharerepo|smarter-?)downloader\.com$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i22" id="ShopperReports@ShopperReports.com">
                         <versionRange  minVersion="3.1.22.0" maxVersion="3.1.22.0">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i376" id="{9e09ac65-43c0-4b9d-970f-11e2e9616c55}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i44" id="sigma@labs.mozilla">
-                          <prefs>
+                                                          <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i501" id="xivars@aol.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i482" id="brasilescapeeight@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i226" id="{462be121-2b54-4218-bf00-b9bf8135b23f}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i246" id="support@vide1flash2.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i48" id="admin@youtubespeedup.com">
-                          <prefs>
+                                                          <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i218" id="ffxtlbr@claro.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i10" id="{8CE11043-9A15-4207-A565-0C94C42D590D}">
-                          <prefs>
+                                                          <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i548" id="/^firefox@(jumpflip|webconnect|browsesmart|mybuzzsearch|outobox|greygray|lemurleap|divapton|secretsauce|batbrowse|whilokii|linkswift|qualitink|browsefox|kozaka|diamondata|glindorus|saltarsmart|bizzybolt|websparkle)\.(com?|net|org|info|biz)$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i79" id="GifBlock@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i69" id="{977f3b97-5461-4346-92c8-a14c749b77c9}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i17" id="{3252b9ae-c69a-4eaf-9502-dc9c1f6c009e}">
                         <versionRange  minVersion="2.2" maxVersion="2.2">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i115" id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i477" id="mbrnovone@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i13" id="{E8E88AB0-7182-11DF-904E-6045E0D72085}">
-                          <prefs>
+                                                          <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i446" id="{E90FA778-C2B7-41D0-9FA9-3FEC1CA54D66}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i562" id="iobitapps@mybrowserbar.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i507" id="4zffxtbr-bs@VideoDownloadConverter_4z.com">
                         <versionRange  minVersion="0" maxVersion="5.75.3.25126" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i7" id="{2224e955-00e9-4613-a844-ce69fccaae91}">
-                          <prefs>
+                                                          <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i525" id="/^({65f9f6b7-2dae-46fc-bfaf-f88e4af1beca}|{9ed31f84-c8b3-4926-b950-dff74047ff79}|{0134af61-7a0c-4649-aeca-90d776060cb3}|{02edb56b-9b33-435b-b7df-b2843273a694}|{da51d4f6-3e7e-4ef8-b400-9198e0874606}|{b24577db-155e-4077-bb37-3fdd3c302bb5})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i485" id="/^brasilescape.*\@facebook\.com$//">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i52" id="ff-ext@youtube">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
+              </prefs>
+    </emItem>
+      <emItem  blockID="i644" id="youtubeunblocker@unblocker.yt">
+                        <versionRange  minVersion="43.4.1" maxVersion="77.5.1" severity="3">
+                    </versionRange>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i38" id="{B7082FAA-CB62-4872-9106-E42DD88EDE45}">
                         <versionRange  minVersion="0.1" maxVersion="3.3.0.*">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="3.7a1" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
-                                <versionRange  minVersion="3.3.1" maxVersion="*">
+                                                                <versionRange  minVersion="3.3.1" maxVersion="*">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="5.0a1" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i471" id="firefox@luckyleap.net">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i495" id="kallow@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i483" id="brasilescapefive@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i442" id="pennerdu@faceobooks.ws">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i43" id="supportaccessplugin@gmail.com">
-                          <prefs>
+                                                          <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i588" id="quick_start@gmail.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i340" id="chiang@programmer.net">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
+              </prefs>
+    </emItem>
+      <emItem  blockID="i664" id="123456789@offeringmedia.com">
+                        <versionRange  minVersion="0" maxVersion="*" severity="3">
+                    </versionRange>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i54" id="applebeegifts@mozilla.doslash.org">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i16" id="{27182e60-b5f3-411c-b545-b44205977502}">
                         <versionRange  minVersion="1.0" maxVersion="1.0">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i504" id="aytac@abc.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i92" id="play5@vide04flash.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i117" id="{ce7e73df-6a44-4028-8079-5927a588c948}">
                         <versionRange  minVersion="0" maxVersion="1.0.8" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i474" id="{906000a4-88d9-4d52-b209-7a772970d91f}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i453" id="/^brasilescape.*\@facebook\.com$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
+              </prefs>
+    </emItem>
+      <emItem  blockID="i658" id="low_quality_flash@pie2k.com">
+                        <versionRange  minVersion="46.2" maxVersion="47.1" severity="3">
+                    </versionRange>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i109" id="{392e123b-b691-4a5e-b52f-c4c1027e749c}">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i598" id="{29b136c9-938d-4d3d-8df8-d649d9b74d02}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i286" id="{58bd07eb-0ee0-4df0-8121-dc9b693373df}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i1" id="mozilla_cc@internetdownloadmanager.com">
                         <versionRange  minVersion="2.1" maxVersion="3.3">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="3.0a1" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
-                                <versionRange  minVersion=" " maxVersion="6.9.8">
+                                                                <versionRange  minVersion=" " maxVersion="6.9.8">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="3.7a1pre" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i308" id="9518042e-7ad6-4dac-b377-056e28d00c8f@f1cc0a13-4df1-4d66-938f-088db8838882.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i560" id="adsremoval@adsremoval.net">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i461" id="{8E9E3331-D360-4f87-8803-52DE43566502}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i542" id="/^({bf67a47c-ea97-4caf-a5e3-feeba5331231}|{24a0cfe1-f479-4b19-b627-a96bf1ea3a56})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i493" id="12x3q@3244516.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i344" id="lrcsTube@hansanddeta.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i536" id="{25D77636-38B1-1260-887C-2D4AFA92D6A4}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i426" id="addlyrics@addlyrics.net">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i448" id="{0134af61-7a0c-4649-aeca-90d776060cb3}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i83" id="flash@adobee.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i104" id="yasd@youasdr3.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i530" id="{739df940-c5ee-4bab-9d7e-270894ae687a}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i524" id="/^({4e988b08-8c51-45c1-8d74-73e0c8724579}|{93ec97bf-fe43-4bca-a735-5c5d6a0a40c4}|{aed63b38-7428-4003-a052-ca6834d8bad3}|{0b5130a9-cc50-4ced-99d5-cda8cc12ae48}|{C4CFC0DE-134F-4466-B2A2-FF7C59A8BFAD})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i68" id="flashupdate@adobe.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i382" id="{6926c7f7-6006-42d1-b046-eba1b3010315}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i432" id="lugcla21@gmail.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i91" id="crossriderapp4926@crossrider.com">
                         <versionRange  minVersion="0" maxVersion="0.81.43" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i480" id="pluggets@gmail.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                                <versionRange  minVersion="0" maxVersion="*" severity="1">
+                                                                <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i570" id="jid1-vW9nopuIAJiRHw@jetpack">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i520" id="/^({7316e43a-3ebd-4bb4-95c1-9caf6756c97f}|{0cc09160-108c-4759-bab1-5c12c216e005}|{ef03e721-f564-4333-a331-d4062cee6f2b}|{465fcfbb-47a4-4866-a5d5-d12f9a77da00}|{7557724b-30a9-42a4-98eb-77fcb0fd1be3}|{b7c7d4b0-7a84-4b73-a7ef-48ef59a52c3b})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i460" id="{845cab51-d8d2-472f-8bd9-2b44642d97c2}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i547" id="{87934c42-161d-45bc-8cef-ef18abe2a30c}">
                         <versionRange  minVersion="0" maxVersion="3.7.9999999999" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i6" id="{3f963a5b-e555-4543-90e2-c3908898db71}">
                         <versionRange  minVersion=" " maxVersion="8.5">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i56" id="flash@adobe.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i538" id="{354dbb0a-71d5-4e9f-9c02-6c88b9d387ba}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i451" id="{e44a1809-4d10-4ab8-b343-3326b64c7cdd}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i540" id="/^(ffxtlbr@mixidj\.com|{c0c2693d-2ee8-47b4-9df7-b67a0ee31988}|{67097627-fd8e-4f6b-af4b-ecb65e50112e}|{f6f0f973-a4a3-48cf-9a7a-b7a69c30d71a}|{a3d0e35f-f1da-4ccb-ae77-e9d27777e68d}|{1122b43d-30ee-403f-9bfa-3cc99b0caddd})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i216" id="fdm_ffext@freedownloadmanager.org">
                         <versionRange  minVersion="1.0" maxVersion="1.3.1">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="3.0a1" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
-                                <versionRange  minVersion="1.5.7.5" maxVersion="1.5.7.5" severity="1">
+                                                                <versionRange  minVersion="1.5.7.5" maxVersion="1.5.7.5" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i566" id="{77BEC163-D389-42c1-91A4-C758846296A5}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i533" id="extension@Fast_Free_Converter.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i362" id="addon@defaulttab.com">
                         <versionRange  minVersion="0" maxVersion="1.4.4" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i12" id="masterfiler@gmail.com">
                         <versionRange  severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i576" id="newmoz@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i444" id="fplayer@adobe.flash">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i334" id="{0F827075-B026-42F3-885D-98981EE7B1AE}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i622" id="/^({ebd898f8-fcf6-4694-bc3b-eabc7271eeb1}|{46008e0d-47ac-4daa-a02a-5eb69044431a}|{213c8ed6-1d78-4d8f-8729-25006aa86a76}|{fa23121f-ee7c-4bd8-8c06-123d087282c5}|{19803860-b306-423c-bbb5-f60a7d82cde5})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i518" id="/^({d6e79525-4524-4707-9b97-1d70df8e7e59}|{ddb4644d-1a37-4e6d-8b6e-8e35e2a8ea6c}|{e55007f4-80c5-418e-ac33-10c4d60db01e}|{e77d8ca6-3a60-4ae9-8461-53b22fa3125b}|{e89a62b7-248e-492f-9715-43bf8c507a2f}|{5ce3e0cb-aa83-45cb-a7da-a2684f05b8f3})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i196" id="info@wxdownloadmanager.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i424" id="{C7AE725D-FA5C-4027-BB4C-787EF9F8248A}">
                         <versionRange  minVersion="0" maxVersion="1.0.0.2" severity="1">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="23.0a1" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i336" id="CortonExt@ext.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i103" id="kdrgun@gmail.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i539" id="ScorpionSaver@jetpack">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i3" id="langpack-vi-VN@firefox.mozilla.org">
                         <versionRange  minVersion="2.0" maxVersion="2.0">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i326" id="/^((support2_en@adobe14\.com)|(XN4Xgjw7n4@yUWgc\.com)|(C7yFVpIP@WeolS3acxgS\.com)|(Kbeu4h0z@yNb7QAz7jrYKiiTQ3\.com)|(aWQzX@a6z4gWdPu8FF\.com)|(CBSoqAJLYpCbjTP90@JoV0VMywCjsm75Y0toAd\.com)|(zZ2jWZ1H22Jb5NdELHS@o0jQVWZkY1gx1\.com))$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i470" id="extension@FastFreeConverter.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i162" id="{EB7508CA-C7B2-46E0-8C04-3E94A035BD49}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
+              </prefs>
+    </emItem>
+      <emItem  blockID="i620" id="{21EAF666-26B3-4A3C-ABD0-CA2F5A326744}">
+                        <versionRange  minVersion="0" maxVersion="*" severity="3">
+                    </versionRange>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i354" id="{c0c2693d-2ee8-47b4-9df7-b67a0ee31988}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i106" os="WINNT" id="{97E22097-9A2F-45b1-8DAF-36AD648C7EF4}">
                         <versionRange  minVersion="0" maxVersion="15.0.5" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i46" id="{841468a1-d7f4-4bd3-84e6-bb0f13a06c64}">
                         <versionRange  minVersion="0.1" maxVersion="*">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="9.0a1" maxVersion="9.0" />
                           </targetApplication>
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i505" id="extacylife@a.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i15" id="personas@christopher.beard">
                         <versionRange  minVersion="1.6" maxVersion="1.6">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="3.6" maxVersion="3.6.*" />
                           </targetApplication>
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i304" id="{f0e59437-6148-4a98-b0a6-60d557ef57f4}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i86" id="{45147e67-4020-47e2-8f7a-55464fb535aa}">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i586" id="jid1-0xtMKhXFEs4jIg@jetpack">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i318" id="ffxtlbr@incredibar.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
                         <versionRange  minVersion="1.1b1" maxVersion="1.1b1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i531" id="/^(4cb61367-efbf-4aa1-8e3a-7f776c9d5763@cdece6e9-b2ef-40a9-b178-291da9870c59\.com|0efc9c38-1ec7-49ed-8915-53a48b6b7600@e7f17679-2a42-4659-83c5-7ba961fdf75a\.com|6be3335b-ef79-4b0b-a0ba-b87afbc6f4ad@6bbb4d2e-e33e-4fa5-9b37-934f4fb50182\.com)$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i490" id="now.msn.com@services.mozilla.org">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i523" id="/^({7e8a1050-cf67-4575-92df-dcc60e7d952d}|{b3420a9c-a397-4409-b90d-bcf22da1a08a}|{eca6641f-2176-42ba-bdbe-f3e327f8e0af}|{707dca12-3f99-4d94-afea-06dcc0ae0108}|{aea20431-87fc-40be-bc5b-18066fe2819c}|{30ee6676-1ba6-455a-a7e8-298fa863a546})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i312" id="extension21804@extension21804.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i545" id="superlrcs@svenyor.net">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i324" id="/^((34qEOefiyYtRJT@IM5Munavn\.com)|(Mro5Fm1Qgrmq7B@ByrE69VQfZvZdeg\.com)|(KtoY3KGxrCe5ie@yITPUzbBtsHWeCdPmGe\.com)|(9NgIdLK5Dq4ZMwmRo6zk@FNt2GCCLGyUuOD\.com)|(NNux7bWWW@RBWyXdnl6VGls3WAwi\.com)|(E3wI2n@PEHTuuNVu\.com)|(2d3VuWrG6JHBXbQdbr@3BmSnQL\.com))$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i503" id="{9CE11043-9A15-4207-A565-0C94C42D590D}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i431" id="chinaescapeone@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i108" id="{28bfb930-7620-11e1-b0c4-0800200c9a66}">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
+              </prefs>
+    </emItem>
+      <emItem  blockID="i656" id="hdv@vovcacik.addons.mozilla.org">
+                        <versionRange  minVersion="102.0" maxVersion="102.0" severity="3">
+                    </versionRange>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i262" id="{167d9323-f7cc-48f5-948a-6f012831a69f}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i320" id="torntv@torntv.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i528" id="008abed2-b43a-46c9-9a5b-a771c87b82da@1ad61d53-2bdc-4484-a26b-b888ecae1906.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i469" id="OKitSpace@OKitSpace.es">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i564" id="/^(firefox@vebergreat\.net|EFGLQA@78ETGYN-0W7FN789T87\.COM)$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i167" id="{b64982b1-d112-42b5-b1e4-d3867c4533f8}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i84" id="pink@rosaplugin.info">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
+              </prefs>
+    </emItem>
+      <emItem  blockID="i654" id="{7b1bf0b6-a1b9-42b0-b75d-252036438bdc}">
+                        <versionRange  minVersion="27.8" maxVersion="27.9" severity="3">
+                    </versionRange>
+                                                                <versionRange  minVersion="27.8" maxVersion="27.9" severity="3">
+                    </versionRange>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i568" os="Darwin" id="thunder@xunlei.com">
                         <versionRange  minVersion="0" maxVersion="2.0.6" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i439" id="{d2cf9842-af95-48cd-b873-bfbb48cd7f5e}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i346" id="{a6e67e6f-8615-4fe0-a599-34a73fc3fba5}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i220" id="pricepeep@getpricepeep.com">
                         <versionRange  minVersion="0" maxVersion="2.1.0.19.99" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i590" id="{94cd2cc3-083f-49ba-a218-4cda4b4829fd}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i544" id="/^(93abedcf-8e3a-4d02-b761-d1441e437c09@243f129d-aee2-42c2-bcd1-48858e1c22fd\.com|9acfc440-ac2d-417a-a64c-f6f14653b712@09f9a966-9258-4b12-af32-da29bdcc28c5\.com|58ad0086-1cfb-48bb-8ad2-33a8905572bc@5715d2be-69b9-4930-8f7e-64bdeb961cfd\.com)$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i224" id="{336D0C35-8A85-403a-B9D2-65C292C39087}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i61" id="youtube@youtube3.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                                <versionRange  minVersion="0" maxVersion="*">
+                                                                <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i517" id="/^({16e193c8-1706-40bf-b6f3-91403a9a22be}|{284fed43-2e13-4afe-8aeb-50827d510e20}|{5e3cc5d8-ed11-4bed-bc47-35b4c4bc1033}|{7429e64a-1fd4-4112-a186-2b5630816b91}|{8c9980d7-0f09-4459-9197-99b3e559660c}|{8f1d9545-0bb9-4583-bb3c-5e1ac1e2920c})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i509" id="contato@facefollow.net">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i372" id="5nc3QHFgcb@r06Ws9gvNNVRfH.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i496" id="{ACAA314B-EEBA-48e4-AD47-84E31C44796C}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i67" id="youtube2@youtube2.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i476" id="mbroctone@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i70" id="psid-vhvxQHMZBOzUZA@jetpack">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i473" id="{81b13b5d-fba1-49fd-9a6b-189483ac548a}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i437" id="{4933189D-C7F7-4C6E-834B-A29F087BFD23}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i394" id="{7D4F1959-3F72-49d5-8E59-F02F8AA6815D}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
+              </prefs>
+    </emItem>
+      <emItem  blockID="i402" id="{99079a25-328f-4bd4-be04-00955acaa0a7}">
+                        <versionRange  minVersion="0.1" maxVersion="4.3.1.00" severity="1">
+                    </versionRange>
+                                                                <versionRange  minVersion="0" maxVersion="*" severity="1">
+                    </versionRange>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i165" id="{EEF73632-A085-4fd3-A778-ECD82C8CB297}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i60" id="youtb3@youtb3.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
+              </prefs>
+    </emItem>
+      <emItem  blockID="i662" id="imbaty@taringamp3.com">
+                        <versionRange  minVersion="0" maxVersion="*" severity="3">
+                    </versionRange>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i546" id="firefox@browsefox.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i510" id="{3c9a72a0-b849-40f3-8c84-219109c27554}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i23" id="firefox@bandoo.com">
                         <versionRange  minVersion="5.0" maxVersion="5.0" severity="1">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="3.7a1pre" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i55" id="youtube@youtube7.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i434" id="afurladvisor@anchorfree.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i90" id="videoplugin@player.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i489" id="astrovia@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i497" id="{872b5b88-9db5-4310-bdd0-ac189557e5f5}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i580" id="{51c77233-c0ad-4220-8388-47c11c18b355}">
                         <versionRange  minVersion="0" maxVersion="0.1.9999999" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i541" id="/^({988919ff-0cd8-4d0c-bc7e-60d55a49eb64}|{494b9726-9084-415c-a499-68c07e187244}|{55b95864-3251-45e9-bb30-1a82589aaff1}|{eef3855c-fc2d-41e6-8d91-d368f51b3055}|{90a1b331-c2b4-4933-9f63-ba7b84d60d58}|{d2cf9842-af95-48cd-b873-bfbb48cd7f5e})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i76" id="crossriderapp3924@crossrider.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
-      <emItem  blockID="i445" id="firefoxaddon@youtubeenhancer.com">
+      <emItem  blockID="i648" id="firefoxaddon@youtubeenhancer.com">
                         <versionRange  minVersion="208.7.0" maxVersion="208.7.0" severity="3">
                     </versionRange>
-                    <prefs>
+                                                                <versionRange  minVersion="199.7.0" maxVersion="199.7.0" severity="3">
+                    </versionRange>
+                                                                <versionRange  minVersion="199.7.0" maxVersion="208.7.0" severity="3">
+                    </versionRange>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i441" id="{49c53dce-afa0-49a1-a08b-2eb8e8444128}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i508" id="advance@windowsclient.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i282" id="{33e0daa6-3af3-d8b5-6752-10e949c61516}">
                         <versionRange  minVersion="0" maxVersion="1.1.999" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i452" id="{77beece6-3997-403a-92fa-0055bfcf88e5}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i45" id="{22119944-ED35-4ab1-910B-E619EA06A115}">
                         <versionRange  minVersion="0.1" maxVersion="7.6.1">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="8.0a1" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i82" id="{8f42fb8b-b6f6-45de-81c0-d6d39f54f971}">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i380" id="{cc8f597b-0765-404e-a575-82aefbd81daf}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i322" id="jid0-Y6TVIzs0r7r4xkOogmJPNAGFGBw@jetpack">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i378" id="{a7aae4f0-bc2e-a0dd-fb8d-68ce32c9261f}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i73" id="a1g0a9g219d@a1.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i96" id="youtubeee@youtuber3.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i163" id="info@allpremiumplay.info">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i455" id="7d51fb17-b199-4d8f-894e-decaff4fc36a@a298838b-7f50-4c7c-9277-df6abbd42a0c.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i374" id="update@firefox.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i314" id="crossriderapp8812@crossrider.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
-                    <prefs>
+                                                    <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i21" id="support@update-firefox.com">
-                          <prefs>
+                                                          <prefs>
               </prefs>
     </emItem>
     </emItems>
 
   <pluginItems>
       <pluginItem  blockID="p26">
       <match name="name" exp="^Yahoo Application State Plugin$" />      <match name="description" exp="^Yahoo Application State Plugin$" />      <match name="filename" exp="npYState.dll" />                                    <versionRange >
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="3.0a1" maxVersion="3.*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p27">
       <match name="name" exp="QuickTime Plug-in 7[.]1[.]" />            <match name="filename" exp="npqtplugin.?[.]dll" />                                    <versionRange >
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="3.0a1" maxVersion="3.*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p28">
-                  <match name="filename" exp="NPFFAddOn.dll" />          </pluginItem>
+                  <match name="filename" exp="NPFFAddOn.dll" />                </pluginItem>
       <pluginItem  blockID="p31">
-                  <match name="filename" exp="NPMySrch.dll" />          </pluginItem>
+                  <match name="filename" exp="NPMySrch.dll" />                </pluginItem>
       <pluginItem  blockID="p32">
                   <match name="filename" exp="npViewpoint.dll" />                                    <versionRange >
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="3.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p33">
       <match name="name" exp="[0-6]\.0\.[01]\d{2}\.\d+" />            <match name="filename" exp="npdeploytk.dll" />                      <versionRange  severity="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p34">
                   <match name="filename" exp="[Nn][Pp][Jj][Pp][Ii]1[56]0_[0-9]+\.[Dd][Ll][Ll]" />                                    <versionRange >
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="3.6a1pre" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p80">
       <match name="name" exp="\(TM\)" />      <match name="description" exp="[^\d\._]((0(\.\d+(\.\d+([_\.]\d+)?)?)?)|(1\.(([0-5](\.\d+([_\.]\d+)?)?)|(6(\.0([_\.](0?\d|1\d|2\d|30))?)?)|(7(\.0([_\.][0-2])?)?))))([^\d\._]|$)" />      <match name="filename" exp="(npjp2\.dll)|(libnpjp2\.so)" />                      <versionRange  severity="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p85">
                   <match name="filename" exp="JavaPlugin2_NPAPI\.plugin" />                      <versionRange  minVersion="0" maxVersion="13.6.0" severity="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  os="Darwin" blockID="p89">
                   <match name="filename" exp="AdobePDFViewerNPAPI\.plugin" />                      <versionRange  minVersion="0" maxVersion="10.1.3" severity="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p94">
                   <match name="filename" exp="Flash\ Player\.plugin" />                                    <versionRange  minVersion="0" maxVersion="10.2.159.1" severity="0">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="0.1" maxVersion="17.0.1" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p102">
                   <match name="filename" exp="npmozax\.dll" />                      <versionRange  minVersion="0" maxVersion="*"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p113">
                   <match name="filename" exp="npuplaypc\.dll" />                      <versionRange  minVersion="0" maxVersion="1.0.0.0" severity="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p119">
       <match name="name" exp="Java\(TM\) Plug-in 1\.(6\.0_(\d|[0-2]\d?|3[0-2])|7\.0(_0?([1-4]))?)([^\d\._]|$)" />            <match name="filename" exp="libnpjp2\.so" />                                    <versionRange  severity="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="0.1" maxVersion="17.*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p123">
                   <match name="filename" exp="JavaPlugin2_NPAPI\.plugin" />                                    <versionRange  minVersion="0" maxVersion="14.2.0" severity="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="0.1" maxVersion="17.*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p125">
       <match name="name" exp="Java\(TM\) Platform SE ((6( U(\d|([0-2]\d)|3[0-2]))?)|(7(\sU[0-4])?))(\s[^\d\._U]|$)" />            <match name="filename" exp="npjp2\.dll" />                                    <versionRange  severity="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="0.1" maxVersion="17.*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p129">
                   <match name="filename" exp="Silverlight\.plugin" />                      <versionRange  minVersion="0" maxVersion="5.0.99999" severity="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p132">
       <match name="name" exp="Java\(TM\) Plug-in 1\.7\.0(_0?([5-6]))?([^\d\._]|$)" />            <match name="filename" exp="libnpjp2\.so" />                                    <versionRange  severity="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="0.1" maxVersion="17.*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p134">
       <match name="name" exp="Java\(TM\) Platform SE 7 U[5-6](\s[^\d\._U]|$)" />            <match name="filename" exp="npjp2\.dll" />                                    <versionRange  severity="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="0.1" maxVersion="17.*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p138">
                   <match name="filename" exp="JavaAppletPlugin\.plugin" />                                    <versionRange  minVersion="Java 7 Update 01" maxVersion="Java 7 Update 06" severity="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="0.1" maxVersion="17.*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p152">
                   <match name="filename" exp="npctrl\.dll" />                      <versionRange  minVersion="0" maxVersion="4.1.10328.0" severity="0" vulnerabilitystatus="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p154">
                   <match name="filename" exp="npctrl\.dll" />                      <versionRange  minVersion="5.0" maxVersion="5.1.20124.9999" severity="0" vulnerabilitystatus="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p156">
                   <match name="filename" exp="nppdf32\.dll" />                      <versionRange  minVersion="0" maxVersion="9.5.1" severity="0" vulnerabilitystatus="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p158">
                   <match name="filename" exp="nppdf32\.dll" />                      <versionRange  minVersion="10.0" maxVersion="10.1.5.9999" severity="0" vulnerabilitystatus="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p160">
                   <match name="filename" exp="NPSWF32\.dll" />                                    <versionRange  minVersion="0" maxVersion="10.2.9999" severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="4.0" maxVersion="16.*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p176">
                   <match name="filename" exp="(NPSWF32\.dll)|(Flash\ Player\.plugin)" />                                    <versionRange  minVersion="10.3" maxVersion="10.3.183.18.999" severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="19.0a1" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p176">
                   <match name="filename" exp="(NPSWF32\.dll)|(Flash\ Player\.plugin)" />                                    <versionRange  minVersion="10.3" maxVersion="10.3.183.18.999" severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0.4" maxVersion="17.0.*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p178">
                   <match name="filename" exp="(NPSWF[0-9_]*\.dll)|(Flash\ Player\.plugin)" />                                    <versionRange  minVersion="11.0" maxVersion="11.7.700.169" severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="19.0a1" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p178">
                   <match name="filename" exp="(NPSWF[0-9_]*\.dll)|(Flash\ Player\.plugin)" />                                    <versionRange  minVersion="11.0" maxVersion="11.7.700.169" severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0.4" maxVersion="17.0.*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p180">
                   <match name="filename" exp="JavaAppletPlugin\.plugin" />                                    <versionRange  minVersion="Java 7 Update 0" maxVersion="Java 7 Update 11" severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p182">
       <match name="name" exp="Java\(TM\) Platform SE 7 U([0-9]|(1[0-1]))(\s[^\d\._U]|$)" />            <match name="filename" exp="npjp2\.dll" />                                    <versionRange  severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p184">
       <match name="name" exp="Java\(TM\) Plug-in 1\.7\.0(_0?([0-9]|(1[0-1]))?)?([^\d\._]|$)" />            <match name="filename" exp="libnpjp2\.so" />                                    <versionRange  severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p186">
       <match name="name" exp="Java\(TM\) Platform SE 6 U3[1-8](\s[^\d\._U]|$)" />            <match name="filename" exp="npjp2\.dll" />                                    <versionRange  severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p188">
                   <match name="filename" exp="JavaAppletPlugin\.plugin" />                                    <versionRange  minVersion="Java 6 Update 0" maxVersion="Java 6 Update 38" severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p190">
       <match name="name" exp="Java\(TM\) Plug-in 1\.6\.0_3[1-8]([^\d\._]|$)" />            <match name="filename" exp="libnpjp2\.so" />                                    <versionRange  severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p210">
       <match name="name" exp="Java\(TM\) Plug-in 1\.7\.0(_0?7)?([^\d\._]|$)" />            <match name="filename" exp="libnpjp2\.so" />                                    <versionRange  severity="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="0.1" maxVersion="17.*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p212">
                   <match name="filename" exp="JavaAppletPlugin\.plugin" />                                    <versionRange  minVersion="Java 7 Update 07" maxVersion="Java 7 Update 07" severity="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="0.1" maxVersion="17.*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p214">
       <match name="name" exp="Java\(TM\) Platform SE 7 U7(\s[^\d\._U]|$)" />            <match name="filename" exp="npjp2\.dll" />                                    <versionRange  severity="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="0.1" maxVersion="17.*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p240">
                   <match name="filename" exp="DivXBrowserPlugin\.plugin" />                      <versionRange  minVersion="0" maxVersion="1.4" severity="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  os="Darwin" blockID="p242">
             <match name="description" exp="Flip4Mac" />                                          <versionRange  minVersion="0" maxVersion="2.4.3.999" severity="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="18.0a1" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p248">
                   <match name="filename" exp="Scorch\.plugin" />                      <versionRange  minVersion="0" maxVersion="6.2.0b88" severity="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p250">
                   <match name="filename" exp="npFoxitReaderPlugin\.dll" />                      <versionRange  minVersion="0" maxVersion="2.2.1.530" severity="0" vulnerabilitystatus="2"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  os="Darwin" blockID="p252">
                   <match name="filename" exp="AdobePDFViewerNPAPI\.plugin" />                      <versionRange  minVersion="11.0.0" maxVersion="11.0.01" severity="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p254">
                   <match name="filename" exp="PDF Browser Plugin\.plugin" />                                    <versionRange  minVersion="0" maxVersion="2.4.2" severity="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="18.0a1" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p260">
                   <match name="filename" exp="(NPSWF32\.dll)|(Flash\ Player\.plugin)" />                                    <versionRange  minVersion="0" maxVersion="10.2.9999" severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="18.0a1" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p260">
                   <match name="filename" exp="(NPSWF32\.dll)|(Flash\ Player\.plugin)" />                                    <versionRange  minVersion="0" maxVersion="10.2.9999" severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0.4" maxVersion="17.0.*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p290">
                   <match name="filename" exp="(NPSWF32\.dll)|(Flash\ Player\.plugin)" />                                    <versionRange  minVersion="10.3.183.19" maxVersion="10.3.183.66" severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="19.0a1" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p290">
                   <match name="filename" exp="(NPSWF32\.dll)|(Flash\ Player\.plugin)" />                                    <versionRange  minVersion="10.3.183.19" maxVersion="10.3.183.66" severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0.4" maxVersion="17.0.*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p292">
                   <match name="filename" exp="JavaAppletPlugin\.plugin" />                                    <versionRange  minVersion="Java 7 Update 12" maxVersion="Java 7 Update 15" severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p294">
       <match name="name" exp="Java\(TM\) Platform SE 7 U1[2-5](\s[^\d\._U]|$)" />            <match name="filename" exp="npjp2\.dll" />                                    <versionRange  severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p296">
       <match name="name" exp="Java\(TM\) Plug-in 1\.7\.0_1[2-5]([^\d\._]|$)" />            <match name="filename" exp="libnpjp2\.so" />                                    <versionRange  severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p298">
                   <match name="filename" exp="JavaAppletPlugin\.plugin" />                                    <versionRange  minVersion="Java 6 Update 39" maxVersion="Java 6 Update 41" severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p300">
       <match name="name" exp="Java\(TM\) Platform SE 6 U(39|40|41)(\s[^\d\._U]|$)" />            <match name="filename" exp="npjp2\.dll" />                                    <versionRange  severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p302">
       <match name="name" exp="Java\(TM\) Plug-in 1\.6\.0_(39|40|41)([^\d\._]|$)" />            <match name="filename" exp="libnpjp2\.so" />                                    <versionRange  severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p328">
                   <match name="filename" exp="Silverlight\.plugin" />                                    <versionRange  minVersion="5.1" maxVersion="5.1.20124.9999" severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="19.0a1" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p328">
                   <match name="filename" exp="Silverlight\.plugin" />                                    <versionRange  minVersion="5.1" maxVersion="5.1.20124.9999" severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0.4" maxVersion="17.0.*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p330">
             <match name="description" exp="^Shockwave Flash (([1-9]\.[0-9]+)|(10\.([0-2]|(3 r(([0-9][0-9]?)|1(([0-7][0-9])|8[0-2]))))))( |$)" />      <match name="filename" exp="libflashplayer\.so" />                                    <versionRange  severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="19.0a1" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p330">
             <match name="description" exp="^Shockwave Flash (([1-9]\.[0-9]+)|(10\.([0-2]|(3 r(([0-9][0-9]?)|1(([0-7][0-9])|8[0-2]))))))( |$)" />      <match name="filename" exp="libflashplayer\.so" />                                    <versionRange  severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0.4" maxVersion="17.0.*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p332">
             <match name="description" exp="^Shockwave Flash 11.(0|1) r[0-9]{1,3}$" />      <match name="filename" exp="libflashplayer\.so" />                                    <versionRange  severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="19.0a1" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p332">
             <match name="description" exp="^Shockwave Flash 11.(0|1) r[0-9]{1,3}$" />      <match name="filename" exp="libflashplayer\.so" />                                    <versionRange  severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0.4" maxVersion="17.0.*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p366">
                   <match name="filename" exp="Scorch\.plugin" />                      <versionRange  minVersion="6.2.0" maxVersion="6.2.0" severity="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p408">
                   <match name="filename" exp="QuickTime Plugin\.plugin" />                      <versionRange  minVersion="0" maxVersion="7.6.5" severity="0" vulnerabilitystatus="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p410">
                   <match name="filename" exp="npqtplugin\.dll" />                      <versionRange  minVersion="0" maxVersion="7.7.3" severity="0" vulnerabilitystatus="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p412">
       <match name="name" exp="Java\(TM\) Plug-in 1\.6\.0_4[2-5]([^\d\._]|$)" />            <match name="filename" exp="libnpjp2\.so" />                                    <versionRange  severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p414">
       <match name="name" exp="Java\(TM\) Platform SE 6 U4[2-5](\s[^\d\._U]|$)" />            <match name="filename" exp="npjp2\.dll" />                                    <versionRange  severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p416">
                   <match name="filename" exp="JavaAppletPlugin\.plugin" />                                    <versionRange  minVersion="Java 6 Update 42" maxVersion="Java 6 Update 45" severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p418">
       <match name="name" exp="Java\(TM\) Plug-in 1\.7\.0_(1[6-9]|2[0-4])([^\d\._]|$)" />            <match name="filename" exp="libnpjp2\.so" />                                    <versionRange  severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p420">
       <match name="name" exp="Java\(TM\) Platform SE 7 U(1[6-9]|2[0-4])(\s[^\d\._U]|$)" />            <match name="filename" exp="npjp2\.dll" />                                    <versionRange  severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p422">
                   <match name="filename" exp="JavaAppletPlugin\.plugin" />                                    <versionRange  minVersion="Java 7 Update 16" maxVersion="Java 7 Update 24" severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p428">
                   <match name="filename" exp="np[dD]eployJava1\.dll" />                      <versionRange  severity="0" vulnerabilitystatus="2"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p456">
                   <match name="filename" exp="npvlc\.dll" />                      <versionRange  minVersion="0" maxVersion="2.0.5" severity="0" vulnerabilitystatus="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p457">
       <match name="name" exp="Java(\(TM\))? Plug-in ((1\.7\.0_(2[5-9]|3\d|4[0-4]))|(10\.4[0-4](\.[0-9]+)?))([^\d\._]|$)" />            <match name="filename" exp="libnpjp2\.so" />                                    <versionRange  severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p458">
       <match name="name" exp="Java\(TM\) Platform SE 7 U(2[5-9]|3\d|4[0-4])(\s[^\d\._U]|$)" />            <match name="filename" exp="npjp2\.dll" />                                    <versionRange  severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p459">
                   <match name="filename" exp="JavaAppletPlugin\.plugin" />                                    <versionRange  minVersion="Java 7 Update 25" maxVersion="Java 7 Update 44" severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p556">
                   <match name="filename" exp="npUnity3D32\.dll" />                      <versionRange  minVersion="0" maxVersion="4.3.4.99999999" severity="0" vulnerabilitystatus="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p558">
             <match name="description" exp="^($|Unity Web Player version ([0-3]|(4\.([0-2]|3(\.[0-4])?[^0-9.]))))" />      <match name="filename" exp="Unity Web Player\.plugin" />                      <versionRange  severity="0" vulnerabilitystatus="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p572">
                   <match name="filename" exp="npdjvu\.dll" />                      <versionRange  minVersion="0" maxVersion="6.1.4.27993" severity="0" vulnerabilitystatus="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p574">
                   <match name="filename" exp="NPDjVu\.plugin" />                      <versionRange  minVersion="0" maxVersion="6.1.1" severity="0" vulnerabilitystatus="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p592">
                   <match name="filename" exp="CiscoWebCommunicator\.plugin" />                      <versionRange  minVersion="0" maxVersion="3.0.5.99999999999999" severity="0" vulnerabilitystatus="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
       <pluginItem  blockID="p594">
                   <match name="filename" exp="npCiscoWebCommunicator\.dll" />                      <versionRange  minVersion="0" maxVersion="3.0.5.99999999999999" severity="0" vulnerabilitystatus="1"></versionRange>
-                  </pluginItem>
+                        </pluginItem>
     </pluginItems>
 
   <gfxItems>
     <gfxBlacklistEntry  blockID="g35">      <os>WINNT 6.1</os>      <vendor>0x10de</vendor>              <devices>
                       <device>0x0a6c</device>
                   </devices>
             <feature>DIRECT2D</feature>      <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>      <driverVersion>8.17.12.5896</driverVersion>      <driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>    </gfxBlacklistEntry>
     <gfxBlacklistEntry  blockID="g36">      <os>WINNT 6.1</os>      <vendor>0x10de</vendor>              <devices>
--- a/browser/components/loop/MozLoopService.jsm
+++ b/browser/components/loop/MozLoopService.jsm
@@ -4,23 +4,29 @@
 
 "use strict";
 
 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Promise.jsm");
-let console = (Cu.import("resource://gre/modules/devtools/Console.jsm", {})).console;
+Cu.import("resource://gre/modules/osfile.jsm", this);
 
 this.EXPORTED_SYMBOLS = ["MozLoopService"];
 
+XPCOMUtils.defineLazyModuleGetter(this, "console",
+  "resource://gre/modules/devtools/Console.jsm");
+
 XPCOMUtils.defineLazyModuleGetter(this, "injectLoopAPI",
   "resource:///modules/loop/MozLoopAPI.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "convertToRTCStatsReport",
+  "resource://gre/modules/media/RTCStatsReport.jsm");
+
 XPCOMUtils.defineLazyModuleGetter(this, "Chat", "resource:///modules/Chat.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "CommonUtils",
                                   "resource://services-common/utils.js");
 
 XPCOMUtils.defineLazyModuleGetter(this, "CryptoUtils",
                                   "resource://services-crypto/utils.js");
 
@@ -28,16 +34,20 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource://services-common/hawkclient.js");
 
 XPCOMUtils.defineLazyModuleGetter(this, "deriveHawkCredentials",
                                   "resource://services-common/hawkrequest.js");
 
 XPCOMUtils.defineLazyModuleGetter(this, "MozLoopPushHandler",
                                   "resource:///modules/loop/MozLoopPushHandler.jsm");
 
+XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
+                                   "@mozilla.org/uuid-generator;1",
+                                   "nsIUUIDGenerator");
+
 /**
  * Internal helper methods and state
  *
  * The registration is a two-part process. First we need to connect to
  * and register with the push server. Then we need to take the result of that
  * and register with the Loop server.
  */
 let MozLoopServiceInternal = {
@@ -299,25 +309,90 @@ let MozLoopServiceInternal = {
         map[key] = {};
       map[key][property] = string.value;
     }
 
     return this._localizedStrings = map;
   },
 
   /**
+   * Saves loop logs to the saved-telemetry-pings folder.
+   *
+   * @param {Object} pc The peerConnection in question.
+   */
+  stageForTelemetryUpload: function(window, pc) {
+    window.WebrtcGlobalInformation.getAllStats(allStats => {
+      let internalFormat = allStats.reports[0]; // filtered on pc.id
+      window.WebrtcGlobalInformation.getLogging('', logs => {
+        let report = convertToRTCStatsReport(internalFormat);
+        let logStr = "";
+        logs.forEach(s => { logStr += s + "\n"; });
+
+        // We have stats and logs.
+
+        // Create worker job. ping = saved telemetry ping file header + payload
+        //
+        // Prepare payload according to https://wiki.mozilla.org/Loop/Telemetry
+
+        let ai = Services.appinfo;
+        let uuid = uuidgen.generateUUID().toString();
+        uuid = uuid.substr(1,uuid.length-2); // remove uuid curly braces
+
+        let directory = OS.Path.join(OS.Constants.Path.profileDir,
+                                     "saved-telemetry-pings");
+        let job = {
+          directory: directory,
+          filename: uuid + ".json",
+          ping: {
+            reason: "loop",
+            slug: uuid,
+            payload: {
+              ver: 1,
+              info: {
+                appUpdateChannel: ai.defaultUpdateChannel,
+                appBuildID: ai.appBuildID,
+                appName: ai.name,
+                appVersion: ai.version,
+                reason: "loop",
+                OS: ai.OS,
+                version: Services.sysinfo.getProperty("version")
+              },
+              report: "ice failure",
+              connectionstate: pc.iceConnectionState,
+              stats: report,
+              localSdp: internalFormat.localSdp,
+              remoteSdp: internalFormat.remoteSdp,
+              log: logStr
+            }
+          }
+        };
+
+        // Send job to worker to do log sanitation, transcoding and saving to
+        // disk for pickup by telemetry on next startup, which then uploads it.
+
+        let worker = new ChromeWorker("MozLoopWorker.js");
+        worker.onmessage = function(e) {
+          console.log(e.data.ok ?
+            "Successfully staged loop report for telemetry upload." :
+            ("Failed to stage loop report. Error: " + e.data.fail));
+        }
+        worker.postMessage(job);
+      });
+    }, pc.id);
+  },
+
+  /**
    * Opens the chat window
    *
    * @param {Object} contentWindow The window to open the chat window in, may
    *                               be null.
    * @param {String} title The title of the chat window.
    * @param {String} url The page to load in the chat window.
-   * @param {String} mode May be "minimized" or undefined.
    */
-  openChatWindow: function(contentWindow, title, url, mode) {
+  openChatWindow: function(contentWindow, title, url) {
     // So I guess the origin is the loop server!?
     let origin = this.loopServerUri;
     url = url.spec || url;
 
     let callback = chatbox => {
       // We need to use DOMContentLoaded as otherwise the injection will happen
       // in about:blank and then get lost.
       // Sadly we can't use chatbox.promiseChatLoaded() as promise chaining
@@ -327,18 +402,43 @@ let MozLoopServiceInternal = {
         return;
       }
 
       chatbox.addEventListener("DOMContentLoaded", function loaded(event) {
         if (event.target != chatbox.contentDocument) {
           return;
         }
         chatbox.removeEventListener("DOMContentLoaded", loaded, true);
-        injectLoopAPI(chatbox.contentWindow);
-      }, true);
+
+        let window = chatbox.contentWindow;
+        injectLoopAPI(window);
+
+        let ourID = window.QueryInterface(Ci.nsIInterfaceRequestor)
+            .getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID;
+
+        let onPCLifecycleChange = (pc, winID, type) => {
+          if (winID != ourID) {
+            return;
+          }
+          if (type == "iceconnectionstatechange") {
+            switch(pc.iceConnectionState) {
+              case "failed":
+              case "disconnected":
+                if (Services.telemetry.canSend ||
+                    Services.prefs.getBoolPref("toolkit.telemetry.test")) {
+                  this.stageForTelemetryUpload(window, pc);
+                }
+                break;
+            }
+          }
+        };
+
+        let pc_static = new window.mozRTCPeerConnectionStatic();
+        pc_static.registerPeerConnectionLifecycleCallback(onPCLifecycleChange);
+      }.bind(this), true);
     };
 
     Chat.open(contentWindow, origin, title, url, undefined, undefined, callback);
   }
 };
 
 /**
  * Public API
new file mode 100644
--- /dev/null
+++ b/browser/components/loop/MozLoopWorker.js
@@ -0,0 +1,161 @@
+/* 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/. */
+
+/**
+ * A worker dedicated to loop-report sanitation and writing for MozLoopService.
+ */
+
+"use strict";
+
+importScripts("resource://gre/modules/osfile.jsm");
+
+let File = OS.File;
+let Encoder = new TextEncoder();
+let Counter = 0;
+
+const MAX_LOOP_LOGS = 5;
+/**
+ * Communications with the controller.
+ *
+ * Accepts messages:
+ * { path: filepath, ping: data }
+ *
+ * Sends messages:
+ * { ok: true }
+ * { fail: serialized_form_of_OS.File.Error }
+ */
+
+onmessage = function(e) {
+  if (++Counter > MAX_LOOP_LOGS) {
+    postMessage({
+      fail: "Maximum " + MAX_LOOP_LOGS + "loop reports reached for this session"
+    });
+    return;
+  }
+
+  let directory = e.data.directory;
+  let filename = e.data.filename;
+  let ping = e.data.ping;
+
+  // Anonymize data
+  resetIpMask();
+  ping.payload.localSdp = redactSdp(ping.payload.localSdp);
+  ping.payload.remoteSdp = redactSdp(ping.payload.remoteSdp);
+  ping.payload.log = sanitizeLogs(ping.payload.log);
+
+  let pingStr = anonymizeIPv4(sanitizeUrls(JSON.stringify(ping)));
+
+  // Save to disk
+  let array = Encoder.encode(pingStr);
+  try {
+    File.makeDir(directory,
+                 { unixMode: OS.Constants.S_IRWXU, ignoreExisting: true });
+    File.writeAtomic(OS.Path.join(directory, filename), array);
+    postMessage({ ok: true });
+  } catch (ex if ex instanceof File.Error) {
+    // Instances of OS.File.Error know how to serialize themselves
+    postMessage({fail: File.Error.toMsg(ex)});
+  }
+};
+
+/**
+ * Mask upper 24-bits of ip address with fake numbers. Call resetIpMask() first.
+ */
+
+let IpMap = {};
+let IpCount = 0;
+
+function resetIpMask() {
+  IpMap = {};
+  IpCount = Math.floor(Math.random() * 16777215) + 1;
+}
+
+/**
+ * Masks upper 24-bits of ip address with fake numbers. Grunt function.
+ *
+ * @param {DOMString} ip address
+ */
+function maskIp(ip) {
+  let isInvalidOrRfc1918or3927 = function(p1, p2, p3, p4) {
+    let invalid = octet => octet < 0 || octet > 255;
+    return invalid(p1) || invalid(p2) || invalid(p3) || invalid(p4) ||
+    (p1 == 10) ||
+    (p1 == 172 && p2 >= 16 && p2 <= 31) ||
+    (p1 == 192 && p2 == 168) ||
+    (p1 == 169 && p2 == 254);
+  };
+
+  let [p1, p2, p3, p4] = ip.split(".");
+
+  if (isInvalidOrRfc1918or3927(p1, p2, p3, p4)) {
+    return ip;
+  }
+  let key = [p1, p2, p3].join();
+  if (!IpMap[key]) {
+    do {
+      IpCount = (IpCount + 1049039) % 16777216; // + prime % 2^24
+      p1 = (IpCount >> 16) % 256;
+      p2 = (IpCount >> 8) % 256;
+      p3 = IpCount % 256;
+    } while (isInvalidOrRfc1918or3927(p1, p2, p3, p4));
+    IpMap[key] = p1 + "." + p2 + "." + p3;
+  }
+  return IpMap[key] + "." + p4;
+}
+
+/**
+ * Partially masks ip numbers in input text.
+ *
+ * @param {DOMString} text Input text containing IP numbers as words.
+ */
+function anonymizeIPv4(text) {
+  return text.replace(/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/g,
+                      maskIp.bind(this));
+}
+
+/**
+ * Sanitizes any urls of session information, like
+ *
+ *   - (id=31 url=https://call.services.mozilla.com/#call/ongoing/AQHYjqH_...)
+ *   + (id=31 url=https://call.services.mozilla.com/#call/xxxx)
+ *
+ *   - (id=35 url=about:loopconversation#incoming/1403134352854)
+ *   + (id=35 url=about:loopconversation#incoming/xxxx)
+ *
+ * @param {DOMString} text The text.
+ */
+function sanitizeUrls(text) {
+  let trimUrl = url => url.replace(/(#call|#incoming).*/g,
+                                   (match, type) => type + "/xxxx");
+  return text.replace(/\(id=(\d+) url=([^\)]+)\)/g,
+                      (match, id, url) =>
+                      "(id=" + id + " url=" + trimUrl(url) + ")");
+}
+
+/**
+ * Removes privacy sensitive information from SDP input text outright, like
+ *
+ *   a=fingerprint:sha-256 E9:DE:6A:FE:2A:2F:05: etc.
+ *   a=identity ...
+ *
+ * Redacts lines from match to EOL. Assumes \r\n\ linebreaks.
+ *
+ * @param {DOMString} sdp The sdp text.
+ */
+let redactSdp = sdp => sdp.replace(/\r\na=(fingerprint|identity):.*?\r\n/g,
+                                   "\r\n");
+
+/**
+ * Sanitizes log text of sensitive information, like
+ *
+ *   - srflx(IP4:192.168.1.3:60348/UDP|turn402-oak.tokbox.com:3478)
+ *   + srflx(IP4:192.168.1.3:60348/UDP|xxxx.xxx)
+ *
+ * @param {DOMString} log The log text.
+ */
+function sanitizeLogs(log) {
+  let rex = /(srflx|relay)\(IP4:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{1,5}\/(UDP|TCP)\|[^\)]+\)/g;
+
+  return log.replace(rex, match => match.replace(/\|[^\)]+\)/, "|xxxx.xxx)"));
+}
--- a/browser/components/loop/moz.build
+++ b/browser/components/loop/moz.build
@@ -9,9 +9,10 @@ JAR_MANIFESTS += ['jar.mn']
 JS_MODULES_PATH = 'modules/loop'
 
 XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell/xpcshell.ini']
 
 EXTRA_JS_MODULES += [
     'MozLoopAPI.jsm',
     'MozLoopPushHandler.jsm',
     'MozLoopService.jsm',
+    'MozLoopWorker.js',
 ]
--- a/browser/modules/WebappManager.jsm
+++ b/browser/modules/WebappManager.jsm
@@ -129,55 +129,49 @@ this.WebappManager = {
                              "webapps-notification-icon");
 
         let progressMeter = chromeDoc.createElement("progressmeter");
         progressMeter.setAttribute("mode", "undetermined");
         popupProgressContent.appendChild(progressMeter);
 
         let manifestURL = aData.app.manifestURL;
 
-        let cleanup = () => {
+        let nativeApp = new NativeApp(aData.app, jsonManifest,
+                                      aData.app.categories);
+
+        this.installations[manifestURL] = Promise.defer();
+        this.installations[manifestURL].promise.then(() => {
+          notifyInstallSuccess(aData.app, nativeApp, bundle);
+        }, (error) => {
+          Cu.reportError("Error installing webapp: " + error);
+        }).then(() => {
           popupProgressContent.removeChild(progressMeter);
           delete this.installations[manifestURL];
           if (Object.getOwnPropertyNames(this.installations).length == 0) {
             notification.remove();
           }
-        };
-
-        this.installations[manifestURL] = Promise.defer();
-        this.installations[manifestURL].promise.then(null, (error) => {
-          Cu.reportError("Error installing webapp: " + error);
-          cleanup();
         });
 
-        let nativeApp = new NativeApp(aData.app, jsonManifest,
-                                      aData.app.categories);
         let localDir;
         try {
           localDir = nativeApp.createProfile();
         } catch (ex) {
-          Cu.reportError("Error installing webapp: " + ex);
           DOMApplicationRegistry.denyInstall(aData);
-          cleanup();
           return;
         }
 
         DOMApplicationRegistry.confirmInstall(aData, localDir,
-          (aApp, aManifest, aZipPath) => Task.spawn((function*() {
+          Task.async(function*(aApp, aManifest, aZipPath) {
             try {
               yield nativeApp.install(aApp, aManifest, aZipPath);
-              yield this.installations[manifestURL].promise;
-              notifyInstallSuccess(aApp, nativeApp, bundle);
             } catch (ex) {
               Cu.reportError("Error installing webapp: " + ex);
-              // TODO: Notify user that the installation has failed
-            } finally {
-              cleanup();
+              throw ex;
             }
-          }).bind(this))
+          })
         );
       }
     };
 
     let requestingURI = chromeWin.makeURI(aData.from);
     let manifest = new ManifestHelper(jsonManifest, aData.app.origin);
 
     let host;
--- a/build/autoconf/ffi.m4
+++ b/build/autoconf/ffi.m4
@@ -83,22 +83,18 @@ if test -z "$BUILDING_JS" -o -n "$JS_STA
         ac_configure_args="$ac_configure_args CC=gcc CFLAGS=-maix32"
       else
         ac_configure_args="$ac_configure_args CC=gcc CFLAGS=-maix64"
       fi
     fi
 
     # Use a separate cache file for libffi, since it does things differently
     # from our configure.
-    mkdir -p $_objdir/js/src/ctypes/libffi
-    old_cache_file=$cache_file
-    cache_file=$_objdir/js/src/ctypes/libffi/config.cache
     old_config_files=$CONFIG_FILES
     unset CONFIG_FILES
     AC_OUTPUT_SUBDIRS(js/src/ctypes/libffi)
-    cache_file=$old_cache_file
     ac_configure_args="$_SUBDIR_CONFIG_ARGS"
     CONFIG_FILES=$old_config_files
   fi
 
 fi
 ])
 
--- a/build/autoconf/hooks.m4
+++ b/build/autoconf/hooks.m4
@@ -13,43 +13,55 @@ changequote([, ])dnl
 dnl Wrap AC_INIT_PREPARE to add the above trap.
 define([_MOZ_AC_INIT_PREPARE], defn([AC_INIT_PREPARE]))
 define([AC_INIT_PREPARE],
 [_MOZ_AC_INIT_PREPARE($1)
 MOZ_CONFIG_LOG_TRAP
 ])
 
 dnl Disable the trap when running sub-configures.
-define([_MOZ_AC_OUTPUT_SUBDIRS], defn([AC_OUTPUT_SUBDIRS]))
-define([MOZ_SUBCONFIGURE_WRAP],
-[ _CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
-case "$host" in
-*-mingw*)
+define(GEN_MOZ_AC_OUTPUT_SUBDIRS, [
+define([_MOZ_AC_OUTPUT_SUBDIRS], [
+patsubst($@, [$srcdir/$ac_config_dir], [$srcdir/$moz_config_srcdir])
+])
+])
+GEN_MOZ_AC_OUTPUT_SUBDIRS(defn([AC_OUTPUT_SUBDIRS]))
+
+define([AC_OUTPUT_SUBDIRS],
+[trap '' EXIT
+for moz_config_dir in $1; do
+  case "$moz_config_dir" in
+  *:*)
+    moz_config_srcdir=$(echo $moz_config_dir | awk -F: '{print [$]1}')
+    moz_config_dir=$(echo $moz_config_dir | awk -F: '{print [$]2}')
+    ;;
+  *)
+    moz_config_srcdir=$moz_config_dir
+    ;;
+  esac
+  _CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+  case "$host" in
+  *-mingw*)
     _CONFIG_SHELL=$(cd $(dirname $_CONFIG_SHELL); pwd -W)/$(basename $_CONFIG_SHELL)
     if test ! -e "$_CONFIG_SHELL" -a -e "${_CONFIG_SHELL}.exe"; then
         _CONFIG_SHELL="${_CONFIG_SHELL}.exe"
     fi
     ;;
-esac
+  esac
 
-if test -d "$1"; then
-    (cd "$1"; $PYTHON $_topsrcdir/build/subconfigure.py dump "$_CONFIG_SHELL")
-else
-    mkdir -p "$1"
-fi
-$2
-(cd "$1"; $PYTHON $_topsrcdir/build/subconfigure.py adjust $ac_sub_configure)
-])
-
-define([AC_OUTPUT_SUBDIRS],
-[trap '' EXIT
-for moz_config_dir in $1; do
-  MOZ_SUBCONFIGURE_WRAP([$moz_config_dir],[
-    _MOZ_AC_OUTPUT_SUBDIRS($moz_config_dir)
-  ])
+  if test -d "$moz_config_dir"; then
+    (cd "$moz_config_dir"; eval $PYTHON $_topsrcdir/build/subconfigure.py dump "$_CONFIG_SHELL" $ac_configure_args)
+  else
+    mkdir -p "$moz_config_dir"
+  fi
+  _save_cache_file="$cache_file"
+  ifelse($2,,cache_file="$moz_config_dir/config.cache",cache_file="$2")
+  _MOZ_AC_OUTPUT_SUBDIRS($moz_config_dir)
+  cache_file="$_save_cache_file"
+  (cd "$moz_config_dir"; $PYTHON $_topsrcdir/build/subconfigure.py adjust $ac_sub_configure)
 done
 
 MOZ_CONFIG_LOG_TRAP
 ])
 
 dnl Print error messages in config.log as well as stderr
 define([AC_MSG_ERROR],
 [{ echo "configure: error: $1" 1>&2; echo "configure: error: $1" 1>&5; exit 1; }])
--- a/build/autoconf/icu.m4
+++ b/build/autoconf/icu.m4
@@ -149,37 +149,18 @@ if test -z "$BUILDING_JS" -o -n "$JS_STA
         ICU_CPPFLAGS="$ICU_CPPFLAGS -DUCONFIG_NO_BREAK_ITERATION"
         ICU_CPPFLAGS="$ICU_CPPFLAGS -DUCONFIG_NO_IDNA"
         # we don't need to pass data to and from legacy char* APIs
         ICU_CPPFLAGS="$ICU_CPPFLAGS -DU_CHARSET_IS_UTF8"
         # make sure to not accidentally pick up system-icu headers
         ICU_CPPFLAGS="$ICU_CPPFLAGS -I$icudir/common -I$icudir/i18n"
 
         ICU_CROSS_BUILD_OPT=""
-        ICU_SRCDIR=""
-        if test "$HOST_OS_ARCH" = "WINNT"; then
-    	ICU_SRCDIR="--srcdir=$(cd $srcdir/intl/icu/source; pwd -W)"
-        fi
 
         if test "$CROSS_COMPILE"; then
-    	# Building host tools.  It is necessary to build target binary.
-    	case "$HOST_OS_ARCH" in
-    	    Darwin)
-    		ICU_TARGET=MacOSX
-    		;;
-    	    Linux)
-    		ICU_TARGET=Linux
-    		;;
-    	    WINNT)
-    		ICU_TARGET=MSYS/MSVC
-    		;;
-            DragonFly|FreeBSD|NetBSD|OpenBSD|GNU_kFreeBSD)
-    		ICU_TARGET=BSD
-    		;;
-    	esac
     	# Remove _DEPEND_CFLAGS from HOST_FLAGS to avoid configure error
     	HOST_ICU_CFLAGS="$HOST_CFLAGS"
     	HOST_ICU_CXXFLAGS="$HOST_CXXFLAGS"
 
     	HOST_ICU_CFLAGS=`echo $HOST_ICU_CFLAGS | sed "s|$_DEPEND_CFLAGS||g"`
     	HOST_ICU_CXXFLAGS=`echo $HOST_ICU_CFXXLAGS | sed "s|$_DEPEND_CFLAGS||g"`
 
     	# ICU requires RTTI
@@ -191,34 +172,30 @@ if test -z "$BUILDING_JS" -o -n "$JS_STA
 
     	HOST_ICU_BUILD_OPTS=""
     	if test -n "$MOZ_DEBUG"; then
     	    HOST_ICU_BUILD_OPTS="$HOST_ICU_BUILD_OPTS --enable-debug"
     	fi
 
     	abs_srcdir=`(cd $srcdir; pwd)`
     	mkdir -p $_objdir/intl/icu/host
-    	(cd $_objdir/intl/icu/host
-    	 MOZ_SUBCONFIGURE_WRAP([.],[
-    	 AR="$HOST_AR" RANLIB="$HOST_RANLIB" \
-    	 CC="$HOST_CC" CXX="$HOST_CXX" LD="$HOST_LD" \
-    	 CFLAGS="$HOST_ICU_CFLAGS $HOST_OPTIMIZE_FLAGS" \
-    	 CPPFLAGS="$ICU_CPPFLAGS" \
-    	 CXXFLAGS="$HOST_ICU_CXXFLAGS $HOST_OPTIMIZE_FLAGS" \
-    	 LDFLAGS="$HOST_LDFLAGS" \
-    		$SHELL $abs_srcdir/intl/icu/source/runConfigureICU \
-    		$HOST_ICU_BUILD_OPTS \
-    		$ICU_TARGET \
-    	dnl Shell quoting is fun.
-    		${ICU_SRCDIR+"$ICU_SRCDIR"} \
-    		--enable-static --disable-shared \
-    		--enable-extras=no --enable-icuio=no --enable-layout=no \
-    		--enable-tests=no --enable-samples=no || exit 1
-    	 ])
-    	) || exit 1
+        (export AR="$HOST_AR"
+         export RANLIB="$HOST_RANLIB"
+         export CC="$HOST_CC"
+         export CXX="$HOST_CXX"
+         export CPP="$HOST_CPP"
+         export LD="$HOST_LD"
+         export CFLAGS="$HOST_ICU_CFLAGS $HOST_OPTIMIZE_FLAGS"
+         export CPPFLAGS="$ICU_CPPFLAGS"
+         export CXXFLAGS="$HOST_ICU_CXXFLAGS $HOST_OPTIMIZE_FLAGS"
+         export LDFLAGS="$HOST_LDFLAGS"
+         ac_configure_args="$HOST_ICU_BUILD_OPTS"
+         ac_configure_args="$ac_configure_args --enable-static --disable-shared --enable-extras=no --enable-icuio=no --enable-layout=no --enable-tests=no --enable-samples=no"
+         AC_OUTPUT_SUBDIRS(intl/icu/source:intl/icu/host)
+        ) || exit 1
     	# generate config/icucross.mk
     	$GMAKE -C $_objdir/intl/icu/host/ config/icucross.mk
 
     	# --with-cross-build requires absolute path
     	ICU_HOST_PATH=`cd $_objdir/intl/icu/host && pwd`
     	ICU_CROSS_BUILD_OPT="--with-cross-build=$ICU_HOST_PATH"
     	ICU_TARGET_OPT="--build=$build --host=$target"
         else
@@ -303,37 +280,26 @@ if test -z "$BUILDING_JS" -o -n "$JS_STA
           ICU_CXXFLAGS="$ICU_CXXFLAGS -DU_STATIC_IMPLEMENTATION"
           ICU_CFLAGS="$ICU_CFLAGS -DU_STATIC_IMPLEMENTATION"
           if test "$GNU_CC"; then
             ICU_CFLAGS="$ICU_CFLAGS -fvisibility=hidden"
             ICU_CXXFLAGS="$ICU_CXXFLAGS -fvisibility=hidden"
           fi
         fi
 
-        # We cannot use AC_OUTPUT_SUBDIRS since ICU tree is out of spidermonkey.
-        # When using AC_OUTPUT_SUBDIRS, objdir of ICU is out of objdir
-        # due to relative path.
-        # If building ICU moves into root of mozilla tree, we can use
-        # AC_OUTPUT_SUBDIR instead.
-        mkdir -p $_objdir/intl/icu/target
-        (cd $_objdir/intl/icu/target
-         MOZ_SUBCONFIGURE_WRAP([.],[
-           AR="$AR" CC="$CC" CXX="$CXX" LD="$LD" \
-           ARFLAGS="$ARFLAGS" \
-           CPPFLAGS="$ICU_CPPFLAGS $CPPFLAGS" \
-           CFLAGS="$ICU_CFLAGS" \
-           CXXFLAGS="$ICU_CXXFLAGS" \
-           LDFLAGS="$ICU_LDFLAGS $LDFLAGS" \
-           $SHELL $_topsrcdir/intl/icu/source/configure \
-    		$ICU_BUILD_OPTS \
-    		$ICU_CROSS_BUILD_OPT \
-    		$ICU_LINK_OPTS \
-    		${ICU_SRCDIR+"$ICU_SRCDIR"} \
-    		$ICU_TARGET_OPT \
-    		--disable-extras --disable-icuio --disable-layout \
-    		--disable-tests --disable-samples || exit 1
-           ])
+        (export AR="$AR"
+         export CC="$CC"
+         export CXX="$CXX"
+         export LD="$LD"
+         export ARFLAGS="$ARFLAGS"
+         export CPPFLAGS="$ICU_CPPFLAGS $CPPFLAGS"
+         export CFLAGS="$ICU_CFLAGS"
+         export CXXFLAGS="$ICU_CXXFLAGS"
+         export LDFLAGS="$ICU_LDFLAGS $LDFLAGS"
+         ac_configure_args="$ICU_BUILD_OPTS $ICU_CROSS_BUILD_OPT $ICU_LINK_OPTS $ICU_TARGET_OPT"
+         ac_configure_args="$ac_configure_args --disable-extras --disable-icuio --disable-layout --disable-tests --disable-samples"
+         AC_OUTPUT_SUBDIRS(intl/icu/source:intl/icu/target)
         ) || exit 1
     fi
 
 fi
 
 ])
--- a/build/sanitizers/lsan_suppressions.txt
+++ b/build/sanitizers/lsan_suppressions.txt
@@ -60,19 +60,16 @@ leak:event_base_once
 leak:nsLocalFile::OpenNSPRFileDesc
 
 # Bug 1023585 - Leak of array buffer in JSStructuredCloneWriter::transferOwnership(). m1
 leak:AllocateArrayBufferContents
 
 # Bug 1022010 - Small leak under _render_glyph_outline. bc1
 leak:_render_glyph_outline
 
-# Bug 1022954 - ScriptSource leaks sourceMapURL_ sometimes. dt
-leak:ScriptSource::setSourceMapURL
-
 # Bug 1023548 - Small leak under SECITEM_AllocItem_Util. bc1, bc3
 leak:SECITEM_AllocItem_Util
 
 # This is a one-time leak, so it is probably okay to ignore. bc1, oth
 leak:GlobalPrinters::InitializeGlobalPrinters
 leak:nsPSPrinterList::GetPrinterList
 
 # Bug 1028456 - More leaks with _PR_Getfd, in nsLocalFile::CopyToNative and do_create. bc1, bc3
--- a/build/subconfigure.py
+++ b/build/subconfigure.py
@@ -1,15 +1,16 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # This script is used to capture the content of config.status-generated
 # files and subsequently restore their timestamp if they haven't changed.
 
+import argparse
 import os
 import re
 import subprocess
 import sys
 import pickle
 
 class File(object):
     def __init__(self, path):
@@ -55,34 +56,64 @@ PRECIOUS_VARS = set([
 
 
 # Autoconf, in some of the sub-configures used in the tree, likes to error
 # out when "precious" variables change in value. The solution it gives to
 # straighten things is to either run make distclean or remove config.cache.
 # There's no reason not to do the latter automatically instead of failing,
 # doing the cleanup (which, on buildbots means a full clobber), and
 # restarting from scratch.
-def maybe_clear_cache():
+def maybe_clear_cache(args):
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--target', type=str)
+    parser.add_argument('--host', type=str)
+    parser.add_argument('--build', type=str)
+    args, others = parser.parse_known_args(args)
+    env = dict(os.environ)
+    for kind in ('target', 'host', 'build'):
+        arg = getattr(args, kind)
+        if arg is not None:
+            env['%s_alias' % kind] = arg
+    # configure can take variables assignments in its arguments, and that
+    # overrides whatever is in the environment.
+    for arg in others:
+        if arg[:1] != '-' and '=' in arg:
+            key, value = arg.split('=', 1)
+            env[key] = value
+
     comment = re.compile(r'^\s+#')
     cache = {}
     with open('config.cache') as f:
-        for line in f.readlines():
+        for line in f:
             if not comment.match(line) and '=' in line:
-                key, value = line.split('=', 1)
+                key, value = line.rstrip(os.linesep).split('=', 1)
+                # If the value is quoted, unquote it
+                if value[:1] == "'":
+                    value = value[1:-1].replace("'\\''", "'")
                 cache[key] = value
     for precious in PRECIOUS_VARS:
-        entry = 'ac_cv_env_%s_value' % precious
-        if entry in cache and (not precious in os.environ or os.environ[precious] != cache[entry]):
+        # If there is no entry at all for that precious variable, then
+        # its value is not precious for that particular configure.
+        if 'ac_cv_env_%s_set' % precious not in cache:
+            continue
+        is_set = cache.get('ac_cv_env_%s_set' % precious) == 'set'
+        value = cache.get('ac_cv_env_%s_value' % precious) if is_set else None
+        if value != env.get(precious):
+            print 'Removing config.cache because of %s value change from:' \
+                % precious
+            print '  %s' % (value if value is not None else 'undefined')
+            print 'to:'
+            print '  %s' % env.get(precious, 'undefined')
             os.remove('config.cache')
             return
 
 
-def dump(dump_file, shell):
+def dump(dump_file, shell, args):
     if os.path.exists('config.cache'):
-        maybe_clear_cache()
+        maybe_clear_cache(args)
     if not os.path.exists('config.status'):
         if os.path.exists(dump_file):
             os.remove(dump_file)
         return
 
     config_files = [File('config.status')]
 
     # Scan the config.status output for information about configuration files
@@ -127,11 +158,11 @@ def adjust(dump_file, configure):
 
     os.remove(dump_file)
 
 
 CONFIG_DUMP = 'config_files.pkl'
 
 if __name__ == '__main__':
     if sys.argv[1] == 'dump':
-        dump(CONFIG_DUMP, sys.argv[2])
+        dump(CONFIG_DUMP, sys.argv[2], sys.argv[3:])
     elif sys.argv[1] == 'adjust':
         adjust(CONFIG_DUMP, sys.argv[2] if len(sys.argv) > 2 else None)
--- a/build/valgrind/mach_commands.py
+++ b/build/valgrind/mach_commands.py
@@ -121,38 +121,45 @@ class MachCommands(MachCommandBase):
             # MACHTYPE is an odd bash-only environment variable that doesn't
             # show up in os.environ, so we have to get it another way.
             machtype = subprocess.check_output(['bash', '-c', 'echo $MACHTYPE']).rstrip()
             supps_file2 = os.path.join(supps_dir, machtype + '.sup')
             if os.path.isfile(supps_file2):
                 valgrind_args.append('--suppressions=' + supps_file2)
 
             exitcode = None
+            timeout = 1100
             try:
                 runner = FirefoxRunner(profile=profile,
                                        binary=self.get_binary_path(),
                                        cmdargs=firefox_args,
                                        env=env,
                                        process_args=kp_kwargs)
                 runner.start(debug_args=valgrind_args)
-                exitcode = runner.wait()
+                # This timeout is slightly less than the no-output timeout on
+                # TBPL, so we'll timeout here first and give an informative
+                # message.
+                exitcode = runner.wait(timeout=timeout)
 
             finally:
                 errs = outputHandler.error_count
                 supps = outputHandler.suppression_count
                 if errs != supps:
                     status = 1  # turns the TBPL job orange
-                    print('TEST-UNEXPECTED-FAILURE | valgrind-test | error parsing:', errs, "errors seen, but", supps, "generated suppressions seen")
+                    print('TEST-UNEXPECTED-FAIL | valgrind-test | error parsing: {} errors seen, but {} generated suppressions seen'.format(errs, supps))
 
                 elif errs == 0:
                     status = 0
                     print('TEST-PASS | valgrind-test | valgrind found no errors')
                 else:
                     status = 1  # turns the TBPL job orange
                     # We've already printed details of the errors.
 
-                if exitcode != 0:
+                if exitcode == None:
+                    status = 2  # turns the TBPL job red
+                    print('TEST-UNEXPECTED-FAIL | valgrind-test | Valgrind timed out (reached {} second limit)'.format(timeout))
+                elif exitcode != 0:
                     status = 2  # turns the TBPL job red
                     print('TEST-UNEXPECTED-FAIL | valgrind-test | non-zero exit code from Valgrind')
 
                 httpd.stop()
 
             return status
--- a/config/config.mk
+++ b/config/config.mk
@@ -69,16 +69,17 @@ endif
   TIERS \
   TOOL_DIRS \
   XPCSHELL_TESTS \
   XPIDL_MODULE \
   $(NULL)
 
 _DEPRECATED_VARIABLES := \
   ANDROID_RESFILES \
+  EXPORT_LIBRARY \
   LIBXUL_LIBRARY \
   MOCHITEST_A11Y_FILES \
   MOCHITEST_BROWSER_FILES \
   MOCHITEST_BROWSER_FILES_PARTS \
   MOCHITEST_CHROME_FILES \
   MOCHITEST_FILES \
   MOCHITEST_FILES_PARTS \
   MOCHITEST_METRO_FILES \
@@ -340,17 +341,16 @@ endif
 endif
 
 # If we are building this component into an extension/xulapp, it cannot be
 # statically linked. In the future we may want to add a xulapp meta-component
 # build option.
 
 ifdef XPI_NAME
 ifdef IS_COMPONENT
-EXPORT_LIBRARY=
 FORCE_STATIC_LIB=
 FORCE_SHARED_LIB=1
 endif
 endif
 
 ifndef SHARED_LIBRARY_NAME
 ifdef LIBRARY_NAME
 SHARED_LIBRARY_NAME=$(LIBRARY_NAME)
--- a/config/makefiles/target_binaries.mk
+++ b/config/makefiles/target_binaries.mk
@@ -1,28 +1,15 @@
 # -*- makefile -*-
 # vim:set ts=8 sw=8 sts=8 noet:
 #
 # 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/.
 
-ifdef EXPORT_LIBRARY
-ifeq ($(EXPORT_LIBRARY),1)
-ifdef IS_COMPONENT
-EXPORT_LIBRARY = $(DEPTH)/staticlib/components
-else
-EXPORT_LIBRARY = $(DEPTH)/staticlib
-endif
-else
-# If EXPORT_LIBRARY has a value, we'll be installing there. We also need to cleanup there
-GARBAGE += $(foreach lib,$(LIBRARY),$(EXPORT_LIBRARY)/$(lib))
-endif
-endif # EXPORT_LIBRARY
-
 binaries libs:: $(SUBMAKEFILES) $(TARGETS)
 ifndef NO_DIST_INSTALL
 ifdef SHARED_LIBRARY
 ifdef IS_COMPONENT
 	$(INSTALL) $(IFLAGS2) $(SHARED_LIBRARY) $(FINAL_TARGET)/components
 ifndef NO_COMPONENTS_MANIFEST
 	$(call py_action,buildlist,$(FINAL_TARGET)/chrome.manifest 'manifest components/components.manifest')
 	$(call py_action,buildlist,$(FINAL_TARGET)/components/components.manifest 'binary-component $(SHARED_LIBRARY)')
@@ -36,22 +23,16 @@ ifndef NO_DIST_INSTALL
 ifneq (,$(strip $(PROGRAM)$(SIMPLE_PROGRAMS)))
 PROGRAMS_EXECUTABLES = $(SIMPLE_PROGRAMS) $(PROGRAM)
 PROGRAMS_DEST ?= $(FINAL_TARGET)
 PROGRAMS_TARGET := binaries libs
 INSTALL_TARGETS += PROGRAMS
 endif
 
 ifdef LIBRARY
-ifdef EXPORT_LIBRARY
-LIBRARY_FILES = $(LIBRARY)
-LIBRARY_DEST ?= $(EXPORT_LIBRARY)
-LIBRARY_TARGET = binaries libs
-INSTALL_TARGETS += LIBRARY
-endif
 ifdef DIST_INSTALL
 ifdef IS_COMPONENT
 $(error Shipping static component libs makes no sense.)
 else
 DIST_LIBRARY_FILES = $(LIBRARY)
 DIST_LIBRARY_DEST ?= $(DIST)/lib
 DIST_LIBRARY_TARGET = binaries libs
 INSTALL_TARGETS += DIST_LIBRARY
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -828,17 +828,17 @@ endif
 $(filter %.$(LIB_SUFFIX),$(LIBRARY)): $(OBJS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
 	$(REPORT_BUILD)
 	$(RM) $(LIBRARY)
 	$(EXPAND_AR) $(AR_FLAGS) $(OBJS) $(SHARED_LIBRARY_LIBS)
 
 $(filter-out %.$(LIB_SUFFIX),$(LIBRARY)): $(filter %.$(LIB_SUFFIX),$(LIBRARY)) $(OBJS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
 # When we only build a library descriptor, blow out any existing library
 	$(REPORT_BUILD)
-	$(if $(filter %.$(LIB_SUFFIX),$(LIBRARY)),,$(RM) $(REAL_LIBRARY) $(EXPORT_LIBRARY:%=%/$(REAL_LIBRARY)))
+	$(if $(filter %.$(LIB_SUFFIX),$(LIBRARY)),,$(RM) $(REAL_LIBRARY))
 	$(EXPAND_LIBS_GEN) -o $@ $(OBJS) $(SHARED_LIBRARY_LIBS)
 
 ifeq ($(OS_ARCH),WINNT)
 # Import libraries are created by the rules creating shared libraries.
 # The rules to copy them to $(DIST)/lib depend on $(IMPORT_LIBRARY),
 # but make will happily consider the import library before it is refreshed
 # when rebuilding the corresponding shared library. Defining an empty recipe
 # for import libraries forces make to wait for the shared library recipe to
--- a/configure.in
+++ b/configure.in
@@ -8778,17 +8778,16 @@ AC_SUBST(OBJ_SUFFIX)
 AC_SUBST(BIN_SUFFIX)
 AC_SUBST(ASM_SUFFIX)
 AC_SUBST(IMPORT_LIB_SUFFIX)
 AC_SUBST(USE_N32)
 AC_SUBST(CC_VERSION)
 AC_SUBST(CXX_VERSION)
 AC_SUBST(MSMANIFEST_TOOL)
 AC_SUBST(NS_ENABLE_TSF)
-AC_SUBST(MOZ_APP_COMPONENT_LIBS)
 AC_SUBST(MOZ_APP_EXTRA_LIBS)
 
 AC_SUBST(MOZ_WAVE)
 AC_SUBST(MOZ_VORBIS)
 AC_SUBST(MOZ_TREMOR)
 AC_SUBST(MOZ_OPUS)
 AC_SUBST(MOZ_WEBM)
 AC_SUBST(MOZ_WMF)
@@ -9045,31 +9044,28 @@ if test -z "$MOZ_NATIVE_JEMALLOC" -a "$M
   fi
   EXTRA_CFLAGS="$CFLAGS"
   for var in AS CC CXX CPP LD AR RANLIB STRIP CPPFLAGS EXTRA_CFLAGS LDFLAGS; do
     ac_configure_args="$ac_configure_args $var='`eval echo \\${${var}}`'"
   done
   if test "$CROSS_COMPILE"; then
     ac_configure_args="$ac_configure_args je_cv_static_page_shift=12"
   fi
-  _save_cache_file="$cache_file"
-  cache_file=$_objdir/memory/jemalloc/src/config.cache
 
   if ! test -e memory/jemalloc; then
     mkdir -p memory/jemalloc
   fi
 
   dnl jemalloc's configure uses $srcdir in AC_CONFIG_HEADERS, which syntax uses
   dnl colons, conflicting with the windows-style path in $srcdir.
   dnl Turn it into a msys path just for jemalloc's configure
   _save_srcdir="$srcdir"
   srcdir=`cd $srcdir; pwd`
   AC_OUTPUT_SUBDIRS(memory/jemalloc/src)
   srcdir="$_save_srcdir"
-  cache_file="$_save_cache_file"
   ac_configure_args="$_SUBDIR_CONFIG_ARGS"
 fi
 
 # Run freetype configure script
 
 if test "$MOZ_TREE_FREETYPE"; then
    export CFLAGS="$CFLAGS $MOZ_DEBUG_FLAGS -std=c99"
    export CPPFLAGS="$CPPFLAGS $MOZ_DEBUG_FLAGS"
@@ -9083,17 +9079,17 @@ if test "$MOZ_TREE_FREETYPE"; then
    export ZLIB_LIBS="$MOZ_ZLIB_LIBS "
    export CONFIG_FILES="unix-cc.mk:unix-cc.in unix-def.mk:unix-def.in freetype-config freetype2.pc:freetype2.in"
    ac_configure_args="$ac_configure_args --host=$target --disable-shared --with-pic=yes --with-zlib=yes --without-bzip2 --with-png=yes --without-harfbuzz"
 
    if ! test -e modules; then
      mkdir modules
    fi
 
-   AC_OUTPUT_SUBDIRS(modules/freetype2)
+   AC_OUTPUT_SUBDIRS(modules/freetype2,$cache_file)
 fi
 
 if test -z "$direct_nspr_config"; then
     dnl ========================================================
     dnl = Setup a nice relatively clean build environment for
     dnl = sub-configures.
     dnl ========================================================
     CC="$_SUBDIR_CC"
@@ -9175,24 +9171,19 @@ if test -z "$MOZ_NATIVE_NSPR"; then
     if test -n "$MOZ_LINKER" -a "$ac_cv_func_dladdr" = no ; then
       # dladdr is supported by the new linker, even when the system linker doesn't
       # support it. Trick nspr into using dladdr when it's not supported.
       export CPPFLAGS="-include $_topsrcdir/mozglue/linker/dladdr.h $CPPFLAGS"
     fi
     export LDFLAGS="$LDFLAGS $NSPR_LDFLAGS"
     export CFLAGS="$CFLAGS $MOZ_FRAMEPTR_FLAGS"
 
-    # Use a separate cache file for NSPR since it uses autoconf 2.68.
-    _save_cache_file="$cache_file"
-    cache_file=$_objdir/nsprpub/config.cache
-
     AC_OUTPUT_SUBDIRS(nsprpub)
 
     # .. and restore them
-    cache_file="$_save_cache_file"
     CFLAGS="$_SAVE_CFLAGS"
     CPPFLAGS="$_SAVE_CPPFLAGS"
     LDFLAGS="$_SAVE_LDFLAGS"
 
     ac_configure_args="$_SUBDIR_CONFIG_ARGS"
 fi
 
 dnl ========================================================
@@ -9272,17 +9263,17 @@ export STLPORT_LIBS
 export JS_STANDALONE=no
 export MOZ_LINKER
 export ZLIB_IN_MOZGLUE
 
 if ! test -e js; then
     mkdir js
 fi
 
-AC_OUTPUT_SUBDIRS(js/src)
+AC_OUTPUT_SUBDIRS(js/src,$cache_file)
 ac_configure_args="$_SUBDIR_CONFIG_ARGS"
 
 fi # COMPILE_ENVIRONMENT && !LIBXUL_SDK_DIR
 
 export WRITE_MOZINFO=1
 dnl we need to run config.status after js/src subconfigure because we're
 dnl traversing its moz.build and we need its config.status for that.
 dnl However, writing our own config.status needs to happen before
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -472,18 +472,17 @@ public:
   static nsIScriptSecurityManager* GetSecurityManager()
   {
     return sSecurityManager;
   }
 
   /**
    * Get the ContentSecurityPolicy for a JS context.
    **/
-  static bool GetContentSecurityPolicy(JSContext* aCx,
-                                       nsIContentSecurityPolicy** aCSP);
+  static bool GetContentSecurityPolicy(nsIContentSecurityPolicy** aCSP);
 
   // Returns the subject principal. Guaranteed to return non-null. May only
   // be called when nsContentUtils is initialized.
   static nsIPrincipal* SubjectPrincipal();
 
   // Returns the prinipal of the given JS object. This may only be called on
   // the main thread for objects from the main thread's JSRuntime.
   static nsIPrincipal* ObjectPrincipal(JSObject* aObj);
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -6420,21 +6420,19 @@ nsContentUtils::FindInternalContentViewe
     }
     return docFactory.forget();
   }
 
   return nullptr;
 }
 
 bool
-nsContentUtils::GetContentSecurityPolicy(JSContext* aCx,
-                                         nsIContentSecurityPolicy** aCSP)
+nsContentUtils::GetContentSecurityPolicy(nsIContentSecurityPolicy** aCSP)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-  MOZ_ASSERT(aCx == GetCurrentJSContext());
 
   nsCOMPtr<nsIContentSecurityPolicy> csp;
   nsresult rv = SubjectPrincipal()->GetCsp(getter_AddRefs(csp));
   if (NS_FAILED(rv)) {
     NS_ERROR("CSP: Failed to get CSP from principal.");
     return false;
   }
 
--- a/content/base/src/nsDOMFile.cpp
+++ b/content/base/src/nsDOMFile.cpp
@@ -935,17 +935,17 @@ public:
 
       size_t size = DOMMemoryFileDataOwnerMallocSizeOf(owner->mData);
 
       if (size < LARGE_OBJECT_MIN_SIZE) {
         smallObjectsTotal += size;
       } else {
         SHA1Sum sha1;
         sha1.update(owner->mData, owner->mLength);
-        uint8_t digest[SHA1Sum::HashSize]; // SHA1 digests are 20 bytes long.
+        uint8_t digest[SHA1Sum::kHashSize]; // SHA1 digests are 20 bytes long.
         sha1.finish(digest);
 
         nsAutoCString digestString;
         for (size_t i = 0; i < sizeof(digest); i++) {
           digestString.AppendPrintf("%02x", digest[i]);
         }
 
         nsresult rv = aCallback->Callback(
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -1466,19 +1466,21 @@ nsScriptLoader::PrepareLoadedRequest(nsS
   if (httpChannel) {
     bool requestSucceeded;
     rv = httpChannel->GetRequestSucceeded(&requestSucceeded);
     if (NS_SUCCEEDED(rv) && !requestSucceeded) {
       return NS_ERROR_NOT_AVAILABLE;
     }
 
     nsAutoCString sourceMapURL;
-    httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("X-SourceMap"), sourceMapURL);
-    aRequest->mHasSourceMapURL = true;
-    aRequest->mSourceMapURL = NS_ConvertUTF8toUTF16(sourceMapURL);
+    rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("X-SourceMap"), sourceMapURL);
+    if (NS_SUCCEEDED(rv)) {
+      aRequest->mHasSourceMapURL = true;
+      aRequest->mSourceMapURL = NS_ConvertUTF8toUTF16(sourceMapURL);
+    }
   }
 
   nsCOMPtr<nsIChannel> channel = do_QueryInterface(req);
   // If this load was subject to a CORS check; don't flag it with a
   // separate origin principal, so that it will treat our document's
   // principal as the origin principal
   if (aRequest->mCORSMode == CORS_NONE) {
     rv = nsContentUtils::GetSecurityManager()->
--- a/content/base/test/chrome/nochrome_bug765993.js
+++ b/content/base/test/chrome/nochrome_bug765993.js
@@ -1,4 +1,4 @@
-//@ sourceMappingURL=bar.js.map
+//# sourceMappingURL=bar.js.map
 
 // Define a single function to prevent script source from being gc'd
 function foo() {}
--- a/content/media/MediaDecoderStateMachine.cpp
+++ b/content/media/MediaDecoderStateMachine.cpp
@@ -8,16 +8,17 @@
 #include "windows.h"
 #include "mmsystem.h"
 #endif
 
 #include "mozilla/DebugOnly.h"
 #include <stdint.h>
 
 #include "MediaDecoderStateMachine.h"
+#include "MediaDecoderStateMachineScheduler.h"
 #include "AudioSink.h"
 #include "nsTArray.h"
 #include "MediaDecoder.h"
 #include "MediaDecoderReader.h"
 #include "mozilla/mozalloc.h"
 #include "VideoUtils.h"
 #include "mozilla/dom/TimeRanges.h"
 #include "nsDeque.h"
@@ -163,18 +164,21 @@ static TimeDuration UsecsToDuration(int6
 static int64_t DurationToUsecs(TimeDuration aDuration) {
   return static_cast<int64_t>(aDuration.ToSeconds() * USECS_PER_S);
 }
 
 MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
                                                    MediaDecoderReader* aReader,
                                                    bool aRealTime) :
   mDecoder(aDecoder),
+  mScheduler(new MediaDecoderStateMachineScheduler(
+      aDecoder->GetReentrantMonitor(),
+      &MediaDecoderStateMachine::TimeoutExpired,
+      MOZ_THIS_IN_INITIALIZER_LIST(), aRealTime)),
   mState(DECODER_STATE_DECODING_METADATA),
-  mInRunningStateMachine(false),
   mSyncPointInMediaStream(-1),
   mSyncPointInDecodedStream(-1),
   mPlayDuration(0),
   mStartTime(-1),
   mEndTime(-1),
   mFragmentEndTime(-1),
   mReader(aReader),
   mCurrentFrameTime(0),
@@ -193,40 +197,34 @@ MediaDecoderStateMachine::MediaDecoderSt
   mPositionChangeQueued(false),
   mAudioCompleted(false),
   mGotDurationFromMetaData(false),
   mDispatchedEventToDecode(false),
   mStopAudioThread(true),
   mQuickBuffering(false),
   mMinimizePreroll(false),
   mDecodeThreadWaiting(false),
-  mRealTime(aRealTime),
   mDispatchedDecodeMetadataTask(false),
   mDropAudioUntilNextDiscontinuity(false),
   mDropVideoUntilNextDiscontinuity(false),
   mDecodeToSeekTarget(false),
   mCurrentTimeBeforeSeek(0),
-  mLastFrameStatus(MediaDecoderOwner::NEXT_FRAME_UNINITIALIZED),
-  mTimerId(0)
+  mLastFrameStatus(MediaDecoderOwner::NEXT_FRAME_UNINITIALIZED)
 {
   MOZ_COUNT_CTOR(MediaDecoderStateMachine);
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
 
-  // Only enable realtime mode when "media.realtime_decoder.enabled" is true.
-  if (Preferences::GetBool("media.realtime_decoder.enabled", false) == false)
-    mRealTime = false;
-
   mAmpleVideoFrames =
     std::max<uint32_t>(Preferences::GetUint("media.video-queue.default-size", 10), 3);
 
-  mBufferingWait = mRealTime ? 0 : BUFFERING_WAIT_S;
-  mLowDataThresholdUsecs = mRealTime ? 0 : LOW_DATA_THRESHOLD_USECS;
-
-  mVideoPrerollFrames = mRealTime ? 0 : mAmpleVideoFrames / 2;
-  mAudioPrerollUsecs = mRealTime ? 0 : LOW_AUDIO_USECS * 2;
+  mBufferingWait = mScheduler->IsRealTime() ? 0 : BUFFERING_WAIT_S;
+  mLowDataThresholdUsecs = mScheduler->IsRealTime() ? 0 : LOW_DATA_THRESHOLD_USECS;
+
+  mVideoPrerollFrames = mScheduler->IsRealTime() ? 0 : mAmpleVideoFrames / 2;
+  mAudioPrerollUsecs = mScheduler->IsRealTime() ? 0 : LOW_AUDIO_USECS * 2;
 
 #ifdef XP_WIN
   // Ensure high precision timers are enabled on Windows, otherwise the state
   // machine thread isn't woken up at reliable intervals to set the next frame,
   // and we drop frames while painting. Note that multiple calls to this
   // function per-process is OK, provided each call is matched by a corresponding
   // timeEndPeriod() call.
   timeBeginPeriod(1);
@@ -236,18 +234,16 @@ MediaDecoderStateMachine::MediaDecoderSt
 MediaDecoderStateMachine::~MediaDecoderStateMachine()
 {
   MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread.");
   MOZ_COUNT_DTOR(MediaDecoderStateMachine);
   NS_ASSERTION(!mPendingWakeDecoder.get(),
                "WakeDecoder should have been revoked already");
 
   MOZ_ASSERT(!mDecodeTaskQueue, "Should be released in SHUTDOWN");
-  // No need to cancel the timer here for we've done that in SHUTDOWN.
-  MOZ_ASSERT(!mTimer, "Should be released in SHUTDOWN");
   mReader = nullptr;
 
 #ifdef XP_WIN
   timeEndPeriod(1);
 #endif
 }
 
 bool MediaDecoderStateMachine::HasFutureAudio() {
@@ -1058,34 +1054,25 @@ bool MediaDecoderStateMachine::IsPlaying
 
 nsresult MediaDecoderStateMachine::Init(MediaDecoderStateMachine* aCloneDonor)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   RefPtr<SharedThreadPool> decodePool(GetMediaDecodeThreadPool());
   NS_ENSURE_TRUE(decodePool, NS_ERROR_FAILURE);
 
-  RefPtr<SharedThreadPool> stateMachinePool(
-    SharedThreadPool::Get(NS_LITERAL_CSTRING("Media State Machine"), 1));
-  NS_ENSURE_TRUE(stateMachinePool, NS_ERROR_FAILURE);
-
   mDecodeTaskQueue = new MediaTaskQueue(decodePool.forget());
   NS_ENSURE_TRUE(mDecodeTaskQueue, NS_ERROR_FAILURE);
 
   MediaDecoderReader* cloneReader = nullptr;
   if (aCloneDonor) {
     cloneReader = aCloneDonor->mReader;
   }
 
-  mStateMachineThreadPool = stateMachinePool;
-
-  nsresult rv;
-  mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = mTimer->SetTarget(GetStateMachineThread());
+  nsresult rv = mScheduler->Init();
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Note: This creates a cycle, broken in shutdown.
   mMediaDecodedListener =
     new MediaDataDecodedListener<MediaDecoderStateMachine>(this,
                                                            mDecodeTaskQueue);
   mReader->SetCallback(mMediaDecodedListener);
   mReader->SetTaskQueue(mDecodeTaskQueue);
@@ -1337,18 +1324,18 @@ void MediaDecoderStateMachine::Shutdown(
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
 
   // Once we've entered the shutdown state here there's no going back.
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
 
   // Change state before issuing shutdown request to threads so those
   // threads can start exiting cleanly during the Shutdown call.
   DECODER_LOG(PR_LOG_DEBUG, "Changed state to SHUTDOWN");
-  ScheduleStateMachine();
   mState = DECODER_STATE_SHUTDOWN;
+  mScheduler->ScheduleAndShutdown();
   if (mAudioSink) {
     mAudioSink->PrepareToShutdown();
   }
   mDecoder->GetReentrantMonitor().NotifyAll();
 }
 
 void MediaDecoderStateMachine::StartDecoding()
 {
@@ -1748,16 +1735,17 @@ MediaDecoderStateMachine::StartAudioThre
   if (HasAudio() && !mAudioSink) {
     mAudioCompleted = false;
     mAudioSink = new AudioSink(this,
                                mAudioStartTime, mInfo.mAudio, mDecoder->GetAudioChannel());
     nsresult rv = mAudioSink->Init();
     if (NS_FAILED(rv)) {
       DECODER_LOG(PR_LOG_WARNING, "Changed state to SHUTDOWN because audio sink initialization failed");
       mState = DECODER_STATE_SHUTDOWN;
+      mScheduler->ScheduleAndShutdown();
       return rv;
     }
 
     mAudioSink->SetVolume(mVolume);
     mAudioSink->SetPlaybackRate(mPlaybackRate);
     mAudioSink->SetPreservesPitch(mPreservesPitch);
   }
   return NS_OK;
@@ -1825,18 +1813,18 @@ MediaDecoderStateMachine::DecodeError()
     // Already shutdown.
     return;
   }
 
   // Change state to shutdown before sending error report to MediaDecoder
   // and the HTMLMediaElement, so that our pipeline can start exiting
   // cleanly during the sync dispatch below.
   DECODER_LOG(PR_LOG_WARNING, "Decode error, changed state to SHUTDOWN due to error");
-  ScheduleStateMachine();
   mState = DECODER_STATE_SHUTDOWN;
+  mScheduler->ScheduleAndShutdown();
   mDecoder->GetReentrantMonitor().NotifyAll();
 
   // Dispatch the event to call DecodeError synchronously. This ensures
   // we're in shutdown state by the time we exit the decode thread.
   // If we just moved to shutdown state here on the decode thread, we may
   // cause the state machine to shutdown/free memory without closing its
   // media stream properly, and we'll get callbacks from the media stream
   // causing a crash.
@@ -1906,17 +1894,17 @@ nsresult MediaDecoderStateMachine::Decod
     AudioQueue().AddPopListener(decodeTask, mDecodeTaskQueue);
   }
   if (HasVideo()) {
     RefPtr<nsIRunnable> decodeTask(
       NS_NewRunnableMethod(this, &MediaDecoderStateMachine::DispatchVideoDecodeTaskIfNeeded));
     VideoQueue().AddPopListener(decodeTask, mDecodeTaskQueue);
   }
 
-  if (mRealTime) {
+  if (mScheduler->IsRealTime()) {
     SetStartTime(0);
     res = FinishDecodeMetadata();
     NS_ENSURE_SUCCESS(res, res);
   } else {
     if (HasAudio()) {
       ReentrantMonitorAutoExit unlock(mDecoder->GetReentrantMonitor());
       mReader->RequestAudioData();
     }
@@ -1935,17 +1923,17 @@ MediaDecoderStateMachine::FinishDecodeMe
   AssertCurrentThreadInMonitor();
   NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
   DECODER_LOG(PR_LOG_DEBUG, "Decoding Media Headers");
 
   if (mState == DECODER_STATE_SHUTDOWN) {
     return NS_ERROR_FAILURE;
   }
 
-  if (!mRealTime) {
+  if (!mScheduler->IsRealTime()) {
 
     const VideoData* v = VideoQueue().PeekFront();
     const AudioData* a = AudioQueue().PeekFront();
 
     int64_t startTime = std::min<int64_t>(a ? a->mTime : INT64_MAX,
                                           v ? v->mTime : INT64_MAX);
     if (startTime == INT64_MAX) {
       startTime = 0;
@@ -2169,27 +2157,31 @@ MediaDecoderStateMachine::SeekCompleted(
   UpdatePlaybackPositionInternal(newCurrentTime);
   if (mDecoder->GetDecodedStream()) {
     SetSyncPointForMediaStream();
   }
 
   // Try to decode another frame to detect if we're at the end...
   DECODER_LOG(PR_LOG_DEBUG, "Seek completed, mCurrentFrameTime=%lld", mCurrentFrameTime);
 
+  // Prevent changes in playback position before 'seeked' is fired for we
+  // expect currentTime equals seek target in 'seeked' callback.
+  mScheduler->FreezeScheduling();
   {
     ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
     NS_DispatchToMainThread(stopEvent, NS_DISPATCH_SYNC);
   }
 
   // Reset quick buffering status. This ensures that if we began the
   // seek while quick-buffering, we won't bypass quick buffering mode
   // if we need to buffer after the seek.
   mQuickBuffering = false;
 
   ScheduleStateMachine();
+  mScheduler->ThawScheduling();
 }
 
 // Runnable to dispose of the decoder and state machine on the main thread.
 class nsDecoderDisposeEvent : public nsRunnable {
 public:
   nsDecoderDisposeEvent(already_AddRefed<MediaDecoder> aDecoder,
                         already_AddRefed<MediaDecoderStateMachine> aStateMachine)
     : mDecoder(aDecoder), mStateMachine(aStateMachine) {}
@@ -2287,18 +2279,16 @@ nsresult MediaDecoderStateMachine::RunSt
       // state machine) needs to finish and be released in order to allow
       // that. So we dispatch an event to run after this event runner has
       // finished and released its monitor/references. That event then will
       // dispatch an event to the main thread to release the decoder and
       // state machine.
       GetStateMachineThread()->Dispatch(
         new nsDispatchDisposeEvent(mDecoder, this), NS_DISPATCH_NORMAL);
 
-      mTimer->Cancel();
-      mTimer = nullptr;
       return NS_OK;
     }
 
     case DECODER_STATE_DORMANT: {
       if (IsPlaying()) {
         StopPlayback();
       }
       FlushDecoding();
@@ -2584,17 +2574,17 @@ void MediaDecoderStateMachine::AdvanceFr
   int64_t remainingTime = AUDIO_DURATION_USECS;
   NS_ASSERTION(clock_time >= mStartTime, "Should have positive clock time.");
   nsAutoPtr<VideoData> currentFrame;
 #ifdef PR_LOGGING
   int32_t droppedFrames = 0;
 #endif
   if (VideoQueue().GetSize() > 0) {
     VideoData* frame = VideoQueue().PeekFront();
-    while (mRealTime || clock_time >= frame->mTime) {
+    while (mScheduler->IsRealTime() || clock_time >= frame->mTime) {
       mVideoFrameEndTime = frame->GetEndTime();
       currentFrame = frame;
 #ifdef PR_LOGGING
       VERBOSE_LOG("discarding video frame %lld", frame->mTime);
       if (droppedFrames++) {
         VERBOSE_LOG("discarding video frame %lld (%d so far)", frame->mTime, droppedFrames-1);
       }
 #endif
@@ -2924,128 +2914,53 @@ nsresult MediaDecoderStateMachine::CallR
   AssertCurrentThreadInMonitor();
   NS_ASSERTION(OnStateMachineThread(), "Should be on state machine thread.");
 
   // If audio is being captured, stop the audio sink if it's running
   if (mAudioCaptured) {
     StopAudioThread();
   }
 
-  MOZ_ASSERT(!mInRunningStateMachine, "State machine cycles must run in sequence!");
-  mTimeout = TimeStamp();
-  mInRunningStateMachine = true;
-  nsresult res = RunStateMachine();
-  mInRunningStateMachine = false;
-  return res;
+  return RunStateMachine();
 }
 
-nsresult MediaDecoderStateMachine::TimeoutExpired(int aTimerId)
+nsresult MediaDecoderStateMachine::TimeoutExpired(void* aClosure)
 {
-  ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-  NS_ASSERTION(OnStateMachineThread(), "Must be on state machine thread");
-  mTimer->Cancel();
-  if (mTimerId == aTimerId) {
-    return CallRunStateMachine();
-  } else {
-    return NS_OK;
-  }
+  MediaDecoderStateMachine* p = static_cast<MediaDecoderStateMachine*>(aClosure);
+  return p->CallRunStateMachine();
 }
 
 void MediaDecoderStateMachine::ScheduleStateMachineWithLockAndWakeDecoder() {
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
   DispatchAudioDecodeTaskIfNeeded();
   DispatchVideoDecodeTaskIfNeeded();
 }
 
-class TimerEvent : public nsITimerCallback, public nsRunnable {
-  NS_DECL_THREADSAFE_ISUPPORTS
-public:
-  TimerEvent(MediaDecoderStateMachine* aStateMachine, int aTimerId)
-    : mStateMachine(aStateMachine), mTimerId(aTimerId) {}
-
-  NS_IMETHOD Run() MOZ_OVERRIDE {
-    return mStateMachine->TimeoutExpired(mTimerId);
-  }
-
-  NS_IMETHOD Notify(nsITimer* aTimer) {
-    return mStateMachine->TimeoutExpired(mTimerId);
-  }
-private:
-  ~TimerEvent() {}
-
-  const nsRefPtr<MediaDecoderStateMachine> mStateMachine;
-  int mTimerId;
-};
-
-NS_IMPL_ISUPPORTS(TimerEvent, nsITimerCallback, nsIRunnable);
-
 nsresult MediaDecoderStateMachine::ScheduleStateMachine(int64_t aUsecs) {
-  AssertCurrentThreadInMonitor();
-  NS_ABORT_IF_FALSE(GetStateMachineThread(),
-    "Must have a state machine thread to schedule");
-
-  if (mState == DECODER_STATE_SHUTDOWN) {
-    return NS_ERROR_FAILURE;
-  }
-  aUsecs = std::max<int64_t>(aUsecs, 0);
-
-  TimeStamp timeout = TimeStamp::Now() + UsecsToDuration(aUsecs);
-  if (!mTimeout.IsNull() && timeout >= mTimeout) {
-    // We've already scheduled a timer set to expire at or before this time,
-    // or have an event dispatched to run the state machine.
-    return NS_OK;
-  }
-
-  uint32_t ms = static_cast<uint32_t>((aUsecs / USECS_PER_MS) & 0xFFFFFFFF);
-  if (mRealTime && ms > 40) {
-    ms = 40;
-  }
-
-  // Don't cancel the timer here for this function will be called from
-  // different threads.
-
-  nsresult rv = NS_ERROR_FAILURE;
-  nsRefPtr<TimerEvent> event = new TimerEvent(this, mTimerId+1);
-
-  if (ms == 0) {
-    // Dispatch a runnable to the state machine thread when delay is 0.
-    // It will has less latency than dispatching a runnable to the state
-    // machine thread which will then schedule a zero-delay timer.
-    rv = GetStateMachineThread()->Dispatch(event, NS_DISPATCH_NORMAL);
-  } else if (OnStateMachineThread()) {
-    rv = mTimer->InitWithCallback(event, ms, nsITimer::TYPE_ONE_SHOT);
-  } else {
-    MOZ_ASSERT(false, "non-zero delay timer should be only scheduled in state machine thread");
-  }
-
-  if (NS_SUCCEEDED(rv)) {
-    mTimeout = timeout;
-    ++mTimerId;
-  } else {
-    NS_WARNING("Failed to schedule state machine");
-  }
-
-  return rv;
+  return mScheduler->Schedule(aUsecs);
 }
 
 bool MediaDecoderStateMachine::OnDecodeThread() const
 {
   return mDecodeTaskQueue->IsCurrentThreadIn();
 }
 
 bool MediaDecoderStateMachine::OnStateMachineThread() const
 {
-  bool rv = false;
-  mStateMachineThreadPool->IsOnCurrentThread(&rv);
-  return rv;
+  return mScheduler->OnStateMachineThread();
 }
 
-nsIEventTarget* MediaDecoderStateMachine::GetStateMachineThread()
+nsIEventTarget* MediaDecoderStateMachine::GetStateMachineThread() const
 {
-  return mStateMachineThreadPool->GetEventTarget();
+  return mScheduler->GetStateMachineThread();
+}
+
+bool MediaDecoderStateMachine::IsStateMachineScheduled() const
+{
+  return mScheduler->IsScheduled();
 }
 
 void MediaDecoderStateMachine::SetPlaybackRate(double aPlaybackRate)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   NS_ASSERTION(aPlaybackRate != 0,
       "PlaybackRate == 0 should be handled before this function.");
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
--- a/content/media/MediaDecoderStateMachine.h
+++ b/content/media/MediaDecoderStateMachine.h
@@ -95,16 +95,17 @@ class nsITimer;
 
 namespace mozilla {
 
 class AudioSegment;
 class VideoSegment;
 class MediaTaskQueue;
 class SharedThreadPool;
 class AudioSink;
+class MediaDecoderStateMachineScheduler;
 
 // GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
 // GetTickCount() and conflicts with MediaDecoderStateMachine::GetCurrentTime
 // implementation.
 #ifdef GetCurrentTime
 #undef GetCurrentTime
 #endif
 
@@ -274,29 +275,30 @@ public:
   void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset);
 
   int64_t GetEndMediaTime() const {
     AssertCurrentThreadInMonitor();
     return mEndTime;
   }
 
   // Returns the shared state machine thread.
-  nsIEventTarget* GetStateMachineThread();
+  nsIEventTarget* GetStateMachineThread() const;
 
   // Calls ScheduleStateMachine() after taking the decoder lock. Also
   // notifies the decoder thread in case it's waiting on the decoder lock.
   void ScheduleStateMachineWithLockAndWakeDecoder();
 
   // Schedules the shared state machine thread to run the state machine
   // in aUsecs microseconds from now, if it's not already scheduled to run
   // earlier, in which case the request is discarded.
   nsresult ScheduleStateMachine(int64_t aUsecs = 0);
 
-  // Timer function to implement ScheduleStateMachine(aUsecs).
-  nsresult TimeoutExpired(int aGeneration);
+  // Callback function registered with MediaDecoderStateMachineScheduler
+  // to run state machine cycles.
+  static nsresult TimeoutExpired(void* aClosure);
 
   // Set the media fragment end time. aEndTime is in microseconds.
   void SetFragmentEndTime(int64_t aEndTime);
 
   // Drop reference to decoder.  Only called during shutdown dance.
   void BreakCycles() {
     if (mReader) {
       mReader->BreakCycles();
@@ -442,17 +444,17 @@ protected:
   // Dispatches an asynchronous event to update the media element's ready state.
   void UpdateReadyState();
 
   // Resets playback timing data. Called when we seek, on the decode thread.
   void ResetPlayback();
 
   // Orders the Reader to stop decoding, and blocks until the Reader
   // has stopped decoding and finished delivering samples, then calls
-  // ResetPlayback() to discard all enqueued data. 
+  // ResetPlayback() to discard all enqueued data.
   void FlushDecoding();
 
   // Returns the audio clock, if we have audio, or -1 if we don't.
   // Called on the state machine thread.
   int64_t GetAudioClock();
 
   // Get the video stream position, taking the |playbackRate| change into
   // account. This is a position in the media, not the duration of the playback
@@ -605,20 +607,17 @@ protected:
   // State machine thread run function. Defers to RunStateMachine().
   nsresult CallRunStateMachine();
 
   // Performs one "cycle" of the state machine. Polls the state, and may send
   // a video frame to be displayed, and generally manages the decode. Called
   // periodically via timer to ensure the video stays in sync.
   nsresult RunStateMachine();
 
-  bool IsStateMachineScheduled() const {
-    AssertCurrentThreadInMonitor();
-    return !mTimeout.IsNull();
-  }
+  bool IsStateMachineScheduled() const;
 
   // Returns true if we're not playing and the decode thread has filled its
   // decode buffers and is waiting. We can shut the decode thread down in this
   // case as it may not be needed again.
   bool IsPausedAndDecoderWaiting();
 
   // These return true if the respective stream's decode has not yet reached
   // the end of stream.
@@ -645,16 +644,20 @@ protected:
   // dropped its reference to the decoder. This enables the state machine to
   // keep using the decoder's monitor until the state machine has finished
   // shutting down, without fear of the monitor being destroyed. After
   // shutting down, the state machine will then release this reference,
   // causing the decoder to be destroyed. This is accessed on the decode,
   // state machine, audio and main threads.
   nsRefPtr<MediaDecoder> mDecoder;
 
+  // Used to schedule state machine cycles. This should never outlive
+  // the life cycle of the state machine.
+  const nsAutoPtr<MediaDecoderStateMachineScheduler> mScheduler;
+
   // Time at which the last video sample was requested. If it takes too long
   // before the sample arrives, we will increase the amount of audio we buffer.
   // This is necessary for legacy synchronous decoders to prevent underruns.
   TimeStamp mVideoDecodeStartTime;
 
   // Queue of audio frames. This queue is threadsafe, and is accessed from
   // the audio, decoder, state machine, and main threads.
   MediaQueue<AudioData> mAudioQueue;
@@ -669,29 +672,16 @@ protected:
   // Accessed on state machine, audio, main, and AV thread.
   State mState;
 
   // The task queue in which we run decode tasks. This is referred to as
   // the "decode thread", though in practise tasks can run on a different
   // thread every time they're called.
   RefPtr<MediaTaskQueue> mDecodeTaskQueue;
 
-  RefPtr<SharedThreadPool> mStateMachineThreadPool;
-
-  // Timer to run the state machine cycles. Used by
-  // ScheduleStateMachine(). Access protected by decoder monitor.
-  nsCOMPtr<nsITimer> mTimer;
-
-  // Timestamp at which the next state machine cycle will run.
-  // Access protected by decoder monitor.
-  TimeStamp mTimeout;
-
-  // Used to check if there are state machine cycles are running in sequence.
-  DebugOnly<bool> mInRunningStateMachine;
-
   // The time that playback started from the system clock. This is used for
   // timing the presentation of video frames when there's no audio.
   // Accessed only via the state machine thread.  Must be set via SetPlayStartTime.
   TimeStamp mPlayStartTime;
 
   // When we start writing decoded data to a new DecodedDataStream, or we
   // restart writing due to PlaybackStarted(), we record where we are in the
   // MediaStream and what that corresponds to in the media.
@@ -906,19 +896,16 @@ protected:
   // memory and CPU overhead.
   bool mMinimizePreroll;
 
   // True if the decode thread has gone filled its buffers and is now
   // waiting to be awakened before it continues decoding. Synchronized
   // by the decoder monitor.
   bool mDecodeThreadWaiting;
 
-  // True is we are decoding a realtime stream, like a camera stream
-  bool mRealTime;
-
   // True if we've dispatched a task to the decode task queue to call
   // ReadMetadata on the reader. We maintain a flag to ensure that we don't
   // dispatch multiple tasks to re-do the metadata loading.
   bool mDispatchedDecodeMetadataTask;
 
   // These two flags are true when we need to drop decoded samples that
   // we receive up to the next discontinuity. We do this when we seek;
   // the first sample in each stream after the seek is marked as being
@@ -937,15 +924,12 @@ protected:
 
   // Stores presentation info required for playback. The decoder monitor
   // must be held when accessing this.
   MediaInfo mInfo;
 
   mozilla::MediaMetadataManager mMetadataManager;
 
   MediaDecoderOwner::NextFrameStatus mLastFrameStatus;
-
-  // The id of timer tasks, used to ignore tasks that are scheduled previously.
-  int mTimerId;
 };
 
 } // namespace mozilla;
 #endif
new file mode 100644
--- /dev/null
+++ b/content/media/MediaDecoderStateMachineScheduler.cpp
@@ -0,0 +1,233 @@
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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 "MediaDecoderStateMachineScheduler.h"
+#include "SharedThreadPool.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/ReentrantMonitor.h"
+#include "nsITimer.h"
+#include "nsComponentManagerUtils.h"
+#include "VideoUtils.h"
+
+namespace {
+class TimerEvent : public nsITimerCallback, public nsRunnable {
+  typedef mozilla::MediaDecoderStateMachineScheduler Scheduler;
+  NS_DECL_THREADSAFE_ISUPPORTS
+public:
+  TimerEvent(Scheduler* aScheduler, int aTimerId)
+    : mScheduler(aScheduler), mTimerId(aTimerId) {}
+
+  NS_IMETHOD Run() MOZ_OVERRIDE {
+    return mScheduler->TimeoutExpired(mTimerId);
+  }
+
+  NS_IMETHOD Notify(nsITimer* aTimer) MOZ_OVERRIDE {
+    return mScheduler->TimeoutExpired(mTimerId);
+  }
+private:
+  ~TimerEvent() {}
+  Scheduler* const mScheduler;
+  const int mTimerId;
+};
+
+NS_IMPL_ISUPPORTS(TimerEvent, nsITimerCallback, nsIRunnable);
+} // anonymous namespace
+
+static already_AddRefed<nsIEventTarget>
+CreateStateMachineThread()
+{
+  using mozilla::SharedThreadPool;
+  using mozilla::RefPtr;
+  RefPtr<SharedThreadPool> threadPool(
+      SharedThreadPool::Get(NS_LITERAL_CSTRING("Media State Machine"), 1));
+  nsCOMPtr<nsIEventTarget> rv = threadPool.get();
+  return rv.forget();
+}
+
+namespace mozilla {
+
+MediaDecoderStateMachineScheduler::MediaDecoderStateMachineScheduler(
+    ReentrantMonitor& aMonitor,
+    nsresult (*aTimeoutCallback)(void*),
+    void* aClosure, bool aRealTime)
+  : mTimeoutCallback(aTimeoutCallback)
+  , mClosure(aClosure)
+  // Only enable realtime mode when "media.realtime_decoder.enabled" is true.
+  , mRealTime(aRealTime &&
+              Preferences::GetBool("media.realtime_decoder.enabled", false))
+  , mMonitor(aMonitor)
+  , mEventTarget(CreateStateMachineThread())
+  , mTimer(do_CreateInstance("@mozilla.org/timer;1"))
+  , mTimerId(0)
+  , mState(SCHEDULER_STATE_NONE)
+  , mInRunningStateMachine(false)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_COUNT_CTOR(MediaDecoderStateMachineScheduler);
+}
+
+MediaDecoderStateMachineScheduler::~MediaDecoderStateMachineScheduler()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_COUNT_DTOR(MediaDecoderStateMachineScheduler);
+}
+
+nsresult
+MediaDecoderStateMachineScheduler::Init()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  NS_ENSURE_TRUE(mEventTarget, NS_ERROR_FAILURE);
+  nsresult rv = mTimer->SetTarget(mEventTarget);
+  NS_ENSURE_SUCCESS(rv, rv);
+  return NS_OK;
+}
+
+nsresult
+MediaDecoderStateMachineScheduler::Schedule(int64_t aUsecs)
+{
+  mMonitor.AssertCurrentThreadIn();
+
+  switch(mState) {
+  case SCHEDULER_STATE_SHUTDOWN:
+    return NS_ERROR_FAILURE;
+  case SCHEDULER_STATE_FROZEN:
+    mState = SCHEDULER_STATE_FROZEN_WITH_PENDING_TASK;
+  case SCHEDULER_STATE_FROZEN_WITH_PENDING_TASK:
+    return NS_OK;
+  case SCHEDULER_STATE_NONE:
+    break;
+  }
+
+  aUsecs = std::max<int64_t>(aUsecs, 0);
+
+  TimeStamp timeout = TimeStamp::Now() +
+    TimeDuration::FromMilliseconds(static_cast<double>(aUsecs) / USECS_PER_MS);
+
+  if (!mTimeout.IsNull() && timeout >= mTimeout) {
+    // We've already scheduled a timer set to expire at or before this time,
+    // or have an event dispatched to run the state machine.
+    return NS_OK;
+  }
+
+  uint32_t ms = static_cast<uint32_t>((aUsecs / USECS_PER_MS) & 0xFFFFFFFF);
+  if (IsRealTime() && ms > 40) {
+    ms = 40;
+  }
+
+  // Don't cancel the timer here for this function will be called from
+  // different threads.
+
+  nsresult rv = NS_ERROR_FAILURE;
+  nsRefPtr<TimerEvent> event = new TimerEvent(this, mTimerId+1);
+
+  if (ms == 0) {
+    // Dispatch a runnable to the state machine thread when delay is 0.
+    // It will has less latency than dispatching a runnable to the state
+    // machine thread which will then schedule a zero-delay timer.
+    rv = mEventTarget->Dispatch(event, NS_DISPATCH_NORMAL);
+  } else if (OnStateMachineThread()) {
+    rv = mTimer->InitWithCallback(event, ms, nsITimer::TYPE_ONE_SHOT);
+  } else {
+    MOZ_ASSERT(false, "non-zero delay timer should be only "
+                      "scheduled in state machine thread");
+  }
+
+  if (NS_SUCCEEDED(rv)) {
+    mTimeout = timeout;
+    ++mTimerId;
+  } else {
+    NS_WARNING("Failed to schedule state machine");
+  }
+
+  return rv;
+}
+
+nsresult
+MediaDecoderStateMachineScheduler::TimeoutExpired(int aTimerId)
+{
+  ReentrantMonitorAutoEnter mon(mMonitor);
+  MOZ_ASSERT(OnStateMachineThread());
+  MOZ_ASSERT(!mInRunningStateMachine,
+             "State machine cycles must run in sequence!");
+
+  mInRunningStateMachine = true;
+  // Only run state machine cycles when id matches.
+  nsresult rv = NS_OK;
+  if (mTimerId == aTimerId) {
+    ResetTimer();
+    rv = mTimeoutCallback(mClosure);
+  }
+  mInRunningStateMachine = false;
+
+  return rv;
+}
+
+void
+MediaDecoderStateMachineScheduler::ScheduleAndShutdown()
+{
+  mMonitor.AssertCurrentThreadIn();
+  if (IsFrozen()) {
+    ThawScheduling();
+  }
+  // Schedule next cycle to handle SHUTDOWN in state machine thread.
+  Schedule();
+  // This must be set after calling Schedule()
+  // which does nothing in shutdown state.
+  mState = SCHEDULER_STATE_SHUTDOWN;
+}
+
+bool
+MediaDecoderStateMachineScheduler::OnStateMachineThread() const
+{
+  bool rv = false;
+  mEventTarget->IsOnCurrentThread(&rv);
+  return rv;
+}
+
+bool
+MediaDecoderStateMachineScheduler::IsScheduled() const
+{
+  mMonitor.AssertCurrentThreadIn();
+  return !mTimeout.IsNull();
+}
+
+void
+MediaDecoderStateMachineScheduler::ResetTimer()
+{
+  mMonitor.AssertCurrentThreadIn();
+  mTimer->Cancel();
+  mTimeout = TimeStamp();
+}
+
+void MediaDecoderStateMachineScheduler::FreezeScheduling()
+{
+  mMonitor.AssertCurrentThreadIn();
+  if (mState == SCHEDULER_STATE_SHUTDOWN) {
+    return;
+  }
+  MOZ_ASSERT(mState == SCHEDULER_STATE_NONE);
+  mState = !IsScheduled() ? SCHEDULER_STATE_FROZEN :
+                            SCHEDULER_STATE_FROZEN_WITH_PENDING_TASK;
+  // Nullify pending timer task if any.
+  ++mTimerId;
+  mTimeout = TimeStamp();
+}
+
+void MediaDecoderStateMachineScheduler::ThawScheduling()
+{
+  mMonitor.AssertCurrentThreadIn();
+  if (mState == SCHEDULER_STATE_SHUTDOWN) {
+    return;
+  }
+  // We should be in frozen state and no pending timer task.
+  MOZ_ASSERT(IsFrozen() && !IsScheduled());
+  bool pendingTask = mState == SCHEDULER_STATE_FROZEN_WITH_PENDING_TASK;
+  mState = SCHEDULER_STATE_NONE;
+  if (pendingTask) {
+    Schedule();
+  }
+}
+
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/content/media/MediaDecoderStateMachineScheduler.h
@@ -0,0 +1,86 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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 MediaDecoderStateMachineScheduler_h__
+#define MediaDecoderStateMachineScheduler_h__
+
+#include "nsCOMPtr.h"
+#include "mozilla/TimeStamp.h"
+#include "mozilla/DebugOnly.h"
+
+class nsITimer;
+class nsIEventTarget;
+
+namespace mozilla {
+
+class ReentrantMonitor;
+
+class MediaDecoderStateMachineScheduler {
+  enum State {
+    SCHEDULER_STATE_NONE,
+    SCHEDULER_STATE_FROZEN,
+    SCHEDULER_STATE_FROZEN_WITH_PENDING_TASK,
+    SCHEDULER_STATE_SHUTDOWN
+  };
+public:
+  MediaDecoderStateMachineScheduler(ReentrantMonitor& aMonitor,
+                                    nsresult (*aTimeoutCallback)(void*),
+                                    void* aClosure, bool aRealTime);
+  ~MediaDecoderStateMachineScheduler();
+  nsresult Init();
+  nsresult Schedule(int64_t aUsecs = 0);
+  void ScheduleAndShutdown();
+  nsresult TimeoutExpired(int aTimerId);
+  void FreezeScheduling();
+  void ThawScheduling();
+
+  bool OnStateMachineThread() const;
+  bool IsScheduled() const;
+
+  bool IsRealTime() const {
+    return mRealTime;
+  }
+
+  nsIEventTarget* GetStateMachineThread() const {
+    return mEventTarget;
+  }
+
+  bool IsFrozen() const {
+    return mState == SCHEDULER_STATE_FROZEN ||
+           mState == SCHEDULER_STATE_FROZEN_WITH_PENDING_TASK;
+  }
+
+private:
+  void ResetTimer();
+
+  // Callback function provided by MediaDecoderStateMachine to run
+  // state machine cycles.
+  nsresult (*const mTimeoutCallback)(void*);
+  // Since StateMachineScheduler will never outlive the state machine,
+  // it is safe to keep a raw pointer only to avoid reference cycles.
+  void* const mClosure;
+  // True is we are decoding a realtime stream, like a camera stream
+  const bool mRealTime;
+  // Monitor of the decoder
+  ReentrantMonitor& mMonitor;
+  // State machine thread
+  const nsCOMPtr<nsIEventTarget> mEventTarget;
+  // Timer to schedule callbacks to run the state machine cycles.
+  nsCOMPtr<nsITimer> mTimer;
+  // Timestamp at which the next state machine cycle will run.
+  TimeStamp mTimeout;
+  // The id of timer tasks, timer callback will only run if id matches.
+  int mTimerId;
+  // No more state machine cycles in shutdown state.
+  State mState;
+
+  // Used to check if state machine cycles are running in sequence.
+  DebugOnly<bool> mInRunningStateMachine;
+};
+
+} // namespace mozilla
+
+#endif // MediaDecoderStateMachineScheduler_h__
--- a/content/media/MediaResource.h
+++ b/content/media/MediaResource.h
@@ -142,16 +142,20 @@ public:
   }
 
   // Clears byte range values.
   void Clear() {
     mStart = 0;
     mEnd = 0;
   }
 
+  bool Contains(const MediaByteRange& aByteRange) const {
+    return aByteRange.mStart >= mStart && aByteRange.mEnd <= mEnd;
+  }
+
   int64_t mStart, mEnd;
 };
 
 // Represents a section of contiguous media, with a start and end offset, and
 // a timestamp representing the start time.
 class TimestampedMediaByteRange : public MediaByteRange {
 public:
   TimestampedMediaByteRange() : MediaByteRange(), mStartTime(-1) {}
--- a/content/media/fmp4/MP4Reader.cpp
+++ b/content/media/fmp4/MP4Reader.cpp
@@ -8,16 +8,17 @@
 #include "MediaResource.h"
 #include "nsSize.h"
 #include "VideoUtils.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "ImageContainer.h"
 #include "Layers.h"
 #include "SharedThreadPool.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/dom/TimeRanges.h"
 
 using mozilla::layers::Image;
 using mozilla::layers::LayerManager;
 using mozilla::layers::LayersBackend;
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* GetDemuxerLog() {
   static PRLogModuleInfo* log = nullptr;
@@ -548,9 +549,28 @@ MP4Reader::Seek(int64_t aTime,
   if (mDemuxer->HasValidAudio()) {
     mDemuxer->SeekAudio(
       mQueuedVideoSample ? mQueuedVideoSample->composition_timestamp : aTime);
   }
 
   return NS_OK;
 }
 
+nsresult
+MP4Reader::GetBuffered(dom::TimeRanges* aBuffered, int64_t aStartTime)
+{
+  nsTArray<MediaByteRange> ranges;
+  if (NS_FAILED(mDecoder->GetResource()->GetCachedRanges(ranges))) {
+    return NS_ERROR_FAILURE;
+  }
+
+  nsTArray<Interval<Microseconds>> timeRanges;
+  mDemuxer->ConvertByteRangesToTime(ranges, &timeRanges);
+
+  for (size_t i = 0; i < timeRanges.Length(); i++) {
+    aBuffered->Add((timeRanges[i].start - aStartTime) / 1000000.0,
+                   (timeRanges[i].end - aStartTime) / 1000000.0);
+  }
+
+  return NS_OK;
+}
+
 } // namespace mozilla
--- a/content/media/fmp4/MP4Reader.h
+++ b/content/media/fmp4/MP4Reader.h
@@ -47,16 +47,19 @@ public:
 
   virtual nsresult Seek(int64_t aTime,
                         int64_t aStartTime,
                         int64_t aEndTime,
                         int64_t aCurrentTime) MOZ_OVERRIDE;
 
   virtual bool IsMediaSeekable() MOZ_OVERRIDE;
 
+  virtual nsresult GetBuffered(dom::TimeRanges* aBuffered,
+                               int64_t aStartTime) MOZ_OVERRIDE;
+
 private:
 
   // Destroys all decoder resources.
   void Shutdown();
 
   // Initializes mLayersBackendType if possible.
   void InitLayersBackendType();
 
--- a/content/media/fmp4/ffmpeg/FFmpegAACDecoder.cpp
+++ b/content/media/fmp4/ffmpeg/FFmpegAACDecoder.cpp
@@ -66,16 +66,17 @@ void
 FFmpegAACDecoder<LIBAV_VER>::DecodePacket(MP4Sample* aSample)
 {
   nsAutoPtr<AVFrame> frame(avcodec_alloc_frame());
   avcodec_get_frame_defaults(frame);
 
   AVPacket packet;
   av_init_packet(&packet);
 
+  aSample->Pad(FF_INPUT_BUFFER_PADDING_SIZE);
   packet.data = aSample->data;
   packet.size = aSample->size;
   packet.pos = aSample->byte_offset;
 
   int decoded;
   int bytesConsumed =
     avcodec_decode_audio4(&mCodecContext, frame.get(), &decoded, &packet);
 
--- a/content/media/fmp4/ffmpeg/FFmpegDataDecoder.cpp
+++ b/content/media/fmp4/ffmpeg/FFmpegDataDecoder.cpp
@@ -80,21 +80,24 @@ FFmpegDataDecoder<LIBAV_VER>::Init()
 
   // FFmpeg takes this as a suggestion for what format to use for audio samples.
   mCodecContext.request_sample_fmt = AV_SAMPLE_FMT_FLT;
 
   // FFmpeg will call back to this to negotiate a video pixel format.
   mCodecContext.get_format = ChoosePixelFormat;
 
   mCodecContext.thread_count = PR_GetNumberOfProcessors();
-  mCodecContext.thread_type = FF_THREAD_FRAME;
+  mCodecContext.thread_type = FF_THREAD_SLICE | FF_THREAD_FRAME;
   mCodecContext.thread_safe_callbacks = false;
 
+  mCodecContext.extradata_size = mExtraData.length();
+  for (int i = 0; i < FF_INPUT_BUFFER_PADDING_SIZE; i++) {
+    mExtraData.append(0);
+  }
   mCodecContext.extradata = mExtraData.begin();
-  mCodecContext.extradata_size = mExtraData.length();
 
   AVDictionary* opts = nullptr;
   if (avcodec_open2(&mCodecContext, codec, &opts) < 0) {
     NS_WARNING("Couldn't initialise ffmpeg decoder");
     return NS_ERROR_FAILURE;
   }
 
   if (mCodecContext.codec_type == AVMEDIA_TYPE_AUDIO &&
--- a/content/media/fmp4/ffmpeg/FFmpegH264Decoder.cpp
+++ b/content/media/fmp4/ffmpeg/FFmpegH264Decoder.cpp
@@ -48,16 +48,17 @@ FFmpegH264Decoder<LIBAV_VER>::Init()
 }
 
 void
 FFmpegH264Decoder<LIBAV_VER>::DecodeFrame(mp4_demuxer::MP4Sample* aSample)
 {
   AVPacket packet;
   av_init_packet(&packet);
 
+  aSample->Pad(FF_INPUT_BUFFER_PADDING_SIZE);
   packet.data = aSample->data;
   packet.size = aSample->size;
   packet.pts = aSample->composition_timestamp;
   packet.flags = aSample->is_sync_point ? AV_PKT_FLAG_KEY : 0;
   packet.pos = aSample->byte_offset;
 
   nsAutoPtr<AVFrame> frame(avcodec_alloc_frame());
   avcodec_get_frame_defaults(frame);
@@ -132,17 +133,21 @@ FFmpegH264Decoder<LIBAV_VER>::AllocateBu
     return avcodec_default_get_buffer(aCodecContext, aFrame);
   }
 }
 
 /* static */ void
 FFmpegH264Decoder<LIBAV_VER>::ReleaseBufferCb(AVCodecContext* aCodecContext,
                                               AVFrame* aFrame)
 {
-  reinterpret_cast<Image*>(aFrame->opaque)->Release();
+  Image* image = reinterpret_cast<Image*>(aFrame->opaque);
+  avcodec_default_release_buffer(aCodecContext, aFrame);
+  if (image) {
+    image->Release();
+  }
 }
 
 int
 FFmpegH264Decoder<LIBAV_VER>::AllocateYUV420PVideoBuffer(
   AVCodecContext* aCodecContext, AVFrame* aFrame)
 {
   // Older versions of ffmpeg require that edges be allocated* around* the
   // actual image.
--- a/content/media/gmp/GMPMessageUtils.h
+++ b/content/media/gmp/GMPMessageUtils.h
@@ -2,20 +2,35 @@
 /* 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 GMPMessageUtils_h_
 #define GMPMessageUtils_h_
 
 #include "gmp-video-codec.h"
+#include "gmp-video-frame-encoded.h"
 
 namespace IPC {
 
 template <>
+struct ParamTraits<GMPErr>
+: public ContiguousEnumSerializer<GMPErr,
+                                  GMPNoErr,
+                                  GMPLastErr>
+{};
+
+template <>
+struct ParamTraits<GMPVideoFrameType>
+: public ContiguousEnumSerializer<GMPVideoFrameType,
+                                  kGMPKeyFrame,
+                                  kGMPSkipFrame>
+{};
+
+template <>
 struct ParamTraits<GMPVideoCodecComplexity>
 : public ContiguousEnumSerializer<GMPVideoCodecComplexity,
                                   kGMPComplexityNormal,
                                   kGMPComplexityInvalid>
 {};
 
 template <>
 struct ParamTraits<GMPVP8ResilienceMode>
@@ -34,67 +49,21 @@ struct ParamTraits<GMPVideoCodecType>
 template <>
 struct ParamTraits<GMPVideoCodecMode>
 : public ContiguousEnumSerializer<GMPVideoCodecMode,
                                   kGMPRealtimeVideo,
                                   kGMPCodecModeInvalid>
 {};
 
 template <>
-struct ParamTraits<GMPVideoCodecVP8>
-{
-  typedef GMPVideoCodecVP8 paramType;
-
-  static void Write(Message* aMsg, const paramType& aParam)
-  {
-    WriteParam(aMsg, aParam.mPictureLossIndicationOn);
-    WriteParam(aMsg, aParam.mFeedbackModeOn);
-    WriteParam(aMsg, aParam.mComplexity);
-    WriteParam(aMsg, aParam.mResilience);
-    WriteParam(aMsg, aParam.mNumberOfTemporalLayers);
-    WriteParam(aMsg, aParam.mDenoisingOn);
-    WriteParam(aMsg, aParam.mErrorConcealmentOn);
-    WriteParam(aMsg, aParam.mAutomaticResizeOn);
-    WriteParam(aMsg, aParam.mFrameDroppingOn);
-    WriteParam(aMsg, aParam.mKeyFrameInterval);
-  }
-
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
-  {
-    if (ReadParam(aMsg, aIter, &(aResult->mPictureLossIndicationOn)) &&
-        ReadParam(aMsg, aIter, &(aResult->mFeedbackModeOn)) &&
-        ReadParam(aMsg, aIter, &(aResult->mComplexity)) &&
-        ReadParam(aMsg, aIter, &(aResult->mResilience)) &&
-        ReadParam(aMsg, aIter, &(aResult->mNumberOfTemporalLayers)) &&
-        ReadParam(aMsg, aIter, &(aResult->mDenoisingOn)) &&
-        ReadParam(aMsg, aIter, &(aResult->mErrorConcealmentOn)) &&
-        ReadParam(aMsg, aIter, &(aResult->mAutomaticResizeOn)) &&
-        ReadParam(aMsg, aIter, &(aResult->mFrameDroppingOn)) &&
-        ReadParam(aMsg, aIter, &(aResult->mKeyFrameInterval))) {
-      return true;
-    }
-
-    return false;
-  }
-
-  static void Log(const paramType& aParam, std::wstring* aLog)
-  {
-    aLog->append(StringPrintf(L"[%d, %d, %d, %d, %u, %d, %d, %d, %d, %d]",
-                              aParam.mPictureLossIndicationOn,
-                              aParam.mFeedbackModeOn,
-                              aParam.mComplexity,
-                              aParam.mResilience,
-                              aParam.mNumberOfTemporalLayers,
-                              aParam.mDenoisingOn,
-                              aParam.mErrorConcealmentOn,
-                              aParam.mAutomaticResizeOn,
-                              aParam.mFrameDroppingOn,
-                              aParam.mKeyFrameInterval));
-  }
-};
+struct ParamTraits<GMPBufferType>
+: public ContiguousEnumSerializer<GMPBufferType,
+                                  GMP_BufferSingle,
+                                  GMP_BufferInvalid>
+{};
 
 template <>
 struct ParamTraits<GMPSimulcastStream>
 {
   typedef GMPSimulcastStream paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
@@ -131,40 +100,43 @@ struct ParamTraits<GMPSimulcastStream>
 
 template <>
 struct ParamTraits<GMPVideoCodec>
 {
   typedef GMPVideoCodec paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
+    WriteParam(aMsg, aParam.mGMPApiVersion);
     WriteParam(aMsg, aParam.mCodecType);
     WriteParam(aMsg, nsAutoCString(aParam.mPLName));
     WriteParam(aMsg, aParam.mPLType);
     WriteParam(aMsg, aParam.mWidth);
     WriteParam(aMsg, aParam.mHeight);
     WriteParam(aMsg, aParam.mStartBitrate);
     WriteParam(aMsg, aParam.mMaxBitrate);
     WriteParam(aMsg, aParam.mMinBitrate);
     WriteParam(aMsg, aParam.mMaxFramerate);
-    if (aParam.mCodecType == kGMPVideoCodecVP8) {
-      WriteParam(aMsg, aParam.mCodecSpecific.mVP8);
-    } else {
-      MOZ_ASSERT(false, "Serializing unknown codec type!");
-    }
+    WriteParam(aMsg, aParam.mFrameDroppingOn);
+    WriteParam(aMsg, aParam.mKeyFrameInterval);
     WriteParam(aMsg, aParam.mQPMax);
     WriteParam(aMsg, aParam.mNumberOfSimulcastStreams);
     for (uint32_t i = 0; i < aParam.mNumberOfSimulcastStreams; i++) {
       WriteParam(aMsg, aParam.mSimulcastStream[i]);
     }
     WriteParam(aMsg, aParam.mMode);
   }
 
   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   {
+    // NOTE: make sure this matches any versions supported
+    if (!ReadParam(aMsg, aIter, &(aResult->mGMPApiVersion)) ||
+      aResult->mGMPApiVersion != kGMPVersion33) {
+        return false;
+    }
     if (!ReadParam(aMsg, aIter, &(aResult->mCodecType))) {
       return false;
     }
 
     nsAutoCString plName;
     if (!ReadParam(aMsg, aIter, &plName) ||
         plName.Length() > kGMPPayloadNameSize - 1) {
       return false;
@@ -173,26 +145,19 @@ struct ParamTraits<GMPVideoCodec>
     memset(aResult->mPLName + plName.Length(), 0, kGMPPayloadNameSize - plName.Length());
 
     if (!ReadParam(aMsg, aIter, &(aResult->mPLType)) ||
         !ReadParam(aMsg, aIter, &(aResult->mWidth)) ||
         !ReadParam(aMsg, aIter, &(aResult->mHeight)) ||
         !ReadParam(aMsg, aIter, &(aResult->mStartBitrate)) ||
         !ReadParam(aMsg, aIter, &(aResult->mMaxBitrate)) ||
         !ReadParam(aMsg, aIter, &(aResult->mMinBitrate)) ||
-        !ReadParam(aMsg, aIter, &(aResult->mMaxFramerate))) {
-      return false;
-    }
-
-    if (aResult->mCodecType == kGMPVideoCodecVP8) {
-      if (!ReadParam(aMsg, aIter, &(aResult->mCodecSpecific.mVP8))) {
-        return false;
-      }
-    } else {
-      MOZ_ASSERT(false, "De-serializing unknown codec type!");
+        !ReadParam(aMsg, aIter, &(aResult->mMaxFramerate)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mFrameDroppingOn)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mKeyFrameInterval))) {
       return false;
     }
 
     if (!ReadParam(aMsg, aIter, &(aResult->mQPMax)) ||
         !ReadParam(aMsg, aIter, &(aResult->mNumberOfSimulcastStreams))) {
       return false;
     }
 
@@ -221,109 +186,11 @@ struct ParamTraits<GMPVideoCodec>
     }
     aLog->append(StringPrintf(L"[%s, %u, %u]",
                               codecName,
                               aParam.mWidth,
                               aParam.mHeight));
   }
 };
 
-template <>
-struct ParamTraits<GMPCodecSpecificInfoVP8>
-{
-  typedef GMPCodecSpecificInfoVP8 paramType;
-
-  static void Write(Message* aMsg, const paramType& aParam)
-  {
-    WriteParam(aMsg, aParam.mHasReceivedSLI);
-    WriteParam(aMsg, aParam.mPictureIdSLI);
-    WriteParam(aMsg, aParam.mHasReceivedRPSI);
-    WriteParam(aMsg, aParam.mPictureIdRPSI);
-    WriteParam(aMsg, aParam.mPictureId);
-    WriteParam(aMsg, aParam.mNonReference);
-    WriteParam(aMsg, aParam.mSimulcastIdx);
-    WriteParam(aMsg, aParam.mTemporalIdx);
-    WriteParam(aMsg, aParam.mLayerSync);
-    WriteParam(aMsg, aParam.mTL0PicIdx);
-    WriteParam(aMsg, aParam.mKeyIdx);
-  }
-
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
-  {
-    if (ReadParam(aMsg, aIter, &(aResult->mHasReceivedSLI)) &&
-        ReadParam(aMsg, aIter, &(aResult->mPictureIdSLI)) &&
-        ReadParam(aMsg, aIter, &(aResult->mHasReceivedRPSI)) &&
-        ReadParam(aMsg, aIter, &(aResult->mPictureIdRPSI)) &&
-        ReadParam(aMsg, aIter, &(aResult->mPictureId)) &&
-        ReadParam(aMsg, aIter, &(aResult->mNonReference)) &&
-        ReadParam(aMsg, aIter, &(aResult->mSimulcastIdx)) &&
-        ReadParam(aMsg, aIter, &(aResult->mTemporalIdx)) &&
-        ReadParam(aMsg, aIter, &(aResult->mLayerSync)) &&
-        ReadParam(aMsg, aIter, &(aResult->mTL0PicIdx)) &&
-        ReadParam(aMsg, aIter, &(aResult->mKeyIdx))) {
-      return true;
-    }
-    return false;
-  }
-
-  static void Log(const paramType& aParam, std::wstring* aLog)
-  {
-    aLog->append(StringPrintf(L"[%d, %u, %d, %u, %d, %d, %u, %u, %d, %d, %d]",
-                              aParam.mHasReceivedSLI,
-                              aParam.mPictureIdSLI,
-                              aParam.mHasReceivedRPSI,
-                              aParam.mPictureIdRPSI,
-                              aParam.mPictureId,
-                              aParam.mNonReference,
-                              aParam.mSimulcastIdx,
-                              aParam.mTemporalIdx,
-                              aParam.mLayerSync,
-                              aParam.mTL0PicIdx,
-                              aParam.mKeyIdx));
-  }
-};
-
-template <>
-struct ParamTraits<GMPCodecSpecificInfo>
-{
-  typedef GMPCodecSpecificInfo paramType;
-
-  static void Write(Message* aMsg, const paramType& aParam)
-  {
-    WriteParam(aMsg, aParam.mCodecType);
-    if (aParam.mCodecType == kGMPVideoCodecVP8) {
-      WriteParam(aMsg, aParam.mCodecSpecific.mVP8);
-    } else {
-      MOZ_ASSERT(false, "Serializing unknown codec type!");
-    }
-  }
-
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
-  {
-    if (!ReadParam(aMsg, aIter, &(aResult->mCodecType))) {
-      return false;
-    }
-
-    if (aResult->mCodecType == kGMPVideoCodecVP8) {
-      if (!ReadParam(aMsg, aIter, &(aResult->mCodecSpecific.mVP8))) {
-        return false;
-      }
-    } else {
-      MOZ_ASSERT(false, "De-serializing unknown codec type!");
-      return false;
-    }
-
-    return true;
-  }
-
-  static void Log(const paramType& aParam, std::wstring* aLog)
-  {
-    const char* codecName = nullptr;
-    if (aParam.mCodecType == kGMPVideoCodecVP8) {
-      codecName = "VP8";
-    }
-    aLog->append(StringPrintf(L"[%s]", codecName));
-  }
-};
-
 } // namespace IPC
 
 #endif // GMPMessageUtils_h_
--- a/content/media/gmp/GMPParent.h
+++ b/content/media/gmp/GMPParent.h
@@ -11,16 +11,17 @@
 #include "GMPVideoEncoderParent.h"
 #include "mozilla/gmp/PGMPParent.h"
 #include "nsCOMPtr.h"
 #include "nscore.h"
 #include "nsISupports.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nsIFile.h"
+#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
 
 class nsILineInputStream;
 class nsIThread;
 
 namespace mozilla {
 namespace gmp {
 
 class GMPCapability
@@ -33,17 +34,17 @@ public:
 enum GMPState {
   GMPStateNotLoaded,
   GMPStateLoaded
 };
 
 class GMPParent MOZ_FINAL : public PGMPParent
 {
 public:
-  NS_INLINE_DECL_REFCOUNTING(GMPParent)
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(GMPParent)
 
   GMPParent();
 
   nsresult Init(nsIFile* aPluginDir);
   nsresult LoadProcess();
   void MaybeUnloadProcess();
   void UnloadProcess();
   bool SupportsAPI(const nsCString& aAPI, const nsCString& aTag);
--- a/content/media/gmp/GMPPlatform.cpp
+++ b/content/media/gmp/GMPPlatform.cpp
@@ -22,25 +22,26 @@ public:
   : mTask(aTask)
   {
     MOZ_ASSERT(mTask);
   }
 
   void Run()
   {
     mTask->Run();
+    mTask->Destroy();
     mTask = nullptr;
   }
 
 private:
   ~Runnable()
   {
   }
 
-  nsAutoPtr<GMPTask> mTask;
+  GMPTask* mTask;
 };
 
 class SyncRunnable MOZ_FINAL
 {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SyncRunnable)
 
   SyncRunnable(GMPTask* aTask, MessageLoop* aMessageLoop)
@@ -66,29 +67,30 @@ public:
     while (!mDone) {
       lock.Wait();
     }
   }
 
   void Run()
   {
     mTask->Run();
+    mTask->Destroy();
     mTask = nullptr;
     MonitorAutoLock lock(mMonitor);
     mDone = true;
     lock.Notify();
   }
 
 private:
   ~SyncRunnable()
   {
   }
 
   bool mDone;
-  nsAutoPtr<GMPTask> mTask;
+  GMPTask* mTask;
   MessageLoop* mMessageLoop;
   Monitor mMonitor;
 };
 
 GMPErr
 CreateThread(GMPThread** aThread)
 {
   if (!aThread) {
@@ -103,17 +105,16 @@ CreateThread(GMPThread** aThread)
 GMPErr
 RunOnMainThread(GMPTask* aTask)
 {
   if (!aTask || !sMainLoop) {
     return GMPGenericErr;
   }
 
   nsRefPtr<Runnable> r = new Runnable(aTask);
-
   sMainLoop->PostTask(FROM_HERE, NewRunnableMethod(r.get(), &Runnable::Run));
 
   return GMPNoErr;
 }
 
 GMPErr
 SyncRunOnMainThread(GMPTask* aTask)
 {
@@ -147,16 +148,19 @@ InitPlatformAPI(GMPPlatformAPI& aPlatfor
     sMainLoop = MessageLoop::current();
   }
 
   aPlatformAPI.version = 0;
   aPlatformAPI.createthread = &CreateThread;
   aPlatformAPI.runonmainthread = &RunOnMainThread;
   aPlatformAPI.syncrunonmainthread = &SyncRunOnMainThread;
   aPlatformAPI.createmutex = &CreateMutex;
+  aPlatformAPI.createrecord = nullptr;
+  aPlatformAPI.settimer = nullptr;
+  aPlatformAPI.getcurrenttime = nullptr;
 }
 
 GMPThreadImpl::GMPThreadImpl()
 : mMutex("GMPThreadImpl"),
   mThread("GMPThread")
 {
 }
 
--- a/content/media/gmp/GMPPlatform.h
+++ b/content/media/gmp/GMPPlatform.h
@@ -8,16 +8,18 @@
 
 #include "mozilla/Mutex.h"
 #include "gmp-platform.h"
 #include "base/thread.h"
 
 namespace mozilla {
 namespace gmp {
 
+class GMPChild;
+
 void InitPlatformAPI(GMPPlatformAPI& aPlatformAPI);
 
 class GMPThreadImpl : public GMPThread
 {
 public:
   GMPThreadImpl();
   virtual ~GMPThreadImpl();
 
--- a/content/media/gmp/GMPService.cpp
+++ b/content/media/gmp/GMPService.cpp
@@ -178,17 +178,17 @@ GeckoMediaPluginService::GetThread(nsITh
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 GeckoMediaPluginService::GetGMPVideoDecoder(nsTArray<nsCString>* aTags,
                                             const nsAString& aOrigin,
                                             GMPVideoHost** aOutVideoHost,
-                                            GMPVideoDecoder** aGMPVD)
+                                            GMPVideoDecoderProxy** aGMPVD)
 {
   MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
   NS_ENSURE_ARG(aTags && aTags->Length() > 0);
   NS_ENSURE_ARG(aOutVideoHost);
   NS_ENSURE_ARG(aGMPVD);
 
   if (mShuttingDownOnGMPThread) {
     return NS_ERROR_FAILURE;
@@ -212,17 +212,17 @@ GeckoMediaPluginService::GetGMPVideoDeco
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 GeckoMediaPluginService::GetGMPVideoEncoder(nsTArray<nsCString>* aTags,
                                             const nsAString& aOrigin,
                                             GMPVideoHost** aOutVideoHost,
-                                            GMPVideoEncoder** aGMPVE)
+                                            GMPVideoEncoderProxy** aGMPVE)
 {
   MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
   NS_ENSURE_ARG(aTags && aTags->Length() > 0);
   NS_ENSURE_ARG(aOutVideoHost);
   NS_ENSURE_ARG(aGMPVE);
 
   if (mShuttingDownOnGMPThread) {
     return NS_ERROR_FAILURE;
@@ -359,31 +359,51 @@ GeckoMediaPluginService::SelectPluginFor
         gmp->SetOrigin(aOrigin);
       }
       return gmp;
     }
   }
   return nullptr;
 }
 
+class CreateGMPParentTask : public nsRunnable {
+public:
+  NS_IMETHOD Run() {
+    MOZ_ASSERT(NS_IsMainThread());
+    mParent = new GMPParent();
+    return NS_OK;
+  }
+  already_AddRefed<GMPParent> GetParent() {
+    return mParent.forget();
+  }
+private:
+  nsRefPtr<GMPParent> mParent;
+};
 
 void
 GeckoMediaPluginService::AddOnGMPThread(const nsAString& aDirectory)
 {
   MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
 
   nsCOMPtr<nsIFile> directory;
   nsresult rv = NS_NewLocalFile(aDirectory, false, getter_AddRefs(directory));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return;
   }
 
-  nsRefPtr<GMPParent> gmp = new GMPParent();
+  // The GMPParent inherits from IToplevelProtocol, which must be created
+  // on the main thread to be threadsafe. See Bug 1035653.
+  nsRefPtr<CreateGMPParentTask> task(new CreateGMPParentTask());
+  nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
+  MOZ_ASSERT(mainThread);
+  mozilla::SyncRunnable::DispatchToThread(mainThread, task);
+  nsRefPtr<GMPParent> gmp = task->GetParent();
   rv = gmp->Init(directory);
   if (NS_FAILED(rv)) {
+    NS_WARNING("Can't Create GMPParent");
     return;
   }
 
   mPlugins.AppendElement(gmp);
 }
 
 void
 GeckoMediaPluginService::RemoveOnGMPThread(const nsAString& aDirectory)
--- a/content/media/gmp/GMPService.h
+++ b/content/media/gmp/GMPService.h
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 GMPService_h_
 #define GMPService_h_
 
+#include "nsString.h"
 #include "mozIGeckoMediaPluginService.h"
 #include "nsIObserver.h"
 #include "nsTArray.h"
 #include "mozilla/Mutex.h"
 #include "nsString.h"
 #include "nsCOMPtr.h"
 #include "nsIThread.h"
 #include "nsThreadUtils.h"
new file mode 100644
--- /dev/null
+++ b/content/media/gmp/GMPSharedMemManager.cpp
@@ -0,0 +1,116 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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 "GMPSharedMemManager.h"
+#include "GMPMessageUtils.h"
+#include "mozilla/ipc/SharedMemory.h"
+#include "mozilla/StaticPtr.h"
+#include "mozilla/ClearOnShutdown.h"
+
+namespace mozilla {
+namespace gmp {
+
+// Really one set of pools on each side of the plugin API.
+
+// YUV buffers go from Encoder parent to child; pool there, and then return
+// with Decoded() frames to the Decoder parent and goes into the parent pool.
+// Compressed (encoded) data goes from the Decoder parent to the child;
+// pool there, and then return with Encoded() frames and goes into the parent
+// pool.
+static StaticAutoPtr<nsTArray<ipc::Shmem>> sGmpFreelist[GMPSharedMemManager::kGMPNumTypes];
+static uint32_t sGMPShmemManagerCount = 0;
+
+GMPSharedMemManager::GMPSharedMemManager()
+{
+  if (!sGMPShmemManagerCount) {
+    for (uint32_t i = 0; i < GMPSharedMemManager::kGMPNumTypes; i++) {
+      sGmpFreelist[i] = new nsTArray<ipc::Shmem>();
+    }
+  }
+  sGMPShmemManagerCount++;
+}
+
+GMPSharedMemManager::~GMPSharedMemManager()
+{
+  MOZ_ASSERT(sGMPShmemManagerCount > 0);
+  sGMPShmemManagerCount--;
+  if (!sGMPShmemManagerCount) {
+    for (uint32_t i = 0; i < GMPSharedMemManager::kGMPNumTypes; i++) {
+      sGmpFreelist[i] = nullptr;
+    }
+  }
+}
+
+static nsTArray<ipc::Shmem>&
+GetGmpFreelist(GMPSharedMemManager::GMPMemoryClasses aTypes)
+{
+  return *(sGmpFreelist[aTypes]);
+}
+
+static uint32_t sGmpAllocated[GMPSharedMemManager::kGMPNumTypes]; // 0's
+
+bool
+GMPSharedMemManager::MgrAllocShmem(GMPMemoryClasses aClass, size_t aSize,
+                                   ipc::Shmem::SharedMemory::SharedMemoryType aType,
+                                   ipc::Shmem* aMem)
+{
+  CheckThread();
+
+  // first look to see if we have a free buffer large enough
+  for (uint32_t i = 0; i < GetGmpFreelist(aClass).Length(); i++) {
+    MOZ_ASSERT(GetGmpFreelist(aClass)[i].IsWritable());
+    if (aSize <= GetGmpFreelist(aClass)[i].Size<uint8_t>()) {
+      *aMem = GetGmpFreelist(aClass)[i];
+      GetGmpFreelist(aClass).RemoveElementAt(i);
+      return true;
+    }
+  }
+
+  // Didn't find a buffer free with enough space; allocate one
+  size_t pagesize = ipc::SharedMemory::SystemPageSize();
+  aSize = (aSize + (pagesize-1)) & ~(pagesize-1); // round up to page size
+  bool retval = Alloc(aSize, aType, aMem);
+  if (retval) {
+    sGmpAllocated[aClass]++;
+  }
+  return retval;
+}
+
+bool
+GMPSharedMemManager::MgrDeallocShmem(GMPMemoryClasses aClass, ipc::Shmem& aMem)
+{
+  CheckThread();
+
+  size_t size = aMem.Size<uint8_t>();
+  size_t total = 0;
+  // XXX This works; there are better pool algorithms.  We need to avoid
+  // "falling off a cliff" with too low a number
+  if (GetGmpFreelist(aClass).Length() > 10) {
+    Dealloc(GetGmpFreelist(aClass)[0]);
+    GetGmpFreelist(aClass).RemoveElementAt(0);
+    // The allocation numbers will be fubar on the Child!
+    sGmpAllocated[aClass]--;
+  }
+  for (uint32_t i = 0; i < GetGmpFreelist(aClass).Length(); i++) {
+    MOZ_ASSERT(GetGmpFreelist(aClass)[i].IsWritable());
+    total += GetGmpFreelist(aClass)[i].Size<uint8_t>();
+    if (size < GetGmpFreelist(aClass)[i].Size<uint8_t>()) {
+      GetGmpFreelist(aClass).InsertElementAt(i, aMem);
+      return true;
+    }
+  }
+  GetGmpFreelist(aClass).AppendElement(aMem);
+
+  return true;
+}
+
+uint32_t
+GMPSharedMemManager::NumInUse(GMPMemoryClasses aClass)
+{
+  return sGmpAllocated[aClass] - GetGmpFreelist(aClass).Length();
+}
+
+}
+}
--- a/content/media/gmp/GMPSharedMemManager.h
+++ b/content/media/gmp/GMPSharedMemManager.h
@@ -2,25 +2,53 @@
 /* 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 GMPSharedMemManager_h_
 #define GMPSharedMemManager_h_
 
 #include "mozilla/ipc/Shmem.h"
+#include "nsTArray.h"
 
 namespace mozilla {
 namespace gmp {
 
 class GMPSharedMemManager
 {
 public:
-  virtual bool MgrAllocShmem(size_t aSize,
+  typedef enum {
+    kGMPFrameData = 0,
+    kGMPEncodedData,
+    kGMPNumTypes
+  } GMPMemoryClasses;
+
+  // This is a heuristic - max of 10 free in the Child pool, plus those
+  // in-use for the encoder and decoder at the given moment and not yet
+  // returned to the parent pool (which is not included).  If more than
+  // this are needed, we presume the client has either crashed or hung
+  // (perhaps temporarily).
+  static const uint32_t kGMPBufLimit = 20;
+
+  GMPSharedMemManager();
+  virtual ~GMPSharedMemManager();
+
+  virtual bool MgrAllocShmem(GMPMemoryClasses aClass, size_t aSize,
                              ipc::Shmem::SharedMemory::SharedMemoryType aType,
-                             ipc::Shmem* aMem) = 0;
-  virtual bool MgrDeallocShmem(ipc::Shmem& aMem) = 0;
+                             ipc::Shmem* aMem);
+  virtual bool MgrDeallocShmem(GMPMemoryClasses aClass, ipc::Shmem& aMem);
+
+  // So we can know if data is "piling up" for the plugin - I.e. it's hung or crashed
+  virtual uint32_t NumInUse(GMPMemoryClasses aClass);
+
+  // Parent and child impls will differ here
+  virtual void CheckThread() = 0;
+
+  // These have to be implemented using the AllocShmem/etc provided by the IPDL-generated interfaces,
+  // so have the Parent/Child implement them.
+  virtual bool Alloc(size_t aSize, ipc::Shmem::SharedMemory::SharedMemoryType aType, ipc::Shmem* aMem) = 0;
+  virtual void Dealloc(ipc::Shmem& aMem) = 0;
 };
 
 } // namespace gmp
 } // namespace mozilla
 
 #endif // GMPSharedMemManager_h_
--- a/content/media/gmp/GMPTypes.ipdlh
+++ b/content/media/gmp/GMPTypes.ipdlh
@@ -1,24 +1,27 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
+using GMPBufferType from "gmp-video-codec.h";
+
 namespace mozilla {
 namespace gmp {
 
 struct GMPVideoEncodedFrameData
 {
-  int64_t mCaptureTime_ms;
   uint32_t mEncodedWidth;
   uint32_t mEncodedHeight;
-  uint32_t mTimeStamp;
+  uint64_t mTimestamp; // microseconds
+  uint64_t mDuration; // microseconds
   uint32_t mFrameType;
   uint32_t mSize;
+  GMPBufferType mBufferType;
   Shmem mBuffer;
   bool mCompleteFrame;
 };
 
 struct GMPPlaneData
 {
   int32_t mSize;
   int32_t mStride;
@@ -27,14 +30,14 @@ struct GMPPlaneData
 
 struct GMPVideoi420FrameData
 {
   GMPPlaneData mYPlane;
   GMPPlaneData mUPlane;
   GMPPlaneData mVPlane;
   int32_t mWidth;
   int32_t mHeight;
-  uint32_t mTimestamp;
-  int64_t mRenderTime_ms;
+  uint64_t mTimestamp; // microseconds
+  uint64_t mDuration; // microseconds
 };
 
 }
 }
--- a/content/media/gmp/GMPVideoDecoderChild.cpp
+++ b/content/media/gmp/GMPVideoDecoderChild.cpp
@@ -75,67 +75,89 @@ GMPVideoDecoderChild::ReceivedDecodedFra
 void
 GMPVideoDecoderChild::InputDataExhausted()
 {
   MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
 
   SendInputDataExhausted();
 }
 
-bool
-GMPVideoDecoderChild::MgrAllocShmem(size_t aSize,
-                                    ipc::Shmem::SharedMemory::SharedMemoryType aType,
-                                    ipc::Shmem* aMem)
+void
+GMPVideoDecoderChild::DrainComplete()
 {
   MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
 
-  return AllocShmem(aSize, aType, aMem);
+  SendDrainComplete();
 }
 
-bool
-GMPVideoDecoderChild::MgrDeallocShmem(Shmem& aMem)
+void
+GMPVideoDecoderChild::ResetComplete()
 {
   MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
 
-  return DeallocShmem(aMem);
+  SendResetComplete();
+}
+
+void
+GMPVideoDecoderChild::CheckThread()
+{
+  MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
 }
 
 bool
 GMPVideoDecoderChild::RecvInitDecode(const GMPVideoCodec& aCodecSettings,
+                                     const nsTArray<uint8_t>& aCodecSpecific,
                                      const int32_t& aCoreCount)
 {
   if (!mVideoDecoder) {
     return false;
   }
 
   // Ignore any return code. It is OK for this to fail without killing the process.
-  mVideoDecoder->InitDecode(aCodecSettings, this, aCoreCount);
-
+  mVideoDecoder->InitDecode(aCodecSettings,
+                            aCodecSpecific.Elements(),
+                            aCodecSpecific.Length(),
+                            this,
+                            aCoreCount);
   return true;
 }
 
 bool
 GMPVideoDecoderChild::RecvDecode(const GMPVideoEncodedFrameData& aInputFrame,
                                  const bool& aMissingFrames,
-                                 const GMPCodecSpecificInfo& aCodecSpecificInfo,
+                                 const nsTArray<uint8_t>& aCodecSpecificInfo,
                                  const int64_t& aRenderTimeMs)
 {
   if (!mVideoDecoder) {
     return false;
   }
 
   auto f = new GMPVideoEncodedFrameImpl(aInputFrame, &mVideoHost);
 
   // Ignore any return code. It is OK for this to fail without killing the process.
-  mVideoDecoder->Decode(f, aMissingFrames, aCodecSpecificInfo, aRenderTimeMs);
+  mVideoDecoder->Decode(f,
+                        aMissingFrames,
+                        aCodecSpecificInfo.Elements(),
+                        aCodecSpecificInfo.Length(),
+                        aRenderTimeMs);
 
   return true;
 }
 
 bool
+GMPVideoDecoderChild::RecvChildShmemForPool(Shmem& aFrameBuffer)
+{
+  if (aFrameBuffer.IsWritable()) {
+    mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPFrameData,
+                                               aFrameBuffer);
+  }
+  return true;
+}
+
+bool
 GMPVideoDecoderChild::RecvReset()
 {
   if (!mVideoDecoder) {
     return false;
   }
 
   // Ignore any return code. It is OK for this to fail without killing the process.
   mVideoDecoder->Reset();
--- a/content/media/gmp/GMPVideoDecoderChild.h
+++ b/content/media/gmp/GMPVideoDecoderChild.h
@@ -6,53 +6,75 @@
 #ifndef GMPVideoDecoderChild_h_
 #define GMPVideoDecoderChild_h_
 
 #include "nsString.h"
 #include "mozilla/gmp/PGMPVideoDecoderChild.h"
 #include "gmp-video-decode.h"
 #include "GMPSharedMemManager.h"
 #include "GMPVideoHost.h"
+#include "mozilla/gmp/GMPTypes.h"
 
 namespace mozilla {
 namespace gmp {
 
 class GMPChild;
 
 class GMPVideoDecoderChild : public PGMPVideoDecoderChild,
-                             public GMPDecoderCallback,
+                             public GMPVideoDecoderCallback,
                              public GMPSharedMemManager
 {
 public:
   GMPVideoDecoderChild(GMPChild* aPlugin);
   virtual ~GMPVideoDecoderChild();
 
   void Init(GMPVideoDecoder* aDecoder);
   GMPVideoHostImpl& Host();
 
-  // GMPDecoderCallback
+  // GMPVideoDecoderCallback
   virtual void Decoded(GMPVideoi420Frame* decodedFrame) MOZ_OVERRIDE;
   virtual void ReceivedDecodedReferenceFrame(const uint64_t pictureId) MOZ_OVERRIDE;
   virtual void ReceivedDecodedFrame(const uint64_t pictureId) MOZ_OVERRIDE;
   virtual void InputDataExhausted() MOZ_OVERRIDE;
+  virtual void DrainComplete() MOZ_OVERRIDE;
+  virtual void ResetComplete() MOZ_OVERRIDE;
 
   // GMPSharedMemManager
-  virtual bool MgrAllocShmem(size_t aSize,
-                             ipc::Shmem::SharedMemory::SharedMemoryType aType,
-                             ipc::Shmem* aMem) MOZ_OVERRIDE;
-  virtual bool MgrDeallocShmem(Shmem& aMem) MOZ_OVERRIDE;
+  virtual void CheckThread();
+  virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, Shmem* aMem)
+  {
+#ifndef SHMEM_ALLOC_IN_CHILD
+    return CallNeedShmem(aSize, aMem);
+#else
+#ifdef GMP_SAFE_SHMEM
+    return AllocShmem(aSize, aType, aMem);
+#else
+    return AllocUnsafeShmem(aSize, aType, aMem);
+#endif
+#endif
+  }
+  virtual void Dealloc(Shmem& aMem)
+  {
+#ifndef SHMEM_ALLOC_IN_CHILD
+    SendParentShmemForPool(aMem);
+#else
+    DeallocShmem(aMem);
+#endif
+  }
 
 private:
   // PGMPVideoDecoderChild
-  virtual bool RecvInitDecode(const GMPVideoCodec& codecSettings,
-                              const int32_t& coreCount) MOZ_OVERRIDE;
-  virtual bool RecvDecode(const GMPVideoEncodedFrameData& inputFrame,
-                          const bool& missingFrames,
-                          const GMPCodecSpecificInfo& codecSpecificInfo,
-                          const int64_t& renderTimeMs) MOZ_OVERRIDE;
+  virtual bool RecvInitDecode(const GMPVideoCodec& aCodecSettings,
+                              const nsTArray<uint8_t>& aCodecSpecific,
+                              const int32_t& aCoreCount) MOZ_OVERRIDE;
+  virtual bool RecvDecode(const GMPVideoEncodedFrameData& aInputFrame,
+                          const bool& aMissingFrames,
+                          const nsTArray<uint8_t>& aCodecSpecificInfo,
+                          const int64_t& aRenderTimeMs) MOZ_OVERRIDE;
+  virtual bool RecvChildShmemForPool(Shmem& aFrameBuffer) MOZ_OVERRIDE;
   virtual bool RecvReset() MOZ_OVERRIDE;
   virtual bool RecvDrain() MOZ_OVERRIDE;
   virtual bool RecvDecodingComplete() MOZ_OVERRIDE;
 
   GMPChild* mPlugin;
   GMPVideoDecoder* mVideoDecoder;
   GMPVideoHostImpl mVideoHost;
 };
--- a/content/media/gmp/GMPVideoDecoderParent.cpp
+++ b/content/media/gmp/GMPVideoDecoderParent.cpp
@@ -7,16 +7,17 @@
 #include "GMPVideoEncodedFrameImpl.h"
 #include "GMPVideoi420FrameImpl.h"
 #include "GMPParent.h"
 #include <stdio.h>
 #include "mozilla/unused.h"
 #include "GMPMessageUtils.h"
 #include "nsAutoRef.h"
 #include "nsThreadUtils.h"
+#include "mozilla/gmp/GMPTypes.h"
 
 template <>
 class nsAutoRefTraits<GMPVideoEncodedFrame> : public nsPointerRefTraits<GMPVideoEncodedFrame>
 {
 public:
   static void Release(GMPVideoEncodedFrame* aFrame) { aFrame->Destroy(); }
 };
 
@@ -37,160 +38,159 @@ GMPVideoDecoderParent::~GMPVideoDecoderP
 }
 
 GMPVideoHostImpl&
 GMPVideoDecoderParent::Host()
 {
   return mVideoHost;
 }
 
-bool
-GMPVideoDecoderParent::MgrAllocShmem(size_t aSize,
-                                     ipc::Shmem::SharedMemory::SharedMemoryType aType,
-                                     ipc::Shmem* aMem)
-{
-  MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
-
-  return AllocShmem(aSize, aType, aMem);
-}
-
-bool
-GMPVideoDecoderParent::MgrDeallocShmem(Shmem& aMem)
-{
-  MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
-
-  return DeallocShmem(aMem);
-}
-
-GMPVideoErr
+nsresult
 GMPVideoDecoderParent::InitDecode(const GMPVideoCodec& aCodecSettings,
-                                  GMPDecoderCallback* aCallback,
+                                  const nsTArray<uint8_t>& aCodecSpecific,
+                                  GMPVideoDecoderCallback* aCallback,
                                   int32_t aCoreCount)
 {
   if (!mCanSendMessages) {
     NS_WARNING("Trying to use an invalid GMP video decoder!");
-    return GMPVideoGenericErr;
+    return NS_ERROR_FAILURE;
   }
 
   MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
 
   if (!aCallback) {
-    return GMPVideoGenericErr;
+    return NS_ERROR_FAILURE;
   }
   mCallback = aCallback;
 
-  if (!SendInitDecode(aCodecSettings, aCoreCount)) {
-    return GMPVideoGenericErr;
+  if (!SendInitDecode(aCodecSettings, aCodecSpecific, aCoreCount)) {
+    return NS_ERROR_FAILURE;
   }
 
   // Async IPC, we don't have access to a return value.
-  return GMPVideoNoErr;
+  return NS_OK;
 }
 
-GMPVideoErr
+nsresult
 GMPVideoDecoderParent::Decode(GMPVideoEncodedFrame* aInputFrame,
                               bool aMissingFrames,
-                              const GMPCodecSpecificInfo& aCodecSpecificInfo,
+                              const nsTArray<uint8_t>& aCodecSpecificInfo,
                               int64_t aRenderTimeMs)
 {
   nsAutoRef<GMPVideoEncodedFrame> autoDestroy(aInputFrame);
 
   if (!mCanSendMessages) {
     NS_WARNING("Trying to use an invalid GMP video decoder!");
-    return GMPVideoGenericErr;
+    return NS_ERROR_FAILURE;
   }
 
   MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
 
   auto inputFrameImpl = static_cast<GMPVideoEncodedFrameImpl*>(aInputFrame);
 
   GMPVideoEncodedFrameData frameData;
   inputFrameImpl->RelinquishFrameData(frameData);
 
+  // Very rough kill-switch if the plugin stops processing.  If it's merely
+  // hung and continues, we'll come back to life eventually.
+  // 3* is because we're using 3 buffers per frame for i420 data for now.
+  if (NumInUse(kGMPFrameData) > 3*GMPSharedMemManager::kGMPBufLimit ||
+      NumInUse(kGMPEncodedData) > GMPSharedMemManager::kGMPBufLimit) {
+    return NS_ERROR_FAILURE;
+  }
+
   if (!SendDecode(frameData,
                   aMissingFrames,
                   aCodecSpecificInfo,
                   aRenderTimeMs)) {
-    return GMPVideoGenericErr;
+    return NS_ERROR_FAILURE;
   }
 
   // Async IPC, we don't have access to a return value.
-  return GMPVideoNoErr;
+  return NS_OK;
 }
 
-GMPVideoErr
+nsresult
 GMPVideoDecoderParent::Reset()
 {
   if (!mCanSendMessages) {
     NS_WARNING("Trying to use an invalid GMP video decoder!");
-    return GMPVideoGenericErr;
+    return NS_ERROR_FAILURE;
   }
 
   MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
 
   if (!SendReset()) {
-    return GMPVideoGenericErr;
+    return NS_ERROR_FAILURE;
   }
 
   // Async IPC, we don't have access to a return value.
-  return GMPVideoNoErr;
+  return NS_OK;
 }
 
-GMPVideoErr
+nsresult
 GMPVideoDecoderParent::Drain()
 {
   if (!mCanSendMessages) {
     NS_WARNING("Trying to use an invalid GMP video decoder!");
-    return GMPVideoGenericErr;
+    return NS_ERROR_FAILURE;
   }
 
   MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
 
   if (!SendDrain()) {
-    return GMPVideoGenericErr;
+    return NS_ERROR_FAILURE;
   }
 
   // Async IPC, we don't have access to a return value.
-  return GMPVideoNoErr;
+  return NS_OK;
 }
 
 // Note: Consider keeping ActorDestroy sync'd up when making changes here.
-void
+nsresult
 GMPVideoDecoderParent::DecodingComplete()
 {
   if (!mCanSendMessages) {
     NS_WARNING("Trying to use an invalid GMP video decoder!");
-    return;
+    return NS_ERROR_FAILURE;
   }
 
   MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
 
   mCanSendMessages = false;
 
   mCallback = nullptr;
 
   mVideoHost.DoneWithAPI();
 
   unused << SendDecodingComplete();
+
+  return NS_OK;
 }
 
 // Note: Keep this sync'd up with DecodingComplete
 void
 GMPVideoDecoderParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   if (mPlugin) {
     // Ignore any return code. It is OK for this to fail without killing the process.
     mPlugin->VideoDecoderDestroyed(this);
     mPlugin = nullptr;
   }
   mCanSendMessages = false;
   mCallback = nullptr;
   mVideoHost.ActorDestroyed();
 }
 
+void
+GMPVideoDecoderParent::CheckThread()
+{
+  MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
+}
+
 bool
 GMPVideoDecoderParent::RecvDecoded(const GMPVideoi420FrameData& aDecodedFrame)
 {
   if (!mCallback) {
     return false;
   }
 
   auto f = new GMPVideoi420FrameImpl(aDecodedFrame, &mVideoHost);
@@ -236,16 +236,69 @@ GMPVideoDecoderParent::RecvInputDataExha
 
   // Ignore any return code. It is OK for this to fail without killing the process.
   mCallback->InputDataExhausted();
 
   return true;
 }
 
 bool
+GMPVideoDecoderParent::RecvDrainComplete()
+{
+  if (!mCallback) {
+    return false;
+  }
+
+  // Ignore any return code. It is OK for this to fail without killing the process.
+  mCallback->DrainComplete();
+
+  return true;
+}
+
+bool
+GMPVideoDecoderParent::RecvResetComplete()
+{
+  if (!mCallback) {
+    return false;
+  }
+
+  // Ignore any return code. It is OK for this to fail without killing the process.
+  mCallback->ResetComplete();
+
+  return true;
+}
+
+bool
+GMPVideoDecoderParent::RecvParentShmemForPool(Shmem& aEncodedBuffer)
+{
+  if (aEncodedBuffer.IsWritable()) {
+    mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPEncodedData,
+                                               aEncodedBuffer);
+  }
+  return true;
+}
+
+bool
+GMPVideoDecoderParent::AnswerNeedShmem(const uint32_t& aFrameBufferSize,
+                                       Shmem* aMem)
+{
+  ipc::Shmem mem;
+
+  if (!mVideoHost.SharedMemMgr()->MgrAllocShmem(GMPSharedMemManager::kGMPFrameData,
+                                                aFrameBufferSize,
+                                                ipc::SharedMemory::TYPE_BASIC, &mem))
+  {
+    return false;
+  }
+  *aMem = mem;
+  mem = ipc::Shmem();
+  return true;
+}
+
+bool
 GMPVideoDecoderParent::Recv__delete__()
 {
   if (mPlugin) {
     // Ignore any return code. It is OK for this to fail without killing the process.
     mPlugin->VideoDecoderDestroyed(this);
     mPlugin = nullptr;
   }
 
--- a/content/media/gmp/GMPVideoDecoderParent.h
+++ b/content/media/gmp/GMPVideoDecoderParent.h
@@ -7,64 +7,80 @@
 #define GMPVideoDecoderParent_h_
 
 #include "mozilla/RefPtr.h"
 #include "gmp-video-decode.h"
 #include "mozilla/gmp/PGMPVideoDecoderParent.h"
 #include "GMPMessageUtils.h"
 #include "GMPSharedMemManager.h"
 #include "GMPVideoHost.h"
+#include "GMPVideoDecoderProxy.h"
 
 namespace mozilla {
 namespace gmp {
 
 class GMPParent;
 
-class GMPVideoDecoderParent MOZ_FINAL : public GMPVideoDecoder
-                                      , public PGMPVideoDecoderParent
+class GMPVideoDecoderParent MOZ_FINAL : public PGMPVideoDecoderParent
                                       , public GMPSharedMemManager
+                                      , public GMPVideoDecoderProxy
 {
 public:
   NS_INLINE_DECL_REFCOUNTING(GMPVideoDecoderParent)
 
   GMPVideoDecoderParent(GMPParent *aPlugin);
 
   GMPVideoHostImpl& Host();
 
-  // GMPSharedMemManager
-  virtual bool MgrAllocShmem(size_t aSize,
-                             ipc::Shmem::SharedMemory::SharedMemoryType aType,
-                             ipc::Shmem* aMem) MOZ_OVERRIDE;
-  virtual bool MgrDeallocShmem(Shmem& aMem) MOZ_OVERRIDE;
+  // GMPVideoDecoder
+  virtual nsresult InitDecode(const GMPVideoCodec& aCodecSettings,
+                              const nsTArray<uint8_t>& aCodecSpecific,
+                              GMPVideoDecoderCallback* aCallback,
+                              int32_t aCoreCount) MOZ_OVERRIDE;
+  virtual nsresult Decode(GMPVideoEncodedFrame* aInputFrame,
+                          bool aMissingFrames,
+                          const nsTArray<uint8_t>& aCodecSpecificInfo,
+                          int64_t aRenderTimeMs = -1) MOZ_OVERRIDE;
+  virtual nsresult Reset() MOZ_OVERRIDE;
+  virtual nsresult Drain() MOZ_OVERRIDE;
+  virtual nsresult DecodingComplete() MOZ_OVERRIDE;
 
-  // GMPVideoDecoder
-  virtual GMPVideoErr InitDecode(const GMPVideoCodec& aCodecSettings,
-                                 GMPDecoderCallback* aCallback,
-                                 int32_t aCoreCount) MOZ_OVERRIDE;
-  virtual GMPVideoErr Decode(GMPVideoEncodedFrame* aInputFrame,
-                             bool aMissingFrames,
-                             const GMPCodecSpecificInfo& aCodecSpecificInfo,
-                             int64_t aRenderTimeMs = -1) MOZ_OVERRIDE;
-  virtual GMPVideoErr Reset() MOZ_OVERRIDE;
-  virtual GMPVideoErr Drain() MOZ_OVERRIDE;
-  virtual void DecodingComplete() MOZ_OVERRIDE;
+  // GMPSharedMemManager
+  virtual void CheckThread();
+  virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, Shmem* aMem)
+  {
+#ifdef GMP_SAFE_SHMEM
+    return AllocShmem(aSize, aType, aMem);
+#else
+    return AllocUnsafeShmem(aSize, aType, aMem);
+#endif
+  }
+  virtual void Dealloc(Shmem& aMem)
+  {
+    DeallocShmem(aMem);
+  }
 
 private:
   ~GMPVideoDecoderParent();
 
   // PGMPVideoDecoderParent
   virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
   virtual bool RecvDecoded(const GMPVideoi420FrameData& aDecodedFrame) MOZ_OVERRIDE;
   virtual bool RecvReceivedDecodedReferenceFrame(const uint64_t& aPictureId) MOZ_OVERRIDE;
   virtual bool RecvReceivedDecodedFrame(const uint64_t& aPictureId) MOZ_OVERRIDE;
   virtual bool RecvInputDataExhausted() MOZ_OVERRIDE;
+  virtual bool RecvDrainComplete() MOZ_OVERRIDE;
+  virtual bool RecvResetComplete() MOZ_OVERRIDE;
+  virtual bool RecvParentShmemForPool(Shmem& aEncodedBuffer) MOZ_OVERRIDE;
+  virtual bool AnswerNeedShmem(const uint32_t& aFrameBufferSize,
+                               Shmem* aMem) MOZ_OVERRIDE;
   virtual bool Recv__delete__() MOZ_OVERRIDE;
 
   bool mCanSendMessages;
   GMPParent* mPlugin;
-  GMPDecoderCallback* mCallback;
+  GMPVideoDecoderCallback* mCallback;
   GMPVideoHostImpl mVideoHost;
 };
 
 } // namespace gmp
 } // namespace mozilla
 
 #endif // GMPVideoDecoderParent_h_
new file mode 100644
--- /dev/null
+++ b/content/media/gmp/GMPVideoDecoderProxy.h
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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 GMPVideoDecoderProxy_h_
+#define GMPVideoDecoderProxy_h_
+
+#include "nsTArray.h"
+#include "gmp-video-decode.h"
+#include "gmp-video-frame-i420.h"
+#include "gmp-video-frame-encoded.h"
+
+// A proxy to GMPVideoDecoder in the child process.
+// GMPVideoDecoderParent exposes this to users the GMP.
+// This enables Gecko to pass nsTArrays to the child GMP and avoid
+// an extra copy when doing so.
+class GMPVideoDecoderProxy {
+public:
+  virtual nsresult InitDecode(const GMPVideoCodec& aCodecSettings,
+                              const nsTArray<uint8_t>& aCodecSpecific,
+                              GMPVideoDecoderCallback* aCallback,
+                              int32_t aCoreCount) = 0;
+  virtual nsresult Decode(GMPVideoEncodedFrame* aInputFrame,
+                          bool aMissingFrames,
+                          const nsTArray<uint8_t>& aCodecSpecificInfo,
+                          int64_t aRenderTimeMs = -1) = 0;
+  virtual nsresult Reset() = 0;
+  virtual nsresult Drain() = 0;
+  virtual nsresult DecodingComplete() = 0;
+};
+
+#endif
--- a/content/media/gmp/GMPVideoEncodedFrameImpl.cpp
+++ b/content/media/gmp/GMPVideoEncodedFrameImpl.cpp
@@ -9,51 +9,59 @@
 #include "GMPSharedMemManager.h"
 
 namespace mozilla {
 namespace gmp {
 
 GMPVideoEncodedFrameImpl::GMPVideoEncodedFrameImpl(GMPVideoHostImpl* aHost)
 : mEncodedWidth(0),
   mEncodedHeight(0),
-  mTimeStamp(0),
-  mCaptureTime_ms(0),
+  mTimeStamp(0ll),
+  mDuration(0ll),
   mFrameType(kGMPDeltaFrame),
   mSize(0),
   mCompleteFrame(false),
-  mHost(aHost)
+  mHost(aHost),
+  mBufferType(GMP_BufferSingle)
 {
   MOZ_ASSERT(aHost);
   aHost->EncodedFrameCreated(this);
 }
 
 GMPVideoEncodedFrameImpl::GMPVideoEncodedFrameImpl(const GMPVideoEncodedFrameData& aFrameData,
                                                    GMPVideoHostImpl* aHost)
 : mEncodedWidth(aFrameData.mEncodedWidth()),
   mEncodedHeight(aFrameData.mEncodedHeight()),
-  mTimeStamp(aFrameData.mTimeStamp()),
-  mCaptureTime_ms(aFrameData.mCaptureTime_ms()),
+  mTimeStamp(aFrameData.mTimestamp()),
+  mDuration(aFrameData.mDuration()),
   mFrameType(static_cast<GMPVideoFrameType>(aFrameData.mFrameType())),
   mSize(aFrameData.mSize()),
   mCompleteFrame(aFrameData.mCompleteFrame()),
   mHost(aHost),
-  mBuffer(aFrameData.mBuffer())
+  mBuffer(aFrameData.mBuffer()),
+  mBufferType(aFrameData.mBufferType())
 {
   MOZ_ASSERT(aHost);
   aHost->EncodedFrameCreated(this);
 }
 
 GMPVideoEncodedFrameImpl::~GMPVideoEncodedFrameImpl()
 {
   DestroyBuffer();
   if (mHost) {
     mHost->EncodedFrameDestroyed(this);
   }
 }
 
+const GMPEncryptedBufferData*
+GMPVideoEncodedFrameImpl::GetDecryptionData() const
+{
+  return nullptr;
+}
+
 GMPVideoFrameFormat
 GMPVideoEncodedFrameImpl::GetFrameFormat()
 {
   return kGMPEncodedVideoFrame;
 }
 
 void
 GMPVideoEncodedFrameImpl::DoneWithAPI()
@@ -75,79 +83,82 @@ GMPVideoEncodedFrameImpl::ActorDestroyed
   mHost = nullptr;
 }
 
 bool
 GMPVideoEncodedFrameImpl::RelinquishFrameData(GMPVideoEncodedFrameData& aFrameData)
 {
   aFrameData.mEncodedWidth() = mEncodedWidth;
   aFrameData.mEncodedHeight() = mEncodedHeight;
-  aFrameData.mTimeStamp() = mTimeStamp;
-  aFrameData.mCaptureTime_ms() = mCaptureTime_ms;
+  aFrameData.mTimestamp() = mTimeStamp;
+  aFrameData.mDuration() = mDuration;
   aFrameData.mFrameType() = mFrameType;
   aFrameData.mSize() = mSize;
   aFrameData.mCompleteFrame() = mCompleteFrame;
   aFrameData.mBuffer() = mBuffer;
+  aFrameData.mBufferType() = mBufferType;
 
   // This method is called right before Shmem is sent to another process.
   // We need to effectively zero out our member copy so that we don't
   // try to delete Shmem we don't own later.
   mBuffer = ipc::Shmem();
 
   return true;
 }
 
 void
 GMPVideoEncodedFrameImpl::DestroyBuffer()
 {
   if (mHost && mBuffer.IsWritable()) {
-    mHost->SharedMemMgr()->MgrDeallocShmem(mBuffer);
+    mHost->SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPEncodedData, mBuffer);
   }
   mBuffer = ipc::Shmem();
 }
 
-GMPVideoErr
+GMPErr
 GMPVideoEncodedFrameImpl::CreateEmptyFrame(uint32_t aSize)
 {
-  DestroyBuffer();
-
-  if (aSize != 0) {
-    if (!mHost->SharedMemMgr()->MgrAllocShmem(aSize, ipc::SharedMemory::TYPE_BASIC, &mBuffer) ||
+  if (aSize == 0) {
+    DestroyBuffer();
+  } else if (aSize > AllocatedSize()) {
+    DestroyBuffer();
+    if (!mHost->SharedMemMgr()->MgrAllocShmem(GMPSharedMemManager::kGMPEncodedData, aSize,
+                                              ipc::SharedMemory::TYPE_BASIC, &mBuffer) ||
         !Buffer()) {
-      return GMPVideoAllocErr;
+      return GMPAllocErr;
     }
   }
-
   mSize = aSize;
 
-  return GMPVideoNoErr;
+  return GMPNoErr;
 }
 
-GMPVideoErr
+GMPErr
 GMPVideoEncodedFrameImpl::CopyFrame(const GMPVideoEncodedFrame& aFrame)
 {
   auto& f = static_cast<const GMPVideoEncodedFrameImpl&>(aFrame);
 
   if (f.mSize != 0) {
-    GMPVideoErr err = CreateEmptyFrame(f.mSize);
-    if (err != GMPVideoNoErr) {
+    GMPErr err = CreateEmptyFrame(f.mSize);
+    if (err != GMPNoErr) {
       return err;
     }
     memcpy(Buffer(), f.Buffer(), f.mSize);
   }
   mEncodedWidth = f.mEncodedWidth;
   mEncodedHeight = f.mEncodedHeight;
   mTimeStamp = f.mTimeStamp;
-  mCaptureTime_ms = f.mCaptureTime_ms;
+  mDuration = f.mDuration;
   mFrameType = f.mFrameType;
-  mSize = f.mSize;
+  mSize = f.mSize; // already set...
   mCompleteFrame = f.mCompleteFrame;
+  mBufferType = f.mBufferType;
   // Don't copy host, that should have been set properly on object creation via host.
 
-  return GMPVideoNoErr;
+  return GMPNoErr;
 }
 
 void
 GMPVideoEncodedFrameImpl::SetEncodedWidth(uint32_t aEncodedWidth)
 {
   mEncodedWidth = aEncodedWidth;
 }
 
@@ -165,37 +176,37 @@ GMPVideoEncodedFrameImpl::SetEncodedHeig
 
 uint32_t
 GMPVideoEncodedFrameImpl::EncodedHeight()
 {
   return mEncodedHeight;
 }
 
 void
-GMPVideoEncodedFrameImpl::SetTimeStamp(uint32_t aTimeStamp)
+GMPVideoEncodedFrameImpl::SetTimeStamp(uint64_t aTimeStamp)
 {
   mTimeStamp = aTimeStamp;
 }
 
-uint32_t
+uint64_t
 GMPVideoEncodedFrameImpl::TimeStamp()
 {
   return mTimeStamp;
 }
 
 void
-GMPVideoEncodedFrameImpl::SetCaptureTime(int64_t aCaptureTime)
+GMPVideoEncodedFrameImpl::SetDuration(uint64_t aDuration)
 {
-  mCaptureTime_ms = aCaptureTime;
+  mDuration = aDuration;
 }
 
-int64_t
-GMPVideoEncodedFrameImpl::CaptureTime()
+uint64_t
+GMPVideoEncodedFrameImpl::Duration() const
 {
-  return mCaptureTime_ms;
+  return mDuration;
 }
 
 void
 GMPVideoEncodedFrameImpl::SetFrameType(GMPVideoFrameType aFrameType)
 {
   mFrameType = aFrameType;
 }
 
@@ -212,17 +223,18 @@ GMPVideoEncodedFrameImpl::SetAllocatedSi
     return;
   }
 
   if (!mHost) {
     return;
   }
 
   ipc::Shmem new_mem;
-  if (!mHost->SharedMemMgr()->MgrAllocShmem(aNewSize, ipc::SharedMemory::TYPE_BASIC, &new_mem) ||
+  if (!mHost->SharedMemMgr()->MgrAllocShmem(GMPSharedMemManager::kGMPEncodedData, aNewSize,
+                                            ipc::SharedMemory::TYPE_BASIC, &new_mem) ||
       !new_mem.get<uint8_t>()) {
     return;
   }
 
   if (mBuffer.IsReadable()) {
     memcpy(new_mem.get<uint8_t>(), Buffer(), mSize);
   }
 
@@ -277,10 +289,22 @@ GMPVideoEncodedFrameImpl::Buffer()
 }
 
 void
 GMPVideoEncodedFrameImpl::Destroy()
 {
   delete this;
 }
 
+GMPBufferType
+GMPVideoEncodedFrameImpl::BufferType() const
+{
+  return mBufferType;
+}
+
+void
+GMPVideoEncodedFrameImpl::SetBufferType(GMPBufferType aBufferType)
+{
+  mBufferType = aBufferType;
+}
+
 } // namespace gmp
 } // namespace mozilla
--- a/content/media/gmp/GMPVideoEncodedFrameImpl.h
+++ b/content/media/gmp/GMPVideoEncodedFrameImpl.h
@@ -26,19 +26,20 @@
  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  * OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef GMPVideoEncodedFrameImpl_h_
 #define GMPVideoEncodedFrameImpl_h_
 
-#include "gmp-video-errors.h"
+#include "gmp-errors.h"
 #include "gmp-video-frame.h"
 #include "gmp-video-frame-encoded.h"
+#include "gmp-decryption.h"
 #include "mozilla/ipc/Shmem.h"
 
 namespace mozilla {
 namespace gmp {
 
 class GMPVideoHostImpl;
 class GMPVideoEncodedFrameData;
 
@@ -58,47 +59,56 @@ public:
 
   bool RelinquishFrameData(GMPVideoEncodedFrameData& aFrameData);
 
   // GMPVideoFrame
   virtual GMPVideoFrameFormat GetFrameFormat() MOZ_OVERRIDE;
   virtual void Destroy() MOZ_OVERRIDE;
 
   // GMPVideoEncodedFrame
-  virtual GMPVideoErr CreateEmptyFrame(uint32_t aSize) MOZ_OVERRIDE;
-  virtual GMPVideoErr CopyFrame(const GMPVideoEncodedFrame& aFrame) MOZ_OVERRIDE;
+  virtual GMPErr   CreateEmptyFrame(uint32_t aSize) MOZ_OVERRIDE;
+  virtual GMPErr   CopyFrame(const GMPVideoEncodedFrame& aFrame) MOZ_OVERRIDE;
   virtual void     SetEncodedWidth(uint32_t aEncodedWidth) MOZ_OVERRIDE;
   virtual uint32_t EncodedWidth() MOZ_OVERRIDE;
   virtual void     SetEncodedHeight(uint32_t aEncodedHeight) MOZ_OVERRIDE;
   virtual uint32_t EncodedHeight() MOZ_OVERRIDE;
-  virtual void     SetTimeStamp(uint32_t aTimeStamp) MOZ_OVERRIDE;
-  virtual uint32_t TimeStamp() MOZ_OVERRIDE;
-  virtual void     SetCaptureTime(int64_t aCaptureTime) MOZ_OVERRIDE;
-  virtual int64_t  CaptureTime() MOZ_OVERRIDE;
+  // Microseconds
+  virtual void     SetTimeStamp(uint64_t aTimeStamp) MOZ_OVERRIDE;
+  virtual uint64_t TimeStamp() MOZ_OVERRIDE;
+  // Set frame duration (microseconds)
+  // NOTE: next-frame's Timestamp() != this-frame's TimeStamp()+Duration()
+  // depending on rounding to avoid having to track roundoff errors
+  // and dropped/missing frames(!) (which may leave a large gap)
+  virtual void     SetDuration(uint64_t aDuration) MOZ_OVERRIDE;
+  virtual uint64_t Duration() const MOZ_OVERRIDE;
   virtual void     SetFrameType(GMPVideoFrameType aFrameType) MOZ_OVERRIDE;
   virtual GMPVideoFrameType FrameType() MOZ_OVERRIDE;
   virtual void     SetAllocatedSize(uint32_t aNewSize) MOZ_OVERRIDE;
   virtual uint32_t AllocatedSize() MOZ_OVERRIDE;
   virtual void     SetSize(uint32_t aSize) MOZ_OVERRIDE;
   virtual uint32_t Size() MOZ_OVERRIDE;
   virtual void     SetCompleteFrame(bool aCompleteFrame) MOZ_OVERRIDE;
   virtual bool     CompleteFrame() MOZ_OVERRIDE;
   virtual const uint8_t* Buffer() const MOZ_OVERRIDE;
   virtual uint8_t* Buffer() MOZ_OVERRIDE;
+  virtual GMPBufferType BufferType() const MOZ_OVERRIDE;
+  virtual void     SetBufferType(GMPBufferType aBufferType) MOZ_OVERRIDE;
+  virtual const    GMPEncryptedBufferData* GetDecryptionData() const MOZ_OVERRIDE;
 
 private:
   void DestroyBuffer();
 
   uint32_t mEncodedWidth;
   uint32_t mEncodedHeight;
-  uint32_t mTimeStamp;
-  int64_t  mCaptureTime_ms;
+  uint64_t mTimeStamp;
+  uint64_t mDuration;
   GMPVideoFrameType mFrameType;
   uint32_t mSize;
   bool     mCompleteFrame;
   GMPVideoHostImpl* mHost;
   ipc::Shmem mBuffer;
+  GMPBufferType mBufferType;
 };
 
 } // namespace gmp
 } // namespace mozilla
 
 #endif // GMPVideoEncodedFrameImpl_h_
--- a/content/media/gmp/GMPVideoEncoderChild.cpp
+++ b/content/media/gmp/GMPVideoEncoderChild.cpp
@@ -35,82 +35,88 @@ GMPVideoEncoderChild::Init(GMPVideoEncod
 GMPVideoHostImpl&
 GMPVideoEncoderChild::Host()
 {
   return mVideoHost;
 }
 
 void
 GMPVideoEncoderChild::Encoded(GMPVideoEncodedFrame* aEncodedFrame,
-                              const GMPCodecSpecificInfo& aCodecSpecificInfo)
+                              const uint8_t* aCodecSpecificInfo,
+                              uint32_t aCodecSpecificInfoLength)
 {
   MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
 
   auto ef = static_cast<GMPVideoEncodedFrameImpl*>(aEncodedFrame);
 
   GMPVideoEncodedFrameData frameData;
   ef->RelinquishFrameData(frameData);
 
-  SendEncoded(frameData, aCodecSpecificInfo);
+  nsTArray<uint8_t> codecSpecific;
+  codecSpecific.AppendElements(aCodecSpecificInfo, aCodecSpecificInfoLength);
+  SendEncoded(frameData, codecSpecific);
 
   aEncodedFrame->Destroy();
 }
 
-bool
-GMPVideoEncoderChild::MgrAllocShmem(size_t aSize,
-                                    ipc::Shmem::SharedMemory::SharedMemoryType aType,
-                                    ipc::Shmem* aMem)
+void
+GMPVideoEncoderChild::CheckThread()
 {
   MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
-
-  return AllocShmem(aSize, aType, aMem);
-}
-
-bool
-GMPVideoEncoderChild::MgrDeallocShmem(Shmem& aMem)
-{
-  MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
-
-  return DeallocShmem(aMem);
 }
 
 bool
 GMPVideoEncoderChild::RecvInitEncode(const GMPVideoCodec& aCodecSettings,
+                                     const nsTArray<uint8_t>& aCodecSpecific,
                                      const int32_t& aNumberOfCores,
                                      const uint32_t& aMaxPayloadSize)
 {
   if (!mVideoEncoder) {
     return false;
   }
 
   // Ignore any return code. It is OK for this to fail without killing the process.
-  mVideoEncoder->InitEncode(aCodecSettings, this, aNumberOfCores, aMaxPayloadSize);
+  mVideoEncoder->InitEncode(aCodecSettings,
+                            aCodecSpecific.Elements(),
+                            aCodecSpecific.Length(),
+                            this,
+                            aNumberOfCores,
+                            aMaxPayloadSize);
 
   return true;
 }
 
 bool
 GMPVideoEncoderChild::RecvEncode(const GMPVideoi420FrameData& aInputFrame,
-                                 const GMPCodecSpecificInfo& aCodecSpecificInfo,
-                                 const InfallibleTArray<int>& aFrameTypes)
+                                 const nsTArray<uint8_t>& aCodecSpecificInfo,
+                                 const nsTArray<GMPVideoFrameType>& aFrameTypes)
 {
   if (!mVideoEncoder) {
     return false;
   }
 
   auto f = new GMPVideoi420FrameImpl(aInputFrame, &mVideoHost);
 
-  std::vector<GMPVideoFrameType> frameTypes(aFrameTypes.Length());
-  for (uint32_t i = 0; i < aFrameTypes.Length(); i++) {
-    frameTypes[i] = static_cast<GMPVideoFrameType>(aFrameTypes[i]);
+  // Ignore any return code. It is OK for this to fail without killing the process.
+  mVideoEncoder->Encode(f,
+                        aCodecSpecificInfo.Elements(),
+                        aCodecSpecificInfo.Length(),
+                        aFrameTypes.Elements(),
+                        aFrameTypes.Length());
+
+  return true;
+}
+
+bool
+GMPVideoEncoderChild::RecvChildShmemForPool(Shmem& aEncodedBuffer)
+{
+  if (aEncodedBuffer.IsWritable()) {
+    mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPEncodedData,
+                                               aEncodedBuffer);
   }
-
-  // Ignore any return code. It is OK for this to fail without killing the process.
-  mVideoEncoder->Encode(f, aCodecSpecificInfo, frameTypes);
-
   return true;
 }
 
 bool
 GMPVideoEncoderChild::RecvSetChannelParameters(const uint32_t& aPacketLoss,
                                                const uint32_t& aRTT)
 {
   if (!mVideoEncoder) {
--- a/content/media/gmp/GMPVideoEncoderChild.h
+++ b/content/media/gmp/GMPVideoEncoderChild.h
@@ -13,44 +13,64 @@
 #include "GMPVideoHost.h"
 
 namespace mozilla {
 namespace gmp {
 
 class GMPChild;
 
 class GMPVideoEncoderChild : public PGMPVideoEncoderChild,
-                             public GMPEncoderCallback,
+                             public GMPVideoEncoderCallback,
                              public GMPSharedMemManager
 {
 public:
   GMPVideoEncoderChild(GMPChild* aPlugin);
   virtual ~GMPVideoEncoderChild();
 
   void Init(GMPVideoEncoder* aEncoder);
   GMPVideoHostImpl& Host();
 
-  // GMPEncoderCallback
+  // GMPVideoEncoderCallback
   virtual void Encoded(GMPVideoEncodedFrame* aEncodedFrame,
-                       const GMPCodecSpecificInfo& aCodecSpecificInfo) MOZ_OVERRIDE;
+                       const uint8_t* aCodecSpecificInfo,
+                       uint32_t aCodecSpecificInfoLength) MOZ_OVERRIDE;
 
   // GMPSharedMemManager
-  virtual bool MgrAllocShmem(size_t aSize,
-                             ipc::Shmem::SharedMemory::SharedMemoryType aType,
-                             ipc::Shmem* aMem) MOZ_OVERRIDE;
-  virtual bool MgrDeallocShmem(Shmem& aMem) MOZ_OVERRIDE;
+  virtual void CheckThread();
+  virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, Shmem* aMem)
+  {
+#ifndef SHMEM_ALLOC_IN_CHILD
+    return CallNeedShmem(aSize, aMem);
+#else
+#ifdef GMP_SAFE_SHMEM
+    return AllocShmem(aSize, aType, aMem);
+#else
+    return AllocUnsafeShmem(aSize, aType, aMem);
+#endif
+#endif
+  }
+  virtual void Dealloc(Shmem& aMem)
+  {
+#ifndef SHMEM_ALLOC_IN_CHILD
+    SendParentShmemForPool(aMem);
+#else
+    DeallocShmem(aMem);
+#endif
+  }
 
 private:
   // PGMPVideoEncoderChild
   virtual bool RecvInitEncode(const GMPVideoCodec& aCodecSettings,
+                              const nsTArray<uint8_t>& aCodecSpecific,
                               const int32_t& aNumberOfCores,
                               const uint32_t& aMaxPayloadSize) MOZ_OVERRIDE;
   virtual bool RecvEncode(const GMPVideoi420FrameData& aInputFrame,
-                          const GMPCodecSpecificInfo& aCodecSpecificInfo,
-                          const InfallibleTArray<int>& aFrameTypes) MOZ_OVERRIDE;
+                          const nsTArray<uint8_t>& aCodecSpecificInfo,
+                          const nsTArray<GMPVideoFrameType>& aFrameTypes) MOZ_OVERRIDE;
+  virtual bool RecvChildShmemForPool(Shmem& aEncodedBuffer) MOZ_OVERRIDE;
   virtual bool RecvSetChannelParameters(const uint32_t& aPacketLoss,
                                         const uint32_t& aRTT) MOZ_OVERRIDE;
   virtual bool RecvSetRates(const uint32_t& aNewBitRate,
                             const uint32_t& aFrameRate) MOZ_OVERRIDE;
   virtual bool RecvSetPeriodicKeyFrames(const bool& aEnable) MOZ_OVERRIDE;
   virtual bool RecvEncodingComplete() MOZ_OVERRIDE;
 
   GMPChild* mPlugin;
--- a/content/media/gmp/GMPVideoEncoderParent.cpp
+++ b/content/media/gmp/GMPVideoEncoderParent.cpp
@@ -38,147 +38,132 @@ GMPVideoEncoderParent::~GMPVideoEncoderP
 }
 
 GMPVideoHostImpl&
 GMPVideoEncoderParent::Host()
 {
   return mVideoHost;
 }
 
-bool
-GMPVideoEncoderParent::MgrAllocShmem(size_t aSize,
-                                     ipc::Shmem::SharedMemory::SharedMemoryType aType,
-                                     ipc::Shmem* aMem)
-{
-  MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
-
-  return AllocShmem(aSize, aType, aMem);
-}
-
-bool
-GMPVideoEncoderParent::MgrDeallocShmem(Shmem& aMem)
-{
-  MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
-
-  return DeallocShmem(aMem);
-}
-
-GMPVideoErr
+GMPErr
 GMPVideoEncoderParent::InitEncode(const GMPVideoCodec& aCodecSettings,
-                                  GMPEncoderCallback* aCallback,
+                                  const nsTArray<uint8_t>& aCodecSpecific,
+                                  GMPVideoEncoderCallbackProxy* aCallback,
                                   int32_t aNumberOfCores,
                                   uint32_t aMaxPayloadSize)
 {
   if (!mCanSendMessages) {
     NS_WARNING("Trying to use an invalid GMP video encoder!");
-    return GMPVideoGenericErr;
+    return GMPGenericErr;
   }
 
   MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
 
   if (!aCallback) {
-    return GMPVideoGenericErr;
+    return GMPGenericErr;
   }
   mCallback = aCallback;
 
-  if (!SendInitEncode(aCodecSettings, aNumberOfCores, aMaxPayloadSize)) {
-    return GMPVideoGenericErr;
+  if (!SendInitEncode(aCodecSettings, aCodecSpecific, aNumberOfCores, aMaxPayloadSize)) {
+    return GMPGenericErr;
   }
 
   // Async IPC, we don't have access to a return value.
-  return GMPVideoNoErr;
+  return GMPNoErr;
 }
 
-GMPVideoErr
+GMPErr
 GMPVideoEncoderParent::Encode(GMPVideoi420Frame* aInputFrame,
-                              const GMPCodecSpecificInfo& aCodecSpecificInfo,
-                              const std::vector<GMPVideoFrameType>& aFrameTypes)
+                              const nsTArray<uint8_t>& aCodecSpecificInfo,
+                              const nsTArray<GMPVideoFrameType>& aFrameTypes)
 {
   nsAutoRef<GMPVideoi420Frame> frameRef(aInputFrame);
 
   if (!mCanSendMessages) {
     NS_WARNING("Trying to use an invalid GMP video encoder!");
-    return GMPVideoGenericErr;
+    return GMPGenericErr;
   }
 
   MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
 
   auto inputFrameImpl = static_cast<GMPVideoi420FrameImpl*>(aInputFrame);
 
   GMPVideoi420FrameData frameData;
   inputFrameImpl->InitFrameData(frameData);
 
-  InfallibleTArray<int> frameTypes;
-  frameTypes.SetCapacity(aFrameTypes.size());
-  for (std::vector<int>::size_type i = 0; i != aFrameTypes.size(); i++) {
-    frameTypes.AppendElement(static_cast<int>(aFrameTypes[i]));
+  // Very rough kill-switch if the plugin stops processing.  If it's merely
+  // hung and continues, we'll come back to life eventually.
+  // 3* is because we're using 3 buffers per frame for i420 data for now.
+  if (NumInUse(kGMPFrameData) > 3*GMPSharedMemManager::kGMPBufLimit ||
+      NumInUse(kGMPEncodedData) > GMPSharedMemManager::kGMPBufLimit) {
+    return GMPGenericErr;
   }
 
   if (!SendEncode(frameData,
                   aCodecSpecificInfo,
-                  frameTypes)) {
-    return GMPVideoGenericErr;
+                  aFrameTypes)) {
+    return GMPGenericErr;
   }
 
   // Async IPC, we don't have access to a return value.
-  return GMPVideoNoErr;
+  return GMPNoErr;
 }
 
-GMPVideoErr
+GMPErr
 GMPVideoEncoderParent::SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT)
 {
   if (!mCanSendMessages) {
     NS_WARNING("Trying to use an invalid GMP video encoder!");
-    return GMPVideoGenericErr;
+    return GMPGenericErr;
   }
 
   MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
 
   if (!SendSetChannelParameters(aPacketLoss, aRTT)) {
-    return GMPVideoGenericErr;
+    return GMPGenericErr;
   }
 
   // Async IPC, we don't have access to a return value.
-  return GMPVideoNoErr;
+  return GMPNoErr;
 }
 
-GMPVideoErr
+GMPErr
 GMPVideoEncoderParent::SetRates(uint32_t aNewBitRate, uint32_t aFrameRate)
 {
   if (!mCanSendMessages) {
     NS_WARNING("Trying to use an invalid GMP video encoder!");
-    return GMPVideoGenericErr;
+    return GMPGenericErr;
   }
 
   MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
 
   if (!SendSetRates(aNewBitRate, aFrameRate)) {
-    return GMPVideoGenericErr;
+    return GMPGenericErr;
   }
 
   // Async IPC, we don't have access to a return value.
-  return GMPVideoNoErr;
+  return GMPNoErr;
 }
 
-GMPVideoErr
+GMPErr
 GMPVideoEncoderParent::SetPeriodicKeyFrames(bool aEnable)
 {
   if (!mCanSendMessages) {
     NS_WARNING("Trying to use an invalid GMP video encoder!");
-    return GMPVideoGenericErr;
+    return GMPGenericErr;
   }
 
   MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
 
   if (!SendSetPeriodicKeyFrames(aEnable)) {
-    return GMPVideoGenericErr;
+    return GMPGenericErr;
   }
 
   // Async IPC, we don't have access to a return value.
-  return GMPVideoNoErr;
+  return GMPNoErr;
 }
 
 // Note: Consider keeping ActorDestroy sync'd up when making changes here.
 void
 GMPVideoEncoderParent::EncodingComplete()
 {
   if (!mCanSendMessages) {
     NS_WARNING("Trying to use an invalid GMP video encoder!");
@@ -205,29 +190,64 @@ GMPVideoEncoderParent::ActorDestroy(Acto
     mPlugin->VideoEncoderDestroyed(this);
     mPlugin = nullptr;
   }
   mCanSendMessages = false;
   mCallback = nullptr;
   mVideoHost.ActorDestroyed();
 }
 
+void
+GMPVideoEncoderParent::CheckThread()
+{
+  MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
+}
+
 bool
 GMPVideoEncoderParent::RecvEncoded(const GMPVideoEncodedFrameData& aEncodedFrame,
-                                   const GMPCodecSpecificInfo& aCodecSpecificInfo)
+                                   const nsTArray<uint8_t>& aCodecSpecificInfo)
 {
   if (!mCallback) {
     return false;
   }
 
   auto f = new GMPVideoEncodedFrameImpl(aEncodedFrame, &mVideoHost);
 
   // Ignore any return code. It is OK for this to fail without killing the process.
   mCallback->Encoded(f, aCodecSpecificInfo);
 
+  // Return SHM to sender to recycle
+  //SendEncodedReturn(aEncodedFrame, aCodecSpecificInfo);
+  return true;
+}
+
+bool
+GMPVideoEncoderParent::RecvParentShmemForPool(Shmem& aFrameBuffer)
+{
+  if (aFrameBuffer.IsWritable()) {
+    mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPFrameData,
+                                               aFrameBuffer);
+  }
+  return true;
+}
+
+bool
+GMPVideoEncoderParent::AnswerNeedShmem(const uint32_t& aEncodedBufferSize,
+                                       Shmem* aMem)
+{
+  ipc::Shmem mem;
+
+  if (!mVideoHost.SharedMemMgr()->MgrAllocShmem(GMPSharedMemManager::kGMPEncodedData,
+                                                aEncodedBufferSize,
+                                                ipc::SharedMemory::TYPE_BASIC, &mem))
+  {
+    return false;
+  }
+  *aMem = mem;
+  mem = ipc::Shmem();
   return true;
 }
 
 bool
 GMPVideoEncoderParent::Recv__delete__()
 {
   if (mPlugin) {
     // Ignore any return code. It is OK for this to fail without killing the process.
--- a/content/media/gmp/GMPVideoEncoderParent.h
+++ b/content/media/gmp/GMPVideoEncoderParent.h
@@ -7,63 +7,77 @@
 #define GMPVideoEncoderParent_h_
 
 #include "mozilla/RefPtr.h"
 #include "gmp-video-encode.h"
 #include "mozilla/gmp/PGMPVideoEncoderParent.h"
 #include "GMPMessageUtils.h"
 #include "GMPSharedMemManager.h"
 #include "GMPVideoHost.h"
+#include "GMPVideoEncoderProxy.h"
 
 namespace mozilla {
 namespace gmp {
 
 class GMPParent;
 
-class GMPVideoEncoderParent : public GMPVideoEncoder,
+class GMPVideoEncoderParent : public GMPVideoEncoderProxy,
                               public PGMPVideoEncoderParent,
                               public GMPSharedMemManager
 {
 public:
   NS_INLINE_DECL_REFCOUNTING(GMPVideoEncoderParent)
 
   GMPVideoEncoderParent(GMPParent *aPlugin);
 
   GMPVideoHostImpl& Host();
 
-  // GMPSharedMemManager
-  virtual bool MgrAllocShmem(size_t aSize,
-                             ipc::Shmem::SharedMemory::SharedMemoryType aType,
-                             ipc::Shmem* aMem) MOZ_OVERRIDE;
-  virtual bool MgrDeallocShmem(Shmem& aMem) MOZ_OVERRIDE;
+  // GMPVideoEncoderProxy
+  virtual GMPErr InitEncode(const GMPVideoCodec& aCodecSettings,
+                            const nsTArray<uint8_t>& aCodecSpecific,
+                            GMPVideoEncoderCallbackProxy* aCallback,
+                            int32_t aNumberOfCores,
+                            uint32_t aMaxPayloadSize) MOZ_OVERRIDE;
+  virtual GMPErr Encode(GMPVideoi420Frame* aInputFrame,
+                        const nsTArray<uint8_t>& aCodecSpecificInfo,
+                        const nsTArray<GMPVideoFrameType>& aFrameTypes) MOZ_OVERRIDE;
+  virtual GMPErr SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) MOZ_OVERRIDE;
+  virtual GMPErr SetRates(uint32_t aNewBitRate, uint32_t aFrameRate) MOZ_OVERRIDE;
+  virtual GMPErr SetPeriodicKeyFrames(bool aEnable) MOZ_OVERRIDE;
+  virtual void EncodingComplete() MOZ_OVERRIDE;
 
-  // GMPVideoEncoder
-  virtual GMPVideoErr InitEncode(const GMPVideoCodec& aCodecSettings,
-                                 GMPEncoderCallback* aCallback,
-                                 int32_t aNumberOfCores,
-                                 uint32_t aMaxPayloadSize) MOZ_OVERRIDE;
-  virtual GMPVideoErr Encode(GMPVideoi420Frame* aInputFrame,
-                             const GMPCodecSpecificInfo& aCodecSpecificInfo,
-                             const std::vector<GMPVideoFrameType>& aFrameTypes) MOZ_OVERRIDE;
-  virtual GMPVideoErr SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) MOZ_OVERRIDE;
-  virtual GMPVideoErr SetRates(uint32_t aNewBitRate, uint32_t aFrameRate) MOZ_OVERRIDE;
-  virtual GMPVideoErr SetPeriodicKeyFrames(bool aEnable) MOZ_OVERRIDE;
-  virtual void EncodingComplete() MOZ_OVERRIDE;
+  // GMPSharedMemManager
+  virtual void CheckThread();
+  virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, Shmem* aMem)
+  {
+#ifdef GMP_SAFE_SHMEM
+    return AllocShmem(aSize, aType, aMem);
+#else
+    return AllocUnsafeShmem(aSize, aType, aMem);
+#endif
+  }
+  virtual void Dealloc(Shmem& aMem)
+  {
+    DeallocShmem(aMem);
+  }
 
 private:
   virtual ~GMPVideoEncoderParent();
 
   // PGMPVideoEncoderParent
   virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
   virtual bool RecvEncoded(const GMPVideoEncodedFrameData& aEncodedFrame,
-                           const GMPCodecSpecificInfo& aCodecSpecificInfo) MOZ_OVERRIDE;
+                           const nsTArray<uint8_t>& aCodecSpecificInfo) MOZ_OVERRIDE;
+  virtual bool RecvParentShmemForPool(Shmem& aFrameBuffer) MOZ_OVERRIDE;
+  virtual bool AnswerNeedShmem(const uint32_t& aEncodedBufferSize,
+                               Shmem* aMem) MOZ_OVERRIDE;
   virtual bool Recv__delete__() MOZ_OVERRIDE;
 
   bool mCanSendMessages;
   GMPParent* mPlugin;
-  GMPEncoderCallback* mCallback;
+  GMPVideoEncoderCallbackProxy* mCallback;
   GMPVideoHostImpl mVideoHost;
 };
 
 } // namespace gmp
 } // namespace mozilla
 
 #endif // GMPVideoEncoderParent_h_
new file mode 100644
--- /dev/null
+++ b/content/media/gmp/GMPVideoEncoderProxy.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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 GMPVideoEncoderProxy_h_
+#define GMPVideoEncoderProxy_h_
+
+#include "nsTArray.h"
+#include "gmp-video-encode.h"
+#include "gmp-video-frame-i420.h"
+#include "gmp-video-frame-encoded.h"
+
+class GMPVideoEncoderCallbackProxy {
+public:
+  virtual void Encoded(GMPVideoEncodedFrame* aEncodedFrame,
+                       const nsTArray<uint8_t>& aCodecSpecificInfo) = 0;
+};
+
+// A proxy to GMPVideoEncoder in the child process.
+// GMPVideoEncoderParent exposes this to users the GMP.
+// This enables Gecko to pass nsTArrays to the child GMP and avoid
+// an extra copy when doing so.
+class GMPVideoEncoderProxy {
+public:
+  virtual GMPErr InitEncode(const GMPVideoCodec& aCodecSettings,
+                            const nsTArray<uint8_t>& aCodecSpecific,
+                            GMPVideoEncoderCallbackProxy* aCallback,
+                            int32_t aNumberOfCores,
+                            uint32_t aMaxPayloadSize) = 0;
+  virtual GMPErr Encode(GMPVideoi420Frame* aInputFrame,
+                        const nsTArray<uint8_t>& aCodecSpecificInfo,
+                        const nsTArray<GMPVideoFrameType>& aFrameTypes) = 0;
+  virtual GMPErr SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) = 0;
+  virtual GMPErr SetRates(uint32_t aNewBitRate, uint32_t aFrameRate) = 0;
+  virtual GMPErr SetPeriodicKeyFrames(bool aEnable) = 0;
+  virtual void EncodingComplete() = 0;
+};
+
+#endif // GMPVideoEncoderProxy_h_
--- a/content/media/gmp/GMPVideoHost.cpp
+++ b/content/media/gmp/GMPVideoHost.cpp
@@ -15,59 +15,59 @@ GMPVideoHostImpl::GMPVideoHostImpl(GMPSh
 : mSharedMemMgr(aSharedMemMgr)
 {
 }
 
 GMPVideoHostImpl::~GMPVideoHostImpl()
 {
 }
 
-GMPVideoErr
+GMPErr
 GMPVideoHostImpl::CreateFrame(GMPVideoFrameFormat aFormat, GMPVideoFrame** aFrame)
 {
   if (!mSharedMemMgr) {
-    return GMPVideoGenericErr;
+    return GMPGenericErr;
   }
 
   if (!aFrame) {
-    return GMPVideoGenericErr;
+    return GMPGenericErr;
   }
   *aFrame = nullptr;
 
   switch (aFormat) {
     case kGMPI420VideoFrame:
       *aFrame = new GMPVideoi420FrameImpl(this);
-      return GMPVideoNoErr;
+      return GMPNoErr;
     case kGMPEncodedVideoFrame:
       *aFrame = new GMPVideoEncodedFrameImpl(this);
-      return GMPVideoNoErr;
+      return GMPNoErr;
     default:
       NS_NOTREACHED("Unknown frame format!");
   }
 
-  return GMPVideoGenericErr;
+  return GMPGenericErr;
 }
 
-GMPVideoErr
+GMPErr
 GMPVideoHostImpl::CreatePlane(GMPPlane** aPlane)
 {
   if (!mSharedMemMgr) {
-    return GMPVideoGenericErr;
+    return GMPGenericErr;
   }
 
   if (!aPlane) {
-    return GMPVideoGenericErr;
+    return GMPGenericErr;
   }
   *aPlane = nullptr;
 
   auto p = new GMPPlaneImpl(this);
 
   *aPlane = p;
 
-  return GMPVideoNoErr;
+  return GMPNoErr;
 }
 
 GMPSharedMemManager*
 GMPVideoHostImpl::SharedMemMgr()
 {
   return mSharedMemMgr;
 }
 
--- a/content/media/gmp/GMPVideoHost.h
+++ b/content/media/gmp/GMPVideoHost.h
@@ -30,18 +30,18 @@ public:
   void DoneWithAPI();
   void ActorDestroyed();
   void PlaneCreated(GMPPlaneImpl* aPlane);
   void PlaneDestroyed(GMPPlaneImpl* aPlane);
   void EncodedFrameCreated(GMPVideoEncodedFrameImpl* aEncodedFrame);
   void EncodedFrameDestroyed(GMPVideoEncodedFrameImpl* aFrame);
 
   // GMPVideoHost
-  virtual GMPVideoErr CreateFrame(GMPVideoFrameFormat aFormat, GMPVideoFrame** aFrame) MOZ_OVERRIDE;
-  virtual GMPVideoErr CreatePlane(GMPPlane** aPlane) MOZ_OVERRIDE;
+  virtual GMPErr CreateFrame(GMPVideoFrameFormat aFormat, GMPVideoFrame** aFrame) MOZ_OVERRIDE;
+  virtual GMPErr CreatePlane(GMPPlane** aPlane) MOZ_OVERRIDE;
 
 private:
   // All shared memory allocations have to be made by an IPDL actor.
   // This is a reference to the owning actor. If this reference is
   // null then the actor has died and all allocations must fail.
   GMPSharedMemManager* mSharedMemMgr;
 
   // We track all of these things because they need to handle further
--- a/content/media/gmp/GMPVideoPlaneImpl.cpp
+++ b/content/media/gmp/GMPVideoPlaneImpl.cpp
@@ -68,106 +68,107 @@ GMPPlaneImpl::InitPlaneData(GMPPlaneData
   // This method is called right before Shmem is sent to another process.
   // We need to effectively zero out our member copy so that we don't
   // try to delete memory we don't own later.
   mBuffer = ipc::Shmem();
 
   return true;
 }
 
-GMPVideoErr
+GMPErr
 GMPPlaneImpl::MaybeResize(int32_t aNewSize) {
   if (aNewSize <= AllocatedSize()) {
-    return GMPVideoNoErr;
+    return GMPNoErr;
   }
 
   if (!mHost) {
-    return GMPVideoGenericErr;
+    return GMPGenericErr;
   }
 
   ipc::Shmem new_mem;
-  if (!mHost->SharedMemMgr()->MgrAllocShmem(aNewSize, ipc::SharedMemory::TYPE_BASIC, &new_mem) ||
+  if (!mHost->SharedMemMgr()->MgrAllocShmem(GMPSharedMemManager::kGMPFrameData, aNewSize,
+                                            ipc::SharedMemory::TYPE_BASIC, &new_mem) ||
       !new_mem.get<uint8_t>()) {
-    return GMPVideoAllocErr;
+    return GMPAllocErr;
   }
 
   if (mBuffer.IsReadable()) {
     memcpy(new_mem.get<uint8_t>(), Buffer(), mSize);
   }
 
   DestroyBuffer();
 
   mBuffer = new_mem;
 
-  return GMPVideoNoErr;
+  return GMPNoErr;
 }
 
 void
 GMPPlaneImpl::DestroyBuffer()
 {
   if (mHost && mBuffer.IsWritable()) {
-    mHost->SharedMemMgr()->MgrDeallocShmem(mBuffer);
+    mHost->SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPFrameData, mBuffer);
   }
   mBuffer = ipc::Shmem();
 }
 
-GMPVideoErr
+GMPErr
 GMPPlaneImpl::CreateEmptyPlane(int32_t aAllocatedSize, int32_t aStride, int32_t aPlaneSize)
 {
   if (aAllocatedSize < 1 || aStride < 1 || aPlaneSize < 1) {
-    return GMPVideoGenericErr;
+    return GMPGenericErr;
   }
 
-  GMPVideoErr err = MaybeResize(aAllocatedSize);
-  if (err != GMPVideoNoErr) {
+  GMPErr err = MaybeResize(aAllocatedSize);
+  if (err != GMPNoErr) {
     return err;
   }
 
   mSize = aPlaneSize;
   mStride = aStride;
 
-  return GMPVideoNoErr;
+  return GMPNoErr;
 }
 
-GMPVideoErr
+GMPErr
 GMPPlaneImpl::Copy(const GMPPlane& aPlane)
 {
   auto& planeimpl = static_cast<const GMPPlaneImpl&>(aPlane);
 
-  GMPVideoErr err = MaybeResize(planeimpl.mSize);
-  if (err != GMPVideoNoErr) {
+  GMPErr err = MaybeResize(planeimpl.mSize);
+  if (err != GMPNoErr) {
     return err;
   }
 
   if (planeimpl.Buffer() && planeimpl.mSize > 0) {
     memcpy(Buffer(), planeimpl.Buffer(), mSize);
   }
 
   mSize = planeimpl.mSize;
   mStride = planeimpl.mStride;
 
-  return GMPVideoNoErr;
+  return GMPNoErr;
 }
 
-GMPVideoErr
+GMPErr
 GMPPlaneImpl::Copy(int32_t aSize, int32_t aStride, const uint8_t* aBuffer)
 {
-  GMPVideoErr err = MaybeResize(aSize);
-  if (err != GMPVideoNoErr) {
+  GMPErr err = MaybeResize(aSize);
+  if (err != GMPNoErr) {
     return err;
   }
 
   if (aBuffer && aSize > 0) {
     memcpy(Buffer(), aBuffer, aSize);
   }
 
   mSize = aSize;
   mStride = aStride;
 
-  return GMPVideoNoErr;
+  return GMPNoErr;
 }
 
 void
 GMPPlaneImpl::Swap(GMPPlane& aPlane)
 {
   auto& planeimpl = static_cast<GMPPlaneImpl&>(aPlane);
 
   std::swap(mStride, planeimpl.mStride);
--- a/content/media/gmp/GMPVideoPlaneImpl.h
+++ b/content/media/gmp/GMPVideoPlaneImpl.h
@@ -29,34 +29,34 @@ public:
   // This is called when something has gone wrong - specicifically,
   // a child process has crashed. Does not attempt to release Shmem,
   // as the Shmem has already been released.
   void ActorDestroyed();
 
   bool InitPlaneData(GMPPlaneData& aPlaneData);
 
   // GMPPlane
-  virtual GMPVideoErr CreateEmptyPlane(int32_t aAllocatedSize,
-                                       int32_t aStride,
-                                       int32_t aPlaneSize) MOZ_OVERRIDE;
-  virtual GMPVideoErr Copy(const GMPPlane& aPlane) MOZ_OVERRIDE;
-  virtual GMPVideoErr Copy(int32_t aSize,
-                           int32_t aStride,
-                           const uint8_t* aBuffer) MOZ_OVERRIDE;
+  virtual GMPErr CreateEmptyPlane(int32_t aAllocatedSize,
+                                  int32_t aStride,
+                                  int32_t aPlaneSize) MOZ_OVERRIDE;
+  virtual GMPErr Copy(const GMPPlane& aPlane) MOZ_OVERRIDE;
+  virtual GMPErr Copy(int32_t aSize,
+                      int32_t aStride,
+                      const uint8_t* aBuffer) MOZ_OVERRIDE;
   virtual void Swap(GMPPlane& aPlane) MOZ_OVERRIDE;
   virtual int32_t AllocatedSize() const MOZ_OVERRIDE;
   virtual void ResetSize() MOZ_OVERRIDE;
   virtual bool IsZeroSize() const MOZ_OVERRIDE;
   virtual int32_t Stride() const MOZ_OVERRIDE;
   virtual const uint8_t* Buffer() const MOZ_OVERRIDE;
   virtual uint8_t* Buffer() MOZ_OVERRIDE;
   virtual void Destroy() MOZ_OVERRIDE;
 
 private:
-  GMPVideoErr MaybeResize(int32_t aNewSize);
+  GMPErr MaybeResize(int32_t aNewSize);
   void DestroyBuffer();
 
   ipc::Shmem mBuffer;
   int32_t mSize;
   int32_t mStride;
   GMPVideoHostImpl* mHost;
 };
 
--- a/content/media/gmp/GMPVideoi420FrameImpl.cpp
+++ b/content/media/gmp/GMPVideoi420FrameImpl.cpp
@@ -10,31 +10,31 @@ namespace mozilla {
 namespace gmp {
 
 GMPVideoi420FrameImpl::GMPVideoi420FrameImpl(GMPVideoHostImpl* aHost)
 : mYPlane(aHost),
   mUPlane(aHost),
   mVPlane(aHost),
   mWidth(0),
   mHeight(0),
-  mTimestamp(0),
-  mRenderTime_ms(0)
+  mTimestamp(0ll),
+  mDuration(0ll)
 {
   MOZ_ASSERT(aHost);
 }
 
 GMPVideoi420FrameImpl::GMPVideoi420FrameImpl(const GMPVideoi420FrameData& aFrameData,
                                              GMPVideoHostImpl* aHost)
 : mYPlane(aFrameData.mYPlane(), aHost),
   mUPlane(aFrameData.mUPlane(), aHost),
   mVPlane(aFrameData.mVPlane(), aHost),
   mWidth(aFrameData.mWidth()),
   mHeight(aFrameData.mHeight()),
   mTimestamp(aFrameData.mTimestamp()),
-  mRenderTime_ms(aFrameData.mRenderTime_ms())
+  mDuration(aFrameData.mDuration())
 {
   MOZ_ASSERT(aHost);
 }
 
 GMPVideoi420FrameImpl::~GMPVideoi420FrameImpl()
 {
 }
 
@@ -42,17 +42,17 @@ bool
 GMPVideoi420FrameImpl::InitFrameData(GMPVideoi420FrameData& aFrameData)
 {
   mYPlane.InitPlaneData(aFrameData.mYPlane());
   mUPlane.InitPlaneData(aFrameData.mUPlane());
   mVPlane.InitPlaneData(aFrameData.mVPlane());
   aFrameData.mWidth() = mWidth;
   aFrameData.mHeight() = mHeight;
   aFrameData.mTimestamp() = mTimestamp;
-  aFrameData.mRenderTime_ms() = mRenderTime_ms;
+  aFrameData.mDuration() = mDuration;
   return true;
 }
 
 GMPVideoFrameFormat
 GMPVideoi420FrameImpl::GetFrameFormat()
 {
   return kGMPI420VideoFrame;
 }
@@ -101,127 +101,127 @@ GMPVideoi420FrameImpl::GetPlane(GMPPlane
     case kGMPVPlane :
       return &mVPlane;
     default:
       MOZ_CRASH("Unknown plane type!");
   }
   return nullptr;
 }
 
-GMPVideoErr
+GMPErr
 GMPVideoi420FrameImpl::CreateEmptyFrame(int32_t aWidth, int32_t aHeight,
                                         int32_t aStride_y, int32_t aStride_u, int32_t aStride_v)
 {
   if (!CheckDimensions(aWidth, aHeight, aStride_y, aStride_u, aStride_v)) {
-    return GMPVideoGenericErr;
+    return GMPGenericErr;
   }
 
   int32_t size_y = aStride_y * aHeight;
   int32_t half_height = (aHeight + 1) / 2;
   int32_t size_u = aStride_u * half_height;
   int32_t size_v = aStride_v * half_height;
 
-  GMPVideoErr err = mYPlane.CreateEmptyPlane(size_y, aStride_y, size_y);
-  if (err != GMPVideoNoErr) {
+  GMPErr err = mYPlane.CreateEmptyPlane(size_y, aStride_y, size_y);
+  if (err != GMPNoErr) {
     return err;
   }
   err = mUPlane.CreateEmptyPlane(size_u, aStride_u, size_u);
-  if (err != GMPVideoNoErr) {
+  if (err != GMPNoErr) {
     return err;
   }
   err = mVPlane.CreateEmptyPlane(size_v, aStride_v, size_v);
-  if (err != GMPVideoNoErr) {
+  if (err != GMPNoErr) {
     return err;
   }
 
   mWidth = aWidth;
   mHeight = aHeight;
-  mTimestamp = 0;
-  mRenderTime_ms = 0;
+  mTimestamp = 0ll;
+  mDuration = 0ll;
 
-  return GMPVideoNoErr;
+  return GMPNoErr;
 }
 
-GMPVideoErr
+GMPErr
 GMPVideoi420FrameImpl::CreateFrame(int32_t aSize_y, const uint8_t* aBuffer_y,
                                    int32_t aSize_u, const uint8_t* aBuffer_u,
                                    int32_t aSize_v, const uint8_t* aBuffer_v,
                                    int32_t aWidth, int32_t aHeight,
                                    int32_t aStride_y, int32_t aStride_u, int32_t aStride_v)
 {
   MOZ_ASSERT(aBuffer_y);
   MOZ_ASSERT(aBuffer_u);
   MOZ_ASSERT(aBuffer_v);
 
   if (aSize_y < 1 || aSize_u < 1 || aSize_v < 1) {
-    return GMPVideoGenericErr;
+    return GMPGenericErr;
   }
 
   if (!CheckDimensions(aWidth, aHeight, aStride_y, aStride_u, aStride_v)) {
-    return GMPVideoGenericErr;
+    return GMPGenericErr;
   }
 
-  GMPVideoErr err = mYPlane.Copy(aSize_y, aStride_y, aBuffer_y);
-  if (err != GMPVideoNoErr) {
+  GMPErr err = mYPlane.Copy(aSize_y, aStride_y, aBuffer_y);
+  if (err != GMPNoErr) {
     return err;
   }
   err = mUPlane.Copy(aSize_u, aStride_u, aBuffer_u);
-  if (err != GMPVideoNoErr) {
+  if (err != GMPNoErr) {
     return err;
   }
   err = mVPlane.Copy(aSize_v, aStride_v, aBuffer_v);
-  if (err != GMPVideoNoErr) {
+  if (err != GMPNoErr) {
     return err;
   }
 
   mWidth = aWidth;
   mHeight = aHeight;
 
-  return GMPVideoNoErr;
+  return GMPNoErr;
 }
 
-GMPVideoErr
+GMPErr
 GMPVideoi420FrameImpl::CopyFrame(const GMPVideoi420Frame& aFrame)
 {
   auto& f = static_cast<const GMPVideoi420FrameImpl&>(aFrame);
 
-  GMPVideoErr err = mYPlane.Copy(f.mYPlane);
-  if (err != GMPVideoNoErr) {
+  GMPErr err = mYPlane.Copy(f.mYPlane);
+  if (err != GMPNoErr) {
     return err;
   }
 
   err = mUPlane.Copy(f.mUPlane);
-  if (err != GMPVideoNoErr) {
+  if (err != GMPNoErr) {
     return err;
   }
 
   err = mVPlane.Copy(f.mVPlane);
-  if (err != GMPVideoNoErr) {
+  if (err != GMPNoErr) {
     return err;
   }
 
   mWidth = f.mWidth;
   mHeight = f.mHeight;
   mTimestamp = f.mTimestamp;
-  mRenderTime_ms = f.mRenderTime_ms;
+  mDuration = f.mDuration;
 
-  return GMPVideoNoErr;
+  return GMPNoErr;
 }
 
 void
 GMPVideoi420FrameImpl::SwapFrame(GMPVideoi420Frame* aFrame)
 {
   auto f = static_cast<GMPVideoi420FrameImpl*>(aFrame);
   mYPlane.Swap(f->mYPlane);
   mUPlane.Swap(f->mUPlane);
   mVPlane.Swap(f->mVPlane);
   std::swap(mWidth, f->mWidth);
   std::swap(mHeight, f->mHeight);
   std::swap(mTimestamp, f->mTimestamp);
-  std::swap(mRenderTime_ms, f->mRenderTime_ms);
+  std::swap(mDuration, f->mDuration);
 }
 
 uint8_t*
 GMPVideoi420FrameImpl::Buffer(GMPPlaneType aType)
 {
   GMPPlane* p = GetPlane(aType);
   if (p) {
     return p->Buffer();
@@ -254,74 +254,74 @@ GMPVideoi420FrameImpl::Stride(GMPPlaneTy
 {
   const GMPPlane* p = GetPlane(aType);
   if (p) {
     return p->Stride();
   }
   return -1;
 }
 
-GMPVideoErr
+GMPErr
 GMPVideoi420FrameImpl::SetWidth(int32_t aWidth)
 {
   if (!CheckDimensions(aWidth, mHeight,
                        mYPlane.Stride(), mUPlane.Stride(),
                        mVPlane.Stride())) {
-    return GMPVideoGenericErr;
+    return GMPGenericErr;
   }
   mWidth = aWidth;
-  return GMPVideoNoErr;
+  return GMPNoErr;
 }
 
-GMPVideoErr
+GMPErr
 GMPVideoi420FrameImpl::SetHeight(int32_t aHeight)
 {
   if (!CheckDimensions(mWidth, aHeight,
                        mYPlane.Stride(), mUPlane.Stride(),
                        mVPlane.Stride())) {
-    return GMPVideoGenericErr;
+    return GMPGenericErr;
   }
   mHeight = aHeight;
-  return GMPVideoNoErr;
+  return GMPNoErr;
 }
 
 int32_t
 GMPVideoi420FrameImpl::Width() const
 {
   return mWidth;
 }
 
 int32_t
 GMPVideoi420FrameImpl::Height() const
 {
   return mHeight;
 }
 
 void
-GMPVideoi420FrameImpl::SetTimestamp(uint32_t aTimestamp)
+GMPVideoi420FrameImpl::SetTimestamp(uint64_t aTimestamp)
 {
   mTimestamp = aTimestamp;
 }
 
-uint32_t
+uint64_t
 GMPVideoi420FrameImpl::Timestamp() const
 {
   return mTimestamp;
 }
 
 void
-GMPVideoi420FrameImpl::SetRenderTime_ms(int64_t aRenderTime_ms)
+GMPVideoi420FrameImpl::SetDuration(uint64_t aDuration)
 {
-  mRenderTime_ms = aRenderTime_ms;
+  mDuration = aDuration;
 }
 
-int64_t
-GMPVideoi420FrameImpl::RenderTime_ms() const
+uint64_t
+GMPVideoi420FrameImpl::Duration() const
 {
-  return mRenderTime_ms;
+  return mDuration;
 }
 
 bool
 GMPVideoi420FrameImpl::IsZeroSize() const
 {
   return (mYPlane.IsZeroSize() && mUPlane.IsZeroSize() && mVPlane.IsZeroSize());
 }
 
--- a/content/media/gmp/GMPVideoi420FrameImpl.h
+++ b/content/media/gmp/GMPVideoi420FrameImpl.h
@@ -27,55 +27,55 @@ public:
   const GMPPlaneImpl* GetPlane(GMPPlaneType aType) const;
   GMPPlaneImpl* GetPlane(GMPPlaneType aType);
 
   // GMPVideoFrame
   virtual GMPVideoFrameFormat GetFrameFormat() MOZ_OVERRIDE;
   virtual void Destroy() MOZ_OVERRIDE;
 
   // GMPVideoi420Frame
-  virtual GMPVideoErr CreateEmptyFrame(int32_t aWidth,
-                                       int32_t aHeight,
-                                       int32_t aStride_y,
-                                       int32_t aStride_u,
-                                       int32_t aStride_v) MOZ_OVERRIDE;
-  virtual GMPVideoErr CreateFrame(int32_t aSize_y, const uint8_t* aBuffer_y,
-                                  int32_t aSize_u, const uint8_t* aBuffer_u,
-                                  int32_t aSize_v, const uint8_t* aBuffer_v,
-                                  int32_t aWidth,
+  virtual GMPErr CreateEmptyFrame(int32_t aWidth,
                                   int32_t aHeight,
                                   int32_t aStride_y,
                                   int32_t aStride_u,
                                   int32_t aStride_v) MOZ_OVERRIDE;
-  virtual GMPVideoErr CopyFrame(const GMPVideoi420Frame& aFrame) MOZ_OVERRIDE;
+  virtual GMPErr CreateFrame(int32_t aSize_y, const uint8_t* aBuffer_y,
+                             int32_t aSize_u, const uint8_t* aBuffer_u,
+                             int32_t aSize_v, const uint8_t* aBuffer_v,
+                             int32_t aWidth,
+                             int32_t aHeight,
+                             int32_t aStride_y,
+                             int32_t aStride_u,
+                             int32_t aStride_v) MOZ_OVERRIDE;
+  virtual GMPErr CopyFrame(const GMPVideoi420Frame& aFrame) MOZ_OVERRIDE;
   virtual void SwapFrame(GMPVideoi420Frame* aFrame) MOZ_OVERRIDE;
   virtual uint8_t* Buffer(GMPPlaneType aType) MOZ_OVERRIDE;
   virtual const uint8_t* Buffer(GMPPlaneType aType) const MOZ_OVERRIDE;
   virtual int32_t AllocatedSize(GMPPlaneType aType) const MOZ_OVERRIDE;
   virtual int32_t Stride(GMPPlaneType aType) const MOZ_OVERRIDE;
-  virtual GMPVideoErr SetWidth(int32_t aWidth) MOZ_OVERRIDE;
-  virtual GMPVideoErr SetHeight(int32_t aHeight) MOZ_OVERRIDE;
+  virtual GMPErr SetWidth(int32_t aWidth) MOZ_OVERRIDE;
+  virtual GMPErr SetHeight(int32_t aHeight) MOZ_OVERRIDE;
   virtual int32_t Width() const MOZ_OVERRIDE;
   virtual int32_t Height() const MOZ_OVERRIDE;
-  virtual void SetTimestamp(uint32_t aTimestamp) MOZ_OVERRIDE;
-  virtual uint32_t Timestamp() const MOZ_OVERRIDE;
-  virtual void SetRenderTime_ms(int64_t aRenderTime_ms) MOZ_OVERRIDE;
-  virtual int64_t RenderTime_ms() const MOZ_OVERRIDE;
+  virtual void SetTimestamp(uint64_t aTimestamp) MOZ_OVERRIDE;
+  virtual uint64_t Timestamp() const MOZ_OVERRIDE;
+  virtual void SetDuration(uint64_t aDuration) MOZ_OVERRIDE;
+  virtual uint64_t Duration() const MOZ_OVERRIDE;
   virtual bool IsZeroSize() const MOZ_OVERRIDE;
   virtual void ResetSize() MOZ_OVERRIDE;
 
 private:
   bool CheckDimensions(int32_t aWidth, int32_t aHeight,
                        int32_t aStride_y, int32_t aStride_u, int32_t aStride_v);
 
   GMPPlaneImpl mYPlane;
   GMPPlaneImpl mUPlane;
   GMPPlaneImpl mVPlane;
   int32_t mWidth;
   int32_t mHeight;
-  uint32_t mTimestamp;
-  int64_t mRenderTime_ms;
+  uint64_t mTimestamp;
+  uint64_t mDuration;
 };
 
 } // namespace gmp
 } // namespace mozilla
 
 #endif // GMPVideoi420FrameImpl_h_
--- a/content/media/gmp/PGMP.ipdl
+++ b/content/media/gmp/PGMP.ipdl
@@ -4,19 +4,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include protocol PGMPVideoDecoder;
 include protocol PGMPVideoEncoder;
 
 namespace mozilla {
 namespace gmp {
 
-async protocol PGMP
+intr protocol PGMP
 {
   manages PGMPVideoDecoder;
   manages PGMPVideoEncoder;
 child:
-  PGMPVideoDecoder();
-  PGMPVideoEncoder();
+  async PGMPVideoDecoder();
+  async PGMPVideoEncoder();
 };
 
 } // namespace gmp
 } // namespace mozilla
--- a/content/media/gmp/PGMPVideoDecoder.ipdl
+++ b/content/media/gmp/PGMPVideoDecoder.ipdl
@@ -2,38 +2,46 @@
 /* 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 protocol PGMP;
 include GMPTypes;
 
 using GMPVideoCodec from "gmp-video-codec.h";
-using GMPCodecSpecificInfo from "gmp-video-codec.h";
 
 include "GMPMessageUtils.h";
 
 namespace mozilla {
 namespace gmp {
 
-async protocol PGMPVideoDecoder
+intr protocol PGMPVideoDecoder
 {
   manager PGMP;
 child:
-  InitDecode(GMPVideoCodec aCodecSettings,
-             int32_t aCoreCount);
-  Decode(GMPVideoEncodedFrameData aInputFrame,
-         bool aMissingFrames,
-         GMPCodecSpecificInfo aCodecSpecificInfo,
-         int64_t aRenderTimeMs);
-  Reset();
-  Drain();
-  DecodingComplete();
+  async InitDecode(GMPVideoCodec aCodecSettings,
+                   uint8_t[] aCodecSpecific,
+                   int32_t aCoreCount);
+  async Decode(GMPVideoEncodedFrameData aInputFrame,
+               bool aMissingFrames,
+               uint8_t[] aCodecSpecificInfo,
+               int64_t aRenderTimeMs);
+  async Reset();
+  async Drain();
+  async DecodingComplete();
+  async ChildShmemForPool(Shmem aFrameBuffer);
+
 parent:
-  __delete__();
-  Decoded(GMPVideoi420FrameData aDecodedFrame);
-  ReceivedDecodedReferenceFrame(uint64_t aPictureId);
-  ReceivedDecodedFrame(uint64_t aPictureId);
-  InputDataExhausted();
+  async __delete__();
+  async Decoded(GMPVideoi420FrameData aDecodedFrame);
+  async ReceivedDecodedReferenceFrame(uint64_t aPictureId);
+  async ReceivedDecodedFrame(uint64_t aPictureId);
+  async InputDataExhausted();
+  async DrainComplete();
+  async ResetComplete();
+  async ParentShmemForPool(Shmem aEncodedBuffer);
+  // MUST be intr - if sync and we create a new Shmem, when the returned
+  // Shmem is received in the Child it will fail to Deserialize
+  intr NeedShmem(uint32_t aFrameBufferSize) returns (Shmem aMem);
 };
 
 } // namespace gmp
 } // namespace mozilla
--- a/content/media/gmp/PGMPVideoEncoder.ipdl
+++ b/content/media/gmp/PGMPVideoEncoder.ipdl
@@ -2,38 +2,44 @@
 /* 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 protocol PGMP;
 include GMPTypes;
 
 using GMPVideoCodec from "gmp-video-codec.h";
-using GMPCodecSpecificInfo from "gmp-video-codec.h";
+using GMPVideoFrameType from "gmp-video-frame-encoded.h";
 
 include "GMPMessageUtils.h";
 
 namespace mozilla {
 namespace gmp {
 
-async protocol PGMPVideoEncoder
+intr protocol PGMPVideoEncoder
 {
   manager PGMP;
 child:
-  InitEncode(GMPVideoCodec aCodecSettings,
-             int32_t aNumberOfCores,
-             uint32_t aMaxPayloadSize);
-  Encode(GMPVideoi420FrameData aInputFrame,
-         GMPCodecSpecificInfo aCodecSpecificInfo,
-         int[] aFrameTypes);
-  SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT);
-  SetRates(uint32_t aNewBitRate, uint32_t aFrameRate);
-  SetPeriodicKeyFrames(bool aEnable);
-  EncodingComplete();
+  async InitEncode(GMPVideoCodec aCodecSettings,
+                   uint8_t[] aCodecSpecific,
+                   int32_t aNumberOfCores,
+                   uint32_t aMaxPayloadSize);
+  async Encode(GMPVideoi420FrameData aInputFrame,
+               uint8_t[] aCodecSpecificInfo,
+               GMPVideoFrameType[] aFrameTypes);
+  async SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT);
+  async SetRates(uint32_t aNewBitRate, uint32_t aFrameRate);
+  async SetPeriodicKeyFrames(bool aEnable);
+  async EncodingComplete();
+  async ChildShmemForPool(Shmem aEncodedBuffer);
 
 parent:
-  __delete__();
-  Encoded(GMPVideoEncodedFrameData aEncodedFrame,
-          GMPCodecSpecificInfo aCodecSpecificInfo);
+  async __delete__();
+  async Encoded(GMPVideoEncodedFrameData aEncodedFrame,
+                uint8_t[] aCodecSpecificInfo);
+  async ParentShmemForPool(Shmem aFrameBuffer);
+  // MUST be intr - if sync and we create a new Shmem, when the returned
+  // Shmem is received in the Child it will fail to Deserialize
+  intr NeedShmem(uint32_t aEncodedBufferSize) returns (Shmem aMem);
 };
 
 } // namespace gmp
 } // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/content/media/gmp/gmp-api/gmp-async-shutdown.h
@@ -0,0 +1,52 @@
+/*
+* Copyright 2013, Mozilla Foundation and contributors
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef GMP_ASYNC_SHUTDOWN_H_
+#define GMP_ASYNC_SHUTDOWN_H_
+
+// API exposed by the plugin library to manage asynchronous shutdown.
+// Some plugins require special cleanup which may need to make calls
+// to host services and wait for async responses.
+//
+// To enable a plugins to block shutdown until its async shutdown is
+// complete, implement the GMPAsyncShutdown interface and return it when
+// your plugin's GMPGetAPI function is called with "async-shutdown".
+// When your GMPAsyncShutdown's BeginShutdown() implementation is called
+// by the GMP host, you should initate your async shutdown process.
+// Once you have completed shutdown, call the ShutdownComplete() function
+// of the GMPAsyncShutdownHost that is passed as the host argument to the
+// GMPGetAPI() call.
+//
+// Note: Your GMP's GMPShutdown function will still be called after your
+// call to ShutdownComplete().
+//
+// API name: "async-shutdown"
+// Host API: GMPAsyncShutdownHost
+class GMPAsyncShutdown {
+public:
+  virtual ~GMPAsyncShutdown() {}
+
+  virtual void BeginShutdown() = 0;
+};
+
+class GMPAsyncShutdownHost {
+public:
+  virtual ~GMPAsyncShutdownHost() {}
+
+  virtual void ShutdownComplete() = 0;
+};
+
+#endif // GMP_ASYNC_SHUTDOWN_H_
new file mode 100644
--- /dev/null
+++ b/content/media/gmp/gmp-api/gmp-audio-codec.h
@@ -0,0 +1,43 @@
+/*
+* Copyright 2013, Mozilla Foundation and contributors
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef GMP_AUDIO_CODEC_h_
+#define GMP_AUDIO_CODEC_h_
+
+#include <stdint.h>
+
+enum GMPAudioCodecType
+{
+  kGMPAudioCodecAAC,
+  kGMPAudioCodecVorbis,
+  kGMPAudioCodecInvalid // Should always be last.
+};
+
+struct GMPAudioCodec
+{
+  GMPAudioCodecType mCodecType;
+  uint32_t mChannelCount;
+  uint32_t mBitsPerChannel;
+  uint32_t mSamplesPerSecond;
+
+  // Codec extra data, such as vorbis setup header, or
+  // AAC AudioSpecificConfig.
+  // These are null/0 if not externally negotiated
+  const uint8_t* mExtraData;
+  size_t         mExtraDataLen;
+};
+
+#endif // GMP_AUDIO_CODEC_h_
new file mode 100644
--- /dev/null
+++ b/content/media/gmp/gmp-api/gmp-audio-decode.h
@@ -0,0 +1,72 @@
+/*
+* Copyright 2013, Mozilla Foundation and contributors
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef GMP_AUDIO_DECODE_h_
+#define GMP_AUDIO_DECODE_h_
+
+#include "gmp-errors.h"
+#include "gmp-audio-samples.h"
+#include "gmp-audio-codec.h"
+#include <stdint.h>
+
+// ALL METHODS MUST BE CALLED ON THE MAIN THREAD
+class GMPAudioDecoderCallback
+{
+public:
+  virtual ~GMPAudioDecoderCallback() {}
+
+  virtual void Decoded(GMPAudioSamples* aDecodedSamples) = 0;
+
+  virtual void InputDataExhausted() = 0;
+
+  virtual void DrainComplete() = 0;
+
+  virtual void ResetComplete() = 0;
+};
+
+// ALL METHODS MUST BE CALLED ON THE MAIN THREAD
+class GMPAudioDecoder
+{
+public:
+  virtual ~GMPAudioDecoder() {}
+
+  // aCallback: Subclass should retain reference to it until DecodingComplete
+  //            is called. Do not attempt to delete it, host retains ownership.
+  // TODO: Pass AudioHost so decoder can create GMPAudioEncodedFrame objects?
+  virtual GMPErr InitDecode(const GMPAudioCodec& aCodecSettings,
+                            GMPAudioDecoderCallback* aCallback) = 0;
+
+  // Decode encoded audio frames (as a part of an audio stream). The decoded
+  // frames must be returned to the user through the decode complete callback.
+  virtual GMPErr Decode(GMPAudioSamples* aEncodedSamples) = 0;
+
+  // Reset decoder state and prepare for a new call to Decode(...).
+  // Flushes the decoder pipeline.
+  // The decoder should enqueue a task to run ResetComplete() on the main
+  // thread once the reset has finished.
+  virtual GMPErr Reset() = 0;
+
+  // Output decoded frames for any data in the pipeline, regardless of ordering.
+  // All remaining decoded frames should be immediately returned via callback.
+  // The decoder should enqueue a task to run DrainComplete() on the main
+  // thread once the reset has finished.
+  virtual GMPErr Drain() = 0;
+
+  // May free decoder memory.
+  virtual void DecodingComplete() = 0;
+};
+
+#endif // GMP_VIDEO_DECODE_h_
new file mode 100644
--- /dev/null
+++ b/content/media/gmp/gmp-api/gmp-audio-host.h
@@ -0,0 +1,32 @@
+/*
+* Copyright 2013, Mozilla Foundation and contributors
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef GMP_AUDIO_HOST_h_
+#define GMP_AUDIO_HOST_h_
+
+#include "gmp-errors.h"
+#include "gmp-audio-samples.h"
+
+class GMPAudioHost
+{
+public:
+  // Construct various Audio API objects. Host does not retain reference,
+  // caller is owner and responsible for deleting.
+  virtual GMPErr CreateSamples(GMPAudioFormat aFormat,
+                               GMPAudioSamples** aSamples) = 0;
+};
+
+#endif // GMP_AUDIO_HOST_h_
new file mode 100644
--- /dev/null
+++ b/content/media/gmp/gmp-api/gmp-audio-samples.h
@@ -0,0 +1,57 @@
+/*
+* Copyright 2013, Mozilla Foundation and contributors
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef GMP_AUDIO_FRAME_h_
+#define GMP_AUDIO_FRAME_h_
+
+#include <stdint.h>
+#include "gmp-errors.h"
+#include "gmp-decryption.h"
+
+enum GMPAudioFormat
+{
+  kGMPAudioEncodedSamples, // Raw compressed data, i.e. an AAC/Vorbis packet.
+  kGMPAudioIS16Samples, // Interleaved int16_t PCM samples.
+  kGMPAudioSamplesFormatInvalid // Should always be last.
+};
+
+class GMPAudioSamples {
+public:
+  // The format of the buffer.
+  virtual GMPAudioFormat GetFormat() = 0;
+  virtual void Destroy() = 0;
+
+  // MAIN THREAD ONLY
+  // Buffer size must be exactly what's required to contain all samples in
+  // the buffer; every byte is assumed to be part of a sample.
+  virtual GMPErr SetBufferSize(uint32_t aSize) = 0;
+
+  // Size of the buffer in bytes.
+  virtual uint32_t Size() = 0;
+
+  // Timestamps are in microseconds, and are the playback start time of the
+  // first sample in the buffer.
+  virtual void SetTimeStamp(uint64_t aTimeStamp) = 0;
+  virtual uint64_t TimeStamp() = 0;
+  virtual const uint8_t* Buffer() const = 0;
+  virtual uint8_t*       Buffer() = 0;
+
+  // Get data describing how this frame is encrypted, or nullptr if the
+  // buffer is not encrypted.
+  virtual const GMPEncryptedBufferData* GetDecryptionData() const = 0;
+};
+
+#endif // GMP_AUDIO_FRAME_h_
new file mode 100644
--- /dev/null
+++ b/content/media/gmp/gmp-api/gmp-decryption.h
@@ -0,0 +1,208 @@
+/*
+* Copyright 2013, Mozilla Foundation and contributors
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef GMP_DECRYPTION_h_
+#define GMP_DECRYPTION_h_
+
+#include "gmp-platform.h"
+
+class GMPEncryptedBufferData {
+public:
+  // Key ID to identify the decryption key.
+  virtual const uint8_t* KeyId() const = 0;
+
+  // Size (in bytes) of |KeyId()|.
+  virtual uint32_t KeyIdSize() const = 0;
+
+  // Initialization vector.
+  virtual const uint8_t* IV() const = 0;
+
+  // Size (in bytes) of |IV|.
+  virtual uint32_t IVSize() const = 0;
+
+  // Number of enties returned by ClearBytes and CipherBytes().
+  virtual uint32_t NumSubsamples() const = 0;
+
+  virtual const uint32_t* ClearBytes() const = 0;
+
+  virtual const uint32_t* CipherBytes() const = 0;
+};
+
+// These match to the DOMException codes as per:
+// http://www.w3.org/TR/dom/#domexception
+enum GMPDOMException {
+  kGMPNoModificationAllowedError = 7,
+  kGMPNotFoundError = 8,
+  kGMPNotSupportedError = 9,
+  kGMPInvalidStateError = 11,
+  kGMPSyntaxError = 12,
+  kGMPInvalidModificationError = 13,
+  kGMPInvalidAccessError = 15,
+  kGMPSecurityError = 18,
+  kGMPAbortError = 20,
+  kGMPQuotaExceededError = 22,
+  kGMPTimeoutError = 23
+};
+
+// Time in milliseconds, as offset from epoch, 1 Jan 1970.
+typedef int64_t GMPTimestamp;
+
+class GMPDecryptorCallback {
+public:
+  // Resolves a promise for a session created or loaded.
+  // Passes the session id to be exposed to JavaScript.
+  // Must be called before OnSessionMessage().
+  // aSessionId must be null terminated.
+  virtual void OnResolveNewSessionPromise(uint32_t aPromiseId,
+                                          const char* aSessionId,
+                                          uint32_t aSessionIdLength) = 0;
+
+  // Called to resolve a specified promise with "undefined".
+  virtual void OnResolvePromise(uint32_t aPromiseId) = 0;
+
+  // Called to reject a promise with a DOMException.
+  // aMessage is logged to the WebConsole.
+  // aMessage is optional, but if present must be null terminated.
+  virtual void OnRejectPromise(uint32_t aPromiseId,
+                               GMPDOMException aException,
+                               const char* aMessage,
+                               uint32_t aMessageLength) = 0;
+
+  // Called by the CDM when it has a message for session |session_id|.
+  // Length parameters should not include null termination.
+  // aSessionId must be null terminated.
+  virtual void OnSessionMessage(const char* aSessionId,
+                                uint32_t aSessionIdLength,
+                                const uint8_t* aMessage,
+                                uint32_t aMessageLength,
+                                const char* aDestinationURL,
+                                uint32_t aDestinationURLLength) = 0;
+
+  // aSessionId must be null terminated.
+   virtual void OnExpirationChange(const char* aSessionId,
+                                   uint32_t aSessionIdLength,
+                                   GMPTimestamp aExpiryTime) = 0;
+
+  // Called by the GMP when a session is closed. All file IO
+  // that a session requires should be complete before calling this.
+  // aSessionId must be null terminated.
+  virtual void OnSessionClosed(const char* aSessionId,
+                               uint32_t aSessionIdLength) = 0;
+
+  // Called by the GMP when an error occurs in a session.
+  // aSessionId must be null terminated.
+  // aMessage is logged to the WebConsole.
+  // aMessage is optional, but if present must be null terminated.
+  virtual void OnSessionError(const char* aSessionId,
+                              uint32_t aSessionIdLength,
+                              GMPDOMException aException,
+                              uint32_t aSystemCode,
+                              const char* aMessage,
+                              uint32_t aMessageLength) = 0;
+
+  virtual void OnKeyIdUsable(const char* aSessionId,
+                             uint32_t aSessionIdLength,
+                             const uint8_t* aKeyId,
+                             uint32_t aKeyIdLength) = 0;
+
+  // Marks a key as no longer usable.
+  // Note: Keys are assumed to be not usable when a session is closed or removed.
+  virtual void OnKeyIdNotUsable(const char* aSessionId,
+                                uint32_t aSessionIdLength,
+                                const uint8_t* aKeyId,
+                                uint32_t aKeyIdLength) = 0;
+
+};
+
+// Host interface, passed to GetAPIFunc(), with "decrypt".
+class GMPDecryptorHost {
+public:
+
+  // Returns an origin specific string uniquely identifying the device.
+  // The node id contains a random component, and is consistent between
+  // plugin instantiations, unless the user clears it.
+  // Different origins have different node ids.
+  // The node id pointer returned here remains valid for the until shutdown
+  // begins.
+  // *aOutNodeId is null terminated.
+  virtual void GetNodeId(const char** aOutNodeId,
+                         uint32_t* aOutNodeIdLength) = 0;
+
+  virtual void GetSandboxVoucher(const uint8_t** aVoucher,
+                                 uint8_t* aVoucherLength) = 0;
+
+  virtual void GetPluginVoucher(const uint8_t** aVoucher,
+                                uint8_t* aVoucherLength) = 0;
+};
+
+enum GMPSessionType {
+  kGMPTemporySession = 0,
+  kGMPPersistentSession = 1
+};
+
+// API exposed by plugin library to manage decryption sessions.
+// When the Host requests this by calling GMPGetAPIFunc().
+//
+// API name: "eme-decrypt".
+// Host API: GMPDecryptorHost
+class GMPDecryptor {
+public:
+
+  // Sets the callback to use with the decryptor to return results
+  // to Gecko.
+  virtual void Init(GMPDecryptorCallback* aCallback) = 0;
+
+  // Requests the creation of a session given |aType| and |aInitData|.
+  // Decryptor should callback GMPDecryptorCallback::OnSessionCreated()
+  // with the web session ID on success, or OnSessionError() on failure,
+  // and then call OnSessionReady() once all keys for that session are
+  // available.
+  virtual void CreateSession(uint32_t aPromiseId,
+                             const char* aInitDataType,
+                             uint32_t aInitDataTypeSize,
+                             const uint8_t* aInitData,
+                             uint32_t aInitDataSize,
+                             GMPSessionType aSessionType) = 0;
+
+  // Loads a previously loaded persistent session.
+  virtual void LoadSession(uint32_t aPromiseId,
+                           const char* aSessionId,
+                           uint32_t aSessionIdLength) = 0;
+
+  // Updates the session with |aResponse|.
+  virtual void UpdateSession(uint32_t aPromiseId,
+                             const char* aSessionId,
+                             uint32_t aSessionIdLength,
+                             const uint8_t* aResponse,
+                             uint32_t aResponseSize) = 0;
+
+  // Releases the resources (keys) for the specified session.
+  virtual void CloseSession(uint32_t aPromiseId,
+                            const char* aSessionId,
+                            uint32_t aSessionIdLength) = 0;
+
+  // Removes the resources (keys) for the specified session.
+  virtual void RemoveSession(uint32_t aPromiseId,
+                             const char* aSessionId,
+                             uint32_t aSessionIdLength) = 0;
+
+  // Resolve/reject promise on completion.
+  virtual void SetServerCertificate(uint32_t aPromiseId,
+                                    const uint8_t* aServerCert,
+                                    uint32_t aServerCertSize) = 0;
+};
+
+#endif // GMP_DECRYPTION_h_
--- a/content/media/gmp/gmp-api/gmp-errors.h
+++ b/content/media/gmp/gmp-api/gmp-errors.h
@@ -30,12 +30,21 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef GMP_ERRORS_h_
 #define GMP_ERRORS_h_
 
 typedef enum {
   GMPNoErr = 0,
-  GMPGenericErr = 1
+  GMPGenericErr = 1,
+  GMPClosedErr = 2,
+  GMPAllocErr = 3,
+  GMPNotImplementedErr = 4,
+  GMPNotClosedErr = 5,
+  GMPQuotaExceededErr = 6,
+  GMPLastErr // Placeholder, must be last. This enum's values must remain consecutive!
 } GMPErr;
 
+#define GMP_SUCCEEDED(x) ((x) == GMPNoErr)
+#define GMP_FAILED(x) ((x) != GMPNoErr)
+
 #endif // GMP_ERRORS_h_
--- a/content/media/gmp/gmp-api/gmp-platform.h
+++ b/content/media/gmp/gmp-api/gmp-platform.h
@@ -29,22 +29,24 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef GMP_PLATFORM_h_
 #define GMP_PLATFORM_h_
 
 #include "gmp-errors.h"
+#include "gmp-storage.h"
 #include <stdint.h>
 
 /* Platform helper API. */
 
 class GMPTask {
 public:
+  virtual void Destroy() = 0;
   virtual ~GMPTask() {}
   virtual void Run() = 0;
 };
 
 class GMPThread {
 public:
   virtual ~GMPThread() {}
   virtual void Post(GMPTask* aTask) = 0;
@@ -53,27 +55,40 @@ public:
 
 class GMPMutex {
 public:
   virtual ~GMPMutex() {}
   virtual void Acquire() = 0;
   virtual void Release() = 0;
 };
 
+// Time is defined as the number of milliseconds since the
+// Epoch (00:00:00 UTC, January 1, 1970).
+typedef int64_t GMPTimestamp;
+
 typedef GMPErr (*GMPCreateThreadPtr)(GMPThread** aThread);
 typedef GMPErr (*GMPRunOnMainThreadPtr)(GMPTask* aTask);
 typedef GMPErr (*GMPSyncRunOnMainThreadPtr)(GMPTask* aTask);
 typedef GMPErr (*GMPCreateMutexPtr)(GMPMutex** aMutex);
+typedef GMPErr (*GMPCreateRecordPtr)(const char* aRecordName,
+                                     uint32_t aRecordNameSize,
+                                     GMPRecord** aOutRecord,
+                                     GMPRecordClient* aClient);
+typedef GMPErr (*GMPSetTimerOnMainThreadPtr)(GMPTask* aTask, int64_t aTimeoutMS);
+typedef GMPErr (*GMPGetCurrentTimePtr)(GMPTimestamp* aOutTime);
 
 struct GMPPlatformAPI {
   // Increment the version when things change. Can only add to the struct,
   // do not change what already exists. Pointers to functions may be NULL
   // when passed to plugins, but beware backwards compat implications of
   // doing that.
   uint16_t version; // Currently version 0
 
   GMPCreateThreadPtr createthread;
   GMPRunOnMainThreadPtr runonmainthread;
   GMPSyncRunOnMainThreadPtr syncrunonmainthread;
   GMPCreateMutexPtr createmutex;
+  GMPCreateRecordPtr createrecord;
+  GMPSetTimerOnMainThreadPtr settimer;
+  GMPGetCurrentTimePtr getcurrenttime;
 };
 
 #endif // GMP_PLATFORM_h_
new file mode 100644
--- /dev/null
+++ b/content/media/gmp/gmp-api/gmp-storage.h
@@ -0,0 +1,90 @@
+/*
+* Copyright 2013, Mozilla Foundation and contributors
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef GMP_STORAGE_h_
+#define GMP_STORAGE_h_
+
+#include "gmp-errors.h"
+#include <stdint.h>
+
+// Provides basic per-origin storage for CDMs. GMPRecord instances can be
+// retrieved by calling GMPPlatformAPI->openstorage. Multiple GMPRecord
+// can be open at once. This interface is asynchronous, with results
+// being returned via callbacks to the GMPRecordClient pointer provided
+// to the GMPPlatformAPI->openstorage call, on the main thread.
+class GMPRecord {
+public:
+
+  // Opens the record. Calls OnOpenComplete() once the record is open.
+  // Note: OnReadComplete() is only called if this returns GMPNoErr.
+  virtual GMPErr Open() = 0;
+
+  // Reads the entire contents of the file, and calls
+  // GMPRecordClient::OnReadComplete() once the operation is complete.
+  // Note: OnReadComplete() is only called if this returns GMPNoErr.
+  virtual GMPErr Read() = 0;
+
+  // Writes aDataSize bytes of aData into the file, overwritting the contents
+  // of the file. Overwriting with 0 bytes "deletes" the file.
+  // Write 0 bytes to "delete" a file.
+  // Note: OnWriteComplete is only called if this returns GMPNoErr.
+  virtual GMPErr Write(const uint8_t* aData, uint32_t aDataSize) = 0;
+
+  // Closes a file. File must not be used after this is called. Cancels all
+  // callbacks.
+  virtual GMPErr Close() = 0;
+
+  virtual ~GMPRecord() {}
+};
+
+// Callback object that receives the results of GMPRecord calls. Callbacks
+// run asynchronously to the GMPRecord call, on the main thread.
+class GMPRecordClient {
+ public:
+
+  // Response to a GMPRecord::Open() call with the open |status|.
+  // aStatus values:
+  // - GMPNoErr - File opened successfully. File may be empty.
+  // - GMPFileInUse - There file is in use by another client.
+  // - GMPGenericErr - Unspecified error.
+  // Do not use the GMPRecord if aStatus is not GMPNoErr.
+  virtual void OnOpenComplete(GMPErr aStatus) = 0;
+
+  // Response to a GMPRecord::Read() call, where aData is the file contents,
+  // of length aDataSize.
+  // aData is only valid for the duration of the call to OnReadComplete.
+  // Copy it if you want to hang onto it!
+  // aStatus values:
+  // - GMPNoErr - File contents read successfully, aDataSize 0 means file
+  //   is empty.
+  // - GMPFileInUse - There are other operations or clients in use on this file.
+  // - GMPGenericErr - Unspecified error.
+  // Do not continue to use the GMPRecord if aStatus is not GMPNoErr.
+  virtual void OnReadComplete(GMPErr aStatus,
+                              const uint8_t* aData,
+                              uint32_t aDataSize) = 0;
+
+  // Response to a GMPRecord::Write() call.
+  // - GMPNoErr - File contents written successfully.
+  // - GMPFileInUse - There are other operations or clients in use on this file.
+  // - GMPGenericErr - Unspecified error. File should be regarded as corrupt.
+  // Do not continue to use the GMPRecord if aStatus is not GMPNoErr.
+  virtual void OnWriteComplete(GMPErr aStatus) = 0;
+
+  virtual ~GMPRecordClient() {}
+};
+
+#endif // GMP_STORAGE_h_
--- a/content/media/gmp/gmp-api/gmp-video-codec.h
+++ b/content/media/gmp/gmp-api/gmp-video-codec.h
@@ -67,83 +67,103 @@ struct GMPVideoCodecVP8
   bool mPictureLossIndicationOn;
   bool mFeedbackModeOn;
   GMPVideoCodecComplexity mComplexity;
   GMPVP8ResilienceMode mResilience;
   uint32_t mNumberOfTemporalLayers;
   bool mDenoisingOn;
   bool mErrorConcealmentOn;
   bool mAutomaticResizeOn;
-  bool mFrameDroppingOn;
-  int32_t mKeyFrameInterval;
 };
 
 // H264 specific
-struct GMPVideoCodecH264
+
+// Needs to match a binary spec for this structure.
+// Note: the mSPS at the end of this structure is variable length.
+struct GMPVideoCodecH264AVCC
 {
-  uint8_t        mProfile;
+  uint8_t        mVersion; // == 0x01
+  uint8_t        mProfile; // these 3 are profile_level_id
   uint8_t        mConstraints;
   uint8_t        mLevel;
+  uint8_t        mLengthSizeMinusOne; // lower 2 bits (== GMPBufferType-1). Top 6 reserved (1's)
+
+  // SPS/PPS will not generally be present for interactive use unless SDP
+  // parameter-sets are used.
+  uint8_t        mNumSPS; // lower 5 bits; top 5 reserved (1's)
+
+  /*** uint8_t   mSPS[];  (Not defined due to compiler warnings and warnings-as-errors ...) **/
+  // Following mNumSPS is a variable number of bytes, which is the SPS and PPS.
+  // Each SPS == 16 bit size, ("N"), then "N" bytes,
+  // then uint8_t mNumPPS, then each PPS == 16 bit size ("N"), then "N" bytes.
+};
+
+// Codec specific data for H.264 decoding/encoding.
+// Cast the "aCodecSpecific" parameter of GMPVideoDecoder::InitDecode() and
+// GMPVideoEncoder::InitEncode() to this structure.
+struct GMPVideoCodecH264
+{
   uint8_t        mPacketizationMode; // 0 or 1
-  bool           mFrameDroppingOn;
-  int32_t        mKeyFrameInterval;
-  // These are null/0 if not externally negotiated
-  const uint8_t* mSPSData;
-  size_t         mSPSLen;
-  const uint8_t* mPPSData;
-  size_t         mPPSLen;
+  struct GMPVideoCodecH264AVCC mAVCC; // holds a variable-sized struct GMPVideoCodecH264AVCC mAVCC;
 };
 
 enum GMPVideoCodecType
 {
   kGMPVideoCodecVP8,
+
+  // Encoded frames are in AVCC format; NAL length field of 4 bytes, followed
+  // by frame data. May be multiple NALUs per sample. Codec specific extra data
+  // is the AVCC extra data (in AVCC format).
   kGMPVideoCodecH264,
   kGMPVideoCodecInvalid // Should always be last.
 };
 
-union GMPVideoCodecUnion
-{
-  GMPVideoCodecVP8 mVP8;
-  GMPVideoCodecH264 mH264;
-};
-
 // Simulcast is when the same stream is encoded multiple times with different
 // settings such as resolution.
 struct GMPSimulcastStream
 {
   uint32_t mWidth;
   uint32_t mHeight;
   uint32_t mNumberOfTemporalLayers;
   uint32_t mMaxBitrate; // kilobits/sec.
   uint32_t mTargetBitrate; // kilobits/sec.
   uint32_t mMinBitrate; // kilobits/sec.
   uint32_t mQPMax; // minimum quality
 };
 
 enum GMPVideoCodecMode {
   kGMPRealtimeVideo,
   kGMPScreensharing,
+  kGMPStreamingVideo,
   kGMPCodecModeInvalid // Should always be last.
 };
 
+enum GMPApiVersion {
+  kGMPVersion32 = 1, // leveraging that V32 had mCodecType first, and only supported H264
+  kGMPVersion33 = 33,
+};
+
 struct GMPVideoCodec
 {
+  uint32_t mGMPApiVersion;
+
   GMPVideoCodecType mCodecType;
   char mPLName[kGMPPayloadNameSize]; // Must be NULL-terminated!
   uint32_t mPLType;
 
   uint32_t mWidth;
   uint32_t mHeight;
 
   uint32_t mStartBitrate; // kilobits/sec.
   uint32_t mMaxBitrate; // kilobits/sec.
   uint32_t mMinBitrate; // kilobits/sec.
   uint32_t mMaxFramerate;
 
-  GMPVideoCodecUnion mCodecSpecific;
+  bool mFrameDroppingOn;
+  int32_t mKeyFrameInterval;
 
   uint32_t mQPMax;
   uint32_t mNumberOfSimulcastStreams;
   GMPSimulcastStream mSimulcastStream[kGMPMaxSimulcastStreams];
 
   GMPVideoCodecMode mMode;
 };
 
@@ -152,16 +172,17 @@ struct GMPVideoCodec
 // entry; one should check the overall end-of-buffer against where the next
 // length would be.
 enum GMPBufferType {
   GMP_BufferSingle = 0,
   GMP_BufferLength8,
   GMP_BufferLength16,
   GMP_BufferLength24,
   GMP_BufferLength32,
+  GMP_BufferInvalid,
 };
 
 struct GMPCodecSpecificInfoGeneric {
   uint8_t mSimulcastIdx;
 };
 
 struct GMPCodecSpecificInfoH264 {
   uint8_t mSimulcastIdx;
@@ -183,16 +204,17 @@ struct GMPCodecSpecificInfoVP8
   int32_t mTL0PicIdx; // negative value to skip tl0PicIdx
   int8_t mKeyIdx; // negative value to skip keyIdx
 };
 
 union GMPCodecSpecificInfoUnion
 {
   GMPCodecSpecificInfoGeneric mGeneric;
   GMPCodecSpecificInfoVP8 mVP8;
+  GMPCodecSpecificInfoH264 mH264;
 };
 
 // Note: if any pointers are added to this struct or its sub-structs, it
 // must be fitted with a copy-constructor. This is because it is copied
 // in the copy-constructor of VCMEncodedFrame.
 struct GMPCodecSpecificInfo
 {
   GMPVideoCodecType mCodecType;
--- a/content/media/gmp/gmp-api/gmp-video-decode.h
+++ b/content/media/gmp/gmp-api/gmp-video-decode.h
@@ -29,72 +29,87 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef GMP_VIDEO_DECODE_h_
 #define GMP_VIDEO_DECODE_h_
 
-#include "gmp-video-errors.h"
+#include "gmp-errors.h"
 #include "gmp-video-frame-i420.h"
 #include "gmp-video-frame-encoded.h"
 #include "gmp-video-codec.h"
 #include <stdint.h>
 
 // ALL METHODS MUST BE CALLED ON THE MAIN THREAD
-class GMPDecoderCallback
+class GMPVideoDecoderCallback
 {
 public:
-  virtual ~GMPDecoderCallback() {}
+  virtual ~GMPVideoDecoderCallback() {}
 
   virtual void Decoded(GMPVideoi420Frame* aDecodedFrame) = 0;
 
   virtual void ReceivedDecodedReferenceFrame(const uint64_t aPictureId) = 0;
 
   virtual void ReceivedDecodedFrame(const uint64_t aPictureId) = 0;
 
   virtual void InputDataExhausted() = 0;
+
+  virtual void DrainComplete() = 0;
+
+  virtual void ResetComplete() = 0;
 };
 
 // ALL METHODS MUST BE CALLED ON THE MAIN THREAD
 class GMPVideoDecoder
 {
 public:
   virtual ~GMPVideoDecoder() {}
 
-  // aCallback: Subclass should retain reference to it until DecodingComplete
-  //            is called. Do not attempt to delete it, host retains ownership.
-  virtual GMPVideoErr InitDecode(const GMPVideoCodec& aCodecSettings,
-                                 GMPDecoderCallback* aCallback,
-                                 int32_t aCoreCount) = 0;
+  // - aCodecSettings: Details of decoder to create.
+  // - aCodecSpecific: codec specific data, cast to a GMPVideoCodecXXX struct
+  //                   to get codec specific config data.
+  // - aCodecSpecificLength: number of bytes in aCodecSpecific.
+  // - aCallback: Subclass should retain reference to it until DecodingComplete
+  //              is called. Do not attempt to delete it, host retains ownership.
+  // aCoreCount: number of CPU cores.
+  virtual GMPErr InitDecode(const GMPVideoCodec& aCodecSettings,
+                            const uint8_t* aCodecSpecific,
+                            uint32_t aCodecSpecificLength,
+                            GMPVideoDecoderCallback* aCallback,
+                            int32_t aCoreCount) = 0;
 
   // Decode encoded frame (as a part of a video stream). The decoded frame
   // will be returned to the user through the decode complete callback.
   //
-  // inputFrame:        Frame to decode.
-  //
-  // missingFrames:     True if one or more frames have been lost since the previous decode call.
-  //
-  // fragmentation:     Specifies where the encoded frame can be split into separate fragments.
-  //                    The meaning of fragment is codec specific, but often means that each
-  //                    fragment is decodable by itself.
-  //
-  // codecSpecificInfo: Codec-specific data
-  //
-  // renderTimeMs :     System time to render in milliseconds. Only used by decoders with internal
-  //                    rendering.
-  virtual GMPVideoErr Decode(GMPVideoEncodedFrame* aInputFrame,
-                             bool aMissingFrames,
-                             const GMPCodecSpecificInfo& aCodecSpecificInfo,
-                             int64_t aRenderTimeMs = -1) = 0;
+  // - aInputFrame: Frame to decode. Call Destroy() on frame when it's decoded.
+  // - aMissingFrames: True if one or more frames have been lost since the
+  //                   previous decode call.
+  // - aCodecSpecificInfo : codec specific data, pointer to a
+  //                        GMPCodecSpecificInfo structure appropriate for
+  //                        this codec type.
+  // - aCodecSpecificInfoLength : number of bytes in aCodecSpecificInfo
+  // - renderTimeMs : System time to render in milliseconds. Only used by
+  //                  decoders with internal rendering.
+  virtual GMPErr Decode(GMPVideoEncodedFrame* aInputFrame,
+                        bool aMissingFrames,
+                        const uint8_t* aCodecSpecificInfo,
+                        uint32_t aCodecSpecificInfoLength,
+                        int64_t aRenderTimeMs = -1) = 0;
 
-  // Reset decoder state and prepare for a new call to Decode(...). Flushes the decoder pipeline.
-  virtual GMPVideoErr Reset() = 0;
+  // Reset decoder state and prepare for a new call to Decode(...).
+  // Flushes the decoder pipeline.
+  // The decoder should enqueue a task to run ResetComplete() on the main
+  // thread once the reset has finished.
+  virtual GMPErr Reset() = 0;
 
   // Output decoded frames for any data in the pipeline, regardless of ordering.
-  virtual GMPVideoErr Drain() = 0;
+  // All remaining decoded frames should be immediately returned via callback.
+  // The decoder should enqueue a task to run DrainComplete() on the main
+  // thread once the reset has finished.
+  virtual GMPErr Drain() = 0;
 
   // May free decoder memory.
   virtual void DecodingComplete() = 0;
 };
 
 #endif // GMP_VIDEO_DECODE_h_
--- a/content/media/gmp/gmp-api/gmp-video-encode.h
+++ b/content/media/gmp/gmp-api/gmp-video-encode.h
@@ -32,79 +32,92 @@
  */
 
 #ifndef GMP_VIDEO_ENCODE_h_
 #define GMP_VIDEO_ENCODE_h_
 
 #include <vector>
 #include <stdint.h>
 
-#include "gmp-video-errors.h"
+#include "gmp-errors.h"
 #include "gmp-video-frame-i420.h"
 #include "gmp-video-frame-encoded.h"
 #include "gmp-video-codec.h"
 
 // ALL METHODS MUST BE CALLED ON THE MAIN THREAD
-class GMPEncoderCallback
+class GMPVideoEncoderCallback
 {
 public:
-  virtual ~GMPEncoderCallback() {}
+  virtual ~GMPVideoEncoderCallback() {}
 
   virtual void Encoded(GMPVideoEncodedFrame* aEncodedFrame,
-                       const GMPCodecSpecificInfo& aCodecSpecificInfo) = 0;
+                       const uint8_t* aCodecSpecificInfo,
+                       uint32_t aCodecSpecificInfoLength) = 0;
 };
 
 // ALL METHODS MUST BE CALLED ON THE MAIN THREAD
 class GMPVideoEncoder
 {
 public:
   virtual ~GMPVideoEncoder() {}
 
   // Initialize the encoder with the information from the VideoCodec.
   //
   // Input:
   // - codecSettings : Codec settings
+  // - aCodecSpecific : codec specific data, pointer to a
+  //                    GMPCodecSpecific structure appropriate for
+  //                    this codec type.
+  // - aCodecSpecificLength : number of bytes in aCodecSpecific
   // - aCallback: Subclass should retain reference to it until EncodingComplete
   //              is called. Do not attempt to delete it, host retains ownership.
-  // - numberOfCores : Number of cores available for the encoder
-  // - maxPayloadSize : The maximum size each payload is allowed
+  // - aNnumberOfCores : Number of cores available for the encoder
+  // - aMaxPayloadSize : The maximum size each payload is allowed
   //                    to have. Usually MTU - overhead.
-  virtual GMPVideoErr InitEncode(const GMPVideoCodec& aCodecSettings,
-                                 GMPEncoderCallback* aCallback,
-                                 int32_t aNumberOfCores,
-                                 uint32_t aMaxPayloadSize) = 0;
+  virtual GMPErr InitEncode(const GMPVideoCodec& aCodecSettings,
+                            const uint8_t* aCodecSpecific,
+                            uint32_t aCodecSpecificLength,
+                            GMPVideoEncoderCallback* aCallback,
+                            int32_t aNumberOfCores,
+                            uint32_t aMaxPayloadSize) = 0;
 
   // Encode an I420 frame (as a part of a video stream). The encoded frame
   // will be returned to the user through the encode complete callback.
   //
   // Input:
-  // - inputFrame : Frame to be encoded
-  // - codecSpecificInfo : Pointer to codec specific data
-  // - frame_types : The frame type to encode
-  virtual GMPVideoErr Encode(GMPVideoi420Frame* aInputFrame,
-                             const GMPCodecSpecificInfo& aCodecSpecificInfo,
-                             const std::vector<GMPVideoFrameType>& aFrameTypes) = 0;
+  // - aInputFrame : Frame to be encoded
+  // - aCodecSpecificInfo : codec specific data, pointer to a
+  //                        GMPCodecSpecificInfo structure appropriate for
+  //                        this codec type.
+  // - aCodecSpecificInfoLength : number of bytes in aCodecSpecific
+  // - aFrameTypes : The frame type to encode
+  // - aFrameTypesLength : The number of elements in aFrameTypes array.
+  virtual GMPErr Encode(GMPVideoi420Frame* aInputFrame,
+                        const uint8_t* aCodecSpecificInfo,
+                        uint32_t aCodecSpecificInfoLength,
+                        const GMPVideoFrameType* aFrameTypes,
+                        uint32_t aFrameTypesLength) = 0;
 
   // Inform the encoder about the packet loss and round trip time on the
   // network used to decide the best pattern and signaling.
   //
   // - packetLoss : Fraction lost (loss rate in percent =
   // 100 * packetLoss / 255)
   // - rtt : Round-trip time in milliseconds
-  virtual GMPVideoErr SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) = 0;
+  virtual GMPErr SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) = 0;
 
   // Inform the encoder about the new target bit rate.
   //
   // - newBitRate : New target bit rate
   // - frameRate : The target frame rate
-  virtual GMPVideoErr SetRates(uint32_t aNewBitRate, uint32_t aFrameRate) = 0;
+  virtual GMPErr SetRates(uint32_t aNewBitRate, uint32_t aFrameRate) = 0;
 
   // Use this function to enable or disable periodic key frames. Can be useful for codecs
   // which have other ways of stopping error propagation.
   //
   // - enable : Enable or disable periodic key frames
-  virtual GMPVideoErr SetPeriodicKeyFrames(bool aEnable) = 0;
+  virtual GMPErr SetPeriodicKeyFrames(bool aEnable) = 0;
 
   // May free Encoder memory.
   virtual void EncodingComplete() = 0;
 };
 
 #endif // GMP_VIDEO_ENCODE_h_
deleted file mode 100644
--- a/content/media/gmp/gmp-api/gmp-video-errors.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* Copyright (c) 2011, The WebRTC project authors. All rights reserved.
- * Copyright (c) 2014, Mozilla
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- ** Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- ** Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in
- *  the documentation and/or other materials provided with the
- *  distribution.
- *
- ** Neither the name of Google nor the names of its contributors may
- *  be used to endorse or promote products derived from this software
- *  without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef GMP_VIDEO_ERRORS_h_
-#define GMP_VIDEO_ERRORS_h_
-
-enum GMPVideoErr {
-  GMPVideoNoErr = 0,
-  GMPVideoGenericErr = 1,
-  GMPVideoAllocErr = 2
-};
-
-#endif // GMP_VIDEO_ERRORS_h_
--- a/content/media/gmp/gmp-api/gmp-video-frame-encoded.h
+++ b/content/media/gmp/gmp-api/gmp-video-frame-encoded.h
@@ -30,16 +30,19 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef GMP_VIDEO_FRAME_ENCODED_h_
 #define GMP_VIDEO_FRAME_ENCODED_h_
 
 #include <stdint.h>
+#include "gmp-decryption.h"
+#include "gmp-video-frame.h"
+#include "gmp-video-codec.h"
 
 enum GMPVideoFrameType
 {
   kGMPKeyFrame = 0,
   kGMPDeltaFrame = 1,
   kGMPGoldenFrame = 2,
   kGMPAltRefFrame = 3,
   kGMPSkipFrame = 4
@@ -53,32 +56,43 @@ enum GMPVideoFrameType
 // access the underlying buffer(s).
 //
 // Methods that create or destroy shared memory must be called on the main
 // thread. They are marked below.
 class GMPVideoEncodedFrame : public GMPVideoFrame
 {
 public:
   // MAIN THREAD ONLY
-  virtual GMPVideoErr CreateEmptyFrame(uint32_t aSize) = 0;
+  virtual GMPErr CreateEmptyFrame(uint32_t aSize) = 0;
   // MAIN THREAD ONLY
-  virtual GMPVideoErr CopyFrame(const GMPVideoEncodedFrame& aVideoFrame) = 0;
+  virtual GMPErr CopyFrame(const GMPVideoEncodedFrame& aVideoFrame) = 0;
   virtual void     SetEncodedWidth(uint32_t aEncodedWidth) = 0;
   virtual uint32_t EncodedWidth() = 0;
   virtual void     SetEncodedHeight(uint32_t aEncodedHeight) = 0;
   virtual uint32_t EncodedHeight() = 0;
-  virtual void     SetTimeStamp(uint32_t aTimeStamp) = 0;
-  virtual uint32_t TimeStamp() = 0;
-  virtual void     SetCaptureTime(int64_t aCaptureTime) = 0;
-  virtual int64_t  CaptureTime() = 0;
+  // Microseconds
+  virtual void     SetTimeStamp(uint64_t aTimeStamp) = 0;
+  virtual uint64_t TimeStamp() = 0;
+  // Set frame duration (microseconds)
+  // NOTE: next-frame's Timestamp() != this-frame's TimeStamp()+Duration()
+  // depending on rounding to avoid having to track roundoff errors
+  // and dropped/missing frames(!) (which may leave a large gap)
+  virtual void     SetDuration(uint64_t aDuration) = 0;
+  virtual uint64_t Duration() const = 0;
   virtual void     SetFrameType(GMPVideoFrameType aFrameType) = 0;
   virtual GMPVideoFrameType FrameType() = 0;
   virtual void     SetAllocatedSize(uint32_t aNewSize) = 0;
   virtual uint32_t AllocatedSize() = 0;
   virtual void     SetSize(uint32_t aSize) = 0;
   virtual uint32_t Size() = 0;
   virtual void     SetCompleteFrame(bool aCompleteFrame) = 0;
   virtual bool     CompleteFrame() = 0;
   virtual const uint8_t* Buffer() const = 0;
   virtual uint8_t*       Buffer() = 0;
+  virtual GMPBufferType  BufferType() const = 0;
+  virtual void     SetBufferType(GMPBufferType aBufferType) = 0;
+
+  // Get data describing how this frame is encrypted, or nullptr if the
+  // frame is not encrypted.
+  virtual const GMPEncryptedBufferData* GetDecryptionData() const = 0;
 };
 
 #endif // GMP_VIDEO_FRAME_ENCODED_h_
--- a/content/media/gmp/gmp-api/gmp-video-frame-i420.h
+++ b/content/media/gmp/gmp-api/gmp-video-frame-i420.h
@@ -29,17 +29,17 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef GMP_VIDEO_FRAME_I420_h_
 #define GMP_VIDEO_FRAME_I420_h_
 
-#include "gmp-video-errors.h"
+#include "gmp-errors.h"
 #include "gmp-video-frame.h"
 #include "gmp-video-plane.h"
 
 #include <stdint.h>
 
 enum GMPPlaneType {
   kGMPYPlane = 0,
   kGMPUPlane = 1,
@@ -58,32 +58,32 @@ enum GMPPlaneType {
 // thread. They are marked below.
 class GMPVideoi420Frame : public GMPVideoFrame {
 public:
   // MAIN THREAD ONLY
   // CreateEmptyFrame: Sets frame dimensions and allocates buffers based
   // on set dimensions - height and plane stride.
   // If required size is bigger than the allocated one, new buffers of adequate
   // size will be allocated.
-  virtual GMPVideoErr CreateEmptyFrame(int32_t aWidth, int32_t aHeight,
-                                       int32_t aStride_y, int32_t aStride_u, int32_t aStride_v) = 0;
+  virtual GMPErr CreateEmptyFrame(int32_t aWidth, int32_t aHeight,
+                                  int32_t aStride_y, int32_t aStride_u, int32_t aStride_v) = 0;
 
   // MAIN THREAD ONLY
   // CreateFrame: Sets the frame's members and buffers. If required size is
   // bigger than allocated one, new buffers of adequate size will be allocated.
-  virtual GMPVideoErr CreateFrame(int32_t aSize_y, const uint8_t* aBuffer_y,
-                                  int32_t aSize_u, const uint8_t* aBuffer_u,
-                                  int32_t aSize_v, const uint8_t* aBuffer_v,
-                                  int32_t aWidth, int32_t aHeight,
-                                  int32_t aStride_y, int32_t aStride_u, int32_t aStride_v) = 0;
+  virtual GMPErr CreateFrame(int32_t aSize_y, const uint8_t* aBuffer_y,
+                             int32_t aSize_u, const uint8_t* aBuffer_u,
+                             int32_t aSize_v, const uint8_t* aBuffer_v,
+                             int32_t aWidth, int32_t aHeight,
+                             int32_t aStride_y, int32_t aStride_u, int32_t aStride_v) = 0;
 
   // MAIN THREAD ONLY
   // Copy frame: If required size is bigger than allocated one, new buffers of
   // adequate size will be allocated.
-  virtual GMPVideoErr CopyFrame(const GMPVideoi420Frame& aVideoFrame) = 0;
+  virtual GMPErr CopyFrame(const GMPVideoi420Frame& aVideoFrame) = 0;
 
   // Swap Frame.
   virtual void SwapFrame(GMPVideoi420Frame* aVideoFrame) = 0;
 
   // Get pointer to buffer per plane.
   virtual uint8_t* Buffer(GMPPlaneType aType) = 0;
 
   // Overloading with const.
@@ -91,38 +91,41 @@ public:
 
   // Get allocated size per plane.
   virtual int32_t AllocatedSize(GMPPlaneType aType) const = 0;
 
   // Get allocated stride per plane.
   virtual int32_t Stride(GMPPlaneType aType) const = 0;
 
   // Set frame width.
-  virtual GMPVideoErr SetWidth(int32_t aWidth) = 0;
+  virtual GMPErr SetWidth(int32_t aWidth) = 0;
 
   // Set frame height.
-  virtual GMPVideoErr SetHeight(int32_t aHeight) = 0;
+  virtual GMPErr SetHeight(int32_t aHeight) = 0;
 
   // Get frame width.
   virtual int32_t Width() const = 0;
 
   // Get frame height.
   virtual int32_t Height() const = 0;
 
-  // Set frame timestamp (90kHz).
-  virtual void SetTimestamp(uint32_t aTimestamp) = 0;
+  // Set frame timestamp (microseconds)
+  virtual void SetTimestamp(uint64_t aTimestamp) = 0;
 
-  // Get frame timestamp (90kHz).
-  virtual uint32_t Timestamp() const = 0;
+  // Get frame timestamp (microseconds)
+  virtual uint64_t Timestamp() const = 0;
 
-  // Set render time in miliseconds.
-  virtual void SetRenderTime_ms(int64_t aRenderTime_ms) = 0;
+  // Set frame duration (microseconds)
+  // NOTE: next-frame's Timestamp() != this-frame's TimeStamp()+Duration()
+  // depending on rounding to avoid having to track roundoff errors
+  // and dropped/missing frames(!) (which may leave a large gap)
+  virtual void SetDuration(uint64_t aDuration) = 0;
 
-  // Get render time in miliseconds.
-  virtual int64_t RenderTime_ms() const = 0;
+  // Get frame duration (microseconds)
+  virtual uint64_t Duration() const = 0;
 
   // Return true if underlying plane buffers are of zero size, false if not.
   virtual bool IsZeroSize() const = 0;
 
   // Reset underlying plane buffers sizes to 0. This function doesn't clear memory.
   virtual void ResetSize() = 0;
 };
 
--- a/content/media/gmp/gmp-api/gmp-video-frame.h
+++ b/content/media/gmp/gmp-api/gmp-video-frame.h
@@ -29,17 +29,16 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef GMP_VIDEO_FRAME_h_
 #define GMP_VIDEO_FRAME_h_
 
-#include "gmp-video-errors.h"
 #include "gmp-video-plane.h"
 
 enum GMPVideoFrameFormat {
   kGMPEncodedVideoFrame = 0,
   kGMPI420VideoFrame = 1
 };
 
 class GMPVideoFrame {
--- a/content/media/gmp/gmp-api/gmp-video-host.h
+++ b/content/media/gmp/gmp-api/gmp-video-host.h
@@ -29,23 +29,23 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef GMP_VIDEO_HOST_h_
 #define GMP_VIDEO_HOST_h_
 
-#include "gmp-video-errors.h"
+#include "gmp-errors.h"
 #include "gmp-video-frame-i420.h"
 #include "gmp-video-frame-encoded.h"
 #include "gmp-video-codec.h"
 
 class GMPVideoHost
 {
 public:
   // Construct various video API objects. Host does not retain reference,
   // caller is owner and responsible for deleting.
-  virtual GMPVideoErr CreateFrame(GMPVideoFrameFormat aFormat, GMPVideoFrame** aFrame) = 0;
-  virtual GMPVideoErr CreatePlane(GMPPlane** aPlane) = 0;
+  virtual GMPErr CreateFrame(GMPVideoFrameFormat aFormat, GMPVideoFrame** aFrame) = 0;
+  virtual GMPErr CreatePlane(GMPPlane** aPlane) = 0;
 };
 
 #endif // GMP_VIDEO_HOST_h_
--- a/content/media/gmp/gmp-api/gmp-video-plane.h
+++ b/content/media/gmp/gmp-api/gmp-video-plane.h
@@ -29,17 +29,17 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef GMP_VIDEO_PLANE_h_
 #define GMP_VIDEO_PLANE_h_
 
-#include "gmp-video-errors.h"
+#include "gmp-errors.h"
 #include <stdint.h>
 
 // The implementation backing this interface uses shared memory for the
 // buffer(s). This means it can only be used by the "owning" process.
 // At first the process which created the object owns it. When the object
 // is passed to an interface the creator loses ownership and must Destroy()
 // the object. Further attempts to use it may fail due to not being able to
 // access the underlying buffer(s).
@@ -47,28 +47,28 @@
 // Methods that create or destroy shared memory must be called on the main
 // thread. They are marked below.
 class GMPPlane {
 public:
   // MAIN THREAD ONLY
   // CreateEmptyPlane - set allocated size, actual plane size and stride:
   // If current size is smaller than current size, then a buffer of sufficient
   // size will be allocated.
-  virtual GMPVideoErr CreateEmptyPlane(int32_t aAllocatedSize,
-                                       int32_t aStride,
-                                       int32_t aPlaneSize) = 0;
+  virtual GMPErr CreateEmptyPlane(int32_t aAllocatedSize,
+                                  int32_t aStride,
+                                  int32_t aPlaneSize) = 0;
 
   // MAIN THREAD ONLY
   // Copy the entire plane data.
-  virtual GMPVideoErr Copy(const GMPPlane& aPlane) = 0;
+  virtual GMPErr Copy(const GMPPlane& aPlane) = 0;
 
   // MAIN THREAD ONLY
   // Copy buffer: If current size is smaller
   // than current size, then a buffer of sufficient size will be allocated.
-  virtual GMPVideoErr Copy(int32_t aSize, int32_t aStride, const uint8_t* aBuffer) = 0;
+  virtual GMPErr Copy(int32_t aSize, int32_t aStride, const uint8_t* aBuffer) = 0;
 
   // Swap plane data.
   virtual void Swap(GMPPlane& aPlane) = 0;
 
   // Get allocated size.
   virtual int32_t AllocatedSize() const = 0;
 
   // Set actual size.
--- a/content/media/gmp/moz.build
+++ b/content/media/gmp/moz.build
@@ -6,53 +6,62 @@
 
 XPIDL_MODULE = 'content_geckomediaplugins'
 
 XPIDL_SOURCES += [
     'mozIGeckoMediaPluginService.idl',
 ]
 
 EXPORTS += [
+    'gmp-api/gmp-async-shutdown.h',
+    'gmp-api/gmp-audio-codec.h',
+    'gmp-api/gmp