Preferences::GetBool is not thread-safe, StaticPrefs are.
Also StaticPrefs are nicer anyway.
There's a lot of Preferences:: usage in dom/media which looks suspicious, though
I don't know if all that runs on the main thread.
Differential Revision: https://phabricator.services.mozilla.com/D38097
--HG--
extra : moz-landing-system : lando
This also removes the following prefs, because they're unused:
- media.autoplay.allow-muted pref
- media.autoplay.blackList-override-default
Differential Revision: https://phabricator.services.mozilla.com/D36396
--HG--
extra : rebase_source : 0570540496302b3efedadf4d5115ee5422d5c279
Changes:
- rebalance chunk
- turn off three tests that are nearly permafail
Differential Revision: https://phabricator.services.mozilla.com/D34932
--HG--
extra : moz-landing-system : lando
This allows us to avoid a (probably small) copy when we stash the pending input.
Differential Revision: https://phabricator.services.mozilla.com/D34662
--HG--
extra : moz-landing-system : lando
As seen in this profile of a Twitch replay: https://perfht.ml/2K9Ydb3 we can
often end up spending time in TrackBuffersManager::CodedFrameProcessing()
shaving off bytes from the front off TrackBuffersManager::mInputBuffer. This
requires all the remaining bytes to be memmove'd down to the start of this
array. Sometimes we have close to 1MB in that buffer, and when we're just
trying to consume a few hundred bytes, that becomes high overhead.
So intead of using this "slice off, shuffle down" approach change
TrackBuffersManager::mInputBuffer to be a new type MediaSpan, which maintains a
RefPtr to a MediaByteBuffer and a span defining the subregion of the buffer we
care about. This means the RemoveElementsAt(0,N) operation becomes basically
free, and we can eliminate a few other copies we were doing as well.
Differential Revision: https://phabricator.services.mozilla.com/D34661
--HG--
extra : moz-landing-system : lando
This allows us to avoid a (probably small) copy when we stash the pending input.
Differential Revision: https://phabricator.services.mozilla.com/D34662
--HG--
extra : moz-landing-system : lando
As seen in this profile of a Twitch replay: https://perfht.ml/2K9Ydb3 we can
often end up spending time in TrackBuffersManager::CodedFrameProcessing()
shaving off bytes from the front off TrackBuffersManager::mInputBuffer. This
requires all the remaining bytes to be memmove'd down to the start of this
array. Sometimes we have close to 1MB in that buffer, and when we're just
trying to consume a few hundred bytes, that becomes high overhead.
So intead of using this "slice off, shuffle down" approach change
TrackBuffersManager::mInputBuffer to be a new type MediaSpan, which maintains a
RefPtr to a MediaByteBuffer and a span defining the subregion of the buffer we
care about. This means the RemoveElementsAt(0,N) operation becomes basically
free, and we can eliminate a few other copies we were doing as well.
Differential Revision: https://phabricator.services.mozilla.com/D34661
--HG--
extra : moz-landing-system : lando
A lot of the overhead in MoofParser::RebuildFragmentedIndex(BoxContext&) is
copying data into the BoxReader's storage. In the MSE case the underlying data
being read is actually buffered in memory, so we may be able to just read the
in-memory data directly, avoiding the copy.
Note that the data may not be stored in a single contiguous ResourceItem in the
SourceBufferResource's ResourQueue. If so, it's not as straightforward to hand
out a uint8_t* to the underlying data. So we just copy it in that case for
simplicity. In most cases, the data in a single MP4 box would be appended in a
single append, and so is likely to be in a single ResourceItem.
Differential Revision: https://phabricator.services.mozilla.com/D33877
--HG--
extra : moz-landing-system : lando
The demuxer's low level byte reading abstraction is ResourceQueue::CopyData(),
but that's doing a linear scan through its list of ResourceItems in
GetOffsetAt() in order to find the ResourceItem in which the data to be read
lies. This sometimes shows up at the bottom of call stacks.
We could make this faster by doing a bisection search to find the ResourceItem
we need.
Differential Revision: https://phabricator.services.mozilla.com/D33871
--HG--
extra : moz-landing-system : lando
A lot of the overhead in MoofParser::RebuildFragmentedIndex(BoxContext&) is
copying data into the BoxReader's storage. In the MSE case the underlying data
being read is actually buffered in memory, so we may be able to just read the
in-memory data directly, avoiding the copy.
Note that the data may not be stored in a single contiguous ResourceItem in the
SourceBufferResource's ResourQueue. If so, it's not as straightforward to hand
out a uint8_t* to the underlying data. So we just copy it in that case for
simplicity. In most cases, the data in a single MP4 box would be appended in a
single append, and so is likely to be in a single ResourceItem.
Differential Revision: https://phabricator.services.mozilla.com/D33877
--HG--
extra : moz-landing-system : lando
The demuxer's low level byte reading abstraction is ResourceQueue::CopyData(),
but that's doing a linear scan through its list of ResourceItems in
GetOffsetAt() in order to find the ResourceItem in which the data to be read
lies. This sometimes shows up at the bottom of call stacks.
We could make this faster by doing a bisection search to find the ResourceItem
we need.
Differential Revision: https://phabricator.services.mozilla.com/D33871
--HG--
extra : moz-landing-system : lando
This patch structurizes the media debug information via webidl dictionaries
that are returned by HTMLMediaElement::GetMozRequestDebugInfo() and
MediaSource::GetMozDebugReaderData().
Differential Revision: https://phabricator.services.mozilla.com/D27893
--HG--
extra : moz-landing-system : lando
This patch structurizes the media debug information via webidl dictionaries
that are returned by HTMLMediaElement::GetMozRequestDebugInfo() and
MediaSource::GetMozDebugReaderData().
Differential Revision: https://phabricator.services.mozilla.com/D27893
--HG--
extra : moz-landing-system : lando
This is split from the previous changeset since if we include dom/ the file size is too
large for phabricator to handle.
This is an autogenerated commit to handle scripts loading mochitest harness files, in
the simple case where the script src is on the same line as the tag.
This was generated with https://bug1544322.bmoattachments.org/attachment.cgi?id=9058170
using the `--part 2` argument.
Differential Revision: https://phabricator.services.mozilla.com/D27457
--HG--
extra : moz-landing-system : lando
Disable test_isTypeSupported on android version >= 28 (Android 9.0) since our
infra there doesn't support cross origins there, at least until bug 1335740
is resolved.
Differential Revision: https://phabricator.services.mozilla.com/D27215
--HG--
extra : moz-landing-system : lando
YouTube.com/tv uses YouTube specific extensions to MediaSource.isTypeSupported
in order to determine whether it serves 4K. It checks with bogus values, and if
we reject the bogus values, it assumes we're responding truthfully to the other
queries. So add support to reject the bogus values on YouTube.com.
With this patch, we can play 4K on YouTube.com/tv.
Differential Revision: https://phabricator.services.mozilla.com/D26655
--HG--
extra : moz-landing-system : lando
YouTube.com/tv uses YouTube specific extensions to MediaSource.isTypeSupported
in order to determine whether it serves 4K. It checks with bogus values, and if
we reject the bogus values, it assumes we're responding truthfully to the other
queries. So add support to reject the bogus values on YouTube.com.
With this patch, we can play 4K on YouTube.com/tv.
Differential Revision: https://phabricator.services.mozilla.com/D26655
--HG--
extra : moz-landing-system : lando
Disabled the following for windows10-aarch64:
- test_getUserMedia_audioCapture
- test_AudioChange_mp4.html
- test_bug1255618.html
- test_singleSourceDest
- test_mediaElementAudioSourceNodeFidelity
- test_maxChannelCount
- test_abort
- test_audio_capture_error
- test_call_start_from_end_handler
- test_recognition_service_error
- test_success_without_recognition_service
- test_ExperimentalAsync
- test_peerConnection_restartIceNoBundle.html
All of these tests tend to fail on the first run of the push, then pass on the retry run.
Differential Revision: https://phabricator.services.mozilla.com/D24569
--HG--
extra : moz-landing-system : lando
Disable the following:
- test_MediaSource_flac_mp4 (keeps getting missed somehow)
- dom/media/test/mochitest.ini
Disabling the entire `dom/media/test/mochitest.ini` manifest file does have collateral damage in that it disables tests that are running fine; the alternative is to disable only the EME tests, but the failure count numbers somewhere close to 50.
Differential Revision: https://phabricator.services.mozilla.com/D24094
--HG--
extra : moz-landing-system : lando
We now allow frames to have a negative time (so that they can be decoded and trimmed).
Differential Revision: https://phabricator.services.mozilla.com/D21474
--HG--
extra : moz-landing-system : lando
This prevents re-creating a new audio decoder which on Android can take an awful long time.
Differential Revision: https://phabricator.services.mozilla.com/D20969
--HG--
extra : moz-landing-system : lando
Some audio decoders, such as AAC and Opus have a need for a pre-roll content. As such, in order to be able to fully get the content of the first frame we keep the frame just prior that would have normally been dropped.
We set this frame to have a duration of 1us so that it will be dropped later by the decoding pipeline. The starting time of the first frame is adjusted so that we have continuous data, without gap in the buffered range.
Differential Revision: https://phabricator.services.mozilla.com/D20322
--HG--
extra : moz-landing-system : lando
There's two cases to handle.
1- A Frame isn't entirely contained between appendWindowStart and appendWindowEnd
2- A new frame is appended which overlaps partially an existing frame.
To achieve this we tweak the start time and duration of the sample added (case 1), or the frame about to be partially covered (case 2). We then set a flag that will indicate to the decoder that the decompressed frame will have to be truncated.
Differential Revision: https://phabricator.services.mozilla.com/D20172
--HG--
extra : moz-landing-system : lando
Check that we can resume after appening a partial media segment header and calling abort().
Depends on D18651
Differential Revision: https://phabricator.services.mozilla.com/D18762
--HG--
extra : moz-landing-system : lando
The logic was redundant with the next step that will already remove all until the next keyframe.
Depends on D18321
Differential Revision: https://phabricator.services.mozilla.com/D18322
--HG--
extra : moz-landing-system : lando
Per spec:
https://w3c.github.io/media-source/#sourcebuffer-coded-frame-removal
Step 3 of the Coded Frame Removal Interval:
"Remove all media data, from this track buffer, that contain starting timestamps greater than or equal to start and less than the remove end timestamp. "
So to decide if a frame should be removed from a track buffer, its start time is the only information to be used.
Differential Revision: https://phabricator.services.mozilla.com/D18321
--HG--
extra : moz-landing-system : lando
Using a variant more clearly indicates how MoofParser works: you cannot request
a specific track id and to parse all tracks. Callers must now explicitly select
one or the other.
Differential Revision: https://phabricator.services.mozilla.com/D18135
--HG--
extra : moz-landing-system : lando
Using track_id 0 is forbidden by the mp4 spec, however, some sites still serve
media using this track_id. We've been using the 0 track ID to trigger special
handling in the MoofParser where we will parse multiple tracks, and this led us
to be tolerant of tracks using this reserved id (though we likely had some bugs
due to this).
Since sites are using this track_id, and as other browsers (and Firefox until I
broke this) tolerate such media, we should too. In order to do so correctly, we
should no longer us track_id=0 as a special case in the MoofParser, and instead
have an explicit flag, which is what this patch does.
Differential Revision: https://phabricator.services.mozilla.com/D16428
--HG--
extra : moz-landing-system : lando
Using track_id 0 is forbidden by the mp4 spec, however, some sites still serve
media using this track_id. We've been using the 0 track ID to trigger special
handling in the MoofParser where we will parse multiple tracks, and this led us
to be tolerant of tracks using this reserved id (though we likely had some bugs
due to this).
Since sites are using this track_id, and as other browsers (and Firefox until I
broke this) tolerate such media, we should too. In order to do so correctly, we
should no longer us track_id=0 as a special case in the MoofParser, and instead
have an explicit flag, which is what this patch does.
Differential Revision: https://phabricator.services.mozilla.com/D16428
--HG--
extra : moz-landing-system : lando
This changeset updates all the test that were wrongly using ok() and wanted to
use is() AND for which the assert is still passing without any modification
required.
Differential Revision: https://phabricator.services.mozilla.com/D8739
--HG--
extra : moz-landing-system : lando
Summary: When removing frames from the trackbuffer we may remove frames outside the original removal interval as we must remove all frames depending on the removed frames.
Differential Revision: https://phabricator.services.mozilla.com/D2837
AV1 support is behind a pref, as such, the result of canPlayType should depends on the value of that pref.
Additionally to this change we remove AOMDecoder::IsSupportedCodec as it implied confusion on what a codec mimetype is. There are two type of codec mimetype: the one describing the container content ("av1") and the one describing the codec itself "video/av1")
AOMDecoder shouldn't know anything about containers (e.g. mp4 or webm)
--HG--
extra : rebase_source : 72ebe662f76fb6c9d8be1f753890601aac440061
AV1 support is behind a pref, as such, the result of canPlayType should depends on the value of that pref.
Additionally to this change we remove AOMDecoder::IsSupportedCodec as it implied confusion on what a codec mimetype is. There are two type of codec mimetype: the one describing the container content ("av1") and the one describing the codec itself "video/av1")
AOMDecoder shouldn't know anything about containers (e.g. mp4 or webm)
Summary:
MediaCapabilities provide a finer detail on VP9 being supported or not. YouTube will use that information to determine which resolutions to support when using VP9
Depends on D1772
Reviewers: bryce
Tags: #secure-revision
Bug #: 1409664
Differential Revision: https://phabricator.services.mozilla.com/D1794
Summary:
TaskQueue no longer requires an explicit call to BeginShutdown() as such we no longer have a need for AutoTaskQueue.
Depends on D1621
Tags: #secure-revision
Bug #: 1409664
Differential Revision: https://phabricator.services.mozilla.com/D1622
Some MSE streams will resend the same init segment. In these cases we can treat
the following data as belonging to the already existing stream. We do this by
reusing the same stream id. This stops us tearing down and restarting decoders
in these cases. This has the benefit of stopping us introducing gaps to audio
and/or video.
Differential Revision: https://phabricator.services.mozilla.com/D1837
--HG--
extra : moz-landing-system : lando
Re-creating a new demuxer is fine, provided that the SourceBufferResource exists. However, a resource is only created upon receiving an init segment.
The segment following a call to changeType() must be an init segment, will let the demuxer creation occurs there.
Differential Revision: https://phabricator.services.mozilla.com/D1812
Previous commit added SetNextGetSampleIndexIfNeeded, let's re-use it for GetSample.
We continue to have an exception code as it caters for the most common code path, which is we retrieve one sample after the other.
MozReview-Commit-ID: HOQ53qwZj7w
--HG--
extra : rebase_source : cc9bc0b41a7085d28554f7ed764a18decfea327d
The assumption that when calling GetNextRandomAccessPoint the next GetSample index would always be known was incorrect. It assumed that the call to GetNextRandomAccessPoint would always be preceded by a call to GetSample.
This is not always how the MediaSourceDemuxer called it.
MozReview-Commit-ID: H1MyPpDEytk
--HG--
extra : rebase_source : 07f70ee87ae5084016a094c564382090a3045e94
Temporary diagnostic code to help determine what the problem might be.
MozReview-Commit-ID: D5Dm32aZ1Ia
--HG--
extra : rebase_source : ba0955c2b880823986277919f05a32e9095b14fa
This was done automatically replacing:
s/mozilla::Move/std::move/
s/ Move(/ std::move(/
s/(Move(/(std::move(/
Removing the 'using mozilla::Move;' lines.
And then with a few manual fixups, see the bug for the split series..
MozReview-Commit-ID: Jxze3adipUh
Change rules so we enforce ["foo", "bar"] rather than [ "foo", "bar" ].
MozReview-Commit-ID: KX6wJd8jmeJ
--HG--
extra : rebase_source : 6800cf4e701a33f246418e0deb35a206af8104f4
When using a media element with a Media Source, the resource fetching algorithm is to be called in "local" mode:
https://www.w3.org/TR/media-source/#mediasource-attach
"Continue the resource fetch algorithm by running the remaining "Otherwise (mode is local)" steps, with these clarifications"
https://html.spec.whatwg.org/multipage/media.html#concept-media-load-resource
Under the local mode, the steps that would cause the element to fire suspend, stalled or progress can never occur.
We only prevent the stalled event to be fired, many websites rely on the progress event to be fired (such as when the init segment has been parsed). The HTML5 media spec will be amended to clearly indicate that progress is to be fired even with mediasource
MozReview-Commit-ID: DkoQzoV0JzO
--HG--
extra : rebase_source : 1e916eee50c9935f168797bb5a92052191cda59d
Add .eslintrc.js to configure globals from mediasource.js and to add extra
rules to encourage use of let and const over var.
Linting changes:
- Prefer const and let to var. This provides tighter scoping and avoids
reassignment.
- Mozilla rules do not allow for shadowing of variables, so several tests have
had promise lists renamed to avoid this.
- Numerous minor fixes to formatting including using double quotes, spacing,
missing semicolons.
- Remove some unused variables.
- Arrays have spaces after opening braces and before closing braces, e.g.
[ "foo" ], this is to be consistent with our clang-format rules.
- Fix naming of resourcePathSeen in test_MediaSource_memory_reporting.html.
MozReview-Commit-ID: 5q6oS7EWLTk
--HG--
extra : rebase_source : 9b67b294f338ca9205b52fded3af63e6c3ac9a5a
The aim of those changes is to be incubated in the WICG.
MozReview-Commit-ID: K93xiTod6tw
--HG--
extra : rebase_source : 788122a69b6cab96bab9c2ae6e8cdf7c61d4ed07
The aim of those changes is to be incubated in the WICG.
MozReview-Commit-ID: 5wEUnWz8i7kBug 1280613
--HG--
extra : rebase_source : 4360d2c34025bf3c87fff49f0e2aa01975fff15b
Currently, the new init segment provided following a call to changeType() must contain the same number of audio and video tracks as previously.
The Chrome team has indicated concerns in regards to this restriction. TBD.
MozReview-Commit-ID: 3S6YVtQILF9
--HG--
extra : rebase_source : 59574301d8d4b6f04fc40a97a0917222f1d42fe4
Non functional code.
SourceBuffer.changeType allows to reconfigure a sourceBuffer so that a new codec type or new container format can be fed later.
The new code is placed behind the media.mediasource.experimental.enabled pref.
MozReview-Commit-ID: 5wj6J4uzLbA
--HG--
extra : rebase_source : b6f57246e0a4c856f6365bb0c8ec8d759a770105
This patch converts all the prefs in MediaPrefs to the new StaticPrefs system.
Note that the "media.wmf.skip-blacklist" pref was present in both MediaPrefs
and gfxPrefs. The copy in MediaPrefs was never used; this explains why this
patch does not add an entry for it to StaticPrefList.h.
Note also that the patch removes themedia.rust.mp4parser pref, because it's
unused.
MozReview-Commit-ID: IfHP37NbIjY
--HG--
extra : rebase_source : df84ea813b7c366d7be663c696891325610149c8
PinForSeek() is called only when playback reaches the end. In other words,
it is not called for most cases of seeking. It should be OK not to call it at
all during seeking.
MozReview-Commit-ID: 1xXX1321bO7
--HG--
extra : rebase_source : df8ba3f59da2a337b456546af4b54abaddfe38a9
extra : intermediate-source : 0a70419f9ce639ac0784a0632db4598d6be511f8
extra : source : bfddad9b922386c91fcfa7657a7ac274991d15f4
To prevent another heap allocation, we re-use the TaskQueue internal monitor.
As a TaskQueue is refcounted, and the MozPromise::Then() holds a reference to the taskqueue, it ensures that the monitor isn't immediately destroyed when Await() execution unwinds.
Instead it will live until either the lambda or Await() completes, whichever comes last.
MozReview-Commit-ID: EeG6LLAiiyp
--HG--
extra : rebase_source : c5872733c0444737682632dd10d8844c44c4d429
Mostly-mechanical replacement of MOZ_LOG with DDMOZ_LOG, usually just removing
the class name and `this` pointer (as they are already implicitly recorded).
Some files needed a bit more work when logging was done from helper classes or
static functions.
MozReview-Commit-ID: IeJJmzYqWMQ
--HG--
extra : rebase_source : 94200838dcdaf6c3bda9de30042ce2d307237eef
Mostly-mechanical additions:
- Log constructions&destructions, usually by just inheriting from
DecoderDoctorLifeLogger, otherwise with explicit log commands (for internal
classes for which DecoderDoctorTraits can't be specialized),
- Log links between most objects, e.g.: Media element -> decoder -> state
machine -> reader -> demuxer -> resource, etc.
And logging some important properties and events (JS events, duration change,
frames being decoded, etc.)
More will be added later on, from just converting MOZ_LOGs, and as needed.
MozReview-Commit-ID: KgNhHSz35t0
--HG--
extra : rebase_source : dd7206e350e32671adc6f3b9e54ebf777251de2c
For the project to export Gecko's media stack and import it into Servo,
I need a way to shutdown an abstract MediaResource. So I'd like to move
BaseMediaResource::Close() up into MediaResource class.
MozReview-Commit-ID: 9JmxJPs02PN
--HG--
extra : rebase_source : e61cc1a3a79b3e4ca7e9fa86a602e6e26044e247
Also devirtualize ChannelMediaDecoder::DownloadProgressed() and move it to private.
MozReview-Commit-ID: ITv3ISRbN5t
--HG--
extra : rebase_source : aa75bc11fc1a4af8df15db9224928b1f02267b80
The spec [1] defines what's the init segment, and the parser would return error
if the format is not correct.
[1] https://w3c.github.io/media-source/webm-byte-stream-format.html
MozReview-Commit-ID: 3nFHHdn5b89
--HG--
extra : rebase_source : 66fe592958801c4f9e2115f7729df2b9ece55ac3
The spec [1] defines what's the media segment, and the parser would return error
if the format is not correct.
[1] https://w3c.github.io/media-source/webm-byte-stream-format.html
MozReview-Commit-ID: 4hq59Pywz2t
--HG--
extra : rebase_source : 1136d2a673f11d612e0eb711db6affdce42bb525
The value by which we pre-roll is inconsequential, so long as we seek to the previous packet than the one we want. So 80ms will do.
MozReview-Commit-ID: 8iPOtjReZnb
--HG--
extra : rebase_source : 42908c6afc84cf783356fb7311ffe99b4ec76d96
mManager would be accessed in both main thread and task queue, and be set on task
queue, so we need to make sure it's thread-safe.
MozReview-Commit-ID: m76KeEsDgB
It would only be accessed on task queue now, so we don't need to lock it.
MozReview-Commit-ID: 6jd36TQW4aA
--HG--
extra : rebase_source : e8bb53a226154312496149ab8f6b00dead49a3b6
mTaskQueue is only read on the main thread, but read and written on the demuxer's taskqueue. We need to ensure that accesses are synchronised.
MozReview-Commit-ID: Gbc15iYgZOe
--HG--
extra : rebase_source : 006ff3f73c9895fa2f29e56123e690cdf66fe2c5
The use of the TrackBuffersManager once detached is explictly forbidden, as such
OnTaskQueue() can only be used before the DetachTask ran: we now strongly assert
as such.
MozReview-Commit-ID: ycOI4QRElb
--HG--
extra : rebase_source : ecce8ac75587470c15268ab729b068f049702a8a
Ensure the TBM would always be detached from demuxers, before calling
TBM::detach().
MozReview-Commit-ID: DLWZHB3M3GG
--HG--
extra : rebase_source : 9e455022ba9360fb549222e9ad1238a3ae9d88ad
From [1], the task was executed after finished detach task. It would be caused
by queuing two detach tasks in the task queue.
If the previous detach task is still waiting in the task queue when we're calling
the second detach(), then we might have two detach tasks in the queue.
[1] https://treeherder.mozilla.org/logviewer.html#?job_id=134315866&repo=try&lineNumber=2540
MozReview-Commit-ID: HohgKqeZy0s
--HG--
extra : rebase_source : 0d20f1b8648acaf2ed8e75b2631e905629c2abaf
Should never access the TrackBuffersManager once the SourceBuffer has been detached.
MozReview-Commit-ID: EgVINj9B1vZ
--HG--
extra : rebase_source : 4b4dc3e5c4b507fe4cc40e80f507b575a8b87eb3
After detaching TBM, we should not access it anymore. So we should finish all
other related detaching process, before detaching TBM.
MozReview-Commit-ID: 8bNzqXVHVyy
--HG--
extra : rebase_source : e135eb3d0fd4e5c41bbac4ebfc8d6fcbd1b32d5b
The use of the TrackBuffersManager once detached is explictly forbidden, as such
OnTaskQueue() can only be used before the DetachTask ran: we now strongly assert
as such.
MozReview-Commit-ID: ycOI4QRElb
--HG--
extra : rebase_source : 44ea3d0eb292e5c285d0aa4e10eefa41f20beed7
Ensure the TBM would always be detached from demuxers, before calling
TBM::detach().
MozReview-Commit-ID: DLWZHB3M3GG
--HG--
extra : rebase_source : 0334b71534cfaccaf1d8985d827fe4e5d5bf0e9f