Bug 1105209 - Add media resource request API. r=kentuckyfriedtakahe

This commit is contained in:
Alfredo Yang 2014-12-15 22:25:00 -05:00
parent cd08fa0c57
commit 0605a67301
12 changed files with 77 additions and 15 deletions

View File

@ -2734,6 +2734,12 @@ MediaDecoderStateMachine::FlushDecoding()
DecodeTaskQueue()->FlushAndDispatch(task); DecodeTaskQueue()->FlushAndDispatch(task);
} }
// These flags will be reset when the decoded data returned in OnAudioDecoded()
// and OnVideoDecoded(). Because the decode tasks are flushed, these flags need
// to be reset here.
mAudioRequestPending = false;
mVideoRequestPending = false;
// We must reset playback so that all references to frames queued // We must reset playback so that all references to frames queued
// in the state machine are dropped, else subsequent calls to Shutdown() // in the state machine are dropped, else subsequent calls to Shutdown()
// or ReleaseMediaResources() can fail on B2G. // or ReleaseMediaResources() can fail on B2G.

View File

@ -204,6 +204,14 @@ private:
}; };
#endif #endif
void MP4Reader::RequestCodecResource() {
#ifdef MOZ_GONK_MEDIACODEC
if(mVideo.mDecoder) {
mVideo.mDecoder->AllocateMediaResources();
}
#endif
}
bool MP4Reader::IsWaitingOnCodecResource() { bool MP4Reader::IsWaitingOnCodecResource() {
#ifdef MOZ_GONK_MEDIACODEC #ifdef MOZ_GONK_MEDIACODEC
return mVideo.mDecoder && mVideo.mDecoder->IsWaitingMediaResources(); return mVideo.mDecoder && mVideo.mDecoder->IsWaitingMediaResources();
@ -273,6 +281,14 @@ MP4Reader::IsSupportedVideoMimeType(const char* aMimeType)
mPlatform->SupportsVideoMimeType(aMimeType); mPlatform->SupportsVideoMimeType(aMimeType);
} }
void
MP4Reader::PreReadMetadata()
{
if (mPlatform) {
RequestCodecResource();
}
}
nsresult nsresult
MP4Reader::ReadMetadata(MediaInfo* aInfo, MP4Reader::ReadMetadata(MediaInfo* aInfo,
MetadataTags** aTags) MetadataTags** aTags)
@ -729,6 +745,7 @@ MP4Reader::Flush(TrackType aTrack)
data.RejectPromise(CANCELED, __func__); data.RejectPromise(CANCELED, __func__);
} }
data.mDiscontinuity = true; data.mDiscontinuity = true;
data.mUpdateScheduled = false;
} }
if (aTrack == kVideo) { if (aTrack == kVideo) {
mQueuedVideoSample = nullptr; mQueuedVideoSample = nullptr;

View File

@ -45,6 +45,11 @@ public:
virtual bool HasAudio() MOZ_OVERRIDE; virtual bool HasAudio() MOZ_OVERRIDE;
virtual bool HasVideo() MOZ_OVERRIDE; virtual bool HasVideo() MOZ_OVERRIDE;
// PreReadMetadata() is called by MediaDecoderStateMachine::DecodeMetadata()
// before checking hardware resource. In Gonk, it requests hardware codec so
// MediaDecoderStateMachine could go to DORMANT state if the hardware codec is
// not available.
virtual void PreReadMetadata() MOZ_OVERRIDE;
virtual nsresult ReadMetadata(MediaInfo* aInfo, virtual nsresult ReadMetadata(MediaInfo* aInfo,
MetadataTags** aTags) MOZ_OVERRIDE; MetadataTags** aTags) MOZ_OVERRIDE;
@ -107,6 +112,7 @@ private:
bool IsSupportedAudioMimeType(const char* aMimeType); bool IsSupportedAudioMimeType(const char* aMimeType);
bool IsSupportedVideoMimeType(const char* aMimeType); bool IsSupportedVideoMimeType(const char* aMimeType);
void NotifyResourcesStatusChanged(); void NotifyResourcesStatusChanged();
void RequestCodecResource();
bool IsWaitingOnCodecResource(); bool IsWaitingOnCodecResource();
virtual bool IsWaitingOnCDMResource() MOZ_OVERRIDE; virtual bool IsWaitingOnCDMResource() MOZ_OVERRIDE;

View File

@ -231,6 +231,7 @@ public:
virtual bool IsDormantNeeded() { virtual bool IsDormantNeeded() {
return false; return false;
}; };
virtual void AllocateMediaResources() {}
virtual void ReleaseMediaResources() {} virtual void ReleaseMediaResources() {}
virtual void ReleaseDecoder() {} virtual void ReleaseDecoder() {}
}; };

View File

@ -164,6 +164,12 @@ GonkMediaDataDecoder::IsDormantNeeded() {
return mDecoder.get() ? true : false; return mDecoder.get() ? true : false;
} }
void
GonkMediaDataDecoder::AllocateMediaResources()
{
mManager->AllocateMediaResources();
}
void void
GonkMediaDataDecoder::ReleaseMediaResources() { GonkMediaDataDecoder::ReleaseMediaResources() {
mManager->ReleaseMediaResources(); mManager->ReleaseMediaResources();

View File

@ -35,6 +35,8 @@ public:
nsRefPtr<MediaData>& aOutput) = 0; nsRefPtr<MediaData>& aOutput) = 0;
virtual nsresult Flush() = 0; virtual nsresult Flush() = 0;
virtual void AllocateMediaResources() {};
virtual void ReleaseMediaResources() {}; virtual void ReleaseMediaResources() {};
}; };
@ -65,6 +67,8 @@ public:
virtual bool IsDormantNeeded() MOZ_OVERRIDE; virtual bool IsDormantNeeded() MOZ_OVERRIDE;
virtual void AllocateMediaResources() MOZ_OVERRIDE;
virtual void ReleaseMediaResources() MOZ_OVERRIDE; virtual void ReleaseMediaResources() MOZ_OVERRIDE;
private: private:

View File

@ -474,6 +474,12 @@ GonkVideoDecoderManager::Flush()
return NS_OK; return NS_OK;
} }
void
GonkVideoDecoderManager::AllocateMediaResources()
{
mDecoder->RequestMediaResources();
}
void void
GonkVideoDecoderManager::codecReserved() GonkVideoDecoderManager::codecReserved()
{ {

View File

@ -52,6 +52,8 @@ public:
virtual nsresult Flush() MOZ_OVERRIDE; virtual nsresult Flush() MOZ_OVERRIDE;
virtual void AllocateMediaResources();
virtual void ReleaseMediaResources(); virtual void ReleaseMediaResources();
static void RecycleCallback(TextureClient* aClient, void* aClosure); static void RecycleCallback(TextureClient* aClient, void* aClosure);

View File

@ -135,6 +135,12 @@ MediaCodecProxy::requestResource()
return true; return true;
} }
void
MediaCodecProxy::RequestMediaResources()
{
requestResource();
}
void void
MediaCodecProxy::cancelResource() MediaCodecProxy::cancelResource()
{ {
@ -572,7 +578,6 @@ status_t MediaCodecProxy::Output(MediaBuffer** aBuffer, int64_t aTimeoutUs)
status_t err = dequeueOutputBuffer(&index, &offset, &size, status_t err = dequeueOutputBuffer(&index, &offset, &size,
&timeUs, &flags, aTimeoutUs); &timeUs, &flags, aTimeoutUs);
if (err != OK) { if (err != OK) {
ALOG("Output returned %d", err);
return err; return err;
} }
@ -598,9 +603,10 @@ status_t MediaCodecProxy::Output(MediaBuffer** aBuffer, int64_t aTimeoutUs)
bool MediaCodecProxy::IsWaitingResources() bool MediaCodecProxy::IsWaitingResources()
{ {
// Write Lock for mCodec if (mResourceHandler.get()) {
RWLock::AutoWLock awl(mCodecLock); return mResourceHandler->IsWaitingResource();
return mCodec == nullptr; }
return false;
} }
bool MediaCodecProxy::IsDormantNeeded() bool MediaCodecProxy::IsDormantNeeded()

View File

@ -131,6 +131,7 @@ public:
bool Prepare(); bool Prepare();
bool IsWaitingResources(); bool IsWaitingResources();
bool IsDormantNeeded(); bool IsDormantNeeded();
void RequestMediaResources();
void ReleaseMediaResources(); void ReleaseMediaResources();
// This updates mOutputBuffer when receiving INFO_OUTPUT_BUFFERS_CHANGED event. // This updates mOutputBuffer when receiving INFO_OUTPUT_BUFFERS_CHANGED event.
bool UpdateOutputBuffers(); bool UpdateOutputBuffers();

View File

@ -5,15 +5,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MediaResourceHandler.h" #include "MediaResourceHandler.h"
#include "mozilla/NullPtr.h" #include "mozilla/NullPtr.h"
namespace android { namespace android {
MediaResourceHandler::MediaResourceHandler(const wp<ResourceListener> &aListener) MediaResourceHandler::MediaResourceHandler(const wp<ResourceListener> &aListener)
: mListener(aListener) : mListener(aListener)
, mState(MediaResourceManagerClient::CLIENT_STATE_WAIT_FOR_RESOURCE)
, mType(IMediaResourceManagerService::INVALID_RESOURCE_TYPE) , mType(IMediaResourceManagerService::INVALID_RESOURCE_TYPE)
, mWaitingResource(false)
{ {
} }
@ -22,6 +21,13 @@ MediaResourceHandler::~MediaResourceHandler()
cancelResource(); cancelResource();
} }
bool
MediaResourceHandler::IsWaitingResource()
{
Mutex::Autolock al(mLock);
return mWaitingResource;
}
bool bool
MediaResourceHandler::requestResource(IMediaResourceManagerService::ResourceType aType) MediaResourceHandler::requestResource(IMediaResourceManagerService::ResourceType aType)
{ {
@ -45,6 +51,7 @@ MediaResourceHandler::requestResource(IMediaResourceManagerService::ResourceType
mClient = client; mClient = client;
mService = service; mService = service;
mType = aType; mType = aType;
mWaitingResource = true;
return true; return true;
} }
@ -58,6 +65,7 @@ MediaResourceHandler::cancelResource()
mService->cancelClient(mClient, (int)mType); mService->cancelClient(mClient, (int)mType);
} }
mWaitingResource = false;
mClient = nullptr; mClient = nullptr;
mService = nullptr; mService = nullptr;
} }
@ -70,19 +78,15 @@ MediaResourceHandler::statusChanged(int aEvent)
Mutex::Autolock autoLock(mLock); Mutex::Autolock autoLock(mLock);
MediaResourceManagerClient::State state = (MediaResourceManagerClient::State)aEvent;
if (state == mState) {
return;
}
mState = state;
listener = mListener.promote(); listener = mListener.promote();
if (listener == nullptr) { if (listener == nullptr) {
return; return;
} }
if (mState == MediaResourceManagerClient::CLIENT_STATE_RESOURCE_ASSIGNED) { mWaitingResource = false;
MediaResourceManagerClient::State state = (MediaResourceManagerClient::State)aEvent;
if (state == MediaResourceManagerClient::CLIENT_STATE_RESOURCE_ASSIGNED) {
listener->resourceReserved(); listener->resourceReserved();
} else { } else {
listener->resourceCanceled(); listener->resourceCanceled();

View File

@ -42,6 +42,8 @@ public:
// Cancel Resource // Cancel Resource
void cancelResource(); void cancelResource();
bool IsWaitingResource();
protected: protected:
// MediaResourceManagerClient::EventListener::statusChanged() // MediaResourceManagerClient::EventListener::statusChanged()
virtual void statusChanged(int event); virtual void statusChanged(int event);
@ -57,10 +59,11 @@ private:
// Resource Management // Resource Management
Mutex mLock; Mutex mLock;
MediaResourceManagerClient::State mState;
sp<IMediaResourceManagerClient> mClient; sp<IMediaResourceManagerClient> mClient;
sp<IMediaResourceManagerService> mService; sp<IMediaResourceManagerService> mService;
IMediaResourceManagerService::ResourceType mType; IMediaResourceManagerService::ResourceType mType;
bool mWaitingResource;
}; };
} // namespace android } // namespace android