CLOSED TREE
This commit is contained in:
Ryan VanderMeulen 2015-08-04 15:55:24 -04:00
Родитель 10cd0eb56a 1d5a6d99ea
Коммит ba1fcc1f0a
70 изменённых файлов: 750 добавлений и 837 удалений

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73"> <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="67c38af8347f93ddc005a53f427d651b744b55c1"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="c5425d9f1f5184731a59ed4bc99295acbde30390"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73"> <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="67c38af8347f93ddc005a53f427d651b744b55c1"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="c5425d9f1f5184731a59ed4bc99295acbde30390"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="67c38af8347f93ddc005a53f427d651b744b55c1"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="c5425d9f1f5184731a59ed4bc99295acbde30390"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8bc59310552179f9a8bc6cdd0188e2475df52fb7"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8bc59310552179f9a8bc6cdd0188e2475df52fb7"/>

Просмотреть файл

@ -17,7 +17,7 @@
</project> </project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="67c38af8347f93ddc005a53f427d651b744b55c1"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="c5425d9f1f5184731a59ed4bc99295acbde30390"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/> <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ddfd98cdafefaa1b60273d5568b8dbd13730dae"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ddfd98cdafefaa1b60273d5568b8dbd13730dae"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73"> <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="67c38af8347f93ddc005a53f427d651b744b55c1"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="c5425d9f1f5184731a59ed4bc99295acbde30390"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="07c383a786f188904311a37f6062c2cb84c9b61d"> <project name="platform_build" path="build" remote="b2g" revision="07c383a786f188904311a37f6062c2cb84c9b61d">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="67c38af8347f93ddc005a53f427d651b744b55c1"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="c5425d9f1f5184731a59ed4bc99295acbde30390"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="67c38af8347f93ddc005a53f427d651b744b55c1"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="c5425d9f1f5184731a59ed4bc99295acbde30390"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8bc59310552179f9a8bc6cdd0188e2475df52fb7"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8bc59310552179f9a8bc6cdd0188e2475df52fb7"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73"> <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="67c38af8347f93ddc005a53f427d651b744b55c1"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="c5425d9f1f5184731a59ed4bc99295acbde30390"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -1,9 +1,9 @@
{ {
"git": { "git": {
"git_revision": "67c38af8347f93ddc005a53f427d651b744b55c1", "git_revision": "c5425d9f1f5184731a59ed4bc99295acbde30390",
"remote": "https://git.mozilla.org/releases/gaia.git", "remote": "https://git.mozilla.org/releases/gaia.git",
"branch": "" "branch": ""
}, },
"revision": "72807eee01421a4ddf6180b2e5a66757a42a7984", "revision": "68ce99a4e1761c06e5f31f6674ee46fef1bbf44b",
"repo_path": "integration/gaia-central" "repo_path": "integration/gaia-central"
} }

Просмотреть файл

@ -17,7 +17,7 @@
</project> </project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="67c38af8347f93ddc005a53f427d651b744b55c1"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="c5425d9f1f5184731a59ed4bc99295acbde30390"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/> <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ddfd98cdafefaa1b60273d5568b8dbd13730dae"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ddfd98cdafefaa1b60273d5568b8dbd13730dae"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="07c383a786f188904311a37f6062c2cb84c9b61d"> <project name="platform_build" path="build" remote="b2g" revision="07c383a786f188904311a37f6062c2cb84c9b61d">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="67c38af8347f93ddc005a53f427d651b744b55c1"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="c5425d9f1f5184731a59ed4bc99295acbde30390"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -7,11 +7,10 @@
"unpack": true "unpack": true
}, },
{ {
"size": 11179576, "size": 4079256,
"digest": "91567ce8e2bb8ab0ebc60c31e90731d88a1ea889fb71bcf55c735746a60fa7610b7e040ea3d8f727b6f692ae3ee703d6f3b30cdbd76fdf5617f77d9c38aa20ed", "digest": "bb5238558bcf6db2ca395513c8dccaa15dd61b3c375598eb6a685356b0c1a2d9840e3bf81bc00242b872fd798541f53d723777c754412abf0e772b7cc284937c",
"algorithm": "sha512", "algorithm": "sha512",
"filename": "gtk3.tar.xz", "filename": "gtk3.tar.xz",
"setup": "setup.sh",
"unpack": true "unpack": true
}, },
{ {

Просмотреть файл

@ -10,11 +10,10 @@
"unpack": true "unpack": true
}, },
{ {
"size": 12057960, "size": 4431740,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e", "digest": "68fc56b0fb0cdba629b95683d6649ff76b00dccf97af90960c3d7716f6108b2162ffd5ffcd5c3a60a21b28674df688fe4dabc67345e2da35ec5abeae3d48c8e3",
"algorithm": "sha512", "algorithm": "sha512",
"filename": "gtk3.tar.xz", "filename": "gtk3.tar.xz",
"setup": "setup.sh",
"unpack": true "unpack": true
} }
] ]

Просмотреть файл

@ -7,11 +7,10 @@
"unpack": true "unpack": true
}, },
{ {
"size": 12057960, "size": 4431740,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e", "digest": "68fc56b0fb0cdba629b95683d6649ff76b00dccf97af90960c3d7716f6108b2162ffd5ffcd5c3a60a21b28674df688fe4dabc67345e2da35ec5abeae3d48c8e3",
"algorithm": "sha512", "algorithm": "sha512",
"filename": "gtk3.tar.xz", "filename": "gtk3.tar.xz",
"setup": "setup.sh",
"unpack": true "unpack": true
}, },
{ {

Просмотреть файл

@ -10,11 +10,10 @@
"unpack": true "unpack": true
}, },
{ {
"size": 12057960, "size": 4431740,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e", "digest": "68fc56b0fb0cdba629b95683d6649ff76b00dccf97af90960c3d7716f6108b2162ffd5ffcd5c3a60a21b28674df688fe4dabc67345e2da35ec5abeae3d48c8e3",
"algorithm": "sha512", "algorithm": "sha512",
"filename": "gtk3.tar.xz", "filename": "gtk3.tar.xz",
"setup": "setup.sh",
"unpack": true "unpack": true
} }
] ]

Просмотреть файл

@ -640,7 +640,11 @@ getUserMedia.sharingMenu.accesskey = d
# getUserMedia.sharingMenuMicrophoneApplication, # getUserMedia.sharingMenuMicrophoneApplication,
# getUserMedia.sharingMenuMicrophoneScreen, # getUserMedia.sharingMenuMicrophoneScreen,
# getUserMedia.sharingMenuMicrophoneWindow, # getUserMedia.sharingMenuMicrophoneWindow,
# getUserMedia.sharingMenuMicrophoneBrowser): # getUserMedia.sharingMenuMicrophoneBrowser,
# getUserMedia.sharingMenuAudioCaptureApplication,
# getUserMedia.sharingMenuAudioCaptureScreen,
# getUserMedia.sharingMenuAudioCaptureWindow,
# getUserMedia.sharingMenuAudioCaptureBrowser):
# %S is the website origin (e.g. www.mozilla.org) # %S is the website origin (e.g. www.mozilla.org)
getUserMedia.sharingMenuCamera = %S (camera) getUserMedia.sharingMenuCamera = %S (camera)
getUserMedia.sharingMenuMicrophone = %S (microphone) getUserMedia.sharingMenuMicrophone = %S (microphone)
@ -667,10 +671,10 @@ getUserMedia.sharingMenuMicrophoneApplication = %S (microphone and application)
getUserMedia.sharingMenuMicrophoneScreen = %S (microphone and screen) getUserMedia.sharingMenuMicrophoneScreen = %S (microphone and screen)
getUserMedia.sharingMenuMicrophoneWindow = %S (microphone and window) getUserMedia.sharingMenuMicrophoneWindow = %S (microphone and window)
getUserMedia.sharingMenuMicrophoneBrowser = %S (microphone and tab) getUserMedia.sharingMenuMicrophoneBrowser = %S (microphone and tab)
getUserMedia.sharingMenuMicrophoneApplication = %S (tab audio and application) getUserMedia.sharingMenuAudioCaptureApplication = %S (tab audio and application)
getUserMedia.sharingMenuMicrophoneScreen = %S (tab audio and screen) getUserMedia.sharingMenuAudioCaptureScreen = %S (tab audio and screen)
getUserMedia.sharingMenuMicrophoneWindow = %S (tab audio and window) getUserMedia.sharingMenuAudioCaptureWindow = %S (tab audio and window)
getUserMedia.sharingMenuMicrophoneBrowser = %S (tab audio and tab) getUserMedia.sharingMenuAudioCaptureBrowser = %S (tab audio and tab)
# LOCALIZATION NOTE(getUserMedia.sharingMenuUnknownHost): this is used for the website # LOCALIZATION NOTE(getUserMedia.sharingMenuUnknownHost): this is used for the website
# origin for the sharing menu if no readable origin could be deduced from the URL. # origin for the sharing menu if no readable origin could be deduced from the URL.
getUserMedia.sharingMenuUnknownHost = Unknown origin getUserMedia.sharingMenuUnknownHost = Unknown origin

Просмотреть файл

@ -57,7 +57,7 @@ build() {
cd build/$name cd build/$name
eval ../../$name-$version/configure --disable-static $* $configure_args eval ../../$name-$version/configure --disable-static $* $configure_args
make $make_flags make $make_flags
make install DESTDIR=$root_dir/gtk3 make install-strip DESTDIR=$root_dir/gtk3
find $root_dir/gtk3 -name \*.la -delete find $root_dir/gtk3 -name \*.la -delete
cd ../.. cd ../..
} }
@ -103,44 +103,5 @@ build gtk+
rm -rf $root_dir/gtk3/usr/local/share/gtk-doc rm -rf $root_dir/gtk3/usr/local/share/gtk-doc
rm -rf $root_dir/gtk3/usr/local/share/locale rm -rf $root_dir/gtk3/usr/local/share/locale
# mock build environment doesn't have fonts in /usr/share/fonts, but
# has some in /usr/share/X11/fonts. Add this directory to the
# fontconfig configuration without changing the gtk3 tooltool package.
cat << EOF > $root_dir/gtk3/usr/local/etc/fonts/local.conf
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<dir>/usr/share/X11/fonts</dir>
</fontconfig>
EOF
cat <<EOF > $root_dir/gtk3/setup.sh
#!/bin/sh
cd \$(dirname \$0)
# pango expects absolute paths in pango.modules, and TOOLTOOL_DIR may vary...
LD_LIBRARY_PATH=./usr/local/lib \
PANGO_SYSCONFDIR=./usr/local/etc \
PANGO_LIBDIR=./usr/local/lib \
./usr/local/bin/pango-querymodules > ./usr/local/etc/pango/pango.modules
# same with gdb-pixbuf and loaders.cache
LD_LIBRARY_PATH=./usr/local/lib \
GDK_PIXBUF_MODULE_FILE=./usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache \
GDK_PIXBUF_MODULEDIR=./usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders \
./usr/local/bin/gdk-pixbuf-query-loaders > ./usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache
# The fontconfig version in the tooltool package has known uses of
# uninitialized memory when creating its cache, and while most users
# will already have an existing cache, running Firefox on automation
# will create it. Combined with valgrind, this generates irrelevant
# errors.
# So create the fontconfig cache beforehand.
./usr/local/bin/fc-cache
EOF
chmod +x $root_dir/gtk3/setup.sh
cd $cwd cd $cwd
tar -C $root_dir -Jcf gtk3.tar.xz gtk3 tar -C $root_dir -Jcf gtk3.tar.xz gtk3

Просмотреть файл

@ -11,6 +11,7 @@ if [ -d "$TOOLTOOL_DIR/gtk3" ]; then
export PATH="$TOOLTOOL_DIR/gtk3/usr/local/bin:${PATH}" export PATH="$TOOLTOOL_DIR/gtk3/usr/local/bin:${PATH}"
# Ensure cairo, gdk-pixbuf, etc. are not taken from the system installed packages. # Ensure cairo, gdk-pixbuf, etc. are not taken from the system installed packages.
LDFLAGS="-L$TOOLTOOL_DIR/gtk3/usr/local/lib ${LDFLAGS}" LDFLAGS="-L$TOOLTOOL_DIR/gtk3/usr/local/lib ${LDFLAGS}"
mk_add_options "export LD_LIBRARY_PATH=$TOOLTOOL_DIR/gtk3/usr/local/lib"
ac_add_options --enable-default-toolkit=cairo-gtk3 ac_add_options --enable-default-toolkit=cairo-gtk3
# Set things up to use Gtk+3 from the tooltool package # Set things up to use Gtk+3 from the tooltool package
@ -21,8 +22,37 @@ if [ -d "$TOOLTOOL_DIR/gtk3" ]; then
mk_add_options "export GDK_PIXBUF_MODULEDIR=$TOOLTOOL_DIR/gtk3/usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders" mk_add_options "export GDK_PIXBUF_MODULEDIR=$TOOLTOOL_DIR/gtk3/usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders"
mk_add_options "export LD_LIBRARY_PATH=$TOOLTOOL_DIR/gtk3/usr/local/lib" mk_add_options "export LD_LIBRARY_PATH=$TOOLTOOL_DIR/gtk3/usr/local/lib"
# Until a tooltool with bug 1188571 landed is available everywhere # pango expects absolute paths in pango.modules, and TOOLTOOL_DIR may vary...
$TOOLTOOL_DIR/gtk3/setup.sh LD_LIBRARY_PATH=$TOOLTOOL_DIR/gtk3/usr/local/lib \
PANGO_SYSCONFDIR=$TOOLTOOL_DIR/gtk3/usr/local/etc \
PANGO_LIBDIR=$TOOLTOOL_DIR/gtk3/usr/local/lib \
$TOOLTOOL_DIR/gtk3/usr/local/bin/pango-querymodules > $TOOLTOOL_DIR/gtk3/usr/local/etc/pango/pango.modules
# same with gdb-pixbuf and loaders.cache
LD_LIBRARY_PATH=$TOOLTOOL_DIR/gtk3/usr/local/lib \
GDK_PIXBUF_MODULE_FILE=$TOOLTOOL_DIR/gtk3/usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache \
GDK_PIXBUF_MODULEDIR=$TOOLTOOL_DIR/gtk3/usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders \
$TOOLTOOL_DIR/gtk3/usr/local/bin/gdk-pixbuf-query-loaders > $TOOLTOOL_DIR/gtk3/usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache
# The fontconfig version in the tooltool package has known uses of
# uninitialized memory when creating its cache, and while most users
# will already have an existing cache, running Firefox on automation
# will create it. Combined with valgrind, this generates irrelevant
# errors.
# So create the fontconfig cache beforehand.
$TOOLTOOL_DIR/gtk3/usr/local/bin/fc-cache
# mock build environment doesn't have fonts in /usr/share/fonts, but
# has some in /usr/share/X11/fonts. Add this directory to the
# fontconfig configuration without changing the gtk3 tooltool package.
cat << EOF > $TOOLTOOL_DIR/gtk3/usr/local/etc/fonts/local.conf
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<dir>/usr/share/X11/fonts</dir>
</fontconfig>
EOF
else else
ac_add_options --enable-default-toolkit=cairo-gtk2 ac_add_options --enable-default-toolkit=cairo-gtk2
fi fi

Просмотреть файл

@ -3728,12 +3728,14 @@ bool HTMLMediaElement::CanActivateAutoplay()
{ {
// For stream inputs, we activate autoplay on HAVE_NOTHING because // For stream inputs, we activate autoplay on HAVE_NOTHING because
// this element itself might be blocking the stream from making progress by // this element itself might be blocking the stream from making progress by
// being paused. // being paused. We also activate autopaly when playing a media source since
// the data download is controlled by the script and there is no way to
// evaluate MediaDecoder::CanPlayThrough().
return !mPausedForInactiveDocumentOrChannel && return !mPausedForInactiveDocumentOrChannel &&
mAutoplaying && mAutoplaying &&
mPaused && mPaused &&
((mDecoder && mReadyState >= nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA) || ((mDecoder && mReadyState >= nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA) ||
mSrcStream) && mSrcStream || mMediaSource) &&
HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay) && HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay) &&
mAutoplayEnabled && mAutoplayEnabled &&
!IsEditable(); !IsEditable();

Просмотреть файл

@ -96,7 +96,7 @@ function IccContact(aContact) {
let anrLen = aContact.anr ? aContact.anr.length : 0; let anrLen = aContact.anr ? aContact.anr.length : 0;
for (let i = 0; i < anrLen; i++) { for (let i = 0; i < anrLen; i++) {
this._numbers.push(anr[i]); this._numbers.push(aContact.anr[i]);
} }
if (aContact.email) { if (aContact.email) {
@ -717,7 +717,7 @@ Icc.prototype = {
if (length > 0) { if (length > 0) {
iccContact.anr = []; iccContact.anr = [];
for (let i = 0; i < length; i++) { for (let i = 0; i < length; i++) {
iccContact.anr.push(anrArray[i].value); iccContact.anr.push(anrArray[i]);
} }
} }
} }

Просмотреть файл

@ -280,13 +280,25 @@ ThreadedDriver::RunThread()
bool stillProcessing = true; bool stillProcessing = true;
while (stillProcessing) { while (stillProcessing) {
GraphTime prevCurrentTime, nextCurrentTime; mIterationStart = IterationEnd();
GetIntervalForIteration(prevCurrentTime, nextCurrentTime); mIterationEnd += GetIntervalForIteration();
mStateComputedTime = mNextStateComputedTime; if (mStateComputedTime < mIterationEnd) {
STREAM_LOG(LogLevel::Warning, ("Media graph global underrun detected"));
mIterationEnd = mStateComputedTime;
}
if (mIterationStart >= mIterationEnd) {
NS_ASSERTION(mIterationStart == mIterationEnd ,
"Time can't go backwards!");
// This could happen due to low clock resolution, maybe?
STREAM_LOG(LogLevel::Debug, ("Time did not advance"));
}
MOZ_ASSERT(mStateComputedTime == mNextStateComputedTime);
mNextStateComputedTime = mNextStateComputedTime =
mGraphImpl->RoundUpToNextAudioBlock( mGraphImpl->RoundUpToNextAudioBlock(
nextCurrentTime + mGraphImpl->MillisecondsToMediaTime(AUDIO_TARGET_MS)); mIterationEnd + mGraphImpl->MillisecondsToMediaTime(AUDIO_TARGET_MS));
STREAM_LOG(LogLevel::Debug, STREAM_LOG(LogLevel::Debug,
("interval[%ld; %ld] state[%ld; %ld]", ("interval[%ld; %ld] state[%ld; %ld]",
(long)mIterationStart, (long)mIterationEnd, (long)mIterationStart, (long)mIterationEnd,
@ -294,8 +306,8 @@ ThreadedDriver::RunThread()
mGraphImpl->mFlushSourcesNow = mGraphImpl->mFlushSourcesOnNextIteration; mGraphImpl->mFlushSourcesNow = mGraphImpl->mFlushSourcesOnNextIteration;
mGraphImpl->mFlushSourcesOnNextIteration = false; mGraphImpl->mFlushSourcesOnNextIteration = false;
stillProcessing = mGraphImpl->OneIteration(prevCurrentTime, stillProcessing = mGraphImpl->OneIteration(mIterationStart,
nextCurrentTime, mIterationEnd,
StateComputedTime(), StateComputedTime(),
mNextStateComputedTime); mNextStateComputedTime);
@ -310,36 +322,21 @@ ThreadedDriver::RunThread()
} }
} }
void MediaTime
SystemClockDriver::GetIntervalForIteration(GraphTime& aFrom, GraphTime& aTo) SystemClockDriver::GetIntervalForIteration()
{ {
TimeStamp now = TimeStamp::Now(); TimeStamp now = TimeStamp::Now();
aFrom = mIterationStart = IterationEnd(); MediaTime interval =
aTo = mIterationEnd = mGraphImpl->SecondsToMediaTime((now - mCurrentTimeStamp).ToSeconds()) + IterationEnd(); mGraphImpl->SecondsToMediaTime((now - mCurrentTimeStamp).ToSeconds());
mCurrentTimeStamp = now; mCurrentTimeStamp = now;
MOZ_LOG(gMediaStreamGraphLog, LogLevel::Verbose, ("Updating current time to %f (real %f, mStateComputedTime %f)", MOZ_LOG(gMediaStreamGraphLog, LogLevel::Verbose,
mGraphImpl->MediaTimeToSeconds(aTo), ("Updating current time to %f (real %f, mStateComputedTime %f)",
(now - mInitialTimeStamp).ToSeconds(), mGraphImpl->MediaTimeToSeconds(IterationEnd() + interval),
mGraphImpl->MediaTimeToSeconds(StateComputedTime()))); (now - mInitialTimeStamp).ToSeconds(),
mGraphImpl->MediaTimeToSeconds(StateComputedTime())));
if (mStateComputedTime < aTo) { return interval;
STREAM_LOG(LogLevel::Warning, ("Media graph global underrun detected"));
aTo = mIterationEnd = mStateComputedTime;
}
if (aFrom >= aTo) {
NS_ASSERTION(aFrom == aTo , "Time can't go backwards!");
// This could happen due to low clock resolution, maybe?
STREAM_LOG(LogLevel::Debug, ("Time did not advance"));
}
}
GraphTime
SystemClockDriver::GetCurrentTime()
{
return IterationEnd();
} }
TimeStamp TimeStamp
@ -432,31 +429,12 @@ OfflineClockDriver::~OfflineClockDriver()
} }
} }
void MediaTime
OfflineClockDriver::GetIntervalForIteration(GraphTime& aFrom, GraphTime& aTo) OfflineClockDriver::GetIntervalForIteration()
{ {
aFrom = mIterationStart = IterationEnd(); return mGraphImpl->MillisecondsToMediaTime(mSlice);
aTo = mIterationEnd = IterationEnd() + mGraphImpl->MillisecondsToMediaTime(mSlice);
if (mStateComputedTime < aTo) {
STREAM_LOG(LogLevel::Warning, ("Media graph global underrun detected"));
aTo = mIterationEnd = mStateComputedTime;
}
if (aFrom >= aTo) {
NS_ASSERTION(aFrom == aTo , "Time can't go backwards!");
// This could happen due to low clock resolution, maybe?
STREAM_LOG(LogLevel::Debug, ("Time did not advance"));
}
} }
GraphTime
OfflineClockDriver::GetCurrentTime()
{
return mIterationEnd;
}
void void
OfflineClockDriver::WaitForNextIteration() OfflineClockDriver::WaitForNextIteration()
{ {
@ -705,24 +683,6 @@ AudioCallbackDriver::Revive()
} }
} }
void
AudioCallbackDriver::GetIntervalForIteration(GraphTime& aFrom,
GraphTime& aTo)
{
}
GraphTime
AudioCallbackDriver::GetCurrentTime()
{
uint64_t position = 0;
if (cubeb_stream_get_position(mAudioStream, &position) != CUBEB_OK) {
NS_WARNING("Could not get current time from cubeb.");
}
return mSampleRate * position;
}
void AudioCallbackDriver::WaitForNextIteration() void AudioCallbackDriver::WaitForNextIteration()
{ {
} }
@ -862,7 +822,7 @@ AudioCallbackDriver::DataCallback(AudioDataValue* aBuffer, long aFrames)
// we don't need to run an iteration and if we do so we may overflow. // we don't need to run an iteration and if we do so we may overflow.
if (mBuffer.Available()) { if (mBuffer.Available()) {
mStateComputedTime = mNextStateComputedTime; MOZ_ASSERT(mStateComputedTime == mNextStateComputedTime);
// State computed time is decided by the audio callback's buffer length. We // State computed time is decided by the audio callback's buffer length. We
// compute the iteration start and end from there, trying to keep the amount // compute the iteration start and end from there, trying to keep the amount

Просмотреть файл

@ -50,23 +50,8 @@ static const int SCHEDULE_SAFETY_MARGIN_MS = 10;
static const int AUDIO_TARGET_MS = 2*MEDIA_GRAPH_TARGET_PERIOD_MS + static const int AUDIO_TARGET_MS = 2*MEDIA_GRAPH_TARGET_PERIOD_MS +
SCHEDULE_SAFETY_MARGIN_MS; SCHEDULE_SAFETY_MARGIN_MS;
/**
* Try have this much video buffered. Video frames are set
* near the end of the iteration of the control loop. The maximum delay
* to the setting of the next video frame is 2*MEDIA_GRAPH_TARGET_PERIOD_MS +
* SCHEDULE_SAFETY_MARGIN_MS. This is not optimal yet.
*/
static const int VIDEO_TARGET_MS = 2*MEDIA_GRAPH_TARGET_PERIOD_MS +
SCHEDULE_SAFETY_MARGIN_MS;
class MediaStreamGraphImpl; class MediaStreamGraphImpl;
/**
* Microseconds relative to the start of the graph timeline.
*/
typedef int64_t GraphTime;
const GraphTime GRAPH_TIME_MAX = MEDIA_TIME_MAX;
class AudioCallbackDriver; class AudioCallbackDriver;
class OfflineClockDriver; class OfflineClockDriver;
@ -84,13 +69,6 @@ public:
explicit GraphDriver(MediaStreamGraphImpl* aGraphImpl); explicit GraphDriver(MediaStreamGraphImpl* aGraphImpl);
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GraphDriver); NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GraphDriver);
/* When the graph wakes up to do an iteration, this returns the range of time
* that will be processed. */
virtual void GetIntervalForIteration(GraphTime& aFrom,
GraphTime& aTo) = 0;
/* Returns the current time for this graph. This is the end of the current
* iteration. */
virtual GraphTime GetCurrentTime() = 0;
/* For real-time graphs, this waits until it's time to process more data. For /* For real-time graphs, this waits until it's time to process more data. For
* offline graphs, this is a no-op. */ * offline graphs, this is a no-op. */
virtual void WaitForNextIteration() = 0; virtual void WaitForNextIteration() = 0;
@ -277,6 +255,11 @@ public:
virtual bool OnThread() override { return !mThread || NS_GetCurrentThread() == mThread; } virtual bool OnThread() override { return !mThread || NS_GetCurrentThread() == mThread; }
/* When the graph wakes up to do an iteration, implementations return the
* range of time that will be processed. This is called only once per
* iteration; it may determine the interval from state in a previous
* call. */
virtual MediaTime GetIntervalForIteration() = 0;
protected: protected:
nsCOMPtr<nsIThread> mThread; nsCOMPtr<nsIThread> mThread;
}; };
@ -290,9 +273,7 @@ class SystemClockDriver : public ThreadedDriver
public: public:
explicit SystemClockDriver(MediaStreamGraphImpl* aGraphImpl); explicit SystemClockDriver(MediaStreamGraphImpl* aGraphImpl);
virtual ~SystemClockDriver(); virtual ~SystemClockDriver();
virtual void GetIntervalForIteration(GraphTime& aFrom, virtual MediaTime GetIntervalForIteration() override;
GraphTime& aTo) override;
virtual GraphTime GetCurrentTime() override;
virtual void WaitForNextIteration() override; virtual void WaitForNextIteration() override;
virtual void WakeUp() override; virtual void WakeUp() override;
@ -311,9 +292,7 @@ class OfflineClockDriver : public ThreadedDriver
public: public:
OfflineClockDriver(MediaStreamGraphImpl* aGraphImpl, GraphTime aSlice); OfflineClockDriver(MediaStreamGraphImpl* aGraphImpl, GraphTime aSlice);
virtual ~OfflineClockDriver(); virtual ~OfflineClockDriver();
virtual void GetIntervalForIteration(GraphTime& aFrom, virtual MediaTime GetIntervalForIteration() override;
GraphTime& aTo) override;
virtual GraphTime GetCurrentTime() override;
virtual void WaitForNextIteration() override; virtual void WaitForNextIteration() override;
virtual void WakeUp() override; virtual void WakeUp() override;
virtual TimeStamp GetCurrentTimeStamp() override; virtual TimeStamp GetCurrentTimeStamp() override;
@ -374,9 +353,6 @@ public:
virtual void Stop() override; virtual void Stop() override;
virtual void Resume() override; virtual void Resume() override;
virtual void Revive() override; virtual void Revive() override;
virtual void GetIntervalForIteration(GraphTime& aFrom,
GraphTime& aTo) override;
virtual GraphTime GetCurrentTime() override;
virtual void WaitForNextIteration() override; virtual void WaitForNextIteration() override;
virtual void WakeUp() override; virtual void WakeUp() override;

Просмотреть файл

@ -414,9 +414,8 @@ bool MediaDecoderStateMachine::HaveEnoughDecodedAudio(int64_t aAmpleAudioUSecs)
return false; return false;
} }
// We don't have to check SourceMediaStream::HaveEnoughBuffered() in the // MDSM will ensure buffering level is high enough for playback speed at 1x
// case of stream-capture for MDSM will ensure buffering level is high enough // at which the DecodedStream is playing.
// for playback speed at 1x at which the DecodedStream is playing.
return true; return true;
} }
@ -1275,7 +1274,6 @@ void MediaDecoderStateMachine::SetDormant(bool aDormant)
} else if ((aDormant != true) && (mState == DECODER_STATE_DORMANT)) { } else if ((aDormant != true) && (mState == DECODER_STATE_DORMANT)) {
mDecodingFrozenAtStateDecoding = true; mDecodingFrozenAtStateDecoding = true;
ScheduleStateMachine(); ScheduleStateMachine();
mCurrentPosition = 0;
mDecodingFirstFrame = true; mDecodingFirstFrame = true;
SetState(DECODER_STATE_DECODING_NONE); SetState(DECODER_STATE_DECODING_NONE);
mDecoder->GetReentrantMonitor().NotifyAll(); mDecoder->GetReentrantMonitor().NotifyAll();

Просмотреть файл

@ -48,6 +48,12 @@ const int64_t MEDIA_TIME_MAX = TRACK_TICKS_MAX;
typedef MediaTime StreamTime; typedef MediaTime StreamTime;
const StreamTime STREAM_TIME_MAX = MEDIA_TIME_MAX; const StreamTime STREAM_TIME_MAX = MEDIA_TIME_MAX;
/**
* Media time relative to the start of the graph timeline.
*/
typedef MediaTime GraphTime;
const GraphTime GRAPH_TIME_MAX = MEDIA_TIME_MAX;
/** /**
* A MediaSegment is a chunk of media data sequential in time. Different * A MediaSegment is a chunk of media data sequential in time. Different
* types of data have different subclasses of MediaSegment, all inheriting * types of data have different subclasses of MediaSegment, all inheriting

Просмотреть файл

@ -71,17 +71,6 @@ MediaStreamGraphImpl::~MediaStreamGraphImpl()
LIFECYCLE_LOG("MediaStreamGraphImpl::~MediaStreamGraphImpl\n"); LIFECYCLE_LOG("MediaStreamGraphImpl::~MediaStreamGraphImpl\n");
} }
StreamTime
MediaStreamGraphImpl::GetDesiredBufferEnd(MediaStream* aStream)
{
StreamTime current = IterationEnd() - aStream->mBufferStartTime;
// When waking up media decoders, we need a longer safety margin, as it can
// take more time to get new samples. A factor of two seem to work.
return current +
2 * MillisecondsToMediaTime(std::max(AUDIO_TARGET_MS, VIDEO_TARGET_MS));
}
void void
MediaStreamGraphImpl::FinishStream(MediaStream* aStream) MediaStreamGraphImpl::FinishStream(MediaStream* aStream)
{ {
@ -261,48 +250,6 @@ MediaStreamGraphImpl::ExtractPendingInput(SourceMediaStream* aStream,
} }
} }
void
MediaStreamGraphImpl::UpdateBufferSufficiencyState(SourceMediaStream* aStream)
{
StreamTime desiredEnd = GetDesiredBufferEnd(aStream);
nsTArray<SourceMediaStream::ThreadAndRunnable> runnables;
{
MutexAutoLock lock(aStream->mMutex);
for (uint32_t i = 0; i < aStream->mUpdateTracks.Length(); ++i) {
SourceMediaStream::TrackData* data = &aStream->mUpdateTracks[i];
if (data->mCommands & SourceMediaStream::TRACK_CREATE) {
// This track hasn't been created yet, so we have no sufficiency
// data. The track will be created in the next iteration of the
// control loop and then we'll fire insufficiency notifications
// if necessary.
continue;
}
if (data->mCommands & SourceMediaStream::TRACK_END) {
// This track will end, so no point in firing not-enough-data
// callbacks.
continue;
}
StreamBuffer::Track* track = aStream->mBuffer.FindTrack(data->mID);
// Note that track->IsEnded() must be false, otherwise we would have
// removed the track from mUpdateTracks already.
NS_ASSERTION(!track->IsEnded(), "What is this track doing here?");
data->mHaveEnough = track->GetEnd() >= desiredEnd;
if (!data->mHaveEnough) {
runnables.MoveElementsFrom(data->mDispatchWhenNotEnough);
}
}
}
for (uint32_t i = 0; i < runnables.Length(); ++i) {
// This dispatch was observed to fail in test_video_dimensions.html on
// win8 64 debug when invoked from noop_resampler::fill on the cubeb audio
// thread.
nsCOMPtr<nsIRunnable> r = runnables[i].mRunnable;
runnables[i].mTarget->Dispatch(r.forget(), AbstractThread::DontAssertDispatchSuccess);
}
}
StreamTime StreamTime
MediaStreamGraphImpl::GraphTimeToStreamTime(MediaStream* aStream, MediaStreamGraphImpl::GraphTimeToStreamTime(MediaStream* aStream,
GraphTime aTime) GraphTime aTime)
@ -1452,10 +1399,6 @@ MediaStreamGraphImpl::Process(GraphTime aFrom, GraphTime aTo)
} }
PlayVideo(stream); PlayVideo(stream);
} }
SourceMediaStream* is = stream->AsSourceStream();
if (is) {
UpdateBufferSufficiencyState(is);
}
GraphTime end; GraphTime end;
if (!stream->mBlocked.GetAt(aTo, &end) || end < GRAPH_TIME_MAX) { if (!stream->mBlocked.GetAt(aTo, &end) || end < GRAPH_TIME_MAX) {
allBlockedForever = false; allBlockedForever = false;
@ -2485,7 +2428,6 @@ SourceMediaStream::AddTrackInternal(TrackID aID, TrackRate aRate, StreamTime aSt
data->mEndOfFlushedData = aStart; data->mEndOfFlushedData = aStart;
data->mCommands = TRACK_CREATE; data->mCommands = TRACK_CREATE;
data->mData = aSegment; data->mData = aSegment;
data->mHaveEnough = false;
if (!(aFlags & ADDTRACK_QUEUED) && GraphImpl()) { if (!(aFlags & ADDTRACK_QUEUED) && GraphImpl()) {
GraphImpl()->EnsureNextIteration(); GraphImpl()->EnsureNextIteration();
} }
@ -2646,17 +2588,6 @@ SourceMediaStream::RemoveDirectListener(MediaStreamDirectListener* aListener)
} }
} }
bool
SourceMediaStream::HaveEnoughBuffered(TrackID aID)
{
MutexAutoLock lock(mMutex);
TrackData *track = FindDataForTrack(aID);
if (track) {
return track->mHaveEnough;
}
return false;
}
StreamTime StreamTime
SourceMediaStream::GetEndOfAppendedData(TrackID aID) SourceMediaStream::GetEndOfAppendedData(TrackID aID)
{ {
@ -2669,28 +2600,6 @@ SourceMediaStream::GetEndOfAppendedData(TrackID aID)
return 0; return 0;
} }
void
SourceMediaStream::DispatchWhenNotEnoughBuffered(TrackID aID,
TaskQueue* aSignalQueue, nsIRunnable* aSignalRunnable)
{
MutexAutoLock lock(mMutex);
TrackData* data = FindDataForTrack(aID);
if (!data) {
nsCOMPtr<nsIRunnable> r = aSignalRunnable;
aSignalQueue->Dispatch(r.forget());
return;
}
if (data->mHaveEnough) {
if (data->mDispatchWhenNotEnough.IsEmpty()) {
data->mDispatchWhenNotEnough.AppendElement()->Init(aSignalQueue, aSignalRunnable);
}
} else {
nsCOMPtr<nsIRunnable> r = aSignalRunnable;
aSignalQueue->Dispatch(r.forget());
}
}
void void
SourceMediaStream::EndTrack(TrackID aID) SourceMediaStream::EndTrack(TrackID aID)
{ {

Просмотреть файл

@ -12,6 +12,7 @@
#include "mozilla/dom/AudioChannelBinding.h" #include "mozilla/dom/AudioChannelBinding.h"
#include "AudioSegment.h"
#include "AudioStream.h" #include "AudioStream.h"
#include "nsTArray.h" #include "nsTArray.h"
#include "nsIRunnable.h" #include "nsIRunnable.h"
@ -21,7 +22,6 @@
#include "VideoSegment.h" #include "VideoSegment.h"
#include "MainThreadUtils.h" #include "MainThreadUtils.h"
#include "nsAutoRef.h" #include "nsAutoRef.h"
#include "GraphDriver.h"
#include <speex/speex_resampler.h> #include <speex/speex_resampler.h>
#include "DOMMediaStream.h" #include "DOMMediaStream.h"
#include "AudioContext.h" #include "AudioContext.h"
@ -815,11 +815,6 @@ public:
* or the stream was already finished. * or the stream was already finished.
*/ */
bool AppendToTrack(TrackID aID, MediaSegment* aSegment, MediaSegment *aRawSegment = nullptr); bool AppendToTrack(TrackID aID, MediaSegment* aSegment, MediaSegment *aRawSegment = nullptr);
/**
* Returns true if the buffer currently has enough data.
* Returns false if there isn't enough data or if no such track exists.
*/
bool HaveEnoughBuffered(TrackID aID);
/** /**
* Get the stream time of the end of the data that has been appended so far. * Get the stream time of the end of the data that has been appended so far.
* Can be called from any thread but won't be useful if it can race with * Can be called from any thread but won't be useful if it can race with
@ -827,14 +822,6 @@ public:
* that also calls AppendToTrack. * that also calls AppendToTrack.
*/ */
StreamTime GetEndOfAppendedData(TrackID aID); StreamTime GetEndOfAppendedData(TrackID aID);
/**
* Ensures that aSignalRunnable will be dispatched to aSignalThread
* when we don't have enough buffered data in the track (which could be
* immediately). Will dispatch the runnable immediately if the track
* does not exist. No op if a runnable is already present for this track.
*/
void DispatchWhenNotEnoughBuffered(TrackID aID,
TaskQueue* aSignalQueue, nsIRunnable* aSignalRunnable);
/** /**
* Indicate that a track has ended. Do not do any more API calls * Indicate that a track has ended. Do not do any more API calls
* affecting this track. * affecting this track.
@ -930,11 +917,9 @@ protected:
// Each time the track updates are flushed to the media graph thread, // Each time the track updates are flushed to the media graph thread,
// the segment buffer is emptied. // the segment buffer is emptied.
nsAutoPtr<MediaSegment> mData; nsAutoPtr<MediaSegment> mData;
nsTArray<ThreadAndRunnable> mDispatchWhenNotEnough;
// Each time the track updates are flushed to the media graph thread, // Each time the track updates are flushed to the media graph thread,
// this is cleared. // this is cleared.
uint32_t mCommands; uint32_t mCommands;
bool mHaveEnough;
}; };
bool NeedsMixing(); bool NeedsMixing();

Просмотреть файл

@ -76,7 +76,7 @@ SourceBuffer::SetMode(SourceBufferAppendMode aMode, ErrorResult& aRv)
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return; return;
} }
if (mIsUsingFormatReader && mGenerateTimestamps && if (mIsUsingFormatReader && mAttributes->mGenerateTimestamps &&
aMode == SourceBufferAppendMode::Segments) { aMode == SourceBufferAppendMode::Segments) {
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR); aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
return; return;
@ -96,7 +96,7 @@ SourceBuffer::SetMode(SourceBufferAppendMode aMode, ErrorResult& aRv)
mContentManager->RestartGroupStartTimestamp(); mContentManager->RestartGroupStartTimestamp();
} }
mAppendMode = aMode; mAttributes->SetAppendMode(aMode);
} }
void void
@ -119,22 +119,13 @@ SourceBuffer::SetTimestampOffset(double aTimestampOffset, ErrorResult& aRv)
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return; return;
} }
mApparentTimestampOffset = aTimestampOffset; mAttributes->SetApparentTimestampOffset(aTimestampOffset);
mTimestampOffset = TimeUnit::FromSeconds(aTimestampOffset); if (mIsUsingFormatReader &&
if (mIsUsingFormatReader && mAppendMode == SourceBufferAppendMode::Sequence) { mAttributes->GetAppendMode() == SourceBufferAppendMode::Sequence) {
mContentManager->SetGroupStartTimestamp(mTimestampOffset); mContentManager->SetGroupStartTimestamp(mAttributes->GetTimestampOffset());
} }
} }
void
SourceBuffer::SetTimestampOffset(const TimeUnit& aTimestampOffset)
{
MOZ_ASSERT(NS_IsMainThread());
mTimestampOffset = aTimestampOffset;
mApparentTimestampOffset = aTimestampOffset.ToSeconds();
}
already_AddRefed<TimeRanges> already_AddRefed<TimeRanges>
SourceBuffer::GetBuffered(ErrorResult& aRv) SourceBuffer::GetBuffered(ErrorResult& aRv)
{ {
@ -165,11 +156,12 @@ SourceBuffer::SetAppendWindowStart(double aAppendWindowStart, ErrorResult& aRv)
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return; return;
} }
if (aAppendWindowStart < 0 || aAppendWindowStart >= mAppendWindowEnd) { if (aAppendWindowStart < 0 ||
aAppendWindowStart >= mAttributes->GetAppendWindowEnd()) {
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR); aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
return; return;
} }
mAppendWindowStart = aAppendWindowStart; mAttributes->SetAppendWindowStart(aAppendWindowStart);
} }
void void
@ -181,11 +173,12 @@ SourceBuffer::SetAppendWindowEnd(double aAppendWindowEnd, ErrorResult& aRv)
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return; return;
} }
if (IsNaN(aAppendWindowEnd) || aAppendWindowEnd <= mAppendWindowStart) { if (IsNaN(aAppendWindowEnd) ||
aAppendWindowEnd <= mAttributes->GetAppendWindowStart()) {
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR); aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
return; return;
} }
mAppendWindowEnd = aAppendWindowEnd; mAttributes->SetAppendWindowEnd(aAppendWindowEnd);
} }
void void
@ -221,8 +214,8 @@ SourceBuffer::Abort(ErrorResult& aRv)
} }
AbortBufferAppend(); AbortBufferAppend();
mContentManager->ResetParserState(); mContentManager->ResetParserState();
mAppendWindowStart = 0; mAttributes->SetAppendWindowStart(0);
mAppendWindowEnd = PositiveInfinity<double>(); mAttributes->SetAppendWindowEnd(PositiveInfinity<double>());
} }
void void
@ -312,10 +305,6 @@ SourceBuffer::Ended()
SourceBuffer::SourceBuffer(MediaSource* aMediaSource, const nsACString& aType) SourceBuffer::SourceBuffer(MediaSource* aMediaSource, const nsACString& aType)
: DOMEventTargetHelper(aMediaSource->GetParentObject()) : DOMEventTargetHelper(aMediaSource->GetParentObject())
, mMediaSource(aMediaSource) , mMediaSource(aMediaSource)
, mAppendWindowStart(0)
, mAppendWindowEnd(PositiveInfinity<double>())
, mApparentTimestampOffset(0)
, mAppendMode(SourceBufferAppendMode::Segments)
, mUpdating(false) , mUpdating(false)
, mActive(false) , mActive(false)
, mUpdateID(0) , mUpdateID(0)
@ -326,22 +315,24 @@ SourceBuffer::SourceBuffer(MediaSource* aMediaSource, const nsACString& aType)
MOZ_ASSERT(aMediaSource); MOZ_ASSERT(aMediaSource);
mEvictionThreshold = Preferences::GetUint("media.mediasource.eviction_threshold", mEvictionThreshold = Preferences::GetUint("media.mediasource.eviction_threshold",
100 * (1 << 20)); 100 * (1 << 20));
bool generateTimestamps = false;
if (aType.LowerCaseEqualsLiteral("audio/mpeg") ||
aType.LowerCaseEqualsLiteral("audio/aac")) {
generateTimestamps = true;
}
mAttributes = new SourceBufferAttributes(generateTimestamps);
mContentManager = mContentManager =
SourceBufferContentManager::CreateManager(this, SourceBufferContentManager::CreateManager(mAttributes,
aMediaSource->GetDecoder(), aMediaSource->GetDecoder(),
aType); aType);
MSE_DEBUG("Create mContentManager=%p", MSE_DEBUG("Create mContentManager=%p",
mContentManager.get()); mContentManager.get());
if (aType.LowerCaseEqualsLiteral("audio/mpeg") ||
aType.LowerCaseEqualsLiteral("audio/aac")) {
mGenerateTimestamps = true;
} else {
mGenerateTimestamps = false;
}
mIsUsingFormatReader = mIsUsingFormatReader =
Preferences::GetBool("media.mediasource.format-reader", false); Preferences::GetBool("media.mediasource.format-reader", false);
ErrorResult dummy; ErrorResult dummy;
if (mGenerateTimestamps) { if (mAttributes->mGenerateTimestamps) {
SetMode(SourceBufferAppendMode::Sequence, dummy); SetMode(SourceBufferAppendMode::Sequence, dummy);
} else { } else {
SetMode(SourceBufferAppendMode::Segments, dummy); SetMode(SourceBufferAppendMode::Segments, dummy);
@ -446,11 +437,12 @@ SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aR
if (!data) { if (!data) {
return; return;
} }
mContentManager->AppendData(data, mTimestampOffset); mContentManager->AppendData(data, mAttributes->GetTimestampOffset());
StartUpdating(); StartUpdating();
MOZ_ASSERT(mIsUsingFormatReader || mAppendMode == SourceBufferAppendMode::Segments, MOZ_ASSERT(mIsUsingFormatReader ||
mAttributes->GetAppendMode() == SourceBufferAppendMode::Segments,
"We don't handle timestampOffset for sequence mode yet"); "We don't handle timestampOffset for sequence mode yet");
nsCOMPtr<nsIRunnable> task = new BufferAppendRunnable(this, mUpdateID); nsCOMPtr<nsIRunnable> task = new BufferAppendRunnable(this, mUpdateID);
NS_DispatchToMainThread(task); NS_DispatchToMainThread(task);

Просмотреть файл

@ -25,6 +25,7 @@
#include "nsString.h" #include "nsString.h"
#include "nscore.h" #include "nscore.h"
#include "SourceBufferContentManager.h" #include "SourceBufferContentManager.h"
#include "mozilla/Monitor.h"
class JSObject; class JSObject;
struct JSContext; struct JSContext;
@ -40,13 +41,103 @@ namespace dom {
class TimeRanges; class TimeRanges;
class SourceBufferAttributes {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SourceBufferAttributes);
explicit SourceBufferAttributes(bool aGenerateTimestamp)
: mGenerateTimestamps(aGenerateTimestamp)
, mMonitor("SourceBufferAttributes")
, mAppendWindowStart(0)
, mAppendWindowEnd(PositiveInfinity<double>())
, mAppendMode(SourceBufferAppendMode::Segments)
, mApparentTimestampOffset(0)
{}
double GetAppendWindowStart()
{
MonitorAutoLock mon(mMonitor);
return mAppendWindowStart;
}
double GetAppendWindowEnd()
{
MonitorAutoLock mon(mMonitor);
return mAppendWindowEnd;
}
void SetAppendWindowStart(double aWindowStart)
{
MonitorAutoLock mon(mMonitor);
mAppendWindowStart = aWindowStart;
}
void SetAppendWindowEnd(double aWindowEnd)
{
MonitorAutoLock mon(mMonitor);
mAppendWindowEnd = aWindowEnd;
}
double GetApparentTimestampOffset()
{
MonitorAutoLock mon(mMonitor);
return mApparentTimestampOffset;
}
void SetApparentTimestampOffset(double aTimestampOffset)
{
MonitorAutoLock mon(mMonitor);
mApparentTimestampOffset = aTimestampOffset;
mTimestampOffset = media::TimeUnit::FromSeconds(aTimestampOffset);
}
media::TimeUnit GetTimestampOffset()
{
MonitorAutoLock mon(mMonitor);
return mTimestampOffset;
}
void SetTimestampOffset(media::TimeUnit& aTimestampOffset)
{
MonitorAutoLock mon(mMonitor);
mTimestampOffset = aTimestampOffset;
mApparentTimestampOffset = aTimestampOffset.ToSeconds();
}
SourceBufferAppendMode GetAppendMode()
{
MonitorAutoLock mon(mMonitor);
return mAppendMode;
}
void SetAppendMode(SourceBufferAppendMode aAppendMode)
{
MonitorAutoLock mon(mMonitor);
mAppendMode = aAppendMode;
}
// mGenerateTimestamp isn't mutable once the source buffer has been constructed
// We don't need a monitor to protect it across threads.
const bool mGenerateTimestamps;
private:
~SourceBufferAttributes() {};
// Monitor protecting all members below.
Monitor mMonitor;
double mAppendWindowStart;
double mAppendWindowEnd;
SourceBufferAppendMode mAppendMode;
double mApparentTimestampOffset;
media::TimeUnit mTimestampOffset;
};
class SourceBuffer final : public DOMEventTargetHelper class SourceBuffer final : public DOMEventTargetHelper
{ {
public: public:
/** WebIDL Methods. */ /** WebIDL Methods. */
SourceBufferAppendMode Mode() const SourceBufferAppendMode Mode() const
{ {
return mAppendMode; return mAttributes->GetAppendMode();
} }
void SetMode(SourceBufferAppendMode aMode, ErrorResult& aRv); void SetMode(SourceBufferAppendMode aMode, ErrorResult& aRv);
@ -61,21 +152,21 @@ public:
double TimestampOffset() const double TimestampOffset() const
{ {
return mApparentTimestampOffset; return mAttributes->GetApparentTimestampOffset();
} }
void SetTimestampOffset(double aTimestampOffset, ErrorResult& aRv); void SetTimestampOffset(double aTimestampOffset, ErrorResult& aRv);
double AppendWindowStart() const double AppendWindowStart() const
{ {
return mAppendWindowStart; return mAttributes->GetAppendWindowStart();
} }
void SetAppendWindowStart(double aAppendWindowStart, ErrorResult& aRv); void SetAppendWindowStart(double aAppendWindowStart, ErrorResult& aRv);
double AppendWindowEnd() const double AppendWindowEnd() const
{ {
return mAppendWindowEnd; return mAttributes->GetAppendWindowEnd();
} }
void SetAppendWindowEnd(double aAppendWindowEnd, ErrorResult& aRv); void SetAppendWindowEnd(double aAppendWindowEnd, ErrorResult& aRv);
@ -164,24 +255,14 @@ private:
void AppendDataCompletedWithSuccess(bool aHasActiveTracks); void AppendDataCompletedWithSuccess(bool aHasActiveTracks);
void AppendDataErrored(nsresult aError); void AppendDataErrored(nsresult aError);
// Set timestampOffset, must be called on the main thread.
void SetTimestampOffset(const media::TimeUnit& aTimestampOffset);
nsRefPtr<MediaSource> mMediaSource; nsRefPtr<MediaSource> mMediaSource;
uint32_t mEvictionThreshold; uint32_t mEvictionThreshold;
nsRefPtr<SourceBufferContentManager> mContentManager; nsRefPtr<SourceBufferContentManager> mContentManager;
nsRefPtr<SourceBufferAttributes> mAttributes;
double mAppendWindowStart;
double mAppendWindowEnd;
double mApparentTimestampOffset;
media::TimeUnit mTimestampOffset;
SourceBufferAppendMode mAppendMode;
bool mUpdating; bool mUpdating;
bool mGenerateTimestamps;
bool mIsUsingFormatReader; bool mIsUsingFormatReader;
mozilla::Atomic<bool> mActive; mozilla::Atomic<bool> mActive;

Просмотреть файл

@ -18,7 +18,7 @@ namespace mozilla {
#endif #endif
already_AddRefed<SourceBufferContentManager> already_AddRefed<SourceBufferContentManager>
SourceBufferContentManager::CreateManager(dom::SourceBuffer* aParent, SourceBufferContentManager::CreateManager(dom::SourceBufferAttributes* aAttributes,
MediaSourceDecoder* aParentDecoder, MediaSourceDecoder* aParentDecoder,
const nsACString &aType) const nsACString &aType)
{ {
@ -26,7 +26,7 @@ SourceBufferContentManager::CreateManager(dom::SourceBuffer* aParent,
bool useFormatReader = bool useFormatReader =
Preferences::GetBool("media.mediasource.format-reader", false); Preferences::GetBool("media.mediasource.format-reader", false);
if (useFormatReader) { if (useFormatReader) {
manager = new TrackBuffersManager(aParent, aParentDecoder, aType); manager = new TrackBuffersManager(aAttributes, aParentDecoder, aType);
} else { } else {
manager = new TrackBuffer(aParentDecoder, aType); manager = new TrackBuffer(aParentDecoder, aType);
} }

Просмотреть файл

@ -18,6 +18,7 @@ namespace mozilla {
namespace dom { namespace dom {
class SourceBuffer; class SourceBuffer;
class SourceBufferAttributes;
} }
class SourceBufferContentManager { class SourceBufferContentManager {
@ -28,7 +29,8 @@ public:
typedef AppendPromise RangeRemovalPromise; typedef AppendPromise RangeRemovalPromise;
static already_AddRefed<SourceBufferContentManager> static already_AddRefed<SourceBufferContentManager>
CreateManager(dom::SourceBuffer* aParent, MediaSourceDecoder* aParentDecoder, CreateManager(dom::SourceBufferAttributes* aAttributes,
MediaSourceDecoder* aParentDecoder,
const nsACString& aType); const nsACString& aType);
// Add data to the end of the input buffer. // Add data to the end of the input buffer.

Просмотреть файл

@ -90,7 +90,9 @@ private:
}; };
#endif // MOZ_EME #endif // MOZ_EME
TrackBuffersManager::TrackBuffersManager(dom::SourceBuffer* aParent, MediaSourceDecoder* aParentDecoder, const nsACString& aType) TrackBuffersManager::TrackBuffersManager(dom::SourceBufferAttributes* aAttributes,
MediaSourceDecoder* aParentDecoder,
const nsACString& aType)
: mInputBuffer(new MediaByteBuffer) : mInputBuffer(new MediaByteBuffer)
, mAppendState(AppendState::WAITING_FOR_SEGMENT) , mAppendState(AppendState::WAITING_FOR_SEGMENT)
, mBufferFull(false) , mBufferFull(false)
@ -101,9 +103,8 @@ TrackBuffersManager::TrackBuffersManager(dom::SourceBuffer* aParent, MediaSource
, mProcessedInput(0) , mProcessedInput(0)
, mAppendRunning(false) , mAppendRunning(false)
, mTaskQueue(aParentDecoder->GetDemuxer()->GetTaskQueue()) , mTaskQueue(aParentDecoder->GetDemuxer()->GetTaskQueue())
, mParent(new nsMainThreadPtrHolder<dom::SourceBuffer>(aParent, false /* strict */)) , mSourceBufferAttributes(aAttributes)
, mParentDecoder(new nsMainThreadPtrHolder<MediaSourceDecoder>(aParentDecoder, false /* strict */)) , mParentDecoder(new nsMainThreadPtrHolder<MediaSourceDecoder>(aParentDecoder, false /* strict */))
, mMediaSourceDemuxer(mParentDecoder->GetDemuxer())
, mMediaSourceDuration(mTaskQueue, Maybe<double>(), "TrackBuffersManager::mMediaSourceDuration (Mirror)") , mMediaSourceDuration(mTaskQueue, Maybe<double>(), "TrackBuffersManager::mMediaSourceDuration (Mirror)")
, mAbort(false) , mAbort(false)
, mEvictionThreshold(Preferences::GetUint("media.mediasource.eviction_threshold", , mEvictionThreshold(Preferences::GetUint("media.mediasource.eviction_threshold",
@ -620,8 +621,8 @@ TrackBuffersManager::AppendIncomingBuffers()
mIncomingBuffers.Clear(); mIncomingBuffers.Clear();
mAppendWindow = mAppendWindow =
TimeInterval(TimeUnit::FromSeconds(mParent->AppendWindowStart()), TimeInterval(TimeUnit::FromSeconds(mSourceBufferAttributes->GetAppendWindowStart()),
TimeUnit::FromSeconds(mParent->AppendWindowEnd())); TimeUnit::FromSeconds(mSourceBufferAttributes->GetAppendWindowEnd()));
} }
void void
@ -1239,7 +1240,7 @@ TrackBuffersManager::ResolveProcessing(bool aResolveValue, const char* aName)
void void
TrackBuffersManager::CheckSequenceDiscontinuity() TrackBuffersManager::CheckSequenceDiscontinuity()
{ {
if (mParent->mAppendMode == SourceBufferAppendMode::Sequence && if (mSourceBufferAttributes->GetAppendMode() == SourceBufferAppendMode::Sequence &&
mGroupStartTimestamp.isSome()) { mGroupStartTimestamp.isSome()) {
mTimestampOffset = mGroupStartTimestamp.ref(); mTimestampOffset = mGroupStartTimestamp.ref();
mGroupEndTimestamp = mGroupStartTimestamp.ref(); mGroupEndTimestamp = mGroupStartTimestamp.ref();
@ -1314,13 +1315,13 @@ TrackBuffersManager::ProcessFrames(TrackBuffer& aSamples, TrackData& aTrackData)
// 4. If timestampOffset is not 0, then run the following steps: // 4. If timestampOffset is not 0, then run the following steps:
TimeInterval sampleInterval = TimeInterval sampleInterval =
mParent->mGenerateTimestamps mSourceBufferAttributes->mGenerateTimestamps
? TimeInterval(mTimestampOffset, ? TimeInterval(mTimestampOffset,
mTimestampOffset + TimeUnit::FromMicroseconds(sample->mDuration)) mTimestampOffset + TimeUnit::FromMicroseconds(sample->mDuration))
: TimeInterval(TimeUnit::FromMicroseconds(sample->mTime) + mTimestampOffset, : TimeInterval(TimeUnit::FromMicroseconds(sample->mTime) + mTimestampOffset,
TimeUnit::FromMicroseconds(sample->GetEndTime()) + mTimestampOffset); TimeUnit::FromMicroseconds(sample->GetEndTime()) + mTimestampOffset);
TimeUnit decodeTimestamp = TimeUnit decodeTimestamp =
mParent->mGenerateTimestamps mSourceBufferAttributes->mGenerateTimestamps
? mTimestampOffset ? mTimestampOffset
: TimeUnit::FromMicroseconds(sample->mTimecode) + mTimestampOffset; : TimeUnit::FromMicroseconds(sample->mTimecode) + mTimestampOffset;
@ -1332,13 +1333,15 @@ TrackBuffersManager::ProcessFrames(TrackBuffer& aSamples, TrackData& aTrackData)
(decodeTimestamp < trackBuffer.mLastDecodeTimestamp.ref() || (decodeTimestamp < trackBuffer.mLastDecodeTimestamp.ref() ||
decodeTimestamp - trackBuffer.mLastDecodeTimestamp.ref() > 2*trackBuffer.mLongestFrameDuration.ref())) { decodeTimestamp - trackBuffer.mLastDecodeTimestamp.ref() > 2*trackBuffer.mLongestFrameDuration.ref())) {
MSE_DEBUG("Discontinuity detected."); MSE_DEBUG("Discontinuity detected.");
SourceBufferAppendMode appendMode = mSourceBufferAttributes->GetAppendMode();
// 1a. If mode equals "segments": // 1a. If mode equals "segments":
if (mParent->mAppendMode == SourceBufferAppendMode::Segments) { if (appendMode == SourceBufferAppendMode::Segments) {
// Set group end timestamp to presentation timestamp. // Set group end timestamp to presentation timestamp.
mGroupEndTimestamp = sampleInterval.mStart; mGroupEndTimestamp = sampleInterval.mStart;
} }
// 1b. If mode equals "sequence": // 1b. If mode equals "sequence":
if (mParent->mAppendMode == SourceBufferAppendMode::Sequence) { if (appendMode == SourceBufferAppendMode::Sequence) {
// Set group start timestamp equal to the group end timestamp. // Set group start timestamp equal to the group end timestamp.
mGroupStartTimestamp = Some(mGroupEndTimestamp); mGroupStartTimestamp = Some(mGroupEndTimestamp);
} }
@ -1358,17 +1361,17 @@ TrackBuffersManager::ProcessFrames(TrackBuffer& aSamples, TrackData& aTrackData)
if (!sample->mKeyframe) { if (!sample->mKeyframe) {
continue; continue;
} }
if (mParent->mAppendMode == SourceBufferAppendMode::Sequence) { if (appendMode == SourceBufferAppendMode::Sequence) {
// mTimestampOffset was modified during CheckSequenceDiscontinuity. // mTimestampOffset was modified during CheckSequenceDiscontinuity.
// We need to update our variables. // We need to update our variables.
sampleInterval = sampleInterval =
mParent->mGenerateTimestamps mSourceBufferAttributes->mGenerateTimestamps
? TimeInterval(mTimestampOffset, ? TimeInterval(mTimestampOffset,
mTimestampOffset + TimeUnit::FromMicroseconds(sample->mDuration)) mTimestampOffset + TimeUnit::FromMicroseconds(sample->mDuration))
: TimeInterval(TimeUnit::FromMicroseconds(sample->mTime) + mTimestampOffset, : TimeInterval(TimeUnit::FromMicroseconds(sample->mTime) + mTimestampOffset,
TimeUnit::FromMicroseconds(sample->GetEndTime()) + mTimestampOffset); TimeUnit::FromMicroseconds(sample->GetEndTime()) + mTimestampOffset);
decodeTimestamp = decodeTimestamp =
mParent->mGenerateTimestamps mSourceBufferAttributes->mGenerateTimestamps
? mTimestampOffset ? mTimestampOffset
: TimeUnit::FromMicroseconds(sample->mTimecode) + mTimestampOffset; : TimeUnit::FromMicroseconds(sample->mTimecode) + mTimestampOffset;
} }
@ -1428,7 +1431,7 @@ TrackBuffersManager::ProcessFrames(TrackBuffer& aSamples, TrackData& aTrackData)
mGroupEndTimestamp = sampleInterval.mEnd; mGroupEndTimestamp = sampleInterval.mEnd;
} }
// 21. If generate timestamps flag equals true, then set timestampOffset equal to frame end timestamp. // 21. If generate timestamps flag equals true, then set timestampOffset equal to frame end timestamp.
if (mParent->mGenerateTimestamps) { if (mSourceBufferAttributes->mGenerateTimestamps) {
mTimestampOffset = sampleInterval.mEnd; mTimestampOffset = sampleInterval.mEnd;
} }
} }
@ -1679,12 +1682,7 @@ TrackBuffersManager::RestoreCachedVariables()
{ {
MOZ_ASSERT(OnTaskQueue()); MOZ_ASSERT(OnTaskQueue());
if (mTimestampOffset != mLastTimestampOffset) { if (mTimestampOffset != mLastTimestampOffset) {
nsRefPtr<TrackBuffersManager> self = this; mSourceBufferAttributes->SetTimestampOffset(mTimestampOffset);
nsCOMPtr<nsIRunnable> task =
NS_NewRunnableFunction([self] {
self->mParent->SetTimestampOffset(self->mTimestampOffset);
});
AbstractThread::MainThread()->Dispatch(task.forget());
} }
} }

Просмотреть файл

@ -25,9 +25,12 @@ class ContainerParser;
class MediaByteBuffer; class MediaByteBuffer;
class MediaRawData; class MediaRawData;
class MediaSourceDemuxer; class MediaSourceDemuxer;
class SourceBuffer;
class SourceBufferResource; class SourceBufferResource;
namespace dom {
class SourceBufferAttributes;
}
class TrackBuffersManager : public SourceBufferContentManager { class TrackBuffersManager : public SourceBufferContentManager {
public: public:
typedef MozPromise<bool, nsresult, /* IsExclusive = */ true> CodedFrameProcessingPromise; typedef MozPromise<bool, nsresult, /* IsExclusive = */ true> CodedFrameProcessingPromise;
@ -35,7 +38,9 @@ public:
typedef MediaData::Type MediaType; typedef MediaData::Type MediaType;
typedef nsTArray<nsRefPtr<MediaRawData>> TrackBuffer; typedef nsTArray<nsRefPtr<MediaRawData>> TrackBuffer;
TrackBuffersManager(dom::SourceBuffer* aParent, MediaSourceDecoder* aParentDecoder, const nsACString& aType); TrackBuffersManager(dom::SourceBufferAttributes* aAttributes,
MediaSourceDecoder* aParentDecoder,
const nsACString& aType);
bool AppendData(MediaByteBuffer* aData, bool AppendData(MediaByteBuffer* aData,
media::TimeUnit aTimestampOffset) override; media::TimeUnit aTimestampOffset) override;
@ -315,9 +320,8 @@ private:
void RestoreCachedVariables(); void RestoreCachedVariables();
// Strong references to external objects. // Strong references to external objects.
nsMainThreadPtrHandle<dom::SourceBuffer> mParent; nsRefPtr<dom::SourceBufferAttributes> mSourceBufferAttributes;
nsMainThreadPtrHandle<MediaSourceDecoder> mParentDecoder; nsMainThreadPtrHandle<MediaSourceDecoder> mParentDecoder;
nsRefPtr<MediaSourceDemuxer> mMediaSourceDemuxer;
// MediaSource duration mirrored from MediaDecoder on the main thread.. // MediaSource duration mirrored from MediaDecoder on the main thread..
Mirror<Maybe<double>> mMediaSourceDuration; Mirror<Maybe<double>> mMediaSourceDuration;

Просмотреть файл

@ -110,7 +110,6 @@ EXPORTS += [
'DOMMediaStream.h', 'DOMMediaStream.h',
'EncodedBufferCache.h', 'EncodedBufferCache.h',
'FileBlockCache.h', 'FileBlockCache.h',
'GraphDriver.h',
'Intervals.h', 'Intervals.h',
'Latency.h', 'Latency.h',
'MediaCache.h', 'MediaCache.h',

Просмотреть файл

@ -68,7 +68,6 @@ WMFAudioMFTManager::WMFAudioMFTManager(
const AudioInfo& aConfig) const AudioInfo& aConfig)
: mAudioChannels(aConfig.mChannels) : mAudioChannels(aConfig.mChannels)
, mAudioRate(aConfig.mRate) , mAudioRate(aConfig.mRate)
, mAudioFrameOffset(0)
, mAudioFrameSum(0) , mAudioFrameSum(0)
, mMustRecaptureAudioPosition(true) , mMustRecaptureAudioPosition(true)
{ {
@ -267,8 +266,7 @@ WMFAudioMFTManager::Output(int64_t aStreamOffset,
LONGLONG timestampHns = 0; LONGLONG timestampHns = 0;
hr = sample->GetSampleTime(&timestampHns); hr = sample->GetSampleTime(&timestampHns);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr); NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
hr = HNsToFrames(timestampHns, mAudioRate, &mAudioFrameOffset); mAudioTimeOffset = media::TimeUnit::FromMicroseconds(timestampHns / 10);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
mMustRecaptureAudioPosition = false; mMustRecaptureAudioPosition = false;
} }
// We can assume PCM 16 output. // We can assume PCM 16 output.
@ -292,7 +290,7 @@ WMFAudioMFTManager::Output(int64_t aStreamOffset,
buffer->Unlock(); buffer->Unlock();
media::TimeUnit timestamp = media::TimeUnit timestamp =
FramesToTimeUnit(mAudioFrameOffset + mAudioFrameSum, mAudioRate); mAudioTimeOffset + FramesToTimeUnit(mAudioFrameSum, mAudioRate);
NS_ENSURE_TRUE(timestamp.IsValid(), E_FAIL); NS_ENSURE_TRUE(timestamp.IsValid(), E_FAIL);
mAudioFrameSum += numFrames; mAudioFrameSum += numFrames;

Просмотреть файл

@ -42,9 +42,9 @@ private:
uint32_t mAudioRate; uint32_t mAudioRate;
nsTArray<BYTE> mUserData; nsTArray<BYTE> mUserData;
// The offset, in audio frames, at which playback started since the // The offset, at which playback started since the
// last discontinuity. // last discontinuity.
int64_t mAudioFrameOffset; media::TimeUnit mAudioTimeOffset;
// The number of audio frames that we've played since the last // The number of audio frames that we've played since the last
// discontinuity. // discontinuity.
int64_t mAudioFrameSum; int64_t mAudioFrameSum;
@ -59,7 +59,7 @@ private:
const GUID& GetMFTGUID(); const GUID& GetMFTGUID();
const GUID& GetMediaSubtypeGUID(); const GUID& GetMediaSubtypeGUID();
// True if we need to re-initialize mAudioFrameOffset and mAudioFrameSum // True if we need to re-initialize mAudioTimeOffset and mAudioFrameSum
// from the next audio packet we decode. This happens after a seek, since // from the next audio packet we decode. This happens after a seek, since
// WMF doesn't mark a stream as having a discontinuity after a seek(0). // WMF doesn't mark a stream as having a discontinuity after a seek(0).
bool mMustRecaptureAudioPosition; bool mMustRecaptureAudioPosition;

Просмотреть файл

@ -30,6 +30,8 @@ using mozilla::layers::IMFYCbCrImage;
using mozilla::layers::LayerManager; using mozilla::layers::LayerManager;
using mozilla::layers::LayersBackend; using mozilla::layers::LayersBackend;
#if MOZ_WINSDK_MAXVER < 0x0A000000
// Windows 10+ SDK has VP80 and VP90 defines
const GUID MFVideoFormat_VP80 = const GUID MFVideoFormat_VP80 =
{ {
0x30385056, 0x30385056,
@ -45,6 +47,7 @@ const GUID MFVideoFormat_VP90 =
0x0010, 0x0010,
{0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
}; };
#endif
const CLSID CLSID_WebmMfVp8Dec = const CLSID CLSID_WebmMfVp8Dec =
{ {

Просмотреть файл

@ -380,7 +380,7 @@ public:
AudioNodeSizes& aUsage) const AudioNodeSizes& aUsage) const
{ {
aUsage.mEngine = SizeOfIncludingThis(aMallocSizeOf); aUsage.mEngine = SizeOfIncludingThis(aMallocSizeOf);
if (HasNode()) { if (mNode) {
aUsage.mDomNode = mNode->SizeOfIncludingThis(aMallocSizeOf); aUsage.mDomNode = mNode->SizeOfIncludingThis(aMallocSizeOf);
aUsage.mNodeType = mNode->NodeType(); aUsage.mNodeType = mNode->NodeType();
} }

Просмотреть файл

@ -54,8 +54,7 @@ public:
SpeechRecognitionResultList* resultList = SpeechRecognitionResultList* resultList =
new SpeechRecognitionResultList(mRecognition); new SpeechRecognitionResultList(mRecognition);
SpeechRecognitionResult* result = new SpeechRecognitionResult(mRecognition); SpeechRecognitionResult* result = new SpeechRecognitionResult(mRecognition);
ErrorResult rv; if (0 < mRecognition->MaxAlternatives()) {
if (0 < mRecognition->GetMaxAlternatives(rv)) { // GetMaxAlternatives can't fail
SpeechRecognitionAlternative* alternative = SpeechRecognitionAlternative* alternative =
new SpeechRecognitionAlternative(mRecognition); new SpeechRecognitionAlternative(mRecognition);
@ -331,8 +330,7 @@ PocketSphinxSpeechRecognitionService::BuildMockResultList()
SpeechRecognitionResultList* resultList = SpeechRecognitionResultList* resultList =
new SpeechRecognitionResultList(mRecognition); new SpeechRecognitionResultList(mRecognition);
SpeechRecognitionResult* result = new SpeechRecognitionResult(mRecognition); SpeechRecognitionResult* result = new SpeechRecognitionResult(mRecognition);
ErrorResult rv; if (0 < mRecognition->MaxAlternatives()) {
if (0 < mRecognition->GetMaxAlternatives(rv)) { // GetMaxAlternatives can't fail
SpeechRecognitionAlternative* alternative = SpeechRecognitionAlternative* alternative =
new SpeechRecognitionAlternative(mRecognition); new SpeechRecognitionAlternative(mRecognition);

Просмотреть файл

@ -684,13 +684,13 @@ SpeechRecognition::SetInterimResults(bool aArg)
} }
uint32_t uint32_t
SpeechRecognition::GetMaxAlternatives(ErrorResult& aRv) const SpeechRecognition::MaxAlternatives() const
{ {
return mMaxAlternatives; return mMaxAlternatives;
} }
void void
SpeechRecognition::SetMaxAlternatives(uint32_t aArg, ErrorResult& aRv) SpeechRecognition::SetMaxAlternatives(uint32_t aArg)
{ {
mMaxAlternatives = aArg; mMaxAlternatives = aArg;
return; return;

Просмотреть файл

@ -87,9 +87,9 @@ public:
void SetInterimResults(bool aArg); void SetInterimResults(bool aArg);
uint32_t GetMaxAlternatives(ErrorResult& aRv) const; uint32_t MaxAlternatives() const;
void SetMaxAlternatives(uint32_t aArg, ErrorResult& aRv); void SetMaxAlternatives(uint32_t aArg);
void GetServiceURI(nsString& aRetVal, ErrorResult& aRv) const; void GetServiceURI(nsString& aRetVal, ErrorResult& aRv) const;

Просмотреть файл

@ -102,8 +102,7 @@ FakeSpeechRecognitionService::BuildMockResultList()
{ {
SpeechRecognitionResultList* resultList = new SpeechRecognitionResultList(mRecognition); SpeechRecognitionResultList* resultList = new SpeechRecognitionResultList(mRecognition);
SpeechRecognitionResult* result = new SpeechRecognitionResult(mRecognition); SpeechRecognitionResult* result = new SpeechRecognitionResult(mRecognition);
ErrorResult rv; if (0 < mRecognition->MaxAlternatives()) {
if (0 < mRecognition->GetMaxAlternatives(rv)) { // GetMaxAlternatives can't fail
SpeechRecognitionAlternative* alternative = new SpeechRecognitionAlternative(mRecognition); SpeechRecognitionAlternative* alternative = new SpeechRecognitionAlternative(mRecognition);
alternative->mTranscript = NS_LITERAL_STRING("Mock final result"); alternative->mTranscript = NS_LITERAL_STRING("Mock final result");

Просмотреть файл

@ -20,7 +20,6 @@ interface SpeechRecognition : EventTarget {
[Throws] [Throws]
attribute boolean continuous; attribute boolean continuous;
attribute boolean interimResults; attribute boolean interimResults;
[Throws]
attribute unsigned long maxAlternatives; attribute unsigned long maxAlternatives;
[Throws] [Throws]
attribute DOMString serviceURI; attribute DOMString serviceURI;

Просмотреть файл

@ -69,61 +69,6 @@ using namespace layerscope;
class DebugDataSender; class DebugDataSender;
class DebugGLData; class DebugGLData;
/*
* This class handle websocket protocol which included
* handshake and data frame's header
*/
class LayerScopeWebSocketHandler : public nsIInputStreamCallback {
public:
NS_DECL_THREADSAFE_ISUPPORTS
enum SocketStateType {
NoHandshake,
HandshakeSuccess,
HandshakeFailed
};
LayerScopeWebSocketHandler()
: mState(NoHandshake)
, mConnected(false)
{ }
void OpenStream(nsISocketTransport* aTransport);
bool WriteToStream(void *aPtr, uint32_t aSize);
// nsIInputStreamCallback
NS_IMETHODIMP OnInputStreamReady(nsIAsyncInputStream *aStream) override;
private:
virtual ~LayerScopeWebSocketHandler() { CloseConnection(); }
void ReadInputStreamData(nsTArray<nsCString>& aProtocolString);
bool WebSocketHandshake(nsTArray<nsCString>& aProtocolString);
nsresult HandleSocketMessage(nsIAsyncInputStream *aStream);
nsresult ProcessInput(uint8_t *aBuffer, uint32_t aCount);
// Copied from WebsocketChannel, helper function to decode data frame
void ApplyMask(uint32_t aMask, uint8_t *aData, uint64_t aLen);
bool HandleDataFrame(uint8_t *aData, uint32_t aSize);
void CloseConnection();
private:
nsCOMPtr<nsIOutputStream> mOutputStream;
nsCOMPtr<nsIAsyncInputStream> mInputStream;
nsCOMPtr<nsISocketTransport> mTransport;
SocketStateType mState;
bool mConnected;
};
NS_IMPL_ISUPPORTS(LayerScopeWebSocketHandler, nsIInputStreamCallback);
/* /*
* Manage Websocket connections * Manage Websocket connections
*/ */
@ -132,27 +77,18 @@ public:
LayerScopeWebSocketManager(); LayerScopeWebSocketManager();
~LayerScopeWebSocketManager(); ~LayerScopeWebSocketManager();
void AddConnection(nsISocketTransport *aTransport)
{
MOZ_ASSERT(aTransport);
nsRefPtr<LayerScopeWebSocketHandler> temp = new LayerScopeWebSocketHandler();
temp->OpenStream(aTransport);
mHandlers.AppendElement(temp.get());
}
void RemoveConnection(uint32_t aIndex)
{
MOZ_ASSERT(aIndex < mHandlers.Length());
mHandlers.RemoveElementAt(aIndex);
}
void RemoveAllConnections() void RemoveAllConnections()
{ {
MOZ_ASSERT(NS_IsMainThread());
MutexAutoLock lock(mHandlerMutex);
mHandlers.Clear(); mHandlers.Clear();
} }
bool WriteAll(void *ptr, uint32_t size) bool WriteAll(void *ptr, uint32_t size)
{ {
MOZ_ASSERT(NS_IsMainThread());
for (int32_t i = mHandlers.Length() - 1; i >= 0; --i) { for (int32_t i = mHandlers.Length() - 1; i >= 0; --i) {
if (!mHandlers[i]->WriteToStream(ptr, size)) { if (!mHandlers[i]->WriteToStream(ptr, size)) {
// Send failed, remove this handler // Send failed, remove this handler
@ -165,19 +101,116 @@ public:
bool IsConnected() bool IsConnected()
{ {
// This funtion can be called in both main thread and compositor thread.
MutexAutoLock lock(mHandlerMutex);
return (mHandlers.Length() != 0) ? true : false; return (mHandlers.Length() != 0) ? true : false;
} }
void AppendDebugData(DebugGLData *aDebugData); void AppendDebugData(DebugGLData *aDebugData);
void CleanDebugData(); void CleanDebugData();
void DispatchDebugData(); void DispatchDebugData();
private: private:
nsTArray<nsRefPtr<LayerScopeWebSocketHandler> > mHandlers; void AddConnection(nsISocketTransport *aTransport)
nsCOMPtr<nsIThread> mDebugSenderThread; {
nsRefPtr<DebugDataSender> mCurrentSender; MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIServerSocket> mServerSocket; MOZ_ASSERT(aTransport);
MutexAutoLock lock(mHandlerMutex);
nsRefPtr<SocketHandler> temp = new SocketHandler();
temp->OpenStream(aTransport);
mHandlers.AppendElement(temp.get());
}
void RemoveConnection(uint32_t aIndex)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aIndex < mHandlers.Length());
MutexAutoLock lock(mHandlerMutex);
mHandlers.RemoveElementAt(aIndex);
}
friend class SocketListener;
class SocketListener : public nsIServerSocketListener
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
SocketListener() { }
/* nsIServerSocketListener */
NS_IMETHODIMP OnSocketAccepted(nsIServerSocket *aServ,
nsISocketTransport *aTransport) override;
NS_IMETHODIMP OnStopListening(nsIServerSocket *aServ,
nsresult aStatus) override
{
return NS_OK;
}
private:
virtual ~SocketListener() { }
};
/*
* This class handle websocket protocol which included
* handshake and data frame's header
*/
class SocketHandler : public nsIInputStreamCallback {
public:
NS_DECL_THREADSAFE_ISUPPORTS
SocketHandler()
: mState(NoHandshake)
, mConnected(false)
{ }
void OpenStream(nsISocketTransport* aTransport);
bool WriteToStream(void *aPtr, uint32_t aSize);
// nsIInputStreamCallback
NS_IMETHODIMP OnInputStreamReady(nsIAsyncInputStream *aStream) override;
private:
virtual ~SocketHandler() { CloseConnection(); }
void ReadInputStreamData(nsTArray<nsCString>& aProtocolString);
bool WebSocketHandshake(nsTArray<nsCString>& aProtocolString);
void ApplyMask(uint32_t aMask, uint8_t *aData, uint64_t aLen);
bool HandleDataFrame(uint8_t *aData, uint32_t aSize);
void CloseConnection();
nsresult HandleSocketMessage(nsIAsyncInputStream *aStream);
nsresult ProcessInput(uint8_t *aBuffer, uint32_t aCount);
private:
enum SocketStateType {
NoHandshake,
HandshakeSuccess,
HandshakeFailed
};
SocketStateType mState;
nsCOMPtr<nsIOutputStream> mOutputStream;
nsCOMPtr<nsIAsyncInputStream> mInputStream;
nsCOMPtr<nsISocketTransport> mTransport;
bool mConnected;
};
nsTArray<nsRefPtr<SocketHandler> > mHandlers;
nsCOMPtr<nsIThread> mDebugSenderThread;
nsRefPtr<DebugDataSender> mCurrentSender;
nsCOMPtr<nsIServerSocket> mServerSocket;
// Keep mHandlers accessing thread safe.
Mutex mHandlerMutex;
}; };
NS_IMPL_ISUPPORTS(LayerScopeWebSocketManager::SocketListener,
nsIServerSocketListener);
NS_IMPL_ISUPPORTS(LayerScopeWebSocketManager::SocketHandler,
nsIInputStreamCallback);
class DrawSession { class DrawSession {
public: public:
DrawSession() DrawSession()
@ -236,7 +269,9 @@ private:
THArray mChangedHosts; THArray mChangedHosts;
}; };
// Hold all singleton objects used by LayerScope /*
* Hold all singleton objects used by LayerScope.
*/
class LayerScopeManager class LayerScopeManager
{ {
public: public:
@ -708,40 +743,6 @@ protected:
uint64_t mLayerRef; uint64_t mLayerRef;
}; };
class DebugListener : public nsIServerSocketListener
{
virtual ~DebugListener() { }
public:
NS_DECL_THREADSAFE_ISUPPORTS
DebugListener() { }
/* nsIServerSocketListener */
NS_IMETHODIMP OnSocketAccepted(nsIServerSocket *aServ,
nsISocketTransport *aTransport) override
{
if (!gLayerScopeManager.GetSocketManager())
return NS_OK;
printf_stderr("*** LayerScope: Accepted connection\n");
gLayerScopeManager.GetSocketManager()->AddConnection(aTransport);
gLayerScopeManager.GetContentMonitor()->Empty();
return NS_OK;
}
NS_IMETHODIMP OnStopListening(nsIServerSocket *aServ,
nsresult aStatus) override
{
return NS_OK;
}
};
NS_IMPL_ISUPPORTS(DebugListener, nsIServerSocketListener);
class DebugDataSender : public nsIRunnable class DebugDataSender : public nsIRunnable
{ {
virtual ~DebugDataSender() { virtual ~DebugDataSender() {
@ -1135,10 +1136,10 @@ LayerScope::ContentChanged(TextureHost *host)
} }
// ---------------------------------------------- // ----------------------------------------------
// LayerScopeWebSocketHandler implementation // SocketHandler implementation
// ---------------------------------------------- // ----------------------------------------------
void void
LayerScopeWebSocketHandler::OpenStream(nsISocketTransport* aTransport) LayerScopeWebSocketManager::SocketHandler::OpenStream(nsISocketTransport* aTransport)
{ {
MOZ_ASSERT(aTransport); MOZ_ASSERT(aTransport);
@ -1158,7 +1159,7 @@ LayerScopeWebSocketHandler::OpenStream(nsISocketTransport* aTransport)
} }
bool bool
LayerScopeWebSocketHandler::WriteToStream(void *aPtr, LayerScopeWebSocketManager::SocketHandler::WriteToStream(void *aPtr,
uint32_t aSize) uint32_t aSize)
{ {
if (mState == NoHandshake) { if (mState == NoHandshake) {
@ -1214,7 +1215,7 @@ LayerScopeWebSocketHandler::WriteToStream(void *aPtr,
} }
NS_IMETHODIMP NS_IMETHODIMP
LayerScopeWebSocketHandler::OnInputStreamReady(nsIAsyncInputStream *aStream) LayerScopeWebSocketManager::SocketHandler::OnInputStreamReady(nsIAsyncInputStream *aStream)
{ {
MOZ_ASSERT(mInputStream); MOZ_ASSERT(mInputStream);
@ -1240,7 +1241,7 @@ LayerScopeWebSocketHandler::OnInputStreamReady(nsIAsyncInputStream *aStream)
} }
void void
LayerScopeWebSocketHandler::ReadInputStreamData(nsTArray<nsCString>& aProtocolString) LayerScopeWebSocketManager::SocketHandler::ReadInputStreamData(nsTArray<nsCString>& aProtocolString)
{ {
nsLineBuffer<char> lineBuffer; nsLineBuffer<char> lineBuffer;
nsCString line; nsCString line;
@ -1255,7 +1256,7 @@ LayerScopeWebSocketHandler::ReadInputStreamData(nsTArray<nsCString>& aProtocolSt
} }
bool bool
LayerScopeWebSocketHandler::WebSocketHandshake(nsTArray<nsCString>& aProtocolString) LayerScopeWebSocketManager::SocketHandler::WebSocketHandshake(nsTArray<nsCString>& aProtocolString)
{ {
nsresult rv; nsresult rv;
bool isWebSocket = false; bool isWebSocket = false;
@ -1343,7 +1344,7 @@ LayerScopeWebSocketHandler::WebSocketHandshake(nsTArray<nsCString>& aProtocolStr
} }
nsresult nsresult
LayerScopeWebSocketHandler::HandleSocketMessage(nsIAsyncInputStream *aStream) LayerScopeWebSocketManager::SocketHandler::HandleSocketMessage(nsIAsyncInputStream *aStream)
{ {
// The reading and parsing of this input stream is customized for layer viewer. // The reading and parsing of this input stream is customized for layer viewer.
const uint32_t cPacketSize = 1024; const uint32_t cPacketSize = 1024;
@ -1377,7 +1378,7 @@ LayerScopeWebSocketHandler::HandleSocketMessage(nsIAsyncInputStream *aStream)
} }
nsresult nsresult
LayerScopeWebSocketHandler::ProcessInput(uint8_t *aBuffer, LayerScopeWebSocketManager::SocketHandler::ProcessInput(uint8_t *aBuffer,
uint32_t aCount) uint32_t aCount)
{ {
uint32_t avail = aCount; uint32_t avail = aCount;
@ -1465,7 +1466,7 @@ LayerScopeWebSocketHandler::ProcessInput(uint8_t *aBuffer,
} }
void void
LayerScopeWebSocketHandler::ApplyMask(uint32_t aMask, LayerScopeWebSocketManager::SocketHandler::ApplyMask(uint32_t aMask,
uint8_t *aData, uint8_t *aData,
uint64_t aLen) uint64_t aLen)
{ {
@ -1505,7 +1506,7 @@ LayerScopeWebSocketHandler::ApplyMask(uint32_t aMask,
} }
bool bool
LayerScopeWebSocketHandler::HandleDataFrame(uint8_t *aData, LayerScopeWebSocketManager::SocketHandler::HandleDataFrame(uint8_t *aData,
uint32_t aSize) uint32_t aSize)
{ {
// Handle payload data by protocol buffer // Handle payload data by protocol buffer
@ -1539,7 +1540,7 @@ LayerScopeWebSocketHandler::HandleDataFrame(uint8_t *aData,
} }
void void
LayerScopeWebSocketHandler::CloseConnection() LayerScopeWebSocketManager::SocketHandler::CloseConnection()
{ {
gLayerScopeManager.GetSocketManager()->CleanDebugData(); gLayerScopeManager.GetSocketManager()->CleanDebugData();
if (mInputStream) { if (mInputStream) {
@ -1556,18 +1557,18 @@ LayerScopeWebSocketHandler::CloseConnection()
mConnected = false; mConnected = false;
} }
// ---------------------------------------------- // ----------------------------------------------
// LayerScopeWebSocketManager implementation // LayerScopeWebSocketManager implementation
// ---------------------------------------------- // ----------------------------------------------
LayerScopeWebSocketManager::LayerScopeWebSocketManager() LayerScopeWebSocketManager::LayerScopeWebSocketManager()
: mHandlerMutex("LayerScopeWebSocketManager::mHandlerMutex")
{ {
NS_NewThread(getter_AddRefs(mDebugSenderThread)); NS_NewThread(getter_AddRefs(mDebugSenderThread));
mServerSocket = do_CreateInstance(NS_SERVERSOCKET_CONTRACTID); mServerSocket = do_CreateInstance(NS_SERVERSOCKET_CONTRACTID);
int port = gfxPrefs::LayerScopePort(); int port = gfxPrefs::LayerScopePort();
mServerSocket->Init(port, false, -1); mServerSocket->Init(port, false, -1);
mServerSocket->AsyncListen(new DebugListener); mServerSocket->AsyncListen(new SocketListener);
} }
LayerScopeWebSocketManager::~LayerScopeWebSocketManager() LayerScopeWebSocketManager::~LayerScopeWebSocketManager()
@ -1600,10 +1601,23 @@ LayerScopeWebSocketManager::DispatchDebugData()
mCurrentSender = nullptr; mCurrentSender = nullptr;
} }
NS_IMETHODIMP LayerScopeWebSocketManager::SocketListener::OnSocketAccepted(
nsIServerSocket *aServ,
nsISocketTransport *aTransport)
{
if (!gLayerScopeManager.GetSocketManager())
return NS_OK;
printf_stderr("*** LayerScope: Accepted connection\n");
gLayerScopeManager.GetSocketManager()->AddConnection(aTransport);
gLayerScopeManager.GetContentMonitor()->Empty();
return NS_OK;
}
// ---------------------------------------------- // ----------------------------------------------
// LayerScope implementation // LayerScope implementation
// ---------------------------------------------- // ----------------------------------------------
/*static*/
void void
LayerScope::Init() LayerScope::Init()
{ {
@ -1614,6 +1628,7 @@ LayerScope::Init()
gLayerScopeManager.CreateServerSocket(); gLayerScopeManager.CreateServerSocket();
} }
/*static*/
void void
LayerScope::DrawBegin() LayerScope::DrawBegin()
{ {
@ -1624,6 +1639,7 @@ LayerScope::DrawBegin()
gLayerScopeManager.NewDrawSession(); gLayerScopeManager.NewDrawSession();
} }
/*static*/
void void
LayerScope::SetRenderOffset(float aX, float aY) LayerScope::SetRenderOffset(float aX, float aY)
{ {
@ -1635,6 +1651,7 @@ LayerScope::SetRenderOffset(float aX, float aY)
gLayerScopeManager.CurrentSession().mOffsetY = aY; gLayerScopeManager.CurrentSession().mOffsetY = aY;
} }
/*static*/
void void
LayerScope::SetLayerTransform(const gfx::Matrix4x4& aMatrix) LayerScope::SetLayerTransform(const gfx::Matrix4x4& aMatrix)
{ {
@ -1645,6 +1662,7 @@ LayerScope::SetLayerTransform(const gfx::Matrix4x4& aMatrix)
gLayerScopeManager.CurrentSession().mMVMatrix = aMatrix; gLayerScopeManager.CurrentSession().mMVMatrix = aMatrix;
} }
/*static*/
void void
LayerScope::SetDrawRects(size_t aRects, LayerScope::SetDrawRects(size_t aRects,
const gfx::Rect* aLayerRects, const gfx::Rect* aLayerRects,
@ -1665,6 +1683,7 @@ LayerScope::SetDrawRects(size_t aRects,
} }
} }
/*static*/
void void
LayerScope::DrawEnd(gl::GLContext* aGLContext, LayerScope::DrawEnd(gl::GLContext* aGLContext,
const EffectChain& aEffectChain, const EffectChain& aEffectChain,
@ -1692,6 +1711,7 @@ LayerScope::DrawEnd(gl::GLContext* aGLContext,
} }
/*static*/
void void
LayerScope::SendLayer(LayerComposite* aLayer, LayerScope::SendLayer(LayerComposite* aLayer,
int aWidth, int aWidth,
@ -1704,6 +1724,7 @@ LayerScope::SendLayer(LayerComposite* aLayer,
SenderHelper::SendLayer(aLayer, aWidth, aHeight); SenderHelper::SendLayer(aLayer, aWidth, aHeight);
} }
/*static*/
void void
LayerScope::SendLayerDump(UniquePtr<Packet> aPacket) LayerScope::SendLayerDump(UniquePtr<Packet> aPacket)
{ {
@ -1715,6 +1736,7 @@ LayerScope::SendLayerDump(UniquePtr<Packet> aPacket)
new DebugGLLayersData(Move(aPacket))); new DebugGLLayersData(Move(aPacket)));
} }
/*static*/
bool bool
LayerScope::CheckSendable() LayerScope::CheckSendable()
{ {
@ -1734,6 +1756,7 @@ LayerScope::CheckSendable()
return true; return true;
} }
/*static*/
void void
LayerScope::CleanLayer() LayerScope::CleanLayer()
{ {
@ -1742,6 +1765,7 @@ LayerScope::CleanLayer()
} }
} }
/*static*/
void void
LayerScope::SetHWComposed() LayerScope::SetHWComposed()
{ {
@ -1751,11 +1775,13 @@ LayerScope::SetHWComposed()
} }
} }
/*static*/
void void
LayerScope::SetPixelScale(double devPixelsPerCSSPixel) LayerScope::SetPixelScale(double devPixelsPerCSSPixel)
{ {
gLayerScopeManager.SetPixelScale(devPixelsPerCSSPixel); gLayerScopeManager.SetPixelScale(devPixelsPerCSSPixel);
} }
// ---------------------------------------------- // ----------------------------------------------
// LayerScopeAutoFrame implementation // LayerScopeAutoFrame implementation
// ---------------------------------------------- // ----------------------------------------------

Просмотреть файл

@ -47,11 +47,8 @@ function MapIteratorNext() {
// Steps 8-9 (omitted). // Steps 8-9 (omitted).
var mapIterationResultPair = iteratorTemp.mapIterationResultPair; var mapIterationResultPair = iteratorTemp.mapIterationResultPair;
if (!mapIterationResultPair) { if (!mapIterationResultPair)
mapIterationResultPair = iteratorTemp.mapIterationResultPair = NewDenseArray(2); mapIterationResultPair = iteratorTemp.mapIterationResultPair = [null, null];
mapIterationResultPair[0] = null;
mapIterationResultPair[1] = null;
}
var retVal = {value: undefined, done: true}; var retVal = {value: undefined, done: true};

Просмотреть файл

@ -10,11 +10,10 @@
"unpack": true "unpack": true
}, },
{ {
"size": 12057960, "size": 4431740,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e", "digest": "68fc56b0fb0cdba629b95683d6649ff76b00dccf97af90960c3d7716f6108b2162ffd5ffcd5c3a60a21b28674df688fe4dabc67345e2da35ec5abeae3d48c8e3",
"algorithm": "sha512", "algorithm": "sha512",
"filename": "gtk3.tar.xz", "filename": "gtk3.tar.xz",
"setup": "setup.sh",
"unpack": true "unpack": true
} }
] ]

Просмотреть файл

@ -1324,7 +1324,7 @@ static inline ScriptCountsMap::Ptr GetScriptCountsMapEntry(JSScript* script)
return p; return p;
} }
js::PCCounts js::PCCounts&
JSScript::getPCCounts(jsbytecode* pc) { JSScript::getPCCounts(jsbytecode* pc) {
MOZ_ASSERT(containsPC(pc)); MOZ_ASSERT(containsPC(pc));
ScriptCountsMap::Ptr p = GetScriptCountsMapEntry(this); ScriptCountsMap::Ptr p = GetScriptCountsMapEntry(this);

Просмотреть файл

@ -1629,7 +1629,7 @@ class JSScript : public js::gc::TenuredCell
public: public:
bool initScriptCounts(JSContext* cx); bool initScriptCounts(JSContext* cx);
js::PCCounts getPCCounts(jsbytecode* pc); js::PCCounts& getPCCounts(jsbytecode* pc);
void addIonCounts(js::jit::IonScriptCounts* ionCounts); void addIonCounts(js::jit::IonScriptCounts* ionCounts);
js::jit::IonScriptCounts* getIonCounts(); js::jit::IonScriptCounts* getIonCounts();
js::ScriptCounts releaseScriptCounts(); js::ScriptCounts releaseScriptCounts();

Просмотреть файл

@ -1281,7 +1281,7 @@ XPCConvert::NativeArray2JS(MutableHandleValue d, const void** s,
for (i = 0; i < count; i++) { \ for (i = 0; i < count; i++) { \
if (!NativeData2JS(&current, ((_t*)*s)+i, type, iid, pErr) || \ if (!NativeData2JS(&current, ((_t*)*s)+i, type, iid, pErr) || \
!JS_DefineElement(cx, array, i, current, JSPROP_ENUMERATE)) \ !JS_DefineElement(cx, array, i, current, JSPROP_ENUMERATE)) \
goto failure; \ return false; \
} \ } \
PR_END_MACRO PR_END_MACRO
@ -1301,17 +1301,17 @@ XPCConvert::NativeArray2JS(MutableHandleValue d, const void** s,
case nsXPTType::T_BOOL : POPULATE(bool); break; case nsXPTType::T_BOOL : POPULATE(bool); break;
case nsXPTType::T_CHAR : POPULATE(char); break; case nsXPTType::T_CHAR : POPULATE(char); break;
case nsXPTType::T_WCHAR : POPULATE(char16_t); break; case nsXPTType::T_WCHAR : POPULATE(char16_t); break;
case nsXPTType::T_VOID : NS_ERROR("bad type"); goto failure; case nsXPTType::T_VOID : NS_ERROR("bad type"); return false;
case nsXPTType::T_IID : POPULATE(nsID*); break; case nsXPTType::T_IID : POPULATE(nsID*); break;
case nsXPTType::T_DOMSTRING : NS_ERROR("bad type"); goto failure; case nsXPTType::T_DOMSTRING : NS_ERROR("bad type"); return false;
case nsXPTType::T_CHAR_STR : POPULATE(char*); break; case nsXPTType::T_CHAR_STR : POPULATE(char*); break;
case nsXPTType::T_WCHAR_STR : POPULATE(char16_t*); break; case nsXPTType::T_WCHAR_STR : POPULATE(char16_t*); break;
case nsXPTType::T_INTERFACE : POPULATE(nsISupports*); break; case nsXPTType::T_INTERFACE : POPULATE(nsISupports*); break;
case nsXPTType::T_INTERFACE_IS : POPULATE(nsISupports*); break; case nsXPTType::T_INTERFACE_IS : POPULATE(nsISupports*); break;
case nsXPTType::T_UTF8STRING : NS_ERROR("bad type"); goto failure; case nsXPTType::T_UTF8STRING : NS_ERROR("bad type"); return false;
case nsXPTType::T_CSTRING : NS_ERROR("bad type"); goto failure; case nsXPTType::T_CSTRING : NS_ERROR("bad type"); return false;
case nsXPTType::T_ASTRING : NS_ERROR("bad type"); goto failure; case nsXPTType::T_ASTRING : NS_ERROR("bad type"); return false;
default : NS_ERROR("bad type"); goto failure; default : NS_ERROR("bad type"); return false;
} }
if (pErr) if (pErr)
@ -1319,9 +1319,6 @@ XPCConvert::NativeArray2JS(MutableHandleValue d, const void** s,
d.setObject(*array); d.setObject(*array);
return true; return true;
failure:
return false;
#undef POPULATE #undef POPULATE
} }

Просмотреть файл

@ -0,0 +1,9 @@
<!DOCTYPE HTML>
<body style="width:500px; border:2px solid black;">
<div style="width:300px; height:300px; background:yellow; float:left;"></div>
<div style="width:300px; height:400px;">
<span style="display:inline-block; outline:3px solid cyan">
<span style="display:inline-block; width:300px; height:100px; outline:5px solid red" id="d"></span>
</span>
</div>
</body>

Просмотреть файл

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html class="reftest-wait">
<body style="width:500px; border:2px solid black;">
<div style="width:300px; height:300px; background:yellow; float:left;"></div>
<div style="width:300px; height:400px;">
<span style="display:inline-block; outline:3px solid cyan">
<span style="display:inline-block; width:0; height:0; outline:5px solid red" id="d"></span>
</span>
</div>
<script>
window.addEventListener("MozReftestInvalidate", function() {
d.style.width = "300px";
d.style.height = "100px";
document.documentElement.removeAttribute("class");
});
</script>
</body>

Просмотреть файл

@ -1931,3 +1931,4 @@ skip-if(B2G||Mulet) == 1150021-1.xul 1150021-1-ref.xul
== 1169331-1.html 1169331-1-ref.html == 1169331-1.html 1169331-1-ref.html
== 1179078-1.html 1179078-1-ref.html == 1179078-1.html 1179078-1-ref.html
fuzzy(1,74) fuzzy-if(gtkWidget,6,79) == 1174332-1.html 1174332-1-ref.html fuzzy(1,74) fuzzy-if(gtkWidget,6,79) == 1174332-1.html 1174332-1-ref.html
== 1190635-1.html 1190635-1-ref.html

Просмотреть файл

@ -1600,7 +1600,7 @@ nsChangeHint nsStylePosition::CalcDifference(const nsStylePosition& aOther) cons
// elements with percentage heights in descendants which also have // elements with percentage heights in descendants which also have
// percentage heights. This is handled via nsChangeHint_UpdateComputedBSize // percentage heights. This is handled via nsChangeHint_UpdateComputedBSize
// which clears intrinsic sizes for frames that have such replaced elements. // which clears intrinsic sizes for frames that have such replaced elements.
return NS_CombineHint(hint, nsChangeHint_NeedReflow | NS_UpdateHint(hint, nsChangeHint_NeedReflow |
nsChangeHint_UpdateComputedBSize | nsChangeHint_UpdateComputedBSize |
nsChangeHint_ReflowChangesSizeOrPosition); nsChangeHint_ReflowChangesSizeOrPosition);
} }
@ -1610,16 +1610,13 @@ nsChangeHint nsStylePosition::CalcDifference(const nsStylePosition& aOther) cons
mMaxWidth != aOther.mMaxWidth) { mMaxWidth != aOther.mMaxWidth) {
// None of our width differences can affect descendant intrinsic // None of our width differences can affect descendant intrinsic
// sizes and none of them need to force children to reflow. // sizes and none of them need to force children to reflow.
return NS_UpdateHint(hint, NS_SubtractHint(nsChangeHint_AllReflowHints,
NS_CombineHint(hint, NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics,
NS_SubtractHint(nsChangeHint_AllReflowHints, nsChangeHint_NeedDirtyReflow)));
NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics,
nsChangeHint_NeedDirtyReflow)));
} }
// If width and height have not changed, but any of the offsets have changed, // If any of the offsets have changed, then return the respective hints
// then return the respective hints so that we would hopefully be able to // so that we would hopefully be able to avoid reflowing.
// avoid reflowing.
// Note that it is possible that we'll need to reflow when processing // Note that it is possible that we'll need to reflow when processing
// restyles, but we don't have enough information to make a good decision // restyles, but we don't have enough information to make a good decision
// right now. // right now.
@ -1630,7 +1627,7 @@ nsChangeHint nsStylePosition::CalcDifference(const nsStylePosition& aOther) cons
NS_UpdateHint(hint, nsChangeHint(nsChangeHint_RecomputePosition | NS_UpdateHint(hint, nsChangeHint(nsChangeHint_RecomputePosition |
nsChangeHint_UpdateParentOverflow)); nsChangeHint_UpdateParentOverflow));
} else { } else {
return NS_CombineHint(hint, nsChangeHint_AllReflowHints); NS_UpdateHint(hint, nsChangeHint_AllReflowHints);
} }
} }
return hint; return hint;

Просмотреть файл

@ -580,7 +580,9 @@ SampleTable::setSampleAuxiliaryInformationOffsetParams(
} }
data_offset += 4; data_offset += 4;
mCencOffsets.setCapacity(cencOffsetCount); if (mCencOffsets.setCapacity(cencOffsetCount) < 0) {
return ERROR_MALFORMED;
}
if (!version) { if (!version) {
for (uint32_t i = 0; i < cencOffsetCount; i++) { for (uint32_t i = 0; i < cencOffsetCount; i++) {
uint32_t tmp; uint32_t tmp;
@ -1104,8 +1106,12 @@ SampleTable::getSampleCencInfo(
} }
auto& info = mCencInfo[sample_index]; auto& info = mCencInfo[sample_index];
clear_sizes.setCapacity(info.mSubsampleCount); if (clear_sizes.setCapacity(info.mSubsampleCount) < 0) {
cipher_sizes.setCapacity(info.mSubsampleCount); return ERROR_MALFORMED;
}
if (cipher_sizes.setCapacity(info.mSubsampleCount) < 0) {
return ERROR_MALFORMED;
}
for (uint32_t i = 0; i < info.mSubsampleCount; i++) { for (uint32_t i = 0; i < info.mSubsampleCount; i++) {
clear_sizes.push(info.mSubsamples[i].mClearBytes); clear_sizes.push(info.mSubsamples[i].mClearBytes);

Просмотреть файл

@ -18,6 +18,7 @@
#define ANDROID_VECTOR_H #define ANDROID_VECTOR_H
#include <new> #include <new>
#include <assert.h>
#include <stdint.h> #include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
@ -191,7 +192,7 @@ public:
inline iterator end() { return editArray() + size(); } inline iterator end() { return editArray() + size(); }
inline const_iterator begin() const { return array(); } inline const_iterator begin() const { return array(); }
inline const_iterator end() const { return array() + size(); } inline const_iterator end() const { return array() + size(); }
inline void reserve(size_t n) { setCapacity(n); } inline void reserve(size_t n) { assert(setCapacity(n) >= 0); }
inline bool empty() const{ return isEmpty(); } inline bool empty() const{ return isEmpty(); }
inline void push_back(const TYPE& item) { insertAt(item, size(), 1); } inline void push_back(const TYPE& item) { insertAt(item, size(), 1); }
inline void push_front(const TYPE& item) { insertAt(item, 0, 1); } inline void push_front(const TYPE& item) { insertAt(item, 0, 1); }

Просмотреть файл

@ -27,9 +27,8 @@
#include <utils/SharedBuffer.h> #include <utils/SharedBuffer.h>
#include <utils/VectorImpl.h> #include <utils/VectorImpl.h>
#if !defined(SSIZE_MAX) static const uint32_t kMAX_ALLOCATION =
#define SSIZE_MAX ((ssize_t)(SIZE_MAX/2)) ((SIZE_MAX > INT32_MAX ? INT32_MAX : SIZE_MAX) - 1);
#endif
/*****************************************************************************/ /*****************************************************************************/
@ -93,6 +92,7 @@ void* VectorImpl::editArrayImpl()
SharedBuffer* sb = SharedBuffer::bufferFromData(mStorage)->attemptEdit(); SharedBuffer* sb = SharedBuffer::bufferFromData(mStorage)->attemptEdit();
if (sb == 0) { if (sb == 0) {
sb = SharedBuffer::alloc(capacity() * mItemSize); sb = SharedBuffer::alloc(capacity() * mItemSize);
assert(sb);
if (sb) { if (sb) {
_do_copy(sb->data(), mStorage, mCount); _do_copy(sb->data(), mStorage, mCount);
release_storage(); release_storage();
@ -334,7 +334,7 @@ ssize_t VectorImpl::setCapacity(size_t new_capacity)
// we can't reduce the capacity // we can't reduce the capacity
return capacity(); return capacity();
} }
if (new_capacity >= (SSIZE_MAX / mItemSize)) { if (new_capacity >= (kMAX_ALLOCATION / mItemSize)) {
return NO_MEMORY; return NO_MEMORY;
} }
SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize); SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
@ -380,8 +380,11 @@ void* VectorImpl::_grow(size_t where, size_t amount)
this, (int)where, (int)amount, (int)mCount); // caller already checked this, (int)where, (int)amount, (int)mCount); // caller already checked
const size_t new_size = mCount + amount; const size_t new_size = mCount + amount;
assert(amount < kMAX_ALLOCATION - mCount);
if (capacity() < new_size) { if (capacity() < new_size) {
assert(new_size < (SIZE_MAX / 3 - 1));
const size_t new_capacity = max(kMinVectorCapacity, ((new_size*3)+1)/2); const size_t new_capacity = max(kMinVectorCapacity, ((new_size*3)+1)/2);
assert(new_capacity < (kMAX_ALLOCATION / mItemSize));
// ALOGV("grow vector %p, new_capacity=%d", this, (int)new_capacity); // ALOGV("grow vector %p, new_capacity=%d", this, (int)new_capacity);
if ((mStorage) && if ((mStorage) &&
(mCount==where) && (mCount==where) &&
@ -389,10 +392,13 @@ void* VectorImpl::_grow(size_t where, size_t amount)
(mFlags & HAS_TRIVIAL_DTOR)) (mFlags & HAS_TRIVIAL_DTOR))
{ {
const SharedBuffer* cur_sb = SharedBuffer::bufferFromData(mStorage); const SharedBuffer* cur_sb = SharedBuffer::bufferFromData(mStorage);
assert(cur_sb);
SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize); SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize);
assert(sb);
mStorage = sb->data(); mStorage = sb->data();
} else { } else {
SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize); SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
assert(sb);
if (sb) { if (sb) {
void* array = sb->data(); void* array = sb->data();
if (where != 0) { if (where != 0) {
@ -433,18 +439,23 @@ void VectorImpl::_shrink(size_t where, size_t amount)
this, (int)where, (int)amount, (int)mCount); // caller already checked this, (int)where, (int)amount, (int)mCount); // caller already checked
const size_t new_size = mCount - amount; const size_t new_size = mCount - amount;
if (new_size*3 < capacity()) { assert(new_size < (SIZE_MAX / 2));
if (new_size*2 < capacity()) {
const size_t new_capacity = max(kMinVectorCapacity, new_size*2); const size_t new_capacity = max(kMinVectorCapacity, new_size*2);
// ALOGV("shrink vector %p, new_capacity=%d", this, (int)new_capacity); // ALOGV("shrink vector %p, new_capacity=%d", this, (int)new_capacity);
assert(new_capacity < (kMAX_ALLOCATION / mItemSize));
if ((where == new_size) && if ((where == new_size) &&
(mFlags & HAS_TRIVIAL_COPY) && (mFlags & HAS_TRIVIAL_COPY) &&
(mFlags & HAS_TRIVIAL_DTOR)) (mFlags & HAS_TRIVIAL_DTOR))
{ {
const SharedBuffer* cur_sb = SharedBuffer::bufferFromData(mStorage); const SharedBuffer* cur_sb = SharedBuffer::bufferFromData(mStorage);
assert(cur_sb);
SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize); SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize);
assert(sb);
mStorage = sb->data(); mStorage = sb->data();
} else { } else {
SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize); SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
assert(sb);
if (sb) { if (sb) {
void* array = sb->data(); void* array = sb->data();
if (where != 0) { if (where != 0) {
@ -461,6 +472,7 @@ void VectorImpl::_shrink(size_t where, size_t amount)
} }
} else { } else {
void* array = editArrayImpl(); void* array = editArrayImpl();
assert(array);
void* to = reinterpret_cast<uint8_t *>(array) + where*mItemSize; void* to = reinterpret_cast<uint8_t *>(array) + where*mItemSize;
_do_destroy(to, amount); _do_destroy(to, amount);
if (where != new_size) { if (where != new_size) {

Просмотреть файл

@ -289,7 +289,7 @@ JsepSessionImpl::GetRemoteTracksRemoved() const
} }
nsresult nsresult
JsepSessionImpl::AddOfferMSections(const JsepOfferOptions& options, Sdp* sdp) JsepSessionImpl::SetupOfferMSections(const JsepOfferOptions& options, Sdp* sdp)
{ {
// First audio, then video, then datachannel, for interop // First audio, then video, then datachannel, for interop
// TODO(bug 1121756): We need to group these by stream-id, _then_ by media // TODO(bug 1121756): We need to group these by stream-id, _then_ by media
@ -297,19 +297,19 @@ JsepSessionImpl::AddOfferMSections(const JsepOfferOptions& options, Sdp* sdp)
// older versions of Firefox if a video-only stream is added before an // older versions of Firefox if a video-only stream is added before an
// audio-only stream. // audio-only stream.
// We should probably wait until 38 is ESR before trying to do this. // We should probably wait until 38 is ESR before trying to do this.
nsresult rv = AddOfferMSectionsByType( nsresult rv = SetupOfferMSectionsByType(
SdpMediaSection::kAudio, options.mOfferToReceiveAudio, sdp); SdpMediaSection::kAudio, options.mOfferToReceiveAudio, sdp);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
rv = AddOfferMSectionsByType( rv = SetupOfferMSectionsByType(
SdpMediaSection::kVideo, options.mOfferToReceiveVideo, sdp); SdpMediaSection::kVideo, options.mOfferToReceiveVideo, sdp);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (!(options.mDontOfferDataChannel.isSome() && if (!(options.mDontOfferDataChannel.isSome() &&
*options.mDontOfferDataChannel)) { *options.mDontOfferDataChannel)) {
rv = AddOfferMSectionsByType( rv = SetupOfferMSectionsByType(
SdpMediaSection::kApplication, Maybe<size_t>(), sdp); SdpMediaSection::kApplication, Maybe<size_t>(), sdp);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@ -325,9 +325,9 @@ JsepSessionImpl::AddOfferMSections(const JsepOfferOptions& options, Sdp* sdp)
} }
nsresult nsresult
JsepSessionImpl::AddOfferMSectionsByType(SdpMediaSection::MediaType mediatype, JsepSessionImpl::SetupOfferMSectionsByType(SdpMediaSection::MediaType mediatype,
Maybe<size_t> offerToReceiveMaybe, Maybe<size_t> offerToReceiveMaybe,
Sdp* sdp) Sdp* sdp)
{ {
// Convert the Maybe into a size_t*, since that is more readable, especially // Convert the Maybe into a size_t*, since that is more readable, especially
// when using it as an in/out param. // when using it as an in/out param.
@ -467,7 +467,7 @@ JsepSessionImpl::SetRecvAsNeededOrDisable(SdpMediaSection::MediaType mediatype,
if (!msection.IsSending()) { if (!msection.IsSending()) {
// Unused m-section, and no reason to offer to recv on it // Unused m-section, and no reason to offer to recv on it
DisableMsection(sdp, &msection); mSdpHelper.DisableMsection(sdp, &msection);
} }
} }
@ -491,15 +491,15 @@ JsepSessionImpl::AddRecvonlyMsections(SdpMediaSection::MediaType mediatype,
// This function creates a skeleton SDP based on the old descriptions // This function creates a skeleton SDP based on the old descriptions
// (ie; all m-sections are inactive). // (ie; all m-sections are inactive).
nsresult nsresult
JsepSessionImpl::CreateReoffer(const Sdp& oldLocalSdp, JsepSessionImpl::AddReofferMsections(const Sdp& oldLocalSdp,
const Sdp& oldAnswer, const Sdp& oldAnswer,
Sdp* newSdp) Sdp* newSdp)
{ {
nsresult rv; nsresult rv;
for (size_t i = 0; i < oldLocalSdp.GetMediaSectionCount(); ++i) { for (size_t i = 0; i < oldLocalSdp.GetMediaSectionCount(); ++i) {
// We do not set the direction in this function (or disable when previously // We do not set the direction in this function (or disable when previously
// disabled), that happens in |AddOfferMSectionsByType| // disabled), that happens in |SetupOfferMSectionsByType|
rv = CreateOfferMSection(oldLocalSdp.GetMediaSection(i).GetMediaType(), rv = CreateOfferMSection(oldLocalSdp.GetMediaSection(i).GetMediaType(),
SdpDirectionAttribute::kInactive, SdpDirectionAttribute::kInactive,
newSdp); newSdp);
@ -513,8 +513,6 @@ JsepSessionImpl::CreateReoffer(const Sdp& oldLocalSdp,
return NS_OK; return NS_OK;
} }
// TODO(1142105): Do we teach SdpHelper about BundlePolicy, or are
// we getting too much JSEP in there at that point?
void void
JsepSessionImpl::SetupBundle(Sdp* sdp) const JsepSessionImpl::SetupBundle(Sdp* sdp) const
{ {
@ -608,41 +606,42 @@ JsepSessionImpl::CreateOffer(const JsepOfferOptions& options,
return NS_ERROR_UNEXPECTED; return NS_ERROR_UNEXPECTED;
} }
// Undo track assignments from a previous call to CreateOffer
// (ie; if the track has not been negotiated yet, it doesn't necessarily need
// to stay in the same m-section that it was in)
for (auto i = mLocalTracks.begin(); i != mLocalTracks.end(); ++i) {
if (!i->mNegotiated) {
i->mAssignedMLine.reset();
}
}
UniquePtr<Sdp> sdp; UniquePtr<Sdp> sdp;
// Make the basic SDP that is common to offer/answer. // Make the basic SDP that is common to offer/answer.
nsresult rv = CreateGenericSDP(&sdp); nsresult rv = CreateGenericSDP(&sdp);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
++mSessionVersion;
if (mCurrentLocalDescription) { if (mCurrentLocalDescription) {
rv = CreateReoffer(*mCurrentLocalDescription, *GetAnswer(), sdp.get()); rv = AddReofferMsections(*mCurrentLocalDescription,
*GetAnswer(),
sdp.get());
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} }
// Get rid of all m-line assignments that have not been negotiated // Ensure that we have all the m-sections we need, and disable extras
if (NS_SUCCEEDED(rv)) { rv = SetupOfferMSections(options, sdp.get());
for (auto i = mLocalTracks.begin(); i != mLocalTracks.end(); ++i) {
if (!i->mNegotiated) {
i->mAssignedMLine.reset();
}
}
}
// Now add all the m-lines that we are attempting to negotiate.
rv = AddOfferMSections(options, sdp.get());
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
SetupBundle(sdp.get()); SetupBundle(sdp.get());
if (GetAnswer()) { if (mCurrentLocalDescription) {
// We have an old answer from a previous negotiation rv = CopyPreviousTransportParams(*GetAnswer(), *sdp, sdp.get());
rv = SetupTransportParams(*GetAnswer(), *sdp, sdp.get());
NS_ENSURE_SUCCESS(rv,rv); NS_ENSURE_SUCCESS(rv,rv);
} }
*offer = sdp->ToString(); *offer = sdp->ToString();
mGeneratedLocalDescription = Move(sdp); mGeneratedLocalDescription = Move(sdp);
++mSessionVersion;
return NS_OK; return NS_OK;
} }
@ -774,36 +773,10 @@ void
JsepSessionImpl::AddCommonExtmaps(const SdpMediaSection& remoteMsection, JsepSessionImpl::AddCommonExtmaps(const SdpMediaSection& remoteMsection,
SdpMediaSection* msection) SdpMediaSection* msection)
{ {
if (!remoteMsection.GetAttributeList().HasAttribute(
SdpAttribute::kExtmapAttribute)) {
return;
}
auto* ourExtensions = GetRtpExtensions(remoteMsection.GetMediaType()); auto* ourExtensions = GetRtpExtensions(remoteMsection.GetMediaType());
if (!ourExtensions) { if (ourExtensions) {
return; mSdpHelper.AddCommonExtmaps(remoteMsection, *ourExtensions, msection);
}
UniquePtr<SdpExtmapAttributeList> ourExtmap(new SdpExtmapAttributeList);
auto& theirExtmap = remoteMsection.GetAttributeList().GetExtmap().mExtmaps;
for (auto i = theirExtmap.begin(); i != theirExtmap.end(); ++i) {
for (auto j = ourExtensions->begin(); j != ourExtensions->end(); ++j) {
if (i->extensionname == j->extensionname) {
ourExtmap->mExtmaps.push_back(*i);
// RFC 5285 says that ids >= 4096 can be used by the offerer to
// force the answerer to pick, otherwise the value in the offer is
// used.
if (ourExtmap->mExtmaps.back().entry >= 4096) {
ourExtmap->mExtmaps.back().entry = j->entry;
}
}
}
}
if (!ourExtmap->mExtmaps.empty()) {
msection->GetAttributeList().SetAttribute(ourExtmap.release());
} }
} }
@ -836,8 +809,6 @@ JsepSessionImpl::CreateAnswer(const JsepAnswerOptions& options,
const Sdp& offer = *mPendingRemoteDescription; const Sdp& offer = *mPendingRemoteDescription;
std::vector<SdpGroupAttributeList::Group> bundleGroups;
// Copy the bundle groups into our answer // Copy the bundle groups into our answer
UniquePtr<SdpGroupAttributeList> groupAttr(new SdpGroupAttributeList); UniquePtr<SdpGroupAttributeList> groupAttr(new SdpGroupAttributeList);
mSdpHelper.GetBundleGroups(offer, &groupAttr->mGroups); mSdpHelper.GetBundleGroups(offer, &groupAttr->mGroups);
@ -869,9 +840,8 @@ JsepSessionImpl::CreateAnswer(const JsepAnswerOptions& options,
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} }
if (GetAnswer()) { if (mCurrentLocalDescription) {
// We have an old answer from a previous negotiation rv = CopyPreviousTransportParams(*GetAnswer(), *sdp, sdp.get());
rv = SetupTransportParams(*GetAnswer(), *sdp, sdp.get());
NS_ENSURE_SUCCESS(rv,rv); NS_ENSURE_SUCCESS(rv,rv);
} }
@ -953,7 +923,7 @@ JsepSessionImpl::CreateAnswerMSection(const JsepAnswerOptions& options,
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (mSdpHelper.MsectionIsDisabled(remoteMsection)) { if (mSdpHelper.MsectionIsDisabled(remoteMsection)) {
DisableMsection(sdp, &msection); mSdpHelper.DisableMsection(sdp, &msection);
return NS_OK; return NS_OK;
} }
@ -995,13 +965,13 @@ JsepSessionImpl::CreateAnswerMSection(const JsepAnswerOptions& options,
AddCommonExtmaps(remoteMsection, &msection); AddCommonExtmaps(remoteMsection, &msection);
if (!msection.IsReceiving() && !msection.IsSending()) { if (!msection.IsReceiving() && !msection.IsSending()) {
DisableMsection(sdp, &msection); mSdpHelper.DisableMsection(sdp, &msection);
return NS_OK; return NS_OK;
} }
if (msection.GetFormats().empty()) { if (msection.GetFormats().empty()) {
// Could not negotiate anything. Disable m-section. // Could not negotiate anything. Disable m-section.
DisableMsection(sdp, &msection); mSdpHelper.DisableMsection(sdp, &msection);
} }
return NS_OK; return NS_OK;
@ -1158,7 +1128,7 @@ JsepSessionImpl::SetLocalDescription(JsepSdpType type, const std::string& sdp)
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// Create transport objects. // Create transport objects.
mOldTransports = mTransports; mOldTransports = mTransports; // Save in case we need to rollback
for (size_t t = 0; t < parsed->GetMediaSectionCount(); ++t) { for (size_t t = 0; t < parsed->GetMediaSectionCount(); ++t) {
if (t >= mTransports.size()) { if (t >= mTransports.size()) {
mTransports.push_back(RefPtr<JsepTransport>(new JsepTransport)); mTransports.push_back(RefPtr<JsepTransport>(new JsepTransport));
@ -1385,11 +1355,9 @@ JsepSessionImpl::HandleNegotiatedSession(const UniquePtr<Sdp>& local,
mNegotiatedTrackPairs = trackPairs; mNegotiatedTrackPairs = trackPairs;
// Mark all assigned local tracks as negotiated // Mark all assigned local tracks as negotiated
if (NS_SUCCEEDED(rv)) { for (auto i = mLocalTracks.begin(); i != mLocalTracks.end(); ++i) {
for (auto i = mLocalTracks.begin(); i != mLocalTracks.end(); ++i) { if (i->mAssignedMLine.isSome()) {
if (i->mAssignedMLine.isSome()) { i->mNegotiated = true;
i->mNegotiated = true;
}
} }
} }
@ -1679,9 +1647,9 @@ JsepSessionImpl::AddTransportAttributes(SdpMediaSection* msection,
} }
nsresult nsresult
JsepSessionImpl::SetupTransportParams(const Sdp& oldAnswer, JsepSessionImpl::CopyPreviousTransportParams(const Sdp& oldAnswer,
const Sdp& newOffer, const Sdp& newOffer,
Sdp* newLocal) Sdp* newLocal)
{ {
for (size_t i = 0; i < oldAnswer.GetMediaSectionCount(); ++i) { for (size_t i = 0; i < oldAnswer.GetMediaSectionCount(); ++i) {
if (!mSdpHelper.MsectionIsDisabled(newLocal->GetMediaSection(i)) && if (!mSdpHelper.MsectionIsDisabled(newLocal->GetMediaSection(i)) &&
@ -2368,14 +2336,6 @@ JsepSessionImpl::EndOfLocalCandidates(const std::string& defaultCandidateAddr,
return NS_OK; return NS_OK;
} }
SdpHelper::BundledMids bundledMids;
nsresult rv = GetNegotiatedBundledMids(&bundledMids);
if (NS_FAILED(rv)) {
MOZ_ASSERT(false);
mLastError += " (This should have been caught sooner!)";
return NS_ERROR_FAILURE;
}
std::string defaultRtcpCandidateAddrCopy(defaultRtcpCandidateAddr); std::string defaultRtcpCandidateAddrCopy(defaultRtcpCandidateAddr);
if (mState == kJsepStateStable && mTransports[level]->mComponents == 1) { if (mState == kJsepStateStable && mTransports[level]->mComponents == 1) {
// We know we're doing rtcp-mux by now. Don't create an rtcp attr. // We know we're doing rtcp-mux by now. Don't create an rtcp attr.
@ -2383,56 +2343,26 @@ JsepSessionImpl::EndOfLocalCandidates(const std::string& defaultCandidateAddr,
defaultRtcpCandidatePort = 0; defaultRtcpCandidatePort = 0;
} }
SdpMediaSection& msection = sdp->GetMediaSection(level); // If offer/answer isn't done, it is too early to tell whether these defaults
// need to be applied to other m-sections.
// TODO(bug 1142105): Factor some of this out into a helper class SdpHelper::BundledMids bundledMids;
if (mState == kJsepStateStable) { if (mState == kJsepStateStable) {
// offer/answer is done. Do we actually incorporate these defaults? nsresult rv = GetNegotiatedBundledMids(&bundledMids);
if (msection.GetAttributeList().HasAttribute(SdpAttribute::kMidAttribute)) { if (NS_FAILED(rv)) {
std::string mid(msection.GetAttributeList().GetMid()); MOZ_ASSERT(false);
if (bundledMids.count(mid)) { mLastError += " (This should have been caught sooner!)";
const SdpMediaSection* masterBundleMsection(bundledMids[mid]); return NS_ERROR_FAILURE;
if (msection.GetLevel() != masterBundleMsection->GetLevel()) {
// Slave bundle m-section. Skip.
return NS_OK;
}
// Master bundle m-section. Set defaultCandidateAddr and
// defaultCandidatePort on all bundled m-sections.
for (auto i = bundledMids.begin(); i != bundledMids.end(); ++i) {
if (i->second != masterBundleMsection) {
continue;
}
SdpMediaSection* bundledMsection =
mSdpHelper.FindMsectionByMid(*sdp, i->first);
if (!bundledMsection) {
MOZ_ASSERT(false);
continue;
}
mSdpHelper.SetDefaultAddresses(defaultCandidateAddr,
defaultCandidatePort,
defaultRtcpCandidateAddrCopy,
defaultRtcpCandidatePort,
bundledMsection);
}
}
} }
} }
mSdpHelper.SetDefaultAddresses(defaultCandidateAddr, mSdpHelper.SetDefaultAddresses(
defaultCandidatePort, defaultCandidateAddr,
defaultRtcpCandidateAddrCopy, defaultCandidatePort,
defaultRtcpCandidatePort, defaultRtcpCandidateAddrCopy,
&msection); defaultRtcpCandidatePort,
sdp,
// TODO(bug 1095793): Will this have an mid someday? level,
bundledMids);
SdpAttributeList& attrs = msection.GetAttributeList();
attrs.SetAttribute(
new SdpFlagAttribute(SdpAttribute::kEndOfCandidatesAttribute));
if (!mIsOfferer) {
attrs.RemoveAttribute(SdpAttribute::kIceOptionsAttribute);
}
return NS_OK; return NS_OK;
} }
@ -2449,19 +2379,6 @@ JsepSessionImpl::GetNegotiatedBundledMids(SdpHelper::BundledMids* bundledMids)
return mSdpHelper.GetBundledMids(*answerSdp, bundledMids); return mSdpHelper.GetBundledMids(*answerSdp, bundledMids);
} }
void
JsepSessionImpl::DisableMsection(Sdp* sdp, SdpMediaSection* msection) const
{
mSdpHelper.DisableMsection(sdp, msection);
msection->ClearCodecs();
// We need to have something here to fit the grammar
// TODO(bcampen@mozilla.com): What's the accepted way of doing this? Just
// add the codecs we do support? Does it matter? Most endpoints just pick
// something that the other end supported.
msection->AddCodec("111", "NULL", 0, 0);
}
nsresult nsresult
JsepSessionImpl::EnableOfferMsection(SdpMediaSection* msection) JsepSessionImpl::EnableOfferMsection(SdpMediaSection* msection)
{ {

Просмотреть файл

@ -217,14 +217,14 @@ private:
const UniquePtr<Sdp>& remote); const UniquePtr<Sdp>& remote);
nsresult AddTransportAttributes(SdpMediaSection* msection, nsresult AddTransportAttributes(SdpMediaSection* msection,
SdpSetupAttribute::Role dtlsRole); SdpSetupAttribute::Role dtlsRole);
nsresult SetupTransportParams(const Sdp& oldAnswer, nsresult CopyPreviousTransportParams(const Sdp& oldAnswer,
const Sdp& newOffer, const Sdp& newOffer,
Sdp* newLocal); Sdp* newLocal);
nsresult AddOfferMSections(const JsepOfferOptions& options, Sdp* sdp); nsresult SetupOfferMSections(const JsepOfferOptions& options, Sdp* sdp);
// Non-const so it can assign m-line index to tracks // Non-const so it can assign m-line index to tracks
nsresult AddOfferMSectionsByType(SdpMediaSection::MediaType type, nsresult SetupOfferMSectionsByType(SdpMediaSection::MediaType type,
Maybe<size_t> offerToReceive, Maybe<size_t> offerToReceive,
Sdp* sdp); Sdp* sdp);
nsresult BindLocalTracks(SdpMediaSection::MediaType mediatype, nsresult BindLocalTracks(SdpMediaSection::MediaType mediatype,
Sdp* sdp); Sdp* sdp);
nsresult BindTrackToMsection(JsepSendingTrack* track, nsresult BindTrackToMsection(JsepSendingTrack* track,
@ -238,9 +238,9 @@ private:
nsresult AddRecvonlyMsections(SdpMediaSection::MediaType mediatype, nsresult AddRecvonlyMsections(SdpMediaSection::MediaType mediatype,
size_t count, size_t count,
Sdp* sdp); Sdp* sdp);
nsresult CreateReoffer(const Sdp& oldLocalSdp, nsresult AddReofferMsections(const Sdp& oldLocalSdp,
const Sdp& oldAnswer, const Sdp& oldAnswer,
Sdp* newSdp); Sdp* newSdp);
void SetupBundle(Sdp* sdp) const; void SetupBundle(Sdp* sdp) const;
nsresult GetRemoteIds(const Sdp& sdp, nsresult GetRemoteIds(const Sdp& sdp,
const SdpMediaSection& msection, const SdpMediaSection& msection,
@ -280,7 +280,6 @@ private:
nsresult GetNegotiatedBundledMids(SdpHelper::BundledMids* bundledMids); nsresult GetNegotiatedBundledMids(SdpHelper::BundledMids* bundledMids);
void DisableMsection(Sdp* sdp, SdpMediaSection* msection) const;
nsresult EnableOfferMsection(SdpMediaSection* msection); nsresult EnableOfferMsection(SdpMediaSection* msection);
nsresult SetUniquePayloadTypes(); nsresult SetUniquePayloadTypes();

Просмотреть файл

@ -138,6 +138,11 @@ SdpHelper::DisableMsection(Sdp* sdp, SdpMediaSection* msection) const
new SdpDirectionAttribute(SdpDirectionAttribute::kInactive); new SdpDirectionAttribute(SdpDirectionAttribute::kInactive);
msection->GetAttributeList().SetAttribute(direction); msection->GetAttributeList().SetAttribute(direction);
msection->SetPort(0); msection->SetPort(0);
msection->ClearCodecs();
// We need to have something here to fit the grammar, this seems safe.
msection->AddCodec("0", "PCMU", 8000, 1);
} }
void void
@ -266,6 +271,61 @@ SdpHelper::AddCandidateToSdp(Sdp* sdp,
return NS_OK; return NS_OK;
} }
void
SdpHelper::SetDefaultAddresses(const std::string& defaultCandidateAddr,
uint16_t defaultCandidatePort,
const std::string& defaultRtcpCandidateAddr,
uint16_t defaultRtcpCandidatePort,
Sdp* sdp,
uint16_t level,
BundledMids bundledMids)
{
SdpMediaSection& msection = sdp->GetMediaSection(level);
if (msection.GetAttributeList().HasAttribute(SdpAttribute::kMidAttribute)) {
std::string mid(msection.GetAttributeList().GetMid());
if (bundledMids.count(mid)) {
const SdpMediaSection* masterBundleMsection(bundledMids[mid]);
if (msection.GetLevel() != masterBundleMsection->GetLevel()) {
// Slave bundle m-section. Skip.
return;
}
// Master bundle m-section. Set defaultCandidateAddr and
// defaultCandidatePort on all bundled m-sections.
for (auto i = bundledMids.begin(); i != bundledMids.end(); ++i) {
if (i->second != masterBundleMsection) {
continue;
}
SdpMediaSection* bundledMsection = FindMsectionByMid(*sdp, i->first);
if (!bundledMsection) {
MOZ_ASSERT(false);
continue;
}
SetDefaultAddresses(defaultCandidateAddr,
defaultCandidatePort,
defaultRtcpCandidateAddr,
defaultRtcpCandidatePort,
bundledMsection);
}
}
}
SetDefaultAddresses(defaultCandidateAddr,
defaultCandidatePort,
defaultRtcpCandidateAddr,
defaultRtcpCandidatePort,
&msection);
// TODO(bug 1095793): Will this have an mid someday?
SdpAttributeList& attrs = msection.GetAttributeList();
attrs.SetAttribute(
new SdpFlagAttribute(SdpAttribute::kEndOfCandidatesAttribute));
// Remove trickle-ice option
attrs.RemoveAttribute(SdpAttribute::kIceOptionsAttribute);
}
void void
SdpHelper::SetDefaultAddresses(const std::string& defaultCandidateAddr, SdpHelper::SetDefaultAddresses(const std::string& defaultCandidateAddr,
uint16_t defaultCandidatePort, uint16_t defaultCandidatePort,
@ -604,6 +664,39 @@ SdpHelper::GetPtAsInt(const std::string& ptString, uint16_t* ptOutparam)
return true; return true;
} }
void
SdpHelper::AddCommonExtmaps(
const SdpMediaSection& remoteMsection,
const std::vector<SdpExtmapAttributeList::Extmap>& localExtensions,
SdpMediaSection* localMsection)
{
if (!remoteMsection.GetAttributeList().HasAttribute(
SdpAttribute::kExtmapAttribute)) {
return;
}
UniquePtr<SdpExtmapAttributeList> localExtmap(new SdpExtmapAttributeList);
auto& theirExtmap = remoteMsection.GetAttributeList().GetExtmap().mExtmaps;
for (auto i = theirExtmap.begin(); i != theirExtmap.end(); ++i) {
for (auto j = localExtensions.begin(); j != localExtensions.end(); ++j) {
if (i->extensionname == j->extensionname) {
localExtmap->mExtmaps.push_back(*i);
// RFC 5285 says that ids >= 4096 can be used by the offerer to
// force the answerer to pick, otherwise the value in the offer is
// used.
if (localExtmap->mExtmaps.back().entry >= 4096) {
localExtmap->mExtmaps.back().entry = j->entry;
}
}
}
}
if (!localExtmap->mExtmaps.empty()) {
localMsection->GetAttributeList().SetAttribute(localExtmap.release());
}
}
} // namespace mozilla } // namespace mozilla

Просмотреть файл

@ -62,6 +62,13 @@ class SdpHelper {
const std::string& candidate, const std::string& candidate,
const std::string& mid, const std::string& mid,
uint16_t level); uint16_t level);
void SetDefaultAddresses(const std::string& defaultCandidateAddr,
uint16_t defaultCandidatePort,
const std::string& defaultRtcpCandidateAddr,
uint16_t defaultRtcpCandidatePort,
Sdp* sdp,
uint16_t level,
BundledMids bundledMids);
void SetDefaultAddresses(const std::string& defaultCandidateAddr, void SetDefaultAddresses(const std::string& defaultCandidateAddr,
uint16_t defaultCandidatePort, uint16_t defaultCandidatePort,
const std::string& defaultRtcpCandidateAddr, const std::string& defaultRtcpCandidateAddr,
@ -92,6 +99,11 @@ class SdpHelper {
static bool GetPtAsInt(const std::string& ptString, uint16_t* ptOutparam); static bool GetPtAsInt(const std::string& ptString, uint16_t* ptOutparam);
void AddCommonExtmaps(
const SdpMediaSection& remoteMsection,
const std::vector<SdpExtmapAttributeList::Extmap>& localExtensions,
SdpMediaSection* localMsection);
private: private:
std::string& mLastError; std::string& mLastError;

Просмотреть файл

@ -798,20 +798,6 @@ SpdySession31::GenerateSettings()
numberOfEntries++; numberOfEntries++;
} }
nsRefPtr<nsHttpConnectionInfo> ci;
uint32_t cwnd = 0;
GetConnectionInfo(getter_AddRefs(ci));
if (ci)
cwnd = gHttpHandler->ConnMgr()->GetSpdyCWNDSetting(ci);
if (cwnd) {
packet[12 + 8 * numberOfEntries] = PERSISTED_VALUE;
packet[15 + 8 * numberOfEntries] = SETTINGS_TYPE_CWND;
LOG(("SpdySession31::GenerateSettings %p sending CWND %u\n", this, cwnd));
cwnd = PR_htonl(cwnd);
memcpy(packet + 16 + 8 * numberOfEntries, &cwnd, 4);
numberOfEntries++;
}
// Advertise the Push RWIN and on each client SYN_STREAM pipeline // Advertise the Push RWIN and on each client SYN_STREAM pipeline
// a window update with it in order to use larger initial windows with pulled // a window update with it in order to use larger initial windows with pulled
// streams. // streams.
@ -1445,41 +1431,12 @@ SpdySession31::HandleSettings(SpdySession31 *self)
switch (id) switch (id)
{ {
case SETTINGS_TYPE_UPLOAD_BW:
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_UL_BW, value);
break;
case SETTINGS_TYPE_DOWNLOAD_BW:
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_DL_BW, value);
break;
case SETTINGS_TYPE_RTT:
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_RTT, value);
break;
case SETTINGS_TYPE_MAX_CONCURRENT: case SETTINGS_TYPE_MAX_CONCURRENT:
self->mMaxConcurrent = value; self->mMaxConcurrent = value;
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_MAX_STREAMS, value);
self->ProcessPending(); self->ProcessPending();
break; break;
case SETTINGS_TYPE_CWND:
if (flags & PERSIST_VALUE)
{
nsRefPtr<nsHttpConnectionInfo> ci;
self->GetConnectionInfo(getter_AddRefs(ci));
if (ci)
gHttpHandler->ConnMgr()->ReportSpdyCWNDSetting(ci, value);
}
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_CWND, value);
break;
case SETTINGS_TYPE_DOWNLOAD_RETRANS_RATE:
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_RETRANS, value);
break;
case SETTINGS_TYPE_INITIAL_WINDOW: case SETTINGS_TYPE_INITIAL_WINDOW:
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_IW, value >> 10);
{ {
int32_t delta = value - self->mServerInitialStreamWindow; int32_t delta = value - self->mServerInitialStreamWindow;
self->mServerInitialStreamWindow = value; self->mServerInitialStreamWindow = value;

Просмотреть файл

@ -25,6 +25,7 @@ HTTP_ATOM(Age, "Age")
HTTP_ATOM(Allow, "Allow") HTTP_ATOM(Allow, "Allow")
HTTP_ATOM(Alternate_Service, "Alt-Svc") HTTP_ATOM(Alternate_Service, "Alt-Svc")
HTTP_ATOM(Alternate_Service_Used, "Alt-Used") HTTP_ATOM(Alternate_Service_Used, "Alt-Used")
HTTP_ATOM(Alternate_Protocol, "Alternate-Protocol")
HTTP_ATOM(Assoc_Req, "Assoc-Req") HTTP_ATOM(Assoc_Req, "Assoc-Req")
HTTP_ATOM(Authentication, "Authentication") HTTP_ATOM(Authentication, "Authentication")
HTTP_ATOM(Authorization, "Authorization") HTTP_ATOM(Authorization, "Authorization")

Просмотреть файл

@ -1397,13 +1397,21 @@ nsHttpChannel::ProcessResponse()
nsresult rv; nsresult rv;
uint32_t httpStatus = mResponseHead->Status(); uint32_t httpStatus = mResponseHead->Status();
// Gather data on whether the transaction and page (if this is // do some telemetry
// the initial page load) is being loaded with SSL. if (gHttpHandler->IsTelemetryEnabled()) {
Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_IS_SSL, // Gather data on whether the transaction and page (if this is
mConnectionInfo->EndToEndSSL()); // the initial page load) is being loaded with SSL.
if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI) { Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_IS_SSL,
Telemetry::Accumulate(Telemetry::HTTP_PAGELOAD_IS_SSL,
mConnectionInfo->EndToEndSSL()); mConnectionInfo->EndToEndSSL());
if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI) {
Telemetry::Accumulate(Telemetry::HTTP_PAGELOAD_IS_SSL,
mConnectionInfo->EndToEndSSL());
}
// how often do we see something like Alternate-Protocol: "443:quic,p=1"
const char *alt_protocol = mResponseHead->PeekHeader(nsHttp::Alternate_Protocol);
bool saw_quic = (alt_protocol && PL_strstr(alt_protocol, "quic")) ? 1 : 0;
Telemetry::Accumulate(Telemetry::HTTP_SAW_QUIC_ALT_PROTOCOL, saw_quic);
} }
LOG(("nsHttpChannel::ProcessResponse [this=%p httpStatus=%u]\n", LOG(("nsHttpChannel::ProcessResponse [this=%p httpStatus=%u]\n",

Просмотреть файл

@ -747,67 +747,6 @@ nsHttpConnectionMgr::ReportSpdyConnection(nsHttpConnection *conn,
PostEvent(&nsHttpConnectionMgr::OnMsgProcessAllSpdyPendingQ); PostEvent(&nsHttpConnectionMgr::OnMsgProcessAllSpdyPendingQ);
} }
void
nsHttpConnectionMgr::ReportSpdyCWNDSetting(nsHttpConnectionInfo *ci,
uint32_t cwndValue)
{
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
if (!gHttpHandler->UseSpdyPersistentSettings())
return;
if (!ci)
return;
nsConnectionEntry *ent = mCT.Get(ci->HashKey());
if (!ent)
return;
ent = GetSpdyPreferredEnt(ent);
if (!ent) // just to be thorough - but that map should always exist
return;
cwndValue = std::max(2U, cwndValue);
cwndValue = std::min(128U, cwndValue);
ent->mSpdyCWND = cwndValue;
ent->mSpdyCWNDTimeStamp = TimeStamp::Now();
return;
}
// a value of 0 means no setting is available
uint32_t
nsHttpConnectionMgr::GetSpdyCWNDSetting(nsHttpConnectionInfo *ci)
{
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
if (!gHttpHandler->UseSpdyPersistentSettings())
return 0;
if (!ci)
return 0;
nsConnectionEntry *ent = mCT.Get(ci->HashKey());
if (!ent)
return 0;
ent = GetSpdyPreferredEnt(ent);
if (!ent) // just to be thorough - but that map should always exist
return 0;
if (ent->mSpdyCWNDTimeStamp.IsNull())
return 0;
// For privacy tracking reasons, and the fact that CWND is not
// meaningful after some time, we don't honor stored CWND after 8
// hours.
TimeDuration age = TimeStamp::Now() - ent->mSpdyCWNDTimeStamp;
if (age.ToMilliseconds() > (1000 * 60 * 60 * 8))
return 0;
return ent->mSpdyCWND;
}
nsHttpConnectionMgr::nsConnectionEntry * nsHttpConnectionMgr::nsConnectionEntry *
nsHttpConnectionMgr::GetSpdyPreferredEnt(nsConnectionEntry *aOriginalEntry) nsHttpConnectionMgr::GetSpdyPreferredEnt(nsConnectionEntry *aOriginalEntry)
{ {
@ -3669,7 +3608,6 @@ nsConnectionEntry::nsConnectionEntry(nsHttpConnectionInfo *ci)
, mYellowConnection(nullptr) , mYellowConnection(nullptr)
, mGreenDepth(kPipelineOpen) , mGreenDepth(kPipelineOpen)
, mPipeliningPenalty(0) , mPipeliningPenalty(0)
, mSpdyCWND(0)
, mUsingSpdy(false) , mUsingSpdy(false)
, mTestedSpdy(false) , mTestedSpdy(false)
, mInPreferredHash(false) , mInPreferredHash(false)

Просмотреть файл

@ -242,11 +242,6 @@ public:
// bit different. // bit different.
void ReportSpdyConnection(nsHttpConnection *, bool usingSpdy); void ReportSpdyConnection(nsHttpConnection *, bool usingSpdy);
// A spdy server can supply cwnd information for the session that is used
// in future sessions to speed up the opening portions of the connection.
void ReportSpdyCWNDSetting(nsHttpConnectionInfo *host, uint32_t cwndValue);
uint32_t GetSpdyCWNDSetting(nsHttpConnectionInfo *host);
bool SupportsPipelining(nsHttpConnectionInfo *); bool SupportsPipelining(nsHttpConnectionInfo *);
bool GetConnectionData(nsTArray<HttpRetParams> *); bool GetConnectionData(nsTArray<HttpRetParams> *);
@ -366,11 +361,6 @@ private:
// //
nsTArray<nsCString> mCoalescingKeys; nsTArray<nsCString> mCoalescingKeys;
// The value of a recevied SPDY settings type 5 previously received
// for this connection entry and the time it was set.
uint32_t mSpdyCWND;
TimeStamp mSpdyCWNDTimeStamp;
// To have the UsingSpdy flag means some host with the same connection // To have the UsingSpdy flag means some host with the same connection
// entry has done NPN=spdy/* at some point. It does not mean every // entry has done NPN=spdy/* at some point. It does not mean every
// connection is currently using spdy. // connection is currently using spdy.

Просмотреть файл

@ -6,6 +6,15 @@ provides version information such as the application name and the changesets
that it has been built from. This is commonly used in reporting or for that it has been built from. This is commonly used in reporting or for
conditional logic based on the application under test. conditional logic based on the application under test.
Note that mozversion can report the version of remote devices (e.g. Firefox OS)
but it requires the :mod:`mozdevice` dependency in that case. You can require it
along with mozversion by using the extra *device* dependency:
.. code-block:: bash
pip install mozversion[device]
API Usage API Usage
--------- ---------

Просмотреть файл

@ -12,7 +12,6 @@ import tempfile
import xml.dom.minidom import xml.dom.minidom
import zipfile import zipfile
import mozdevice
import mozfile import mozfile
import mozlog import mozlog
@ -189,6 +188,13 @@ class RemoteB2GVersion(B2GVersion):
**kwargs): **kwargs):
B2GVersion.__init__(self, sources, **kwargs) B2GVersion.__init__(self, sources, **kwargs)
try:
import mozdevice
except ImportError:
self._logger.critical("mozdevice is required to get the version"
" of a remote device")
raise
if dm_type == 'adb': if dm_type == 'adb':
dm = mozdevice.DeviceManagerADB(deviceSerial=device_serial, dm = mozdevice.DeviceManagerADB(deviceSerial=device_serial,
serverHost=adb_host, serverHost=adb_host,

Просмотреть файл

@ -6,9 +6,6 @@ from setuptools import setup
PACKAGE_VERSION = '1.3' PACKAGE_VERSION = '1.3'
dependencies = ['mozdevice >= 0.44',
'mozfile >= 1.0',
'mozlog >= 3.0']
setup(name='mozversion', setup(name='mozversion',
version=PACKAGE_VERSION, version=PACKAGE_VERSION,
@ -23,7 +20,8 @@ setup(name='mozversion',
packages=['mozversion'], packages=['mozversion'],
include_package_data=True, include_package_data=True,
zip_safe=False, zip_safe=False,
install_requires=dependencies, install_requires=['mozfile >= 1.0', 'mozlog >= 3.0'],
extras_require={'device': ['mozdevice >= 0.44']},
entry_points=""" entry_points="""
# -*- Entry points: -*- # -*- Entry points: -*-
[console_scripts] [console_scripts]

Просмотреть файл

@ -1456,7 +1456,7 @@
"description": "SPDY: KB read per connection" "description": "SPDY: KB read per connection"
}, },
"SPDY_SETTINGS_UL_BW": { "SPDY_SETTINGS_UL_BW": {
"expires_in_version": "never", "expires_in_version": "42",
"kind": "exponential", "kind": "exponential",
"high": "10000", "high": "10000",
"n_buckets": 100, "n_buckets": 100,
@ -1464,7 +1464,7 @@
"description": "SPDY: Settings Upload Bandwidth" "description": "SPDY: Settings Upload Bandwidth"
}, },
"SPDY_SETTINGS_DL_BW": { "SPDY_SETTINGS_DL_BW": {
"expires_in_version": "never", "expires_in_version": "42",
"kind": "exponential", "kind": "exponential",
"high": "10000", "high": "10000",
"n_buckets": 100, "n_buckets": 100,
@ -1472,7 +1472,7 @@
"description": "SPDY: Settings Download Bandwidth" "description": "SPDY: Settings Download Bandwidth"
}, },
"SPDY_SETTINGS_RTT": { "SPDY_SETTINGS_RTT": {
"expires_in_version": "never", "expires_in_version": "42",
"kind": "exponential", "kind": "exponential",
"high": "1000", "high": "1000",
"n_buckets": 100, "n_buckets": 100,
@ -1485,10 +1485,10 @@
"high": "5000", "high": "5000",
"n_buckets": 100, "n_buckets": 100,
"extended_statistics_ok": true, "extended_statistics_ok": true,
"description": "SPDY: Settings Max Streams parameter" "description": "H2: Settings Max Streams parameter"
}, },
"SPDY_SETTINGS_CWND": { "SPDY_SETTINGS_CWND": {
"expires_in_version": "never", "expires_in_version": "42",
"kind": "exponential", "kind": "exponential",
"high": "500", "high": "500",
"n_buckets": 50, "n_buckets": 50,
@ -1496,7 +1496,7 @@
"description": "SPDY: Settings CWND (packets)" "description": "SPDY: Settings CWND (packets)"
}, },
"SPDY_SETTINGS_RETRANS": { "SPDY_SETTINGS_RETRANS": {
"expires_in_version": "never", "expires_in_version": "42",
"kind": "exponential", "kind": "exponential",
"high": "100", "high": "100",
"n_buckets": 50, "n_buckets": 50,
@ -1509,7 +1509,7 @@
"high": "1000", "high": "1000",
"n_buckets": 50, "n_buckets": 50,
"extended_statistics_ok": true, "extended_statistics_ok": true,
"description": "SPDY: Settings IW (rounded to KB)" "description": "H2: Settings Initial Window (rounded to KB)"
}, },
"DISK_CACHE_CORRUPT_DETAILS": { "DISK_CACHE_CORRUPT_DETAILS": {
"expires_in_version": "40", "expires_in_version": "40",
@ -1657,7 +1657,12 @@
"extended_statistics_ok": true, "extended_statistics_ok": true,
"description": "Time from submission to dispatch of SPDY transaction (ms)" "description": "Time from submission to dispatch of SPDY transaction (ms)"
}, },
"HTTP_DISK_CACHE_OVERHEAD": { "HTTP_SAW_QUIC_ALT_PROTOCOL": {
"expires_in_version": "never",
"kind": "boolean",
"description": "Fraction of responses with a quic alt-protocol advertisement."
},
"HTTP_DISK_CACHE_OVERHEAD": {
"expires_in_version": "default", "expires_in_version": "default",
"kind": "exponential", "kind": "exponential",
"high": "32000000", "high": "32000000",

Просмотреть файл

@ -1063,7 +1063,7 @@ let Histogram = {
if (aHgram.values.length) { if (aHgram.values.length) {
labelPadTo = String(aHgram.values[aHgram.values.length - 1][0]).length; labelPadTo = String(aHgram.values[aHgram.values.length - 1][0]).length;
} }
let maxBarValue = aOptions.exponential ? this.getLogValue(aHgram.max_value) : aHgram.max; let maxBarValue = aOptions.exponential ? this.getLogValue(aHgram.max) : aHgram.max;
for (let [label, value] of aHgram.values) { for (let [label, value] of aHgram.values) {
let barValue = aOptions.exponential ? this.getLogValue(value) : value; let barValue = aOptions.exponential ? this.getLogValue(value) : value;

Просмотреть файл

@ -436,11 +436,29 @@ protected:
bool Update(const IMENotification& aIMENotification); bool Update(const IMENotification& aIMENotification);
bool Init(nsWindow* aWindow); bool Init(nsWindow* aWindow);
bool EnsureValidSelection(nsWindow* aWindow); bool EnsureValidSelection(nsWindow* aWindow);
private:
Selection(const Selection& aOther) = delete;
void operator =(const Selection& aOther) = delete;
}; };
// mSelection stores the latest selection data only when sHasFocus is true.
// Don't access mSelection directly. You should use GetSelection() for
// getting proper state.
Selection mSelection; Selection mSelection;
// mSelection stores the latest selection data only when sHasFocus it true.
// Therefore, if sHasFocus is false, temporary instance should be used. Selection& GetSelection()
Selection GetSelection() { return sHasFocus ? mSelection : Selection(); } {
// When IME has focus, mSelection is automatically updated by
// NOTIFY_IME_OF_SELECTION_CHANGE.
if (sHasFocus) {
return mSelection;
}
// Otherwise, i.e., While IME doesn't have focus, we cannot observe
// selection changes. So, in such case, we need to query selection
// when it's necessary.
static Selection sTempSelection;
sTempSelection.Clear();
return sTempSelection;
}
bool mIsComposing; bool mIsComposing;
bool mIsComposingOnPlugin; bool mIsComposingOnPlugin;