Bug 871485 - Share hw codec between applications/tasks. r=mwu, r=doublec, r=roc

This commit is contained in:
Sotaro Ikeda
2013-06-07 08:15:44 -04:00
parent 6e4fe7c20f
commit ca500d17fb
30 changed files with 1576 additions and 157 deletions

View File

@@ -503,12 +503,28 @@ void MediaDecoderStateMachine::DecodeThreadRun()
while (mState != DECODER_STATE_SHUTDOWN &&
mState != DECODER_STATE_COMPLETED &&
mState != DECODER_STATE_DORMANT &&
!mStopDecodeThread)
{
if (mState == DECODER_STATE_DECODING || mState == DECODER_STATE_BUFFERING) {
DecodeLoop();
} else if (mState == DECODER_STATE_SEEKING) {
DecodeSeek();
} else if (mState == DECODER_STATE_DECODING_METADATA) {
if (NS_FAILED(DecodeMetadata())) {
NS_ASSERTION(mState == DECODER_STATE_SHUTDOWN,
"Should be in shutdown state if metadata loading fails.");
LOG(PR_LOG_DEBUG, ("Decode metadata failed, shutting down decode thread"));
}
} else if (mState == DECODER_STATE_WAIT_FOR_RESOURCES) {
mDecoder->GetReentrantMonitor().Wait();
if (!mReader->IsWaitingMediaResources()) {
// change state to DECODER_STATE_WAIT_FOR_RESOURCES
StartDecodeMetadata();
}
} else if (mState == DECODER_STATE_DORMANT) {
mDecoder->GetReentrantMonitor().Wait();
}
}
@@ -953,6 +969,7 @@ void MediaDecoderStateMachine::DecodeLoop()
if (!mStopDecodeThread &&
mState != DECODER_STATE_SHUTDOWN &&
mState != DECODER_STATE_DORMANT &&
mState != DECODER_STATE_SEEKING)
{
mState = DECODER_STATE_COMPLETED;
@@ -1457,6 +1474,33 @@ void MediaDecoderStateMachine::SetMediaSeekable(bool aMediaSeekable)
mMediaSeekable = aMediaSeekable;
}
bool MediaDecoderStateMachine::IsDormantNeeded()
{
return mReader->IsDormantNeeded();
}
void MediaDecoderStateMachine::SetDormant(bool aDormant)
{
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
if (!mReader) {
return;
}
if (aDormant) {
ScheduleStateMachine();
mState = DECODER_STATE_DORMANT;
mDecoder->GetReentrantMonitor().NotifyAll();
} else if ((aDormant != true) && (mState == DECODER_STATE_DORMANT)) {
ScheduleStateMachine();
mStartTime = 0;
mCurrentFrameTime = 0;
mState = DECODER_STATE_DECODING_METADATA;
mDecoder->GetReentrantMonitor().NotifyAll();
}
}
void MediaDecoderStateMachine::Shutdown()
{
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
@@ -1484,6 +1528,22 @@ void MediaDecoderStateMachine::StartDecoding()
ScheduleStateMachine();
}
void MediaDecoderStateMachine::StartWaitForResources()
{
NS_ASSERTION(OnStateMachineThread() || OnDecodeThread(),
"Should be on state machine or decode thread.");
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
mState = DECODER_STATE_WAIT_FOR_RESOURCES;
}
void MediaDecoderStateMachine::StartDecodeMetadata()
{
NS_ASSERTION(OnStateMachineThread() || OnDecodeThread(),
"Should be on state machine or decode thread.");
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
mState = DECODER_STATE_DECODING_METADATA;
}
void MediaDecoderStateMachine::Play()
{
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
@@ -1815,6 +1875,12 @@ nsresult MediaDecoderStateMachine::DecodeMetadata()
ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
res = mReader->ReadMetadata(&info, &tags);
}
if (NS_SUCCEEDED(res) && (mState == DECODER_STATE_DECODING_METADATA) && (mReader->IsWaitingMediaResources())) {
// change state to DECODER_STATE_WAIT_FOR_RESOURCES
StartWaitForResources();
return NS_OK;
}
mInfo = info;
if (NS_FAILED(res) || (!info.mHasVideo && !info.mHasAudio)) {
@@ -2081,6 +2147,10 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
// Now that those threads are stopped, there's no possibility of
// mPendingWakeDecoder being needed again. Revoke it.
mPendingWakeDecoder = nullptr;
{
ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
mReader->ReleaseMediaResources();
}
NS_ASSERTION(mState == DECODER_STATE_SHUTDOWN,
"How did we escape from the shutdown state?");
// We must daisy-chain these events to destroy the decoder. We must
@@ -2100,6 +2170,26 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
return NS_OK;
}
case DECODER_STATE_DORMANT: {
if (IsPlaying()) {
StopPlayback();
}
StopAudioThread();
StopDecodeThread();
// Now that those threads are stopped, there's no possibility of
// mPendingWakeDecoder being needed again. Revoke it.
mPendingWakeDecoder = nullptr;
{
ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
mReader->ReleaseMediaResources();
}
return NS_OK;
}
case DECODER_STATE_WAIT_FOR_RESOURCES: {
return NS_OK;
}
case DECODER_STATE_DECODING_METADATA: {
// Ensure we have a decode thread to decode metadata.
return ScheduleDecodeThread();