Also, downgrade the assertion because this is just for debugging and
probe reporting usage, which is not something important enough to use a
diagnostic assertion.
Differential Revision: https://phabricator.services.mozilla.com/D206293
As the audio clock would only move forward when it consumes real sample,
if we don't keep sending data when there is a gap between audio and
video, then the audio clock would stall.
Therefore, we need to create fake audio data to cover the gap between
audio and video if the audio track is shorter. But we don't need to
worry about the opposite situation, where the video track is shorter
than the audio track. Because the video sink would simply display the
last video frame to cover the gap.
Differential Revision: https://phabricator.services.mozilla.com/D184272
As the audio clock would only move forward when it consumes real sample,
if we don't keep sending data when there is a gap between audio and
video, then the audio clock would stall.
Therefore, we need to create fake audio data to cover the gap between
audio and video if the audio track is shorter. But we don't need to
worry about the opposite situation, where the video track is shorter
than the audio track. Because the video sink would simply display the
last video frame to cover the gap.
Differential Revision: https://phabricator.services.mozilla.com/D184272
As the audio clock would only move forward when it consumes real sample,
if we don't keep sending data when there is a gap between audio and
video, then the audio clock would stall.
Therefore, we need to create fake audio data to cover the gap between
audio and video if the audio track is shorter. But we don't need to
worry about the opposite situation, where the video track is shorter
than the audio track. Because the video sink would simply display the
last video frame to cover the gap.
Differential Revision: https://phabricator.services.mozilla.com/D184272
When the audio sink shutdown, we should also reset the audible state for
the listeners. Otherwise, MediaDecoderStateMachine would possibly rely
on the incorrect audible state that is produced by previous sink, which
would cause showing the sound indicator even if no sound is being playing.
Eg. Considering following case without the reset of the audible state
1. Sink A is audible -> MDSM set mIsAudioDataAudible=true
2. Stop sink
3. Recreate sink B and it's playing silence -> MDSM's mIsAudioDataAudible=true is still true, this is wrong!
Differential Revision: https://phabricator.services.mozilla.com/D113550
This patch is used to create a consistent clock timeline among
different media sinks. Having a consistent clock timeline can help the
newly created media sink to understand audio data's "adjusted" time,
which can prevent the sink from inserting silence if the sink
incorrectly think there is a gap between data and sink start time.
However, once seeking completed, we should use the media time that
indicates to the new position, instead of using the previous clock time.
Eg. Audio duration = 10, and has seamlessly looped 5 times. Then the
start time of the sample in 2s in the 6th looping would be 2 + 5*10 = 52.
If we switch to the new sink, and use media time (which is 2s) as a
start time to start a new sink, then the new sink would think there is a gap between 2s and 52s, then push a lot of silence. [1]
[1] https://searchfox.org/mozilla-central/rev/9b430bb1a11d7152cab2af4574f451ffb906b052/dom/media/mediasink/AudioSink.cpp#390-426
Differential Revision: https://phabricator.services.mozilla.com/D113548
The original change was introduced when implementing seamless audio
looping, and it's no longer needed. Because now we would properly
adjust the offset of the media queue when entering the looping decoding
state to make the media time and the clock time consistent.
Differential Revision: https://phabricator.services.mozilla.com/D182526
If we seek directly to EOS, it's possible that we still can't know the
track duration because we don't have the last decoded data. Therefore,
we remove the assertion and make it as condition.
Differential Revision: https://phabricator.services.mozilla.com/D182417
This allows video playback to continue uninterrupted.
The AudioSinkWrapper now maintains the correct playback position in the media
data. Previously the replacement AudioSinkWrapper started its clock at the
"current playback position" from the MediaDecoderStateMachine, which did not
include additional time from looping, so silence would be played until the
missing time had passed.
The AudioSinkWrapper now continues to periodically attempt to open a new
output device if not initially available. Previously such attempts were only
performed on state changes such as seeking or unmuting.
The promise returned from MediaDecoderStateMachine::InvokeSetSink() now
resolves regardless of whether the new device can be opened successfully.
Previously the promise could be rejected if the device was necessary for audio
output at the time of the call but no check for device availability (beyond
that of device enumeration) was performed if playback was suspended or muted
or if a subsequent device change had already been queued. Even previously the
underlying device was changed even when the promise was rejected and could be
used if a state change occurred.
Differential Revision: https://phabricator.services.mozilla.com/D181975
This allows video playback to continue uninterrupted.
The AudioSinkWrapper now maintains the correct playback position in the media
data. Previously the replacement AudioSinkWrapper started its clock at the
"current playback position" from the MediaDecoderStateMachine, which did not
include additional time from looping, so silence would be played until the
missing time had passed.
The AudioSinkWrapper now continues to periodically attempt to open a new
output device if not initially available. Previously such attempts were only
performed on state changes such as seeking or unmuting.
The promise returned from MediaDecoderStateMachine::InvokeSetSink() now
resolves regardless of whether the new device can be opened successfully.
Previously the promise could be rejected if the device was necessary for audio
output at the time of the call but no check for device availability (beyond
that of device enumeration) was performed if playback was suspended or muted
or if a subsequent device change had already been queued. Even previously the
underlying device was changed even when the promise was rejected and could be
used if a state change occurred.
Differential Revision: https://phabricator.services.mozilla.com/D181975
This shortens the time it takes to establish the connections for canonicals
living on the main thread, from the thread hop chain:
main thread (MediaDecoderStateMachine::Init)
-> state machine task queue (Mirror::Connect)
-> main thread (AbstractCanonical::AddMirror)
-> state machine task queue (AbstractMirror::UpdateValue)
to the thread hop chain:
main thread (MediaDecoderStateMachine::Init + Canonical::ConnectMirror)
-> state machine task queue (Mirror::AbstractUpdateValue)
No races exist here as MediaDecoderStateMachine initiates its shutdown on main
thread and continues on the task queue (where the mirrors live).
Differential Revision: https://phabricator.services.mozilla.com/D181086
This shortens the time it takes to establish the connections for canonicals
living on the main thread, from the thread hop chain:
main thread (MediaDecoderStateMachine::Init)
-> state machine task queue (Mirror::Connect)
-> main thread (AbstractCanonical::AddMirror)
-> state machine task queue (AbstractMirror::UpdateValue)
to the thread hop chain:
main thread (MediaDecoderStateMachine::Init + Canonical::ConnectMirror)
-> state machine task queue (Mirror::AbstractUpdateValue)
No races exist here as MediaDecoderStateMachine initiates its shutdown on main
thread and continues on the task queue (where the mirrors live).
Differential Revision: https://phabricator.services.mozilla.com/D181086