mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-08 12:37:37 +00:00
Bug 1050667 - fix the non-synchronous waiting state between MediaDecoderStataMachine and MediaOmxReader and OmxDecoder. r=sotaro
This commit is contained in:
parent
b9e39edae5
commit
c36b5a4a96
@ -1419,11 +1419,21 @@ void MediaDecoderStateMachine::StartWaitForResources()
|
|||||||
void MediaDecoderStateMachine::NotifyWaitingForResourcesStatusChanged()
|
void MediaDecoderStateMachine::NotifyWaitingForResourcesStatusChanged()
|
||||||
{
|
{
|
||||||
AssertCurrentThreadInMonitor();
|
AssertCurrentThreadInMonitor();
|
||||||
if (mState != DECODER_STATE_WAIT_FOR_RESOURCES ||
|
DECODER_LOG("NotifyWaitingForResourcesStatusChanged");
|
||||||
mReader->IsWaitingMediaResources()) {
|
RefPtr<nsIRunnable> task(
|
||||||
|
NS_NewRunnableMethod(this,
|
||||||
|
&MediaDecoderStateMachine::DoNotifyWaitingForResourcesStatusChanged));
|
||||||
|
mDecodeTaskQueue->Dispatch(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MediaDecoderStateMachine::DoNotifyWaitingForResourcesStatusChanged()
|
||||||
|
{
|
||||||
|
NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
|
||||||
|
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||||
|
if (mState != DECODER_STATE_WAIT_FOR_RESOURCES) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DECODER_LOG("NotifyWaitingForResourcesStatusChanged");
|
DECODER_LOG("DoNotifyWaitingForResourcesStatusChanged");
|
||||||
// The reader is no longer waiting for resources (say a hardware decoder),
|
// The reader is no longer waiting for resources (say a hardware decoder),
|
||||||
// we can now proceed to decode metadata.
|
// we can now proceed to decode metadata.
|
||||||
SetState(DECODER_STATE_DECODING_NONE);
|
SetState(DECODER_STATE_DECODING_NONE);
|
||||||
|
@ -327,9 +327,9 @@ public:
|
|||||||
// be held.
|
// be held.
|
||||||
bool IsPlaying();
|
bool IsPlaying();
|
||||||
|
|
||||||
|
// Dispatch DoNotifyWaitingForResourcesStatusChanged task to mDecodeTaskQueue.
|
||||||
// Called when the reader may have acquired the hardware resources required
|
// Called when the reader may have acquired the hardware resources required
|
||||||
// to begin decoding. The state machine may move into DECODING_METADATA if
|
// to begin decoding. The decoder monitor must be held while calling this.
|
||||||
// appropriate. The decoder monitor must be held while calling this.
|
|
||||||
void NotifyWaitingForResourcesStatusChanged();
|
void NotifyWaitingForResourcesStatusChanged();
|
||||||
|
|
||||||
// Notifies the state machine that should minimize the number of samples
|
// Notifies the state machine that should minimize the number of samples
|
||||||
@ -636,6 +636,10 @@ protected:
|
|||||||
// and the sink is shutting down.
|
// and the sink is shutting down.
|
||||||
void OnAudioSinkComplete();
|
void OnAudioSinkComplete();
|
||||||
|
|
||||||
|
// The state machine may move into DECODING_METADATA if we are in
|
||||||
|
// DECODER_STATE_WAIT_FOR_RESOURCES.
|
||||||
|
void DoNotifyWaitingForResourcesStatusChanged();
|
||||||
|
|
||||||
// The decoder object that created this state machine. The state machine
|
// The decoder object that created this state machine. The state machine
|
||||||
// holds a strong reference to the decoder to ensure that the decoder stays
|
// holds a strong reference to the decoder to ensure that the decoder stays
|
||||||
// alive once media element has started the decoder shutdown process, and has
|
// alive once media element has started the decoder shutdown process, and has
|
||||||
|
@ -135,6 +135,7 @@ MediaOmxReader::MediaOmxReader(AbstractMediaDecoder *aDecoder)
|
|||||||
, mSkipCount(0)
|
, mSkipCount(0)
|
||||||
, mUseParserDuration(false)
|
, mUseParserDuration(false)
|
||||||
, mLastParserDuration(-1)
|
, mLastParserDuration(-1)
|
||||||
|
, mIsWaitingResources(false)
|
||||||
{
|
{
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
if (!gMediaDecoderLog) {
|
if (!gMediaDecoderLog) {
|
||||||
@ -172,10 +173,16 @@ void MediaOmxReader::Shutdown()
|
|||||||
|
|
||||||
bool MediaOmxReader::IsWaitingMediaResources()
|
bool MediaOmxReader::IsWaitingMediaResources()
|
||||||
{
|
{
|
||||||
if (!mOmxDecoder.get()) {
|
return mIsWaitingResources;
|
||||||
return false;
|
}
|
||||||
|
|
||||||
|
void MediaOmxReader::UpdateIsWaitingMediaResources()
|
||||||
|
{
|
||||||
|
if (mOmxDecoder.get()) {
|
||||||
|
mIsWaitingResources = mOmxDecoder->IsWaitingMediaResources();
|
||||||
|
} else {
|
||||||
|
mIsWaitingResources = false;
|
||||||
}
|
}
|
||||||
return mOmxDecoder->IsWaitingMediaResources();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MediaOmxReader::IsDormantNeeded()
|
bool MediaOmxReader::IsDormantNeeded()
|
||||||
@ -245,13 +252,21 @@ nsresult MediaOmxReader::ReadMetadata(MediaInfo* aInfo,
|
|||||||
ProcessCachedData(0, true);
|
ProcessCachedData(0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mOmxDecoder->TryLoad()) {
|
if (!mOmxDecoder->AllocateMediaResources()) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
// Bug 1050667, both MediaDecoderStateMachine and MediaOmxReader
|
||||||
|
// relies on IsWaitingMediaResources() function. And the waiting state will be
|
||||||
|
// changed by binder thread, so we store the waiting state in a cache value to
|
||||||
|
// make them in the same waiting state.
|
||||||
|
UpdateIsWaitingMediaResources();
|
||||||
if (IsWaitingMediaResources()) {
|
if (IsWaitingMediaResources()) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
// After resources are available, set the metadata.
|
||||||
|
if (!mOmxDecoder->EnsureMetadata()) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
if (isMP3 && mMP3FrameParser.IsMP3()) {
|
if (isMP3 && mMP3FrameParser.IsMP3()) {
|
||||||
int64_t duration = mMP3FrameParser.GetDuration();
|
int64_t duration = mMP3FrameParser.GetDuration();
|
||||||
|
@ -44,6 +44,11 @@ protected:
|
|||||||
android::sp<android::OmxDecoder> mOmxDecoder;
|
android::sp<android::OmxDecoder> mOmxDecoder;
|
||||||
android::sp<android::MediaExtractor> mExtractor;
|
android::sp<android::MediaExtractor> mExtractor;
|
||||||
MP3FrameParser mMP3FrameParser;
|
MP3FrameParser mMP3FrameParser;
|
||||||
|
|
||||||
|
// A cache value updated by UpdateIsWaitingMediaResources(), makes the
|
||||||
|
// "waiting resources state" is synchronous to StateMachine.
|
||||||
|
bool mIsWaitingResources;
|
||||||
|
|
||||||
// Called by ReadMetadata() during MediaDecoderStateMachine::DecodeMetadata()
|
// Called by ReadMetadata() during MediaDecoderStateMachine::DecodeMetadata()
|
||||||
// on decode thread. It create and initialize the OMX decoder including
|
// on decode thread. It create and initialize the OMX decoder including
|
||||||
// setting up custom extractor. The extractor provide the essential
|
// setting up custom extractor. The extractor provide the essential
|
||||||
@ -54,6 +59,11 @@ protected:
|
|||||||
// to activate the decoder automatically.
|
// to activate the decoder automatically.
|
||||||
virtual void EnsureActive();
|
virtual void EnsureActive();
|
||||||
|
|
||||||
|
// Check the underlying HW resources are available and store the result in
|
||||||
|
// mIsWaitingResources. The result might be changed by binder thread,
|
||||||
|
// Can only called by ReadMetadata.
|
||||||
|
void UpdateIsWaitingMediaResources();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MediaOmxReader(AbstractMediaDecoder* aDecoder);
|
MediaOmxReader(AbstractMediaDecoder* aDecoder);
|
||||||
~MediaOmxReader();
|
~MediaOmxReader();
|
||||||
@ -76,7 +86,8 @@ public:
|
|||||||
return mHasVideo;
|
return mHasVideo;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool IsWaitingMediaResources();
|
// Return mIsWaitingResources.
|
||||||
|
virtual bool IsWaitingMediaResources() MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual bool IsDormantNeeded();
|
virtual bool IsDormantNeeded();
|
||||||
virtual void ReleaseMediaResources();
|
virtual void ReleaseMediaResources();
|
||||||
|
@ -162,19 +162,7 @@ bool OmxDecoder::Init(sp<MediaExtractor>& extractor) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OmxDecoder::TryLoad() {
|
bool OmxDecoder::EnsureMetadata() {
|
||||||
|
|
||||||
if (!AllocateMediaResources()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//check if video is waiting resources
|
|
||||||
if (mVideoSource.get()) {
|
|
||||||
if (mVideoSource->IsWaitingResources()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate duration
|
// calculate duration
|
||||||
int64_t totalDurationUs = 0;
|
int64_t totalDurationUs = 0;
|
||||||
int64_t durationUs = 0;
|
int64_t durationUs = 0;
|
||||||
|
@ -152,9 +152,16 @@ public:
|
|||||||
// Note: RTSP requires a custom extractor because it doesn't have a container.
|
// Note: RTSP requires a custom extractor because it doesn't have a container.
|
||||||
bool Init(sp<MediaExtractor>& extractor);
|
bool Init(sp<MediaExtractor>& extractor);
|
||||||
|
|
||||||
bool TryLoad();
|
|
||||||
bool IsDormantNeeded();
|
bool IsDormantNeeded();
|
||||||
|
|
||||||
|
// Called after resources(video/audio codec) are allocated, set the
|
||||||
|
// mDurationUs and video/audio metadata.
|
||||||
|
bool EnsureMetadata();
|
||||||
|
|
||||||
|
// Only called by MediaOmxDecoder, do not call this function arbitrarily.
|
||||||
|
// See bug 1050667.
|
||||||
bool IsWaitingMediaResources();
|
bool IsWaitingMediaResources();
|
||||||
|
|
||||||
bool AllocateMediaResources();
|
bool AllocateMediaResources();
|
||||||
void ReleaseMediaResources();
|
void ReleaseMediaResources();
|
||||||
bool SetVideoFormat();
|
bool SetVideoFormat();
|
||||||
|
Loading…
Reference in New Issue
Block a user