зеркало из https://github.com/mozilla/gecko-dev.git
Коммит
ba1fcc1f0a
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</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="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</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="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="67c38af8347f93ddc005a53f427d651b744b55c1"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c5425d9f1f5184731a59ed4bc99295acbde30390"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8bc59310552179f9a8bc6cdd0188e2475df52fb7"/>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<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="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ddfd98cdafefaa1b60273d5568b8dbd13730dae"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</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="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="07c383a786f188904311a37f6062c2cb84c9b61d">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</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="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="67c38af8347f93ddc005a53f427d651b744b55c1"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c5425d9f1f5184731a59ed4bc99295acbde30390"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<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">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</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="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"git": {
|
||||
"git_revision": "67c38af8347f93ddc005a53f427d651b744b55c1",
|
||||
"git_revision": "c5425d9f1f5184731a59ed4bc99295acbde30390",
|
||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "72807eee01421a4ddf6180b2e5a66757a42a7984",
|
||||
"revision": "68ce99a4e1761c06e5f31f6674ee46fef1bbf44b",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<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="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ddfd98cdafefaa1b60273d5568b8dbd13730dae"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="07c383a786f188904311a37f6062c2cb84c9b61d">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</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="gonk-misc" path="gonk-misc" remote="b2g" revision="4d9fbc08e87731447c19e96e13d8c7444baafcca"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -7,11 +7,10 @@
|
|||
"unpack": true
|
||||
},
|
||||
{
|
||||
"size": 11179576,
|
||||
"digest": "91567ce8e2bb8ab0ebc60c31e90731d88a1ea889fb71bcf55c735746a60fa7610b7e040ea3d8f727b6f692ae3ee703d6f3b30cdbd76fdf5617f77d9c38aa20ed",
|
||||
"size": 4079256,
|
||||
"digest": "bb5238558bcf6db2ca395513c8dccaa15dd61b3c375598eb6a685356b0c1a2d9840e3bf81bc00242b872fd798541f53d723777c754412abf0e772b7cc284937c",
|
||||
"algorithm": "sha512",
|
||||
"filename": "gtk3.tar.xz",
|
||||
"setup": "setup.sh",
|
||||
"unpack": true
|
||||
},
|
||||
{
|
||||
|
|
|
@ -10,11 +10,10 @@
|
|||
"unpack": true
|
||||
},
|
||||
{
|
||||
"size": 12057960,
|
||||
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
|
||||
"size": 4431740,
|
||||
"digest": "68fc56b0fb0cdba629b95683d6649ff76b00dccf97af90960c3d7716f6108b2162ffd5ffcd5c3a60a21b28674df688fe4dabc67345e2da35ec5abeae3d48c8e3",
|
||||
"algorithm": "sha512",
|
||||
"filename": "gtk3.tar.xz",
|
||||
"setup": "setup.sh",
|
||||
"unpack": true
|
||||
}
|
||||
]
|
||||
|
|
|
@ -7,11 +7,10 @@
|
|||
"unpack": true
|
||||
},
|
||||
{
|
||||
"size": 12057960,
|
||||
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
|
||||
"size": 4431740,
|
||||
"digest": "68fc56b0fb0cdba629b95683d6649ff76b00dccf97af90960c3d7716f6108b2162ffd5ffcd5c3a60a21b28674df688fe4dabc67345e2da35ec5abeae3d48c8e3",
|
||||
"algorithm": "sha512",
|
||||
"filename": "gtk3.tar.xz",
|
||||
"setup": "setup.sh",
|
||||
"unpack": true
|
||||
},
|
||||
{
|
||||
|
|
|
@ -10,11 +10,10 @@
|
|||
"unpack": true
|
||||
},
|
||||
{
|
||||
"size": 12057960,
|
||||
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
|
||||
"size": 4431740,
|
||||
"digest": "68fc56b0fb0cdba629b95683d6649ff76b00dccf97af90960c3d7716f6108b2162ffd5ffcd5c3a60a21b28674df688fe4dabc67345e2da35ec5abeae3d48c8e3",
|
||||
"algorithm": "sha512",
|
||||
"filename": "gtk3.tar.xz",
|
||||
"setup": "setup.sh",
|
||||
"unpack": true
|
||||
}
|
||||
]
|
||||
|
|
|
@ -640,7 +640,11 @@ getUserMedia.sharingMenu.accesskey = d
|
|||
# getUserMedia.sharingMenuMicrophoneApplication,
|
||||
# getUserMedia.sharingMenuMicrophoneScreen,
|
||||
# getUserMedia.sharingMenuMicrophoneWindow,
|
||||
# getUserMedia.sharingMenuMicrophoneBrowser):
|
||||
# getUserMedia.sharingMenuMicrophoneBrowser,
|
||||
# getUserMedia.sharingMenuAudioCaptureApplication,
|
||||
# getUserMedia.sharingMenuAudioCaptureScreen,
|
||||
# getUserMedia.sharingMenuAudioCaptureWindow,
|
||||
# getUserMedia.sharingMenuAudioCaptureBrowser):
|
||||
# %S is the website origin (e.g. www.mozilla.org)
|
||||
getUserMedia.sharingMenuCamera = %S (camera)
|
||||
getUserMedia.sharingMenuMicrophone = %S (microphone)
|
||||
|
@ -667,10 +671,10 @@ getUserMedia.sharingMenuMicrophoneApplication = %S (microphone and application)
|
|||
getUserMedia.sharingMenuMicrophoneScreen = %S (microphone and screen)
|
||||
getUserMedia.sharingMenuMicrophoneWindow = %S (microphone and window)
|
||||
getUserMedia.sharingMenuMicrophoneBrowser = %S (microphone and tab)
|
||||
getUserMedia.sharingMenuMicrophoneApplication = %S (tab audio and application)
|
||||
getUserMedia.sharingMenuMicrophoneScreen = %S (tab audio and screen)
|
||||
getUserMedia.sharingMenuMicrophoneWindow = %S (tab audio and window)
|
||||
getUserMedia.sharingMenuMicrophoneBrowser = %S (tab audio and tab)
|
||||
getUserMedia.sharingMenuAudioCaptureApplication = %S (tab audio and application)
|
||||
getUserMedia.sharingMenuAudioCaptureScreen = %S (tab audio and screen)
|
||||
getUserMedia.sharingMenuAudioCaptureWindow = %S (tab audio and window)
|
||||
getUserMedia.sharingMenuAudioCaptureBrowser = %S (tab audio and tab)
|
||||
# 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.
|
||||
getUserMedia.sharingMenuUnknownHost = Unknown origin
|
||||
|
|
|
@ -57,7 +57,7 @@ build() {
|
|||
cd build/$name
|
||||
eval ../../$name-$version/configure --disable-static $* $configure_args
|
||||
make $make_flags
|
||||
make install DESTDIR=$root_dir/gtk3
|
||||
make install-strip DESTDIR=$root_dir/gtk3
|
||||
find $root_dir/gtk3 -name \*.la -delete
|
||||
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/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
|
||||
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}"
|
||||
# Ensure cairo, gdk-pixbuf, etc. are not taken from the system installed packages.
|
||||
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
|
||||
|
||||
# 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 LD_LIBRARY_PATH=$TOOLTOOL_DIR/gtk3/usr/local/lib"
|
||||
|
||||
# Until a tooltool with bug 1188571 landed is available everywhere
|
||||
$TOOLTOOL_DIR/gtk3/setup.sh
|
||||
# pango expects absolute paths in pango.modules, and TOOLTOOL_DIR may vary...
|
||||
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
|
||||
ac_add_options --enable-default-toolkit=cairo-gtk2
|
||||
fi
|
||||
|
|
|
@ -3728,12 +3728,14 @@ bool HTMLMediaElement::CanActivateAutoplay()
|
|||
{
|
||||
// For stream inputs, we activate autoplay on HAVE_NOTHING because
|
||||
// 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 &&
|
||||
mAutoplaying &&
|
||||
mPaused &&
|
||||
((mDecoder && mReadyState >= nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA) ||
|
||||
mSrcStream) &&
|
||||
mSrcStream || mMediaSource) &&
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay) &&
|
||||
mAutoplayEnabled &&
|
||||
!IsEditable();
|
||||
|
|
|
@ -96,7 +96,7 @@ function IccContact(aContact) {
|
|||
|
||||
let anrLen = aContact.anr ? aContact.anr.length : 0;
|
||||
for (let i = 0; i < anrLen; i++) {
|
||||
this._numbers.push(anr[i]);
|
||||
this._numbers.push(aContact.anr[i]);
|
||||
}
|
||||
|
||||
if (aContact.email) {
|
||||
|
@ -717,7 +717,7 @@ Icc.prototype = {
|
|||
if (length > 0) {
|
||||
iccContact.anr = [];
|
||||
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;
|
||||
while (stillProcessing) {
|
||||
GraphTime prevCurrentTime, nextCurrentTime;
|
||||
GetIntervalForIteration(prevCurrentTime, nextCurrentTime);
|
||||
mIterationStart = IterationEnd();
|
||||
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 =
|
||||
mGraphImpl->RoundUpToNextAudioBlock(
|
||||
nextCurrentTime + mGraphImpl->MillisecondsToMediaTime(AUDIO_TARGET_MS));
|
||||
mIterationEnd + mGraphImpl->MillisecondsToMediaTime(AUDIO_TARGET_MS));
|
||||
STREAM_LOG(LogLevel::Debug,
|
||||
("interval[%ld; %ld] state[%ld; %ld]",
|
||||
(long)mIterationStart, (long)mIterationEnd,
|
||||
|
@ -294,8 +306,8 @@ ThreadedDriver::RunThread()
|
|||
|
||||
mGraphImpl->mFlushSourcesNow = mGraphImpl->mFlushSourcesOnNextIteration;
|
||||
mGraphImpl->mFlushSourcesOnNextIteration = false;
|
||||
stillProcessing = mGraphImpl->OneIteration(prevCurrentTime,
|
||||
nextCurrentTime,
|
||||
stillProcessing = mGraphImpl->OneIteration(mIterationStart,
|
||||
mIterationEnd,
|
||||
StateComputedTime(),
|
||||
mNextStateComputedTime);
|
||||
|
||||
|
@ -310,36 +322,21 @@ ThreadedDriver::RunThread()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
SystemClockDriver::GetIntervalForIteration(GraphTime& aFrom, GraphTime& aTo)
|
||||
MediaTime
|
||||
SystemClockDriver::GetIntervalForIteration()
|
||||
{
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
aFrom = mIterationStart = IterationEnd();
|
||||
aTo = mIterationEnd = mGraphImpl->SecondsToMediaTime((now - mCurrentTimeStamp).ToSeconds()) + IterationEnd();
|
||||
|
||||
MediaTime interval =
|
||||
mGraphImpl->SecondsToMediaTime((now - mCurrentTimeStamp).ToSeconds());
|
||||
mCurrentTimeStamp = now;
|
||||
|
||||
MOZ_LOG(gMediaStreamGraphLog, LogLevel::Verbose, ("Updating current time to %f (real %f, mStateComputedTime %f)",
|
||||
mGraphImpl->MediaTimeToSeconds(aTo),
|
||||
(now - mInitialTimeStamp).ToSeconds(),
|
||||
mGraphImpl->MediaTimeToSeconds(StateComputedTime())));
|
||||
MOZ_LOG(gMediaStreamGraphLog, LogLevel::Verbose,
|
||||
("Updating current time to %f (real %f, mStateComputedTime %f)",
|
||||
mGraphImpl->MediaTimeToSeconds(IterationEnd() + interval),
|
||||
(now - mInitialTimeStamp).ToSeconds(),
|
||||
mGraphImpl->MediaTimeToSeconds(StateComputedTime())));
|
||||
|
||||
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
|
||||
SystemClockDriver::GetCurrentTime()
|
||||
{
|
||||
return IterationEnd();
|
||||
return interval;
|
||||
}
|
||||
|
||||
TimeStamp
|
||||
|
@ -432,31 +429,12 @@ OfflineClockDriver::~OfflineClockDriver()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
OfflineClockDriver::GetIntervalForIteration(GraphTime& aFrom, GraphTime& aTo)
|
||||
MediaTime
|
||||
OfflineClockDriver::GetIntervalForIteration()
|
||||
{
|
||||
aFrom = mIterationStart = IterationEnd();
|
||||
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"));
|
||||
}
|
||||
return mGraphImpl->MillisecondsToMediaTime(mSlice);
|
||||
}
|
||||
|
||||
GraphTime
|
||||
OfflineClockDriver::GetCurrentTime()
|
||||
{
|
||||
return mIterationEnd;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
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()
|
||||
{
|
||||
}
|
||||
|
@ -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.
|
||||
if (mBuffer.Available()) {
|
||||
|
||||
mStateComputedTime = mNextStateComputedTime;
|
||||
MOZ_ASSERT(mStateComputedTime == mNextStateComputedTime);
|
||||
|
||||
// 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
|
||||
|
|
|
@ -50,23 +50,8 @@ static const int SCHEDULE_SAFETY_MARGIN_MS = 10;
|
|||
static const int AUDIO_TARGET_MS = 2*MEDIA_GRAPH_TARGET_PERIOD_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;
|
||||
|
||||
/**
|
||||
* Microseconds relative to the start of the graph timeline.
|
||||
*/
|
||||
typedef int64_t GraphTime;
|
||||
const GraphTime GRAPH_TIME_MAX = MEDIA_TIME_MAX;
|
||||
|
||||
class AudioCallbackDriver;
|
||||
class OfflineClockDriver;
|
||||
|
||||
|
@ -84,13 +69,6 @@ public:
|
|||
explicit GraphDriver(MediaStreamGraphImpl* aGraphImpl);
|
||||
|
||||
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
|
||||
* offline graphs, this is a no-op. */
|
||||
virtual void WaitForNextIteration() = 0;
|
||||
|
@ -277,6 +255,11 @@ public:
|
|||
|
||||
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:
|
||||
nsCOMPtr<nsIThread> mThread;
|
||||
};
|
||||
|
@ -290,9 +273,7 @@ class SystemClockDriver : public ThreadedDriver
|
|||
public:
|
||||
explicit SystemClockDriver(MediaStreamGraphImpl* aGraphImpl);
|
||||
virtual ~SystemClockDriver();
|
||||
virtual void GetIntervalForIteration(GraphTime& aFrom,
|
||||
GraphTime& aTo) override;
|
||||
virtual GraphTime GetCurrentTime() override;
|
||||
virtual MediaTime GetIntervalForIteration() override;
|
||||
virtual void WaitForNextIteration() override;
|
||||
virtual void WakeUp() override;
|
||||
|
||||
|
@ -311,9 +292,7 @@ class OfflineClockDriver : public ThreadedDriver
|
|||
public:
|
||||
OfflineClockDriver(MediaStreamGraphImpl* aGraphImpl, GraphTime aSlice);
|
||||
virtual ~OfflineClockDriver();
|
||||
virtual void GetIntervalForIteration(GraphTime& aFrom,
|
||||
GraphTime& aTo) override;
|
||||
virtual GraphTime GetCurrentTime() override;
|
||||
virtual MediaTime GetIntervalForIteration() override;
|
||||
virtual void WaitForNextIteration() override;
|
||||
virtual void WakeUp() override;
|
||||
virtual TimeStamp GetCurrentTimeStamp() override;
|
||||
|
@ -374,9 +353,6 @@ public:
|
|||
virtual void Stop() override;
|
||||
virtual void Resume() override;
|
||||
virtual void Revive() override;
|
||||
virtual void GetIntervalForIteration(GraphTime& aFrom,
|
||||
GraphTime& aTo) override;
|
||||
virtual GraphTime GetCurrentTime() override;
|
||||
virtual void WaitForNextIteration() override;
|
||||
virtual void WakeUp() override;
|
||||
|
||||
|
|
|
@ -414,9 +414,8 @@ bool MediaDecoderStateMachine::HaveEnoughDecodedAudio(int64_t aAmpleAudioUSecs)
|
|||
return false;
|
||||
}
|
||||
|
||||
// We don't have to check SourceMediaStream::HaveEnoughBuffered() in the
|
||||
// case of stream-capture for MDSM will ensure buffering level is high enough
|
||||
// for playback speed at 1x at which the DecodedStream is playing.
|
||||
// MDSM will ensure buffering level is high enough for playback speed at 1x
|
||||
// at which the DecodedStream is playing.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1275,7 +1274,6 @@ void MediaDecoderStateMachine::SetDormant(bool aDormant)
|
|||
} else if ((aDormant != true) && (mState == DECODER_STATE_DORMANT)) {
|
||||
mDecodingFrozenAtStateDecoding = true;
|
||||
ScheduleStateMachine();
|
||||
mCurrentPosition = 0;
|
||||
mDecodingFirstFrame = true;
|
||||
SetState(DECODER_STATE_DECODING_NONE);
|
||||
mDecoder->GetReentrantMonitor().NotifyAll();
|
||||
|
|
|
@ -48,6 +48,12 @@ const int64_t MEDIA_TIME_MAX = TRACK_TICKS_MAX;
|
|||
typedef MediaTime StreamTime;
|
||||
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
|
||||
* types of data have different subclasses of MediaSegment, all inheriting
|
||||
|
|
|
@ -71,17 +71,6 @@ MediaStreamGraphImpl::~MediaStreamGraphImpl()
|
|||
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
|
||||
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
|
||||
MediaStreamGraphImpl::GraphTimeToStreamTime(MediaStream* aStream,
|
||||
GraphTime aTime)
|
||||
|
@ -1452,10 +1399,6 @@ MediaStreamGraphImpl::Process(GraphTime aFrom, GraphTime aTo)
|
|||
}
|
||||
PlayVideo(stream);
|
||||
}
|
||||
SourceMediaStream* is = stream->AsSourceStream();
|
||||
if (is) {
|
||||
UpdateBufferSufficiencyState(is);
|
||||
}
|
||||
GraphTime end;
|
||||
if (!stream->mBlocked.GetAt(aTo, &end) || end < GRAPH_TIME_MAX) {
|
||||
allBlockedForever = false;
|
||||
|
@ -2485,7 +2428,6 @@ SourceMediaStream::AddTrackInternal(TrackID aID, TrackRate aRate, StreamTime aSt
|
|||
data->mEndOfFlushedData = aStart;
|
||||
data->mCommands = TRACK_CREATE;
|
||||
data->mData = aSegment;
|
||||
data->mHaveEnough = false;
|
||||
if (!(aFlags & ADDTRACK_QUEUED) && GraphImpl()) {
|
||||
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
|
||||
SourceMediaStream::GetEndOfAppendedData(TrackID aID)
|
||||
{
|
||||
|
@ -2669,28 +2600,6 @@ SourceMediaStream::GetEndOfAppendedData(TrackID aID)
|
|||
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
|
||||
SourceMediaStream::EndTrack(TrackID aID)
|
||||
{
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "mozilla/dom/AudioChannelBinding.h"
|
||||
|
||||
#include "AudioSegment.h"
|
||||
#include "AudioStream.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsIRunnable.h"
|
||||
|
@ -21,7 +22,6 @@
|
|||
#include "VideoSegment.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#include "nsAutoRef.h"
|
||||
#include "GraphDriver.h"
|
||||
#include <speex/speex_resampler.h>
|
||||
#include "DOMMediaStream.h"
|
||||
#include "AudioContext.h"
|
||||
|
@ -815,11 +815,6 @@ public:
|
|||
* or the stream was already finished.
|
||||
*/
|
||||
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.
|
||||
* 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.
|
||||
*/
|
||||
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
|
||||
* affecting this track.
|
||||
|
@ -930,11 +917,9 @@ protected:
|
|||
// Each time the track updates are flushed to the media graph thread,
|
||||
// the segment buffer is emptied.
|
||||
nsAutoPtr<MediaSegment> mData;
|
||||
nsTArray<ThreadAndRunnable> mDispatchWhenNotEnough;
|
||||
// Each time the track updates are flushed to the media graph thread,
|
||||
// this is cleared.
|
||||
uint32_t mCommands;
|
||||
bool mHaveEnough;
|
||||
};
|
||||
|
||||
bool NeedsMixing();
|
||||
|
|
|
@ -76,7 +76,7 @@ SourceBuffer::SetMode(SourceBufferAppendMode aMode, ErrorResult& aRv)
|
|||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
if (mIsUsingFormatReader && mGenerateTimestamps &&
|
||||
if (mIsUsingFormatReader && mAttributes->mGenerateTimestamps &&
|
||||
aMode == SourceBufferAppendMode::Segments) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||
return;
|
||||
|
@ -96,7 +96,7 @@ SourceBuffer::SetMode(SourceBufferAppendMode aMode, ErrorResult& aRv)
|
|||
mContentManager->RestartGroupStartTimestamp();
|
||||
}
|
||||
|
||||
mAppendMode = aMode;
|
||||
mAttributes->SetAppendMode(aMode);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -119,22 +119,13 @@ SourceBuffer::SetTimestampOffset(double aTimestampOffset, ErrorResult& aRv)
|
|||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
mApparentTimestampOffset = aTimestampOffset;
|
||||
mTimestampOffset = TimeUnit::FromSeconds(aTimestampOffset);
|
||||
if (mIsUsingFormatReader && mAppendMode == SourceBufferAppendMode::Sequence) {
|
||||
mContentManager->SetGroupStartTimestamp(mTimestampOffset);
|
||||
mAttributes->SetApparentTimestampOffset(aTimestampOffset);
|
||||
if (mIsUsingFormatReader &&
|
||||
mAttributes->GetAppendMode() == SourceBufferAppendMode::Sequence) {
|
||||
mContentManager->SetGroupStartTimestamp(mAttributes->GetTimestampOffset());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SourceBuffer::SetTimestampOffset(const TimeUnit& aTimestampOffset)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mTimestampOffset = aTimestampOffset;
|
||||
mApparentTimestampOffset = aTimestampOffset.ToSeconds();
|
||||
}
|
||||
|
||||
already_AddRefed<TimeRanges>
|
||||
SourceBuffer::GetBuffered(ErrorResult& aRv)
|
||||
{
|
||||
|
@ -165,11 +156,12 @@ SourceBuffer::SetAppendWindowStart(double aAppendWindowStart, ErrorResult& aRv)
|
|||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
if (aAppendWindowStart < 0 || aAppendWindowStart >= mAppendWindowEnd) {
|
||||
if (aAppendWindowStart < 0 ||
|
||||
aAppendWindowStart >= mAttributes->GetAppendWindowEnd()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||
return;
|
||||
}
|
||||
mAppendWindowStart = aAppendWindowStart;
|
||||
mAttributes->SetAppendWindowStart(aAppendWindowStart);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -181,11 +173,12 @@ SourceBuffer::SetAppendWindowEnd(double aAppendWindowEnd, ErrorResult& aRv)
|
|||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
if (IsNaN(aAppendWindowEnd) || aAppendWindowEnd <= mAppendWindowStart) {
|
||||
if (IsNaN(aAppendWindowEnd) ||
|
||||
aAppendWindowEnd <= mAttributes->GetAppendWindowStart()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||
return;
|
||||
}
|
||||
mAppendWindowEnd = aAppendWindowEnd;
|
||||
mAttributes->SetAppendWindowEnd(aAppendWindowEnd);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -221,8 +214,8 @@ SourceBuffer::Abort(ErrorResult& aRv)
|
|||
}
|
||||
AbortBufferAppend();
|
||||
mContentManager->ResetParserState();
|
||||
mAppendWindowStart = 0;
|
||||
mAppendWindowEnd = PositiveInfinity<double>();
|
||||
mAttributes->SetAppendWindowStart(0);
|
||||
mAttributes->SetAppendWindowEnd(PositiveInfinity<double>());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -312,10 +305,6 @@ SourceBuffer::Ended()
|
|||
SourceBuffer::SourceBuffer(MediaSource* aMediaSource, const nsACString& aType)
|
||||
: DOMEventTargetHelper(aMediaSource->GetParentObject())
|
||||
, mMediaSource(aMediaSource)
|
||||
, mAppendWindowStart(0)
|
||||
, mAppendWindowEnd(PositiveInfinity<double>())
|
||||
, mApparentTimestampOffset(0)
|
||||
, mAppendMode(SourceBufferAppendMode::Segments)
|
||||
, mUpdating(false)
|
||||
, mActive(false)
|
||||
, mUpdateID(0)
|
||||
|
@ -326,22 +315,24 @@ SourceBuffer::SourceBuffer(MediaSource* aMediaSource, const nsACString& aType)
|
|||
MOZ_ASSERT(aMediaSource);
|
||||
mEvictionThreshold = Preferences::GetUint("media.mediasource.eviction_threshold",
|
||||
100 * (1 << 20));
|
||||
bool generateTimestamps = false;
|
||||
if (aType.LowerCaseEqualsLiteral("audio/mpeg") ||
|
||||
aType.LowerCaseEqualsLiteral("audio/aac")) {
|
||||
generateTimestamps = true;
|
||||
}
|
||||
mAttributes = new SourceBufferAttributes(generateTimestamps);
|
||||
|
||||
mContentManager =
|
||||
SourceBufferContentManager::CreateManager(this,
|
||||
SourceBufferContentManager::CreateManager(mAttributes,
|
||||
aMediaSource->GetDecoder(),
|
||||
aType);
|
||||
MSE_DEBUG("Create mContentManager=%p",
|
||||
mContentManager.get());
|
||||
if (aType.LowerCaseEqualsLiteral("audio/mpeg") ||
|
||||
aType.LowerCaseEqualsLiteral("audio/aac")) {
|
||||
mGenerateTimestamps = true;
|
||||
} else {
|
||||
mGenerateTimestamps = false;
|
||||
}
|
||||
|
||||
mIsUsingFormatReader =
|
||||
Preferences::GetBool("media.mediasource.format-reader", false);
|
||||
ErrorResult dummy;
|
||||
if (mGenerateTimestamps) {
|
||||
if (mAttributes->mGenerateTimestamps) {
|
||||
SetMode(SourceBufferAppendMode::Sequence, dummy);
|
||||
} else {
|
||||
SetMode(SourceBufferAppendMode::Segments, dummy);
|
||||
|
@ -446,11 +437,12 @@ SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aR
|
|||
if (!data) {
|
||||
return;
|
||||
}
|
||||
mContentManager->AppendData(data, mTimestampOffset);
|
||||
mContentManager->AppendData(data, mAttributes->GetTimestampOffset());
|
||||
|
||||
StartUpdating();
|
||||
|
||||
MOZ_ASSERT(mIsUsingFormatReader || mAppendMode == SourceBufferAppendMode::Segments,
|
||||
MOZ_ASSERT(mIsUsingFormatReader ||
|
||||
mAttributes->GetAppendMode() == SourceBufferAppendMode::Segments,
|
||||
"We don't handle timestampOffset for sequence mode yet");
|
||||
nsCOMPtr<nsIRunnable> task = new BufferAppendRunnable(this, mUpdateID);
|
||||
NS_DispatchToMainThread(task);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "nsString.h"
|
||||
#include "nscore.h"
|
||||
#include "SourceBufferContentManager.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
|
||||
class JSObject;
|
||||
struct JSContext;
|
||||
|
@ -40,13 +41,103 @@ namespace dom {
|
|||
|
||||
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
|
||||
{
|
||||
public:
|
||||
/** WebIDL Methods. */
|
||||
SourceBufferAppendMode Mode() const
|
||||
{
|
||||
return mAppendMode;
|
||||
return mAttributes->GetAppendMode();
|
||||
}
|
||||
|
||||
void SetMode(SourceBufferAppendMode aMode, ErrorResult& aRv);
|
||||
|
@ -61,21 +152,21 @@ public:
|
|||
|
||||
double TimestampOffset() const
|
||||
{
|
||||
return mApparentTimestampOffset;
|
||||
return mAttributes->GetApparentTimestampOffset();
|
||||
}
|
||||
|
||||
void SetTimestampOffset(double aTimestampOffset, ErrorResult& aRv);
|
||||
|
||||
double AppendWindowStart() const
|
||||
{
|
||||
return mAppendWindowStart;
|
||||
return mAttributes->GetAppendWindowStart();
|
||||
}
|
||||
|
||||
void SetAppendWindowStart(double aAppendWindowStart, ErrorResult& aRv);
|
||||
|
||||
double AppendWindowEnd() const
|
||||
{
|
||||
return mAppendWindowEnd;
|
||||
return mAttributes->GetAppendWindowEnd();
|
||||
}
|
||||
|
||||
void SetAppendWindowEnd(double aAppendWindowEnd, ErrorResult& aRv);
|
||||
|
@ -164,24 +255,14 @@ private:
|
|||
void AppendDataCompletedWithSuccess(bool aHasActiveTracks);
|
||||
void AppendDataErrored(nsresult aError);
|
||||
|
||||
// Set timestampOffset, must be called on the main thread.
|
||||
void SetTimestampOffset(const media::TimeUnit& aTimestampOffset);
|
||||
|
||||
nsRefPtr<MediaSource> mMediaSource;
|
||||
|
||||
uint32_t mEvictionThreshold;
|
||||
|
||||
nsRefPtr<SourceBufferContentManager> mContentManager;
|
||||
nsRefPtr<SourceBufferAttributes> mAttributes;
|
||||
|
||||
double mAppendWindowStart;
|
||||
double mAppendWindowEnd;
|
||||
|
||||
double mApparentTimestampOffset;
|
||||
media::TimeUnit mTimestampOffset;
|
||||
|
||||
SourceBufferAppendMode mAppendMode;
|
||||
bool mUpdating;
|
||||
bool mGenerateTimestamps;
|
||||
bool mIsUsingFormatReader;
|
||||
|
||||
mozilla::Atomic<bool> mActive;
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace mozilla {
|
|||
#endif
|
||||
|
||||
already_AddRefed<SourceBufferContentManager>
|
||||
SourceBufferContentManager::CreateManager(dom::SourceBuffer* aParent,
|
||||
SourceBufferContentManager::CreateManager(dom::SourceBufferAttributes* aAttributes,
|
||||
MediaSourceDecoder* aParentDecoder,
|
||||
const nsACString &aType)
|
||||
{
|
||||
|
@ -26,7 +26,7 @@ SourceBufferContentManager::CreateManager(dom::SourceBuffer* aParent,
|
|||
bool useFormatReader =
|
||||
Preferences::GetBool("media.mediasource.format-reader", false);
|
||||
if (useFormatReader) {
|
||||
manager = new TrackBuffersManager(aParent, aParentDecoder, aType);
|
||||
manager = new TrackBuffersManager(aAttributes, aParentDecoder, aType);
|
||||
} else {
|
||||
manager = new TrackBuffer(aParentDecoder, aType);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace mozilla {
|
|||
|
||||
namespace dom {
|
||||
class SourceBuffer;
|
||||
class SourceBufferAttributes;
|
||||
}
|
||||
|
||||
class SourceBufferContentManager {
|
||||
|
@ -28,7 +29,8 @@ public:
|
|||
typedef AppendPromise RangeRemovalPromise;
|
||||
|
||||
static already_AddRefed<SourceBufferContentManager>
|
||||
CreateManager(dom::SourceBuffer* aParent, MediaSourceDecoder* aParentDecoder,
|
||||
CreateManager(dom::SourceBufferAttributes* aAttributes,
|
||||
MediaSourceDecoder* aParentDecoder,
|
||||
const nsACString& aType);
|
||||
|
||||
// Add data to the end of the input buffer.
|
||||
|
|
|
@ -90,7 +90,9 @@ private:
|
|||
};
|
||||
#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)
|
||||
, mAppendState(AppendState::WAITING_FOR_SEGMENT)
|
||||
, mBufferFull(false)
|
||||
|
@ -101,9 +103,8 @@ TrackBuffersManager::TrackBuffersManager(dom::SourceBuffer* aParent, MediaSource
|
|||
, mProcessedInput(0)
|
||||
, mAppendRunning(false)
|
||||
, mTaskQueue(aParentDecoder->GetDemuxer()->GetTaskQueue())
|
||||
, mParent(new nsMainThreadPtrHolder<dom::SourceBuffer>(aParent, false /* strict */))
|
||||
, mSourceBufferAttributes(aAttributes)
|
||||
, mParentDecoder(new nsMainThreadPtrHolder<MediaSourceDecoder>(aParentDecoder, false /* strict */))
|
||||
, mMediaSourceDemuxer(mParentDecoder->GetDemuxer())
|
||||
, mMediaSourceDuration(mTaskQueue, Maybe<double>(), "TrackBuffersManager::mMediaSourceDuration (Mirror)")
|
||||
, mAbort(false)
|
||||
, mEvictionThreshold(Preferences::GetUint("media.mediasource.eviction_threshold",
|
||||
|
@ -620,8 +621,8 @@ TrackBuffersManager::AppendIncomingBuffers()
|
|||
mIncomingBuffers.Clear();
|
||||
|
||||
mAppendWindow =
|
||||
TimeInterval(TimeUnit::FromSeconds(mParent->AppendWindowStart()),
|
||||
TimeUnit::FromSeconds(mParent->AppendWindowEnd()));
|
||||
TimeInterval(TimeUnit::FromSeconds(mSourceBufferAttributes->GetAppendWindowStart()),
|
||||
TimeUnit::FromSeconds(mSourceBufferAttributes->GetAppendWindowEnd()));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1239,7 +1240,7 @@ TrackBuffersManager::ResolveProcessing(bool aResolveValue, const char* aName)
|
|||
void
|
||||
TrackBuffersManager::CheckSequenceDiscontinuity()
|
||||
{
|
||||
if (mParent->mAppendMode == SourceBufferAppendMode::Sequence &&
|
||||
if (mSourceBufferAttributes->GetAppendMode() == SourceBufferAppendMode::Sequence &&
|
||||
mGroupStartTimestamp.isSome()) {
|
||||
mTimestampOffset = 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:
|
||||
|
||||
TimeInterval sampleInterval =
|
||||
mParent->mGenerateTimestamps
|
||||
mSourceBufferAttributes->mGenerateTimestamps
|
||||
? TimeInterval(mTimestampOffset,
|
||||
mTimestampOffset + TimeUnit::FromMicroseconds(sample->mDuration))
|
||||
: TimeInterval(TimeUnit::FromMicroseconds(sample->mTime) + mTimestampOffset,
|
||||
TimeUnit::FromMicroseconds(sample->GetEndTime()) + mTimestampOffset);
|
||||
TimeUnit decodeTimestamp =
|
||||
mParent->mGenerateTimestamps
|
||||
mSourceBufferAttributes->mGenerateTimestamps
|
||||
? mTimestampOffset
|
||||
: TimeUnit::FromMicroseconds(sample->mTimecode) + mTimestampOffset;
|
||||
|
||||
|
@ -1332,13 +1333,15 @@ TrackBuffersManager::ProcessFrames(TrackBuffer& aSamples, TrackData& aTrackData)
|
|||
(decodeTimestamp < trackBuffer.mLastDecodeTimestamp.ref() ||
|
||||
decodeTimestamp - trackBuffer.mLastDecodeTimestamp.ref() > 2*trackBuffer.mLongestFrameDuration.ref())) {
|
||||
MSE_DEBUG("Discontinuity detected.");
|
||||
SourceBufferAppendMode appendMode = mSourceBufferAttributes->GetAppendMode();
|
||||
|
||||
// 1a. If mode equals "segments":
|
||||
if (mParent->mAppendMode == SourceBufferAppendMode::Segments) {
|
||||
if (appendMode == SourceBufferAppendMode::Segments) {
|
||||
// Set group end timestamp to presentation timestamp.
|
||||
mGroupEndTimestamp = sampleInterval.mStart;
|
||||
}
|
||||
// 1b. If mode equals "sequence":
|
||||
if (mParent->mAppendMode == SourceBufferAppendMode::Sequence) {
|
||||
if (appendMode == SourceBufferAppendMode::Sequence) {
|
||||
// Set group start timestamp equal to the group end timestamp.
|
||||
mGroupStartTimestamp = Some(mGroupEndTimestamp);
|
||||
}
|
||||
|
@ -1358,17 +1361,17 @@ TrackBuffersManager::ProcessFrames(TrackBuffer& aSamples, TrackData& aTrackData)
|
|||
if (!sample->mKeyframe) {
|
||||
continue;
|
||||
}
|
||||
if (mParent->mAppendMode == SourceBufferAppendMode::Sequence) {
|
||||
if (appendMode == SourceBufferAppendMode::Sequence) {
|
||||
// mTimestampOffset was modified during CheckSequenceDiscontinuity.
|
||||
// We need to update our variables.
|
||||
sampleInterval =
|
||||
mParent->mGenerateTimestamps
|
||||
mSourceBufferAttributes->mGenerateTimestamps
|
||||
? TimeInterval(mTimestampOffset,
|
||||
mTimestampOffset + TimeUnit::FromMicroseconds(sample->mDuration))
|
||||
: TimeInterval(TimeUnit::FromMicroseconds(sample->mTime) + mTimestampOffset,
|
||||
TimeUnit::FromMicroseconds(sample->GetEndTime()) + mTimestampOffset);
|
||||
decodeTimestamp =
|
||||
mParent->mGenerateTimestamps
|
||||
mSourceBufferAttributes->mGenerateTimestamps
|
||||
? mTimestampOffset
|
||||
: TimeUnit::FromMicroseconds(sample->mTimecode) + mTimestampOffset;
|
||||
}
|
||||
|
@ -1428,7 +1431,7 @@ TrackBuffersManager::ProcessFrames(TrackBuffer& aSamples, TrackData& aTrackData)
|
|||
mGroupEndTimestamp = sampleInterval.mEnd;
|
||||
}
|
||||
// 21. If generate timestamps flag equals true, then set timestampOffset equal to frame end timestamp.
|
||||
if (mParent->mGenerateTimestamps) {
|
||||
if (mSourceBufferAttributes->mGenerateTimestamps) {
|
||||
mTimestampOffset = sampleInterval.mEnd;
|
||||
}
|
||||
}
|
||||
|
@ -1679,12 +1682,7 @@ TrackBuffersManager::RestoreCachedVariables()
|
|||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
if (mTimestampOffset != mLastTimestampOffset) {
|
||||
nsRefPtr<TrackBuffersManager> self = this;
|
||||
nsCOMPtr<nsIRunnable> task =
|
||||
NS_NewRunnableFunction([self] {
|
||||
self->mParent->SetTimestampOffset(self->mTimestampOffset);
|
||||
});
|
||||
AbstractThread::MainThread()->Dispatch(task.forget());
|
||||
mSourceBufferAttributes->SetTimestampOffset(mTimestampOffset);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,9 +25,12 @@ class ContainerParser;
|
|||
class MediaByteBuffer;
|
||||
class MediaRawData;
|
||||
class MediaSourceDemuxer;
|
||||
class SourceBuffer;
|
||||
class SourceBufferResource;
|
||||
|
||||
namespace dom {
|
||||
class SourceBufferAttributes;
|
||||
}
|
||||
|
||||
class TrackBuffersManager : public SourceBufferContentManager {
|
||||
public:
|
||||
typedef MozPromise<bool, nsresult, /* IsExclusive = */ true> CodedFrameProcessingPromise;
|
||||
|
@ -35,7 +38,9 @@ public:
|
|||
typedef MediaData::Type MediaType;
|
||||
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,
|
||||
media::TimeUnit aTimestampOffset) override;
|
||||
|
@ -315,9 +320,8 @@ private:
|
|||
void RestoreCachedVariables();
|
||||
|
||||
// Strong references to external objects.
|
||||
nsMainThreadPtrHandle<dom::SourceBuffer> mParent;
|
||||
nsRefPtr<dom::SourceBufferAttributes> mSourceBufferAttributes;
|
||||
nsMainThreadPtrHandle<MediaSourceDecoder> mParentDecoder;
|
||||
nsRefPtr<MediaSourceDemuxer> mMediaSourceDemuxer;
|
||||
|
||||
// MediaSource duration mirrored from MediaDecoder on the main thread..
|
||||
Mirror<Maybe<double>> mMediaSourceDuration;
|
||||
|
|
|
@ -110,7 +110,6 @@ EXPORTS += [
|
|||
'DOMMediaStream.h',
|
||||
'EncodedBufferCache.h',
|
||||
'FileBlockCache.h',
|
||||
'GraphDriver.h',
|
||||
'Intervals.h',
|
||||
'Latency.h',
|
||||
'MediaCache.h',
|
||||
|
|
|
@ -68,7 +68,6 @@ WMFAudioMFTManager::WMFAudioMFTManager(
|
|||
const AudioInfo& aConfig)
|
||||
: mAudioChannels(aConfig.mChannels)
|
||||
, mAudioRate(aConfig.mRate)
|
||||
, mAudioFrameOffset(0)
|
||||
, mAudioFrameSum(0)
|
||||
, mMustRecaptureAudioPosition(true)
|
||||
{
|
||||
|
@ -267,8 +266,7 @@ WMFAudioMFTManager::Output(int64_t aStreamOffset,
|
|||
LONGLONG timestampHns = 0;
|
||||
hr = sample->GetSampleTime(×tampHns);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
hr = HNsToFrames(timestampHns, mAudioRate, &mAudioFrameOffset);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
mAudioTimeOffset = media::TimeUnit::FromMicroseconds(timestampHns / 10);
|
||||
mMustRecaptureAudioPosition = false;
|
||||
}
|
||||
// We can assume PCM 16 output.
|
||||
|
@ -292,7 +290,7 @@ WMFAudioMFTManager::Output(int64_t aStreamOffset,
|
|||
buffer->Unlock();
|
||||
|
||||
media::TimeUnit timestamp =
|
||||
FramesToTimeUnit(mAudioFrameOffset + mAudioFrameSum, mAudioRate);
|
||||
mAudioTimeOffset + FramesToTimeUnit(mAudioFrameSum, mAudioRate);
|
||||
NS_ENSURE_TRUE(timestamp.IsValid(), E_FAIL);
|
||||
|
||||
mAudioFrameSum += numFrames;
|
||||
|
|
|
@ -42,9 +42,9 @@ private:
|
|||
uint32_t mAudioRate;
|
||||
nsTArray<BYTE> mUserData;
|
||||
|
||||
// The offset, in audio frames, at which playback started since the
|
||||
// The offset, at which playback started since the
|
||||
// last discontinuity.
|
||||
int64_t mAudioFrameOffset;
|
||||
media::TimeUnit mAudioTimeOffset;
|
||||
// The number of audio frames that we've played since the last
|
||||
// discontinuity.
|
||||
int64_t mAudioFrameSum;
|
||||
|
@ -59,7 +59,7 @@ private:
|
|||
const GUID& GetMFTGUID();
|
||||
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
|
||||
// WMF doesn't mark a stream as having a discontinuity after a seek(0).
|
||||
bool mMustRecaptureAudioPosition;
|
||||
|
|
|
@ -30,6 +30,8 @@ using mozilla::layers::IMFYCbCrImage;
|
|||
using mozilla::layers::LayerManager;
|
||||
using mozilla::layers::LayersBackend;
|
||||
|
||||
#if MOZ_WINSDK_MAXVER < 0x0A000000
|
||||
// Windows 10+ SDK has VP80 and VP90 defines
|
||||
const GUID MFVideoFormat_VP80 =
|
||||
{
|
||||
0x30385056,
|
||||
|
@ -45,6 +47,7 @@ const GUID MFVideoFormat_VP90 =
|
|||
0x0010,
|
||||
{0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
|
||||
};
|
||||
#endif
|
||||
|
||||
const CLSID CLSID_WebmMfVp8Dec =
|
||||
{
|
||||
|
|
|
@ -380,7 +380,7 @@ public:
|
|||
AudioNodeSizes& aUsage) const
|
||||
{
|
||||
aUsage.mEngine = SizeOfIncludingThis(aMallocSizeOf);
|
||||
if (HasNode()) {
|
||||
if (mNode) {
|
||||
aUsage.mDomNode = mNode->SizeOfIncludingThis(aMallocSizeOf);
|
||||
aUsage.mNodeType = mNode->NodeType();
|
||||
}
|
||||
|
|
|
@ -54,8 +54,7 @@ public:
|
|||
SpeechRecognitionResultList* resultList =
|
||||
new SpeechRecognitionResultList(mRecognition);
|
||||
SpeechRecognitionResult* result = new SpeechRecognitionResult(mRecognition);
|
||||
ErrorResult rv;
|
||||
if (0 < mRecognition->GetMaxAlternatives(rv)) { // GetMaxAlternatives can't fail
|
||||
if (0 < mRecognition->MaxAlternatives()) {
|
||||
SpeechRecognitionAlternative* alternative =
|
||||
new SpeechRecognitionAlternative(mRecognition);
|
||||
|
||||
|
@ -331,8 +330,7 @@ PocketSphinxSpeechRecognitionService::BuildMockResultList()
|
|||
SpeechRecognitionResultList* resultList =
|
||||
new SpeechRecognitionResultList(mRecognition);
|
||||
SpeechRecognitionResult* result = new SpeechRecognitionResult(mRecognition);
|
||||
ErrorResult rv;
|
||||
if (0 < mRecognition->GetMaxAlternatives(rv)) { // GetMaxAlternatives can't fail
|
||||
if (0 < mRecognition->MaxAlternatives()) {
|
||||
SpeechRecognitionAlternative* alternative =
|
||||
new SpeechRecognitionAlternative(mRecognition);
|
||||
|
||||
|
|
|
@ -684,13 +684,13 @@ SpeechRecognition::SetInterimResults(bool aArg)
|
|||
}
|
||||
|
||||
uint32_t
|
||||
SpeechRecognition::GetMaxAlternatives(ErrorResult& aRv) const
|
||||
SpeechRecognition::MaxAlternatives() const
|
||||
{
|
||||
return mMaxAlternatives;
|
||||
}
|
||||
|
||||
void
|
||||
SpeechRecognition::SetMaxAlternatives(uint32_t aArg, ErrorResult& aRv)
|
||||
SpeechRecognition::SetMaxAlternatives(uint32_t aArg)
|
||||
{
|
||||
mMaxAlternatives = aArg;
|
||||
return;
|
||||
|
|
|
@ -87,9 +87,9 @@ public:
|
|||
|
||||
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;
|
||||
|
||||
|
|
|
@ -102,8 +102,7 @@ FakeSpeechRecognitionService::BuildMockResultList()
|
|||
{
|
||||
SpeechRecognitionResultList* resultList = new SpeechRecognitionResultList(mRecognition);
|
||||
SpeechRecognitionResult* result = new SpeechRecognitionResult(mRecognition);
|
||||
ErrorResult rv;
|
||||
if (0 < mRecognition->GetMaxAlternatives(rv)) { // GetMaxAlternatives can't fail
|
||||
if (0 < mRecognition->MaxAlternatives()) {
|
||||
SpeechRecognitionAlternative* alternative = new SpeechRecognitionAlternative(mRecognition);
|
||||
|
||||
alternative->mTranscript = NS_LITERAL_STRING("Mock final result");
|
||||
|
|
|
@ -20,7 +20,6 @@ interface SpeechRecognition : EventTarget {
|
|||
[Throws]
|
||||
attribute boolean continuous;
|
||||
attribute boolean interimResults;
|
||||
[Throws]
|
||||
attribute unsigned long maxAlternatives;
|
||||
[Throws]
|
||||
attribute DOMString serviceURI;
|
||||
|
|
|
@ -69,61 +69,6 @@ using namespace layerscope;
|
|||
class DebugDataSender;
|
||||
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
|
||||
*/
|
||||
|
@ -132,27 +77,18 @@ public:
|
|||
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()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MutexAutoLock lock(mHandlerMutex);
|
||||
mHandlers.Clear();
|
||||
}
|
||||
|
||||
bool WriteAll(void *ptr, uint32_t size)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
for (int32_t i = mHandlers.Length() - 1; i >= 0; --i) {
|
||||
if (!mHandlers[i]->WriteToStream(ptr, size)) {
|
||||
// Send failed, remove this handler
|
||||
|
@ -165,19 +101,116 @@ public:
|
|||
|
||||
bool IsConnected()
|
||||
{
|
||||
// This funtion can be called in both main thread and compositor thread.
|
||||
MutexAutoLock lock(mHandlerMutex);
|
||||
return (mHandlers.Length() != 0) ? true : false;
|
||||
}
|
||||
|
||||
void AppendDebugData(DebugGLData *aDebugData);
|
||||
void CleanDebugData();
|
||||
void DispatchDebugData();
|
||||
|
||||
private:
|
||||
nsTArray<nsRefPtr<LayerScopeWebSocketHandler> > mHandlers;
|
||||
nsCOMPtr<nsIThread> mDebugSenderThread;
|
||||
nsRefPtr<DebugDataSender> mCurrentSender;
|
||||
nsCOMPtr<nsIServerSocket> mServerSocket;
|
||||
void AddConnection(nsISocketTransport *aTransport)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
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 {
|
||||
public:
|
||||
DrawSession()
|
||||
|
@ -236,7 +269,9 @@ private:
|
|||
THArray mChangedHosts;
|
||||
};
|
||||
|
||||
// Hold all singleton objects used by LayerScope
|
||||
/*
|
||||
* Hold all singleton objects used by LayerScope.
|
||||
*/
|
||||
class LayerScopeManager
|
||||
{
|
||||
public:
|
||||
|
@ -708,40 +743,6 @@ protected:
|
|||
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
|
||||
{
|
||||
virtual ~DebugDataSender() {
|
||||
|
@ -1135,10 +1136,10 @@ LayerScope::ContentChanged(TextureHost *host)
|
|||
}
|
||||
|
||||
// ----------------------------------------------
|
||||
// LayerScopeWebSocketHandler implementation
|
||||
// SocketHandler implementation
|
||||
// ----------------------------------------------
|
||||
void
|
||||
LayerScopeWebSocketHandler::OpenStream(nsISocketTransport* aTransport)
|
||||
LayerScopeWebSocketManager::SocketHandler::OpenStream(nsISocketTransport* aTransport)
|
||||
{
|
||||
MOZ_ASSERT(aTransport);
|
||||
|
||||
|
@ -1158,7 +1159,7 @@ LayerScopeWebSocketHandler::OpenStream(nsISocketTransport* aTransport)
|
|||
}
|
||||
|
||||
bool
|
||||
LayerScopeWebSocketHandler::WriteToStream(void *aPtr,
|
||||
LayerScopeWebSocketManager::SocketHandler::WriteToStream(void *aPtr,
|
||||
uint32_t aSize)
|
||||
{
|
||||
if (mState == NoHandshake) {
|
||||
|
@ -1214,7 +1215,7 @@ LayerScopeWebSocketHandler::WriteToStream(void *aPtr,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LayerScopeWebSocketHandler::OnInputStreamReady(nsIAsyncInputStream *aStream)
|
||||
LayerScopeWebSocketManager::SocketHandler::OnInputStreamReady(nsIAsyncInputStream *aStream)
|
||||
{
|
||||
MOZ_ASSERT(mInputStream);
|
||||
|
||||
|
@ -1240,7 +1241,7 @@ LayerScopeWebSocketHandler::OnInputStreamReady(nsIAsyncInputStream *aStream)
|
|||
}
|
||||
|
||||
void
|
||||
LayerScopeWebSocketHandler::ReadInputStreamData(nsTArray<nsCString>& aProtocolString)
|
||||
LayerScopeWebSocketManager::SocketHandler::ReadInputStreamData(nsTArray<nsCString>& aProtocolString)
|
||||
{
|
||||
nsLineBuffer<char> lineBuffer;
|
||||
nsCString line;
|
||||
|
@ -1255,7 +1256,7 @@ LayerScopeWebSocketHandler::ReadInputStreamData(nsTArray<nsCString>& aProtocolSt
|
|||
}
|
||||
|
||||
bool
|
||||
LayerScopeWebSocketHandler::WebSocketHandshake(nsTArray<nsCString>& aProtocolString)
|
||||
LayerScopeWebSocketManager::SocketHandler::WebSocketHandshake(nsTArray<nsCString>& aProtocolString)
|
||||
{
|
||||
nsresult rv;
|
||||
bool isWebSocket = false;
|
||||
|
@ -1343,7 +1344,7 @@ LayerScopeWebSocketHandler::WebSocketHandshake(nsTArray<nsCString>& aProtocolStr
|
|||
}
|
||||
|
||||
nsresult
|
||||
LayerScopeWebSocketHandler::HandleSocketMessage(nsIAsyncInputStream *aStream)
|
||||
LayerScopeWebSocketManager::SocketHandler::HandleSocketMessage(nsIAsyncInputStream *aStream)
|
||||
{
|
||||
// The reading and parsing of this input stream is customized for layer viewer.
|
||||
const uint32_t cPacketSize = 1024;
|
||||
|
@ -1377,7 +1378,7 @@ LayerScopeWebSocketHandler::HandleSocketMessage(nsIAsyncInputStream *aStream)
|
|||
}
|
||||
|
||||
nsresult
|
||||
LayerScopeWebSocketHandler::ProcessInput(uint8_t *aBuffer,
|
||||
LayerScopeWebSocketManager::SocketHandler::ProcessInput(uint8_t *aBuffer,
|
||||
uint32_t aCount)
|
||||
{
|
||||
uint32_t avail = aCount;
|
||||
|
@ -1465,7 +1466,7 @@ LayerScopeWebSocketHandler::ProcessInput(uint8_t *aBuffer,
|
|||
}
|
||||
|
||||
void
|
||||
LayerScopeWebSocketHandler::ApplyMask(uint32_t aMask,
|
||||
LayerScopeWebSocketManager::SocketHandler::ApplyMask(uint32_t aMask,
|
||||
uint8_t *aData,
|
||||
uint64_t aLen)
|
||||
{
|
||||
|
@ -1505,7 +1506,7 @@ LayerScopeWebSocketHandler::ApplyMask(uint32_t aMask,
|
|||
}
|
||||
|
||||
bool
|
||||
LayerScopeWebSocketHandler::HandleDataFrame(uint8_t *aData,
|
||||
LayerScopeWebSocketManager::SocketHandler::HandleDataFrame(uint8_t *aData,
|
||||
uint32_t aSize)
|
||||
{
|
||||
// Handle payload data by protocol buffer
|
||||
|
@ -1539,7 +1540,7 @@ LayerScopeWebSocketHandler::HandleDataFrame(uint8_t *aData,
|
|||
}
|
||||
|
||||
void
|
||||
LayerScopeWebSocketHandler::CloseConnection()
|
||||
LayerScopeWebSocketManager::SocketHandler::CloseConnection()
|
||||
{
|
||||
gLayerScopeManager.GetSocketManager()->CleanDebugData();
|
||||
if (mInputStream) {
|
||||
|
@ -1556,18 +1557,18 @@ LayerScopeWebSocketHandler::CloseConnection()
|
|||
mConnected = false;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------
|
||||
// LayerScopeWebSocketManager implementation
|
||||
// ----------------------------------------------
|
||||
LayerScopeWebSocketManager::LayerScopeWebSocketManager()
|
||||
: mHandlerMutex("LayerScopeWebSocketManager::mHandlerMutex")
|
||||
{
|
||||
NS_NewThread(getter_AddRefs(mDebugSenderThread));
|
||||
|
||||
mServerSocket = do_CreateInstance(NS_SERVERSOCKET_CONTRACTID);
|
||||
int port = gfxPrefs::LayerScopePort();
|
||||
mServerSocket->Init(port, false, -1);
|
||||
mServerSocket->AsyncListen(new DebugListener);
|
||||
mServerSocket->AsyncListen(new SocketListener);
|
||||
}
|
||||
|
||||
LayerScopeWebSocketManager::~LayerScopeWebSocketManager()
|
||||
|
@ -1600,10 +1601,23 @@ LayerScopeWebSocketManager::DispatchDebugData()
|
|||
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
|
||||
// ----------------------------------------------
|
||||
/*static*/
|
||||
void
|
||||
LayerScope::Init()
|
||||
{
|
||||
|
@ -1614,6 +1628,7 @@ LayerScope::Init()
|
|||
gLayerScopeManager.CreateServerSocket();
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void
|
||||
LayerScope::DrawBegin()
|
||||
{
|
||||
|
@ -1624,6 +1639,7 @@ LayerScope::DrawBegin()
|
|||
gLayerScopeManager.NewDrawSession();
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void
|
||||
LayerScope::SetRenderOffset(float aX, float aY)
|
||||
{
|
||||
|
@ -1635,6 +1651,7 @@ LayerScope::SetRenderOffset(float aX, float aY)
|
|||
gLayerScopeManager.CurrentSession().mOffsetY = aY;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void
|
||||
LayerScope::SetLayerTransform(const gfx::Matrix4x4& aMatrix)
|
||||
{
|
||||
|
@ -1645,6 +1662,7 @@ LayerScope::SetLayerTransform(const gfx::Matrix4x4& aMatrix)
|
|||
gLayerScopeManager.CurrentSession().mMVMatrix = aMatrix;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void
|
||||
LayerScope::SetDrawRects(size_t aRects,
|
||||
const gfx::Rect* aLayerRects,
|
||||
|
@ -1665,6 +1683,7 @@ LayerScope::SetDrawRects(size_t aRects,
|
|||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void
|
||||
LayerScope::DrawEnd(gl::GLContext* aGLContext,
|
||||
const EffectChain& aEffectChain,
|
||||
|
@ -1692,6 +1711,7 @@ LayerScope::DrawEnd(gl::GLContext* aGLContext,
|
|||
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void
|
||||
LayerScope::SendLayer(LayerComposite* aLayer,
|
||||
int aWidth,
|
||||
|
@ -1704,6 +1724,7 @@ LayerScope::SendLayer(LayerComposite* aLayer,
|
|||
SenderHelper::SendLayer(aLayer, aWidth, aHeight);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void
|
||||
LayerScope::SendLayerDump(UniquePtr<Packet> aPacket)
|
||||
{
|
||||
|
@ -1715,6 +1736,7 @@ LayerScope::SendLayerDump(UniquePtr<Packet> aPacket)
|
|||
new DebugGLLayersData(Move(aPacket)));
|
||||
}
|
||||
|
||||
/*static*/
|
||||
bool
|
||||
LayerScope::CheckSendable()
|
||||
{
|
||||
|
@ -1734,6 +1756,7 @@ LayerScope::CheckSendable()
|
|||
return true;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void
|
||||
LayerScope::CleanLayer()
|
||||
{
|
||||
|
@ -1742,6 +1765,7 @@ LayerScope::CleanLayer()
|
|||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void
|
||||
LayerScope::SetHWComposed()
|
||||
{
|
||||
|
@ -1751,11 +1775,13 @@ LayerScope::SetHWComposed()
|
|||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void
|
||||
LayerScope::SetPixelScale(double devPixelsPerCSSPixel)
|
||||
{
|
||||
gLayerScopeManager.SetPixelScale(devPixelsPerCSSPixel);
|
||||
}
|
||||
|
||||
// ----------------------------------------------
|
||||
// LayerScopeAutoFrame implementation
|
||||
// ----------------------------------------------
|
||||
|
|
|
@ -47,11 +47,8 @@ function MapIteratorNext() {
|
|||
// Steps 8-9 (omitted).
|
||||
|
||||
var mapIterationResultPair = iteratorTemp.mapIterationResultPair;
|
||||
if (!mapIterationResultPair) {
|
||||
mapIterationResultPair = iteratorTemp.mapIterationResultPair = NewDenseArray(2);
|
||||
mapIterationResultPair[0] = null;
|
||||
mapIterationResultPair[1] = null;
|
||||
}
|
||||
if (!mapIterationResultPair)
|
||||
mapIterationResultPair = iteratorTemp.mapIterationResultPair = [null, null];
|
||||
|
||||
var retVal = {value: undefined, done: true};
|
||||
|
||||
|
|
|
@ -10,11 +10,10 @@
|
|||
"unpack": true
|
||||
},
|
||||
{
|
||||
"size": 12057960,
|
||||
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
|
||||
"size": 4431740,
|
||||
"digest": "68fc56b0fb0cdba629b95683d6649ff76b00dccf97af90960c3d7716f6108b2162ffd5ffcd5c3a60a21b28674df688fe4dabc67345e2da35ec5abeae3d48c8e3",
|
||||
"algorithm": "sha512",
|
||||
"filename": "gtk3.tar.xz",
|
||||
"setup": "setup.sh",
|
||||
"unpack": true
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1324,7 +1324,7 @@ static inline ScriptCountsMap::Ptr GetScriptCountsMapEntry(JSScript* script)
|
|||
return p;
|
||||
}
|
||||
|
||||
js::PCCounts
|
||||
js::PCCounts&
|
||||
JSScript::getPCCounts(jsbytecode* pc) {
|
||||
MOZ_ASSERT(containsPC(pc));
|
||||
ScriptCountsMap::Ptr p = GetScriptCountsMapEntry(this);
|
||||
|
|
|
@ -1629,7 +1629,7 @@ class JSScript : public js::gc::TenuredCell
|
|||
|
||||
public:
|
||||
bool initScriptCounts(JSContext* cx);
|
||||
js::PCCounts getPCCounts(jsbytecode* pc);
|
||||
js::PCCounts& getPCCounts(jsbytecode* pc);
|
||||
void addIonCounts(js::jit::IonScriptCounts* ionCounts);
|
||||
js::jit::IonScriptCounts* getIonCounts();
|
||||
js::ScriptCounts releaseScriptCounts();
|
||||
|
|
|
@ -1281,7 +1281,7 @@ XPCConvert::NativeArray2JS(MutableHandleValue d, const void** s,
|
|||
for (i = 0; i < count; i++) { \
|
||||
if (!NativeData2JS(¤t, ((_t*)*s)+i, type, iid, pErr) || \
|
||||
!JS_DefineElement(cx, array, i, current, JSPROP_ENUMERATE)) \
|
||||
goto failure; \
|
||||
return false; \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
|
@ -1301,17 +1301,17 @@ XPCConvert::NativeArray2JS(MutableHandleValue d, const void** s,
|
|||
case nsXPTType::T_BOOL : POPULATE(bool); break;
|
||||
case nsXPTType::T_CHAR : POPULATE(char); 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_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_WCHAR_STR : POPULATE(char16_t*); break;
|
||||
case nsXPTType::T_INTERFACE : POPULATE(nsISupports*); break;
|
||||
case nsXPTType::T_INTERFACE_IS : POPULATE(nsISupports*); break;
|
||||
case nsXPTType::T_UTF8STRING : NS_ERROR("bad type"); goto failure;
|
||||
case nsXPTType::T_CSTRING : NS_ERROR("bad type"); goto failure;
|
||||
case nsXPTType::T_ASTRING : NS_ERROR("bad type"); goto failure;
|
||||
default : NS_ERROR("bad type"); goto failure;
|
||||
case nsXPTType::T_UTF8STRING : NS_ERROR("bad type"); return false;
|
||||
case nsXPTType::T_CSTRING : NS_ERROR("bad type"); return false;
|
||||
case nsXPTType::T_ASTRING : NS_ERROR("bad type"); return false;
|
||||
default : NS_ERROR("bad type"); return false;
|
||||
}
|
||||
|
||||
if (pErr)
|
||||
|
@ -1319,9 +1319,6 @@ XPCConvert::NativeArray2JS(MutableHandleValue d, const void** s,
|
|||
d.setObject(*array);
|
||||
return true;
|
||||
|
||||
failure:
|
||||
return false;
|
||||
|
||||
#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
|
||||
== 1179078-1.html 1179078-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
|
||||
// percentage heights. This is handled via nsChangeHint_UpdateComputedBSize
|
||||
// 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_ReflowChangesSizeOrPosition);
|
||||
}
|
||||
|
@ -1610,16 +1610,13 @@ nsChangeHint nsStylePosition::CalcDifference(const nsStylePosition& aOther) cons
|
|||
mMaxWidth != aOther.mMaxWidth) {
|
||||
// None of our width differences can affect descendant intrinsic
|
||||
// sizes and none of them need to force children to reflow.
|
||||
return
|
||||
NS_CombineHint(hint,
|
||||
NS_SubtractHint(nsChangeHint_AllReflowHints,
|
||||
NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics,
|
||||
nsChangeHint_NeedDirtyReflow)));
|
||||
NS_UpdateHint(hint, NS_SubtractHint(nsChangeHint_AllReflowHints,
|
||||
NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics,
|
||||
nsChangeHint_NeedDirtyReflow)));
|
||||
}
|
||||
|
||||
// If width and height have not changed, but any of the offsets have changed,
|
||||
// then return the respective hints so that we would hopefully be able to
|
||||
// avoid reflowing.
|
||||
// If any of the offsets have changed, then return the respective hints
|
||||
// so that we would hopefully be able to avoid reflowing.
|
||||
// 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
|
||||
// right now.
|
||||
|
@ -1630,7 +1627,7 @@ nsChangeHint nsStylePosition::CalcDifference(const nsStylePosition& aOther) cons
|
|||
NS_UpdateHint(hint, nsChangeHint(nsChangeHint_RecomputePosition |
|
||||
nsChangeHint_UpdateParentOverflow));
|
||||
} else {
|
||||
return NS_CombineHint(hint, nsChangeHint_AllReflowHints);
|
||||
NS_UpdateHint(hint, nsChangeHint_AllReflowHints);
|
||||
}
|
||||
}
|
||||
return hint;
|
||||
|
|
|
@ -580,7 +580,9 @@ SampleTable::setSampleAuxiliaryInformationOffsetParams(
|
|||
}
|
||||
data_offset += 4;
|
||||
|
||||
mCencOffsets.setCapacity(cencOffsetCount);
|
||||
if (mCencOffsets.setCapacity(cencOffsetCount) < 0) {
|
||||
return ERROR_MALFORMED;
|
||||
}
|
||||
if (!version) {
|
||||
for (uint32_t i = 0; i < cencOffsetCount; i++) {
|
||||
uint32_t tmp;
|
||||
|
@ -1104,8 +1106,12 @@ SampleTable::getSampleCencInfo(
|
|||
}
|
||||
|
||||
auto& info = mCencInfo[sample_index];
|
||||
clear_sizes.setCapacity(info.mSubsampleCount);
|
||||
cipher_sizes.setCapacity(info.mSubsampleCount);
|
||||
if (clear_sizes.setCapacity(info.mSubsampleCount) < 0) {
|
||||
return ERROR_MALFORMED;
|
||||
}
|
||||
if (cipher_sizes.setCapacity(info.mSubsampleCount) < 0) {
|
||||
return ERROR_MALFORMED;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < info.mSubsampleCount; i++) {
|
||||
clear_sizes.push(info.mSubsamples[i].mClearBytes);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#define ANDROID_VECTOR_H
|
||||
|
||||
#include <new>
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
|
@ -191,7 +192,7 @@ public:
|
|||
inline iterator end() { return editArray() + size(); }
|
||||
inline const_iterator begin() const { return array(); }
|
||||
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 void push_back(const TYPE& item) { insertAt(item, size(), 1); }
|
||||
inline void push_front(const TYPE& item) { insertAt(item, 0, 1); }
|
||||
|
|
|
@ -27,9 +27,8 @@
|
|||
#include <utils/SharedBuffer.h>
|
||||
#include <utils/VectorImpl.h>
|
||||
|
||||
#if !defined(SSIZE_MAX)
|
||||
#define SSIZE_MAX ((ssize_t)(SIZE_MAX/2))
|
||||
#endif
|
||||
static const uint32_t kMAX_ALLOCATION =
|
||||
((SIZE_MAX > INT32_MAX ? INT32_MAX : SIZE_MAX) - 1);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
@ -93,6 +92,7 @@ void* VectorImpl::editArrayImpl()
|
|||
SharedBuffer* sb = SharedBuffer::bufferFromData(mStorage)->attemptEdit();
|
||||
if (sb == 0) {
|
||||
sb = SharedBuffer::alloc(capacity() * mItemSize);
|
||||
assert(sb);
|
||||
if (sb) {
|
||||
_do_copy(sb->data(), mStorage, mCount);
|
||||
release_storage();
|
||||
|
@ -334,7 +334,7 @@ ssize_t VectorImpl::setCapacity(size_t new_capacity)
|
|||
// we can't reduce the capacity
|
||||
return capacity();
|
||||
}
|
||||
if (new_capacity >= (SSIZE_MAX / mItemSize)) {
|
||||
if (new_capacity >= (kMAX_ALLOCATION / mItemSize)) {
|
||||
return NO_MEMORY;
|
||||
}
|
||||
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
|
||||
|
||||
const size_t new_size = mCount + amount;
|
||||
assert(amount < kMAX_ALLOCATION - mCount);
|
||||
if (capacity() < new_size) {
|
||||
assert(new_size < (SIZE_MAX / 3 - 1));
|
||||
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);
|
||||
if ((mStorage) &&
|
||||
(mCount==where) &&
|
||||
|
@ -389,10 +392,13 @@ void* VectorImpl::_grow(size_t where, size_t amount)
|
|||
(mFlags & HAS_TRIVIAL_DTOR))
|
||||
{
|
||||
const SharedBuffer* cur_sb = SharedBuffer::bufferFromData(mStorage);
|
||||
assert(cur_sb);
|
||||
SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize);
|
||||
assert(sb);
|
||||
mStorage = sb->data();
|
||||
} else {
|
||||
SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
|
||||
assert(sb);
|
||||
if (sb) {
|
||||
void* array = sb->data();
|
||||
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
|
||||
|
||||
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);
|
||||
// ALOGV("shrink vector %p, new_capacity=%d", this, (int)new_capacity);
|
||||
assert(new_capacity < (kMAX_ALLOCATION / mItemSize));
|
||||
if ((where == new_size) &&
|
||||
(mFlags & HAS_TRIVIAL_COPY) &&
|
||||
(mFlags & HAS_TRIVIAL_DTOR))
|
||||
{
|
||||
const SharedBuffer* cur_sb = SharedBuffer::bufferFromData(mStorage);
|
||||
assert(cur_sb);
|
||||
SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize);
|
||||
assert(sb);
|
||||
mStorage = sb->data();
|
||||
} else {
|
||||
SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
|
||||
assert(sb);
|
||||
if (sb) {
|
||||
void* array = sb->data();
|
||||
if (where != 0) {
|
||||
|
@ -461,6 +472,7 @@ void VectorImpl::_shrink(size_t where, size_t amount)
|
|||
}
|
||||
} else {
|
||||
void* array = editArrayImpl();
|
||||
assert(array);
|
||||
void* to = reinterpret_cast<uint8_t *>(array) + where*mItemSize;
|
||||
_do_destroy(to, amount);
|
||||
if (where != new_size) {
|
||||
|
|
|
@ -289,7 +289,7 @@ JsepSessionImpl::GetRemoteTracksRemoved() const
|
|||
}
|
||||
|
||||
nsresult
|
||||
JsepSessionImpl::AddOfferMSections(const JsepOfferOptions& options, Sdp* sdp)
|
||||
JsepSessionImpl::SetupOfferMSections(const JsepOfferOptions& options, Sdp* sdp)
|
||||
{
|
||||
// First audio, then video, then datachannel, for interop
|
||||
// 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
|
||||
// audio-only stream.
|
||||
// We should probably wait until 38 is ESR before trying to do this.
|
||||
nsresult rv = AddOfferMSectionsByType(
|
||||
nsresult rv = SetupOfferMSectionsByType(
|
||||
SdpMediaSection::kAudio, options.mOfferToReceiveAudio, sdp);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = AddOfferMSectionsByType(
|
||||
rv = SetupOfferMSectionsByType(
|
||||
SdpMediaSection::kVideo, options.mOfferToReceiveVideo, sdp);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!(options.mDontOfferDataChannel.isSome() &&
|
||||
*options.mDontOfferDataChannel)) {
|
||||
rv = AddOfferMSectionsByType(
|
||||
rv = SetupOfferMSectionsByType(
|
||||
SdpMediaSection::kApplication, Maybe<size_t>(), sdp);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -325,9 +325,9 @@ JsepSessionImpl::AddOfferMSections(const JsepOfferOptions& options, Sdp* sdp)
|
|||
}
|
||||
|
||||
nsresult
|
||||
JsepSessionImpl::AddOfferMSectionsByType(SdpMediaSection::MediaType mediatype,
|
||||
Maybe<size_t> offerToReceiveMaybe,
|
||||
Sdp* sdp)
|
||||
JsepSessionImpl::SetupOfferMSectionsByType(SdpMediaSection::MediaType mediatype,
|
||||
Maybe<size_t> offerToReceiveMaybe,
|
||||
Sdp* sdp)
|
||||
{
|
||||
// Convert the Maybe into a size_t*, since that is more readable, especially
|
||||
// when using it as an in/out param.
|
||||
|
@ -467,7 +467,7 @@ JsepSessionImpl::SetRecvAsNeededOrDisable(SdpMediaSection::MediaType mediatype,
|
|||
|
||||
if (!msection.IsSending()) {
|
||||
// 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
|
||||
// (ie; all m-sections are inactive).
|
||||
nsresult
|
||||
JsepSessionImpl::CreateReoffer(const Sdp& oldLocalSdp,
|
||||
const Sdp& oldAnswer,
|
||||
Sdp* newSdp)
|
||||
JsepSessionImpl::AddReofferMsections(const Sdp& oldLocalSdp,
|
||||
const Sdp& oldAnswer,
|
||||
Sdp* newSdp)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
for (size_t i = 0; i < oldLocalSdp.GetMediaSectionCount(); ++i) {
|
||||
// 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(),
|
||||
SdpDirectionAttribute::kInactive,
|
||||
newSdp);
|
||||
|
@ -513,8 +513,6 @@ JsepSessionImpl::CreateReoffer(const Sdp& oldLocalSdp,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// TODO(1142105): Do we teach SdpHelper about BundlePolicy, or are
|
||||
// we getting too much JSEP in there at that point?
|
||||
void
|
||||
JsepSessionImpl::SetupBundle(Sdp* sdp) const
|
||||
{
|
||||
|
@ -608,41 +606,42 @@ JsepSessionImpl::CreateOffer(const JsepOfferOptions& options,
|
|||
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;
|
||||
|
||||
// Make the basic SDP that is common to offer/answer.
|
||||
nsresult rv = CreateGenericSDP(&sdp);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
++mSessionVersion;
|
||||
|
||||
if (mCurrentLocalDescription) {
|
||||
rv = CreateReoffer(*mCurrentLocalDescription, *GetAnswer(), sdp.get());
|
||||
rv = AddReofferMsections(*mCurrentLocalDescription,
|
||||
*GetAnswer(),
|
||||
sdp.get());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// Get rid of all m-line assignments that have not been negotiated
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
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());
|
||||
// Ensure that we have all the m-sections we need, and disable extras
|
||||
rv = SetupOfferMSections(options, sdp.get());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
SetupBundle(sdp.get());
|
||||
|
||||
if (GetAnswer()) {
|
||||
// We have an old answer from a previous negotiation
|
||||
rv = SetupTransportParams(*GetAnswer(), *sdp, sdp.get());
|
||||
if (mCurrentLocalDescription) {
|
||||
rv = CopyPreviousTransportParams(*GetAnswer(), *sdp, sdp.get());
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
*offer = sdp->ToString();
|
||||
mGeneratedLocalDescription = Move(sdp);
|
||||
++mSessionVersion;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -774,36 +773,10 @@ void
|
|||
JsepSessionImpl::AddCommonExtmaps(const SdpMediaSection& remoteMsection,
|
||||
SdpMediaSection* msection)
|
||||
{
|
||||
if (!remoteMsection.GetAttributeList().HasAttribute(
|
||||
SdpAttribute::kExtmapAttribute)) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* ourExtensions = GetRtpExtensions(remoteMsection.GetMediaType());
|
||||
|
||||
if (!ourExtensions) {
|
||||
return;
|
||||
}
|
||||
|
||||
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());
|
||||
if (ourExtensions) {
|
||||
mSdpHelper.AddCommonExtmaps(remoteMsection, *ourExtensions, msection);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -836,8 +809,6 @@ JsepSessionImpl::CreateAnswer(const JsepAnswerOptions& options,
|
|||
|
||||
const Sdp& offer = *mPendingRemoteDescription;
|
||||
|
||||
std::vector<SdpGroupAttributeList::Group> bundleGroups;
|
||||
|
||||
// Copy the bundle groups into our answer
|
||||
UniquePtr<SdpGroupAttributeList> groupAttr(new SdpGroupAttributeList);
|
||||
mSdpHelper.GetBundleGroups(offer, &groupAttr->mGroups);
|
||||
|
@ -869,9 +840,8 @@ JsepSessionImpl::CreateAnswer(const JsepAnswerOptions& options,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (GetAnswer()) {
|
||||
// We have an old answer from a previous negotiation
|
||||
rv = SetupTransportParams(*GetAnswer(), *sdp, sdp.get());
|
||||
if (mCurrentLocalDescription) {
|
||||
rv = CopyPreviousTransportParams(*GetAnswer(), *sdp, sdp.get());
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
|
@ -953,7 +923,7 @@ JsepSessionImpl::CreateAnswerMSection(const JsepAnswerOptions& options,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mSdpHelper.MsectionIsDisabled(remoteMsection)) {
|
||||
DisableMsection(sdp, &msection);
|
||||
mSdpHelper.DisableMsection(sdp, &msection);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -995,13 +965,13 @@ JsepSessionImpl::CreateAnswerMSection(const JsepAnswerOptions& options,
|
|||
AddCommonExtmaps(remoteMsection, &msection);
|
||||
|
||||
if (!msection.IsReceiving() && !msection.IsSending()) {
|
||||
DisableMsection(sdp, &msection);
|
||||
mSdpHelper.DisableMsection(sdp, &msection);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (msection.GetFormats().empty()) {
|
||||
// Could not negotiate anything. Disable m-section.
|
||||
DisableMsection(sdp, &msection);
|
||||
mSdpHelper.DisableMsection(sdp, &msection);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1158,7 +1128,7 @@ JsepSessionImpl::SetLocalDescription(JsepSdpType type, const std::string& sdp)
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Create transport objects.
|
||||
mOldTransports = mTransports;
|
||||
mOldTransports = mTransports; // Save in case we need to rollback
|
||||
for (size_t t = 0; t < parsed->GetMediaSectionCount(); ++t) {
|
||||
if (t >= mTransports.size()) {
|
||||
mTransports.push_back(RefPtr<JsepTransport>(new JsepTransport));
|
||||
|
@ -1385,11 +1355,9 @@ JsepSessionImpl::HandleNegotiatedSession(const UniquePtr<Sdp>& local,
|
|||
mNegotiatedTrackPairs = trackPairs;
|
||||
|
||||
// Mark all assigned local tracks as negotiated
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
for (auto i = mLocalTracks.begin(); i != mLocalTracks.end(); ++i) {
|
||||
if (i->mAssignedMLine.isSome()) {
|
||||
i->mNegotiated = true;
|
||||
}
|
||||
for (auto i = mLocalTracks.begin(); i != mLocalTracks.end(); ++i) {
|
||||
if (i->mAssignedMLine.isSome()) {
|
||||
i->mNegotiated = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1679,9 +1647,9 @@ JsepSessionImpl::AddTransportAttributes(SdpMediaSection* msection,
|
|||
}
|
||||
|
||||
nsresult
|
||||
JsepSessionImpl::SetupTransportParams(const Sdp& oldAnswer,
|
||||
const Sdp& newOffer,
|
||||
Sdp* newLocal)
|
||||
JsepSessionImpl::CopyPreviousTransportParams(const Sdp& oldAnswer,
|
||||
const Sdp& newOffer,
|
||||
Sdp* newLocal)
|
||||
{
|
||||
for (size_t i = 0; i < oldAnswer.GetMediaSectionCount(); ++i) {
|
||||
if (!mSdpHelper.MsectionIsDisabled(newLocal->GetMediaSection(i)) &&
|
||||
|
@ -2368,14 +2336,6 @@ JsepSessionImpl::EndOfLocalCandidates(const std::string& defaultCandidateAddr,
|
|||
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);
|
||||
if (mState == kJsepStateStable && mTransports[level]->mComponents == 1) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
SdpMediaSection& msection = sdp->GetMediaSection(level);
|
||||
|
||||
// TODO(bug 1142105): Factor some of this out into a helper class
|
||||
// If offer/answer isn't done, it is too early to tell whether these defaults
|
||||
// need to be applied to other m-sections.
|
||||
SdpHelper::BundledMids bundledMids;
|
||||
if (mState == kJsepStateStable) {
|
||||
// offer/answer is done. Do we actually incorporate these defaults?
|
||||
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 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);
|
||||
}
|
||||
}
|
||||
nsresult rv = GetNegotiatedBundledMids(&bundledMids);
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_ASSERT(false);
|
||||
mLastError += " (This should have been caught sooner!)";
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
mSdpHelper.SetDefaultAddresses(defaultCandidateAddr,
|
||||
defaultCandidatePort,
|
||||
defaultRtcpCandidateAddrCopy,
|
||||
defaultRtcpCandidatePort,
|
||||
&msection);
|
||||
|
||||
// TODO(bug 1095793): Will this have an mid someday?
|
||||
|
||||
SdpAttributeList& attrs = msection.GetAttributeList();
|
||||
attrs.SetAttribute(
|
||||
new SdpFlagAttribute(SdpAttribute::kEndOfCandidatesAttribute));
|
||||
if (!mIsOfferer) {
|
||||
attrs.RemoveAttribute(SdpAttribute::kIceOptionsAttribute);
|
||||
}
|
||||
mSdpHelper.SetDefaultAddresses(
|
||||
defaultCandidateAddr,
|
||||
defaultCandidatePort,
|
||||
defaultRtcpCandidateAddrCopy,
|
||||
defaultRtcpCandidatePort,
|
||||
sdp,
|
||||
level,
|
||||
bundledMids);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2449,19 +2379,6 @@ JsepSessionImpl::GetNegotiatedBundledMids(SdpHelper::BundledMids* 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
|
||||
JsepSessionImpl::EnableOfferMsection(SdpMediaSection* msection)
|
||||
{
|
||||
|
|
|
@ -217,14 +217,14 @@ private:
|
|||
const UniquePtr<Sdp>& remote);
|
||||
nsresult AddTransportAttributes(SdpMediaSection* msection,
|
||||
SdpSetupAttribute::Role dtlsRole);
|
||||
nsresult SetupTransportParams(const Sdp& oldAnswer,
|
||||
const Sdp& newOffer,
|
||||
Sdp* newLocal);
|
||||
nsresult AddOfferMSections(const JsepOfferOptions& options, Sdp* sdp);
|
||||
nsresult CopyPreviousTransportParams(const Sdp& oldAnswer,
|
||||
const Sdp& newOffer,
|
||||
Sdp* newLocal);
|
||||
nsresult SetupOfferMSections(const JsepOfferOptions& options, Sdp* sdp);
|
||||
// Non-const so it can assign m-line index to tracks
|
||||
nsresult AddOfferMSectionsByType(SdpMediaSection::MediaType type,
|
||||
Maybe<size_t> offerToReceive,
|
||||
Sdp* sdp);
|
||||
nsresult SetupOfferMSectionsByType(SdpMediaSection::MediaType type,
|
||||
Maybe<size_t> offerToReceive,
|
||||
Sdp* sdp);
|
||||
nsresult BindLocalTracks(SdpMediaSection::MediaType mediatype,
|
||||
Sdp* sdp);
|
||||
nsresult BindTrackToMsection(JsepSendingTrack* track,
|
||||
|
@ -238,9 +238,9 @@ private:
|
|||
nsresult AddRecvonlyMsections(SdpMediaSection::MediaType mediatype,
|
||||
size_t count,
|
||||
Sdp* sdp);
|
||||
nsresult CreateReoffer(const Sdp& oldLocalSdp,
|
||||
const Sdp& oldAnswer,
|
||||
Sdp* newSdp);
|
||||
nsresult AddReofferMsections(const Sdp& oldLocalSdp,
|
||||
const Sdp& oldAnswer,
|
||||
Sdp* newSdp);
|
||||
void SetupBundle(Sdp* sdp) const;
|
||||
nsresult GetRemoteIds(const Sdp& sdp,
|
||||
const SdpMediaSection& msection,
|
||||
|
@ -280,7 +280,6 @@ private:
|
|||
|
||||
nsresult GetNegotiatedBundledMids(SdpHelper::BundledMids* bundledMids);
|
||||
|
||||
void DisableMsection(Sdp* sdp, SdpMediaSection* msection) const;
|
||||
nsresult EnableOfferMsection(SdpMediaSection* msection);
|
||||
|
||||
nsresult SetUniquePayloadTypes();
|
||||
|
|
|
@ -138,6 +138,11 @@ SdpHelper::DisableMsection(Sdp* sdp, SdpMediaSection* msection) const
|
|||
new SdpDirectionAttribute(SdpDirectionAttribute::kInactive);
|
||||
msection->GetAttributeList().SetAttribute(direction);
|
||||
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
|
||||
|
@ -266,6 +271,61 @@ SdpHelper::AddCandidateToSdp(Sdp* sdp,
|
|||
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
|
||||
SdpHelper::SetDefaultAddresses(const std::string& defaultCandidateAddr,
|
||||
uint16_t defaultCandidatePort,
|
||||
|
@ -604,6 +664,39 @@ SdpHelper::GetPtAsInt(const std::string& ptString, uint16_t* ptOutparam)
|
|||
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
|
||||
|
||||
|
||||
|
|
|
@ -62,6 +62,13 @@ class SdpHelper {
|
|||
const std::string& candidate,
|
||||
const std::string& mid,
|
||||
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,
|
||||
uint16_t defaultCandidatePort,
|
||||
const std::string& defaultRtcpCandidateAddr,
|
||||
|
@ -92,6 +99,11 @@ class SdpHelper {
|
|||
|
||||
static bool GetPtAsInt(const std::string& ptString, uint16_t* ptOutparam);
|
||||
|
||||
void AddCommonExtmaps(
|
||||
const SdpMediaSection& remoteMsection,
|
||||
const std::vector<SdpExtmapAttributeList::Extmap>& localExtensions,
|
||||
SdpMediaSection* localMsection);
|
||||
|
||||
private:
|
||||
std::string& mLastError;
|
||||
|
||||
|
|
|
@ -798,20 +798,6 @@ SpdySession31::GenerateSettings()
|
|||
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
|
||||
// a window update with it in order to use larger initial windows with pulled
|
||||
// streams.
|
||||
|
@ -1445,41 +1431,12 @@ SpdySession31::HandleSettings(SpdySession31 *self)
|
|||
|
||||
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:
|
||||
self->mMaxConcurrent = value;
|
||||
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_MAX_STREAMS, value);
|
||||
self->ProcessPending();
|
||||
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:
|
||||
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_IW, value >> 10);
|
||||
{
|
||||
int32_t delta = value - self->mServerInitialStreamWindow;
|
||||
self->mServerInitialStreamWindow = value;
|
||||
|
|
|
@ -25,6 +25,7 @@ HTTP_ATOM(Age, "Age")
|
|||
HTTP_ATOM(Allow, "Allow")
|
||||
HTTP_ATOM(Alternate_Service, "Alt-Svc")
|
||||
HTTP_ATOM(Alternate_Service_Used, "Alt-Used")
|
||||
HTTP_ATOM(Alternate_Protocol, "Alternate-Protocol")
|
||||
HTTP_ATOM(Assoc_Req, "Assoc-Req")
|
||||
HTTP_ATOM(Authentication, "Authentication")
|
||||
HTTP_ATOM(Authorization, "Authorization")
|
||||
|
|
|
@ -1397,13 +1397,21 @@ nsHttpChannel::ProcessResponse()
|
|||
nsresult rv;
|
||||
uint32_t httpStatus = mResponseHead->Status();
|
||||
|
||||
// Gather data on whether the transaction and page (if this is
|
||||
// the initial page load) is being loaded with SSL.
|
||||
Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_IS_SSL,
|
||||
mConnectionInfo->EndToEndSSL());
|
||||
if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI) {
|
||||
Telemetry::Accumulate(Telemetry::HTTP_PAGELOAD_IS_SSL,
|
||||
// do some telemetry
|
||||
if (gHttpHandler->IsTelemetryEnabled()) {
|
||||
// Gather data on whether the transaction and page (if this is
|
||||
// the initial page load) is being loaded with SSL.
|
||||
Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_IS_SSL,
|
||||
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",
|
||||
|
|
|
@ -747,67 +747,6 @@ nsHttpConnectionMgr::ReportSpdyConnection(nsHttpConnection *conn,
|
|||
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::GetSpdyPreferredEnt(nsConnectionEntry *aOriginalEntry)
|
||||
{
|
||||
|
@ -3669,7 +3608,6 @@ nsConnectionEntry::nsConnectionEntry(nsHttpConnectionInfo *ci)
|
|||
, mYellowConnection(nullptr)
|
||||
, mGreenDepth(kPipelineOpen)
|
||||
, mPipeliningPenalty(0)
|
||||
, mSpdyCWND(0)
|
||||
, mUsingSpdy(false)
|
||||
, mTestedSpdy(false)
|
||||
, mInPreferredHash(false)
|
||||
|
|
|
@ -242,11 +242,6 @@ public:
|
|||
// bit different.
|
||||
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 GetConnectionData(nsTArray<HttpRetParams> *);
|
||||
|
@ -366,11 +361,6 @@ private:
|
|||
//
|
||||
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
|
||||
// entry has done NPN=spdy/* at some point. It does not mean every
|
||||
// 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
|
||||
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
|
||||
---------
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ import tempfile
|
|||
import xml.dom.minidom
|
||||
import zipfile
|
||||
|
||||
import mozdevice
|
||||
import mozfile
|
||||
import mozlog
|
||||
|
||||
|
@ -189,6 +188,13 @@ class RemoteB2GVersion(B2GVersion):
|
|||
**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':
|
||||
dm = mozdevice.DeviceManagerADB(deviceSerial=device_serial,
|
||||
serverHost=adb_host,
|
||||
|
|
|
@ -6,9 +6,6 @@ from setuptools import setup
|
|||
|
||||
PACKAGE_VERSION = '1.3'
|
||||
|
||||
dependencies = ['mozdevice >= 0.44',
|
||||
'mozfile >= 1.0',
|
||||
'mozlog >= 3.0']
|
||||
|
||||
setup(name='mozversion',
|
||||
version=PACKAGE_VERSION,
|
||||
|
@ -23,7 +20,8 @@ setup(name='mozversion',
|
|||
packages=['mozversion'],
|
||||
include_package_data=True,
|
||||
zip_safe=False,
|
||||
install_requires=dependencies,
|
||||
install_requires=['mozfile >= 1.0', 'mozlog >= 3.0'],
|
||||
extras_require={'device': ['mozdevice >= 0.44']},
|
||||
entry_points="""
|
||||
# -*- Entry points: -*-
|
||||
[console_scripts]
|
||||
|
|
|
@ -1456,7 +1456,7 @@
|
|||
"description": "SPDY: KB read per connection"
|
||||
},
|
||||
"SPDY_SETTINGS_UL_BW": {
|
||||
"expires_in_version": "never",
|
||||
"expires_in_version": "42",
|
||||
"kind": "exponential",
|
||||
"high": "10000",
|
||||
"n_buckets": 100,
|
||||
|
@ -1464,7 +1464,7 @@
|
|||
"description": "SPDY: Settings Upload Bandwidth"
|
||||
},
|
||||
"SPDY_SETTINGS_DL_BW": {
|
||||
"expires_in_version": "never",
|
||||
"expires_in_version": "42",
|
||||
"kind": "exponential",
|
||||
"high": "10000",
|
||||
"n_buckets": 100,
|
||||
|
@ -1472,7 +1472,7 @@
|
|||
"description": "SPDY: Settings Download Bandwidth"
|
||||
},
|
||||
"SPDY_SETTINGS_RTT": {
|
||||
"expires_in_version": "never",
|
||||
"expires_in_version": "42",
|
||||
"kind": "exponential",
|
||||
"high": "1000",
|
||||
"n_buckets": 100,
|
||||
|
@ -1485,10 +1485,10 @@
|
|||
"high": "5000",
|
||||
"n_buckets": 100,
|
||||
"extended_statistics_ok": true,
|
||||
"description": "SPDY: Settings Max Streams parameter"
|
||||
"description": "H2: Settings Max Streams parameter"
|
||||
},
|
||||
"SPDY_SETTINGS_CWND": {
|
||||
"expires_in_version": "never",
|
||||
"expires_in_version": "42",
|
||||
"kind": "exponential",
|
||||
"high": "500",
|
||||
"n_buckets": 50,
|
||||
|
@ -1496,7 +1496,7 @@
|
|||
"description": "SPDY: Settings CWND (packets)"
|
||||
},
|
||||
"SPDY_SETTINGS_RETRANS": {
|
||||
"expires_in_version": "never",
|
||||
"expires_in_version": "42",
|
||||
"kind": "exponential",
|
||||
"high": "100",
|
||||
"n_buckets": 50,
|
||||
|
@ -1509,7 +1509,7 @@
|
|||
"high": "1000",
|
||||
"n_buckets": 50,
|
||||
"extended_statistics_ok": true,
|
||||
"description": "SPDY: Settings IW (rounded to KB)"
|
||||
"description": "H2: Settings Initial Window (rounded to KB)"
|
||||
},
|
||||
"DISK_CACHE_CORRUPT_DETAILS": {
|
||||
"expires_in_version": "40",
|
||||
|
@ -1657,7 +1657,12 @@
|
|||
"extended_statistics_ok": true,
|
||||
"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",
|
||||
"kind": "exponential",
|
||||
"high": "32000000",
|
||||
|
|
|
@ -1063,7 +1063,7 @@ let Histogram = {
|
|||
if (aHgram.values.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) {
|
||||
let barValue = aOptions.exponential ? this.getLogValue(value) : value;
|
||||
|
|
|
@ -436,11 +436,29 @@ protected:
|
|||
bool Update(const IMENotification& aIMENotification);
|
||||
bool Init(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;
|
||||
// mSelection stores the latest selection data only when sHasFocus it true.
|
||||
// Therefore, if sHasFocus is false, temporary instance should be used.
|
||||
Selection GetSelection() { return sHasFocus ? mSelection : Selection(); }
|
||||
|
||||
Selection& GetSelection()
|
||||
{
|
||||
// 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 mIsComposingOnPlugin;
|
||||
|
|
Загрузка…
Ссылка в новой задаче