Bug 1208371 - Hook up DecodedStream with PrincipalHandle. r?mt,jwwang
MozReview-Commit-ID: 1LmiFyfjhsr
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -547,16 +547,18 @@ MediaDecoder::MediaDecoder(MediaDecoderO
, mPlayState(AbstractThread::MainThread(), PLAY_STATE_LOADING,
"MediaDecoder::mPlayState (Canonical)")
, mNextState(AbstractThread::MainThread(), PLAY_STATE_PAUSED,
"MediaDecoder::mNextState (Canonical)")
, mLogicallySeeking(AbstractThread::MainThread(), false,
"MediaDecoder::mLogicallySeeking (Canonical)")
, mSameOriginMedia(AbstractThread::MainThread(), false,
"MediaDecoder::mSameOriginMedia (Canonical)")
+ , mMediaPrincipalHandle(AbstractThread::MainThread(), PRINCIPAL_HANDLE_NONE,
+ "MediaDecoder::mMediaPrincipalHandle (Canonical)")
, mPlaybackBytesPerSecond(AbstractThread::MainThread(), 0.0,
"MediaDecoder::mPlaybackBytesPerSecond (Canonical)")
, mPlaybackRateReliable(AbstractThread::MainThread(), true,
"MediaDecoder::mPlaybackRateReliable (Canonical)")
, mDecoderPosition(AbstractThread::MainThread(), 0,
"MediaDecoder::mDecoderPosition (Canonical)")
, mMediaSeekable(AbstractThread::MainThread(), true,
"MediaDecoder::mMediaSeekable (Canonical)")
@@ -1183,16 +1185,18 @@ MediaDecoder::NotifyDownloadEnded(nsresu
}
}
void
MediaDecoder::NotifyPrincipalChanged()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mShuttingDown);
+ nsCOMPtr<nsIPrincipal> newPrincipal = GetCurrentPrincipal();
+ mMediaPrincipalHandle = MakePrincipalHandle(newPrincipal);
mOwner->NotifyDecoderPrincipalChanged();
}
void
MediaDecoder::NotifyBytesConsumed(int64_t aBytes, int64_t aOffset)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mShuttingDown);
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -772,16 +772,20 @@ protected:
// True if the decoder is seeking.
Canonical<bool> mLogicallySeeking;
// True if the media is same-origin with the element. Data can only be
// passed to MediaStreams when this is true.
Canonical<bool> mSameOriginMedia;
+ // An identifier for the principal of the media. Used to track when
+ // main-thread induced principal changes get reflected on MSG thread.
+ Canonical<PrincipalHandle> mMediaPrincipalHandle;
+
// Estimate of the current playback rate (bytes/second).
Canonical<double> mPlaybackBytesPerSecond;
// True if mPlaybackBytesPerSecond is a reliable estimate.
Canonical<bool> mPlaybackRateReliable;
// Current decoding position in the stream. This is where the decoder
// is up to consuming the stream. This is not adjusted during decoder
@@ -816,16 +820,19 @@ public:
return &mNextState;
}
AbstractCanonical<bool>* CanonicalLogicallySeeking() {
return &mLogicallySeeking;
}
AbstractCanonical<bool>* CanonicalSameOriginMedia() {
return &mSameOriginMedia;
}
+ AbstractCanonical<PrincipalHandle>* CanonicalMediaPrincipalHandle() {
+ return &mMediaPrincipalHandle;
+ }
AbstractCanonical<double>* CanonicalPlaybackBytesPerSecond() {
return &mPlaybackBytesPerSecond;
}
AbstractCanonical<bool>* CanonicalPlaybackRateReliable() {
return &mPlaybackRateReliable;
}
AbstractCanonical<int64_t>* CanonicalDecoderPosition() {
return &mDecoderPosition;
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -256,16 +256,18 @@ MediaDecoderStateMachine::MediaDecoderSt
"MediaDecoderStateMachine::mLogicallySeeking (Mirror)"),
mVolume(mTaskQueue, 1.0, "MediaDecoderStateMachine::mVolume (Mirror)"),
mLogicalPlaybackRate(mTaskQueue, 1.0,
"MediaDecoderStateMachine::mLogicalPlaybackRate (Mirror)"),
mPreservesPitch(mTaskQueue, true,
"MediaDecoderStateMachine::mPreservesPitch (Mirror)"),
mSameOriginMedia(mTaskQueue, false,
"MediaDecoderStateMachine::mSameOriginMedia (Mirror)"),
+ mMediaPrincipalHandle(mTaskQueue, PRINCIPAL_HANDLE_NONE,
+ "MediaDecoderStateMachine::mMediaPrincipalHandle (Mirror)"),
mPlaybackBytesPerSecond(mTaskQueue, 0.0,
"MediaDecoderStateMachine::mPlaybackBytesPerSecond (Mirror)"),
mPlaybackRateReliable(mTaskQueue, true,
"MediaDecoderStateMachine::mPlaybackRateReliable (Mirror)"),
mDecoderPosition(mTaskQueue, 0,
"MediaDecoderStateMachine::mDecoderPosition (Mirror)"),
mMediaSeekable(mTaskQueue, true,
"MediaDecoderStateMachine::mMediaSeekable (Mirror)"),
@@ -342,16 +344,17 @@ MediaDecoderStateMachine::Initialization
mExplicitDuration.Connect(aDecoder->CanonicalExplicitDuration());
mPlayState.Connect(aDecoder->CanonicalPlayState());
mNextPlayState.Connect(aDecoder->CanonicalNextPlayState());
mLogicallySeeking.Connect(aDecoder->CanonicalLogicallySeeking());
mVolume.Connect(aDecoder->CanonicalVolume());
mLogicalPlaybackRate.Connect(aDecoder->CanonicalPlaybackRate());
mPreservesPitch.Connect(aDecoder->CanonicalPreservesPitch());
mSameOriginMedia.Connect(aDecoder->CanonicalSameOriginMedia());
+ mMediaPrincipalHandle.Connect(aDecoder->CanonicalMediaPrincipalHandle());
mPlaybackBytesPerSecond.Connect(aDecoder->CanonicalPlaybackBytesPerSecond());
mPlaybackRateReliable.Connect(aDecoder->CanonicalPlaybackRateReliable());
mDecoderPosition.Connect(aDecoder->CanonicalDecoderPosition());
mMediaSeekable.Connect(aDecoder->CanonicalMediaSeekable());
// Initialize watchers.
mWatchManager.Watch(mBuffered, &MediaDecoderStateMachine::BufferedRangeUpdated);
mWatchManager.Watch(mState, &MediaDecoderStateMachine::UpdateNextFrameStatus);
@@ -380,17 +383,18 @@ MediaDecoderStateMachine::CreateAudioSin
return new AudioSinkWrapper(mTaskQueue, audioSinkCreator);
}
already_AddRefed<media::MediaSink>
MediaDecoderStateMachine::CreateMediaSink(bool aAudioCaptured)
{
RefPtr<media::MediaSink> audioSink = aAudioCaptured
? new DecodedStream(mTaskQueue, mAudioQueue, mVideoQueue,
- mOutputStreamManager, mSameOriginMedia.Ref())
+ mOutputStreamManager, mSameOriginMedia.Ref(),
+ mMediaPrincipalHandle.Ref())
: CreateAudioSink();
RefPtr<media::MediaSink> mediaSink =
new VideoSink(mTaskQueue, audioSink, mVideoQueue,
mVideoFrameContainer, *mFrameStats,
sVideoQueueSendToCompositorSize);
return mediaSink.forget();
}
@@ -2191,16 +2195,17 @@ MediaDecoderStateMachine::FinishShutdown
mExplicitDuration.DisconnectIfConnected();
mPlayState.DisconnectIfConnected();
mNextPlayState.DisconnectIfConnected();
mLogicallySeeking.DisconnectIfConnected();
mVolume.DisconnectIfConnected();
mLogicalPlaybackRate.DisconnectIfConnected();
mPreservesPitch.DisconnectIfConnected();
mSameOriginMedia.DisconnectIfConnected();
+ mMediaPrincipalHandle.DisconnectIfConnected();
mPlaybackBytesPerSecond.DisconnectIfConnected();
mPlaybackRateReliable.DisconnectIfConnected();
mDecoderPosition.DisconnectIfConnected();
mMediaSeekable.DisconnectIfConnected();
mDuration.DisconnectAll();
mIsShutdown.DisconnectAll();
mNextFrameStatus.DisconnectAll();
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -1223,16 +1223,20 @@ private:
// Pitch preservation for the playback rate.
Mirror<bool> mPreservesPitch;
// True if the media is same-origin with the element. Data can only be
// passed to MediaStreams when this is true.
Mirror<bool> mSameOriginMedia;
+ // An identifier for the principal of the media. Used to track when
+ // main-thread induced principal changes get reflected on MSG thread.
+ Mirror<PrincipalHandle> mMediaPrincipalHandle;
+
// Estimate of the current playback rate (bytes/second).
Mirror<double> mPlaybackBytesPerSecond;
// True if mPlaybackBytesPerSecond is a reliable estimate.
Mirror<bool> mPlaybackRateReliable;
// Current decoding position in the stream.
Mirror<int64_t> mDecoderPosition;
--- a/dom/media/mediasink/DecodedStream.cpp
+++ b/dom/media/mediasink/DecodedStream.cpp
@@ -205,21 +205,23 @@ DecodedStreamData::SetPlaying(bool aPlay
UpdateStreamSuspended(mStream, !mPlaying);
}
}
DecodedStream::DecodedStream(AbstractThread* aOwnerThread,
MediaQueue<MediaData>& aAudioQueue,
MediaQueue<MediaData>& aVideoQueue,
OutputStreamManager* aOutputStreamManager,
- const bool& aSameOrigin)
+ const bool& aSameOrigin,
+ const PrincipalHandle& aPrincipalHandle)
: mOwnerThread(aOwnerThread)
, mOutputStreamManager(aOutputStreamManager)
, mPlaying(false)
, mSameOrigin(aSameOrigin)
+ , mPrincipalHandle(aPrincipalHandle)
, mAudioQueue(aAudioQueue)
, mVideoQueue(aVideoQueue)
{
}
DecodedStream::~DecodedStream()
{
MOZ_ASSERT(mStartTime.isNothing(), "playback should've ended.");
@@ -448,17 +450,17 @@ DecodedStream::SetPreservesPitch(bool aP
{
AssertOwnerThread();
mParams.mPreservesPitch = aPreservesPitch;
}
static void
SendStreamAudio(DecodedStreamData* aStream, int64_t aStartTime,
MediaData* aData, AudioSegment* aOutput,
- uint32_t aRate, double aVolume)
+ uint32_t aRate, double aVolume, const PrincipalHandle& aPrincipalHandle)
{
// The amount of audio frames that is used to fuzz rounding errors.
static const int64_t AUDIO_FUZZ_FRAMES = 1;
MOZ_ASSERT(aData);
AudioData* audio = aData->As<AudioData>();
// This logic has to mimic AudioSink closely to make sure we write
// the exact same silences
@@ -487,25 +489,26 @@ SendStreamAudio(DecodedStreamData* aStre
// DecodedAudioDataSink::PlayFromAudioQueue()
audio->EnsureAudioBuffer();
RefPtr<SharedBuffer> buffer = audio->mAudioBuffer;
AudioDataValue* bufferData = static_cast<AudioDataValue*>(buffer->Data());
AutoTArray<const AudioDataValue*, 2> channels;
for (uint32_t i = 0; i < audio->mChannels; ++i) {
channels.AppendElement(bufferData + i * audio->mFrames);
}
- aOutput->AppendFrames(buffer.forget(), channels, audio->mFrames, PRINCIPAL_HANDLE_NONE /* Fixed in later patch */);
+ aOutput->AppendFrames(buffer.forget(), channels, audio->mFrames, aPrincipalHandle);
aStream->mAudioFramesWritten += audio->mFrames;
aOutput->ApplyVolume(aVolume);
aStream->mNextAudioTime = audio->GetEndTime();
}
void
-DecodedStream::SendAudio(double aVolume, bool aIsSameOrigin)
+DecodedStream::SendAudio(double aVolume, bool aIsSameOrigin,
+ const PrincipalHandle& aPrincipalHandle)
{
AssertOwnerThread();
if (!mInfo.HasAudio()) {
return;
}
AudioSegment output;
@@ -513,17 +516,18 @@ DecodedStream::SendAudio(double aVolume,
AutoTArray<RefPtr<MediaData>,10> audio;
TrackID audioTrackId = mInfo.mAudio.mTrackId;
SourceMediaStream* sourceStream = mData->mStream;
// It's OK to hold references to the AudioData because AudioData
// is ref-counted.
mAudioQueue.GetElementsAfter(mData->mNextAudioTime, &audio);
for (uint32_t i = 0; i < audio.Length(); ++i) {
- SendStreamAudio(mData.get(), mStartTime.ref(), audio[i], &output, rate, aVolume);
+ SendStreamAudio(mData.get(), mStartTime.ref(), audio[i], &output, rate,
+ aVolume, aPrincipalHandle);
}
if (!aIsSameOrigin) {
output.ReplaceWithDisabled();
}
// |mNextAudioTime| is updated as we process each audio sample in
// SendStreamAudio(). This is consistent with how |mNextVideoTime|
@@ -539,38 +543,39 @@ DecodedStream::SendAudio(double aVolume,
}
static void
WriteVideoToMediaStream(MediaStream* aStream,
layers::Image* aImage,
int64_t aEndMicroseconds,
int64_t aStartMicroseconds,
const mozilla::gfx::IntSize& aIntrinsicSize,
- VideoSegment* aOutput)
+ VideoSegment* aOutput,
+ const PrincipalHandle& aPrincipalHandle)
{
RefPtr<layers::Image> image = aImage;
StreamTime duration =
aStream->MicrosecondsToStreamTimeRoundDown(aEndMicroseconds) -
aStream->MicrosecondsToStreamTimeRoundDown(aStartMicroseconds);
- aOutput->AppendFrame(image.forget(), duration, aIntrinsicSize, PRINCIPAL_HANDLE_NONE /* Fixed in later patch */);
+ aOutput->AppendFrame(image.forget(), duration, aIntrinsicSize, aPrincipalHandle);
}
static bool
ZeroDurationAtLastChunk(VideoSegment& aInput)
{
// Get the last video frame's start time in VideoSegment aInput.
// If the start time is equal to the duration of aInput, means the last video
// frame's duration is zero.
StreamTime lastVideoStratTime;
aInput.GetLastFrame(&lastVideoStratTime);
return lastVideoStratTime == aInput.GetDuration();
}
void
-DecodedStream::SendVideo(bool aIsSameOrigin)
+DecodedStream::SendVideo(bool aIsSameOrigin, const PrincipalHandle& aPrincipalHandle)
{
AssertOwnerThread();
if (!mInfo.HasVideo()) {
return;
}
VideoSegment output;
@@ -591,23 +596,24 @@ DecodedStream::SendVideo(bool aIsSameOri
// TODO: |mLastVideoImage| should come from the last image rendered
// by the state machine. This will avoid the black frame when capture
// happens in the middle of playback (especially in th middle of a
// video frame). E.g. if we have a video frame that is 30 sec long
// and capture happens at 15 sec, we'll have to append a black frame
// that is 15 sec long.
WriteVideoToMediaStream(sourceStream, mData->mLastVideoImage, v->mTime,
- mData->mNextVideoTime, mData->mLastVideoImageDisplaySize, &output);
+ mData->mNextVideoTime, mData->mLastVideoImageDisplaySize, &output,
+ aPrincipalHandle);
mData->mNextVideoTime = v->mTime;
}
if (mData->mNextVideoTime < v->GetEndTime()) {
- WriteVideoToMediaStream(sourceStream, v->mImage,
- v->GetEndTime(), mData->mNextVideoTime, v->mDisplay, &output);
+ WriteVideoToMediaStream(sourceStream, v->mImage, v->GetEndTime(),
+ mData->mNextVideoTime, v->mDisplay, &output, aPrincipalHandle);
mData->mNextVideoTime = v->GetEndTime();
mData->mLastVideoImage = v->mImage;
mData->mLastVideoImageDisplaySize = v->mDisplay;
}
}
// Check the output is not empty.
if (output.GetLastFrame()) {
@@ -624,17 +630,17 @@ DecodedStream::SendVideo(bool aIsSameOri
if (mVideoQueue.IsFinished() && !mData->mHaveSentFinishVideo) {
if (mData->mEOSVideoCompensation) {
VideoSegment endSegment;
// Calculate the deviation clock time from DecodedStream.
int64_t deviation_usec = sourceStream->StreamTimeToMicroseconds(1);
WriteVideoToMediaStream(sourceStream, mData->mLastVideoImage,
mData->mNextVideoTime + deviation_usec, mData->mNextVideoTime,
- mData->mLastVideoImageDisplaySize, &endSegment);
+ mData->mLastVideoImageDisplaySize, &endSegment, aPrincipalHandle);
mData->mNextVideoTime += deviation_usec;
MOZ_ASSERT(endSegment.GetDuration() > 0);
if (!aIsSameOrigin) {
endSegment.ReplaceWithDisabled();
}
sourceStream->AppendToTrack(videoTrackId, &endSegment);
}
sourceStream->EndTrack(videoTrackId);
@@ -677,18 +683,18 @@ DecodedStream::SendData()
return;
}
// Nothing to do when the stream is finished.
if (mData->mHaveSentFinish) {
return;
}
- SendAudio(mParams.mVolume, mSameOrigin);
- SendVideo(mSameOrigin);
+ SendAudio(mParams.mVolume, mSameOrigin, mPrincipalHandle);
+ SendVideo(mSameOrigin, mPrincipalHandle);
AdvanceTracks();
bool finished = (!mInfo.HasAudio() || mAudioQueue.IsFinished()) &&
(!mInfo.HasVideo() || mVideoQueue.IsFinished());
if (finished && !mData->mHaveSentFinish) {
mData->mHaveSentFinish = true;
mData->mStream->Finish();
--- a/dom/media/mediasink/DecodedStream.h
+++ b/dom/media/mediasink/DecodedStream.h
@@ -32,17 +32,18 @@ template <class T> class MediaQueue;
class DecodedStream : public media::MediaSink {
using media::MediaSink::PlaybackParams;
public:
DecodedStream(AbstractThread* aOwnerThread,
MediaQueue<MediaData>& aAudioQueue,
MediaQueue<MediaData>& aVideoQueue,
OutputStreamManager* aOutputStreamManager,
- const bool& aSameOrigin);
+ const bool& aSameOrigin,
+ const PrincipalHandle& aPrincipalHandle);
// MediaSink functions.
const PlaybackParams& GetPlaybackParams() const override;
void SetPlaybackParams(const PlaybackParams& aParams) override;
RefPtr<GenericPromise> OnEnded(TrackType aType) override;
int64_t GetEndTime(TrackType aType) const override;
int64_t GetPosition(TimeStamp* aTimeStamp = nullptr) const override;
@@ -65,18 +66,18 @@ public:
protected:
virtual ~DecodedStream();
private:
void CreateData(PlaybackInfoInit&& aInit, MozPromiseHolder<GenericPromise>&& aPromise);
void DestroyData(UniquePtr<DecodedStreamData> aData);
void OnDataCreated(UniquePtr<DecodedStreamData> aData);
void AdvanceTracks();
- void SendAudio(double aVolume, bool aIsSameOrigin);
- void SendVideo(bool aIsSameOrigin);
+ void SendAudio(double aVolume, bool aIsSameOrigin, const PrincipalHandle& aPrincipalHandle);
+ void SendVideo(bool aIsSameOrigin, const PrincipalHandle& aPrincipalHandle);
void SendData();
void AssertOwnerThread() const {
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
}
void ConnectListener();
void DisconnectListener();
@@ -92,16 +93,18 @@ private:
/*
* Worker thread only members.
*/
UniquePtr<DecodedStreamData> mData;
RefPtr<GenericPromise> mFinishPromise;
bool mPlaying;
const bool& mSameOrigin; // valid until Shutdown() is called.
+ const PrincipalHandle& mPrincipalHandle; // valid until Shutdown() is called.
+
PlaybackParams mParams;
Maybe<int64_t> mStartTime;
MediaInfo mInfo;
MediaQueue<MediaData>& mAudioQueue;
MediaQueue<MediaData>& mVideoQueue;