зеркало из https://github.com/mozilla/gecko-dev.git
Коммит
ba1fcc1f0a
|
@ -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(×tampHns);
|
hr = sample->GetSampleTime(×tampHns);
|
||||||
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(¤t, ((_t*)*s)+i, type, iid, pErr) || \
|
if (!NativeData2JS(¤t, ((_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;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче