Bug 947905: Release OmxDecoder on main thread

OmxDecoder refers to MediaResource, which must be released on
the main thread. This patch changes the MP3 parser logic to send
a runnable to the main thread for releasing OmxDecoder.
This commit is contained in:
Thomas Zimmermann 2013-12-12 09:57:56 +01:00
parent 16042c396f
commit 0c1b4a5df0
2 changed files with 36 additions and 9 deletions

View File

@ -41,6 +41,25 @@ using namespace mozilla;
namespace mozilla {
class ReleaseOmxDecoderRunnable : public nsRunnable
{
public:
ReleaseOmxDecoderRunnable(const android::sp<android::OmxDecoder>& aOmxDecoder)
: mOmxDecoder(aOmxDecoder)
{
}
NS_METHOD Run() MOZ_OVERRIDE
{
MOZ_ASSERT(NS_IsMainThread());
mOmxDecoder = nullptr; // release OmxDecoder
return NS_OK;
}
private:
android::sp<android::OmxDecoder> mOmxDecoder;
};
class OmxDecoderProcessCachedDataTask : public Task
{
public:
@ -53,7 +72,13 @@ public:
{
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(mOmxDecoder.get());
mOmxDecoder->ProcessCachedData(mOffset, false);
int64_t rem = mOmxDecoder->ProcessCachedData(mOffset, false);
if (rem <= 0) {
ReleaseOmxDecoderRunnable* r = new ReleaseOmxDecoderRunnable(mOmxDecoder);
mOmxDecoder.clear();
NS_DispatchToMainThread(r);
}
}
private:
@ -292,6 +317,8 @@ OmxDecoder::OmxDecoder(MediaResource *aResource,
OmxDecoder::~OmxDecoder()
{
MOZ_ASSERT(NS_IsMainThread());
ReleaseMediaResources();
// unregister AMessage handler from ALooper.
@ -398,7 +425,7 @@ bool OmxDecoder::TryLoad() {
// Feed MP3 parser with cached data. Local files will be fully
// cached already, network streams will update with sucessive
// calls to NotifyDataArrived.
if (ProcessCachedData(0, true)) {
if (ProcessCachedData(0, true) >= 0) {
durationUs = mMP3FrameParser.GetDuration();
if (durationUs > totalDurationUs) {
totalDurationUs = durationUs;
@ -1017,7 +1044,7 @@ void OmxDecoder::ReleaseAllPendingVideoBuffersLocked()
releasingVideoBuffers.clear();
}
bool OmxDecoder::ProcessCachedData(int64_t aOffset, bool aWaitForCompletion)
int64_t OmxDecoder::ProcessCachedData(int64_t aOffset, bool aWaitForCompletion)
{
// We read data in chunks of 32 KiB. We can reduce this
// value if media, such as sdcards, is too slow.
@ -1030,10 +1057,10 @@ bool OmxDecoder::ProcessCachedData(int64_t aOffset, bool aWaitForCompletion)
MOZ_ASSERT(mResource);
int64_t resourceLength = mResource->GetCachedDataEnd(0);
NS_ENSURE_TRUE(resourceLength >= 0, false);
NS_ENSURE_TRUE(resourceLength >= 0, -1);
if (aOffset >= resourceLength) {
return true; // Cache is empty, nothing to do
return 0; // Cache is empty, nothing to do
}
int64_t bufferLength = std::min<int64_t>(resourceLength-aOffset, sReadSize);
@ -1041,7 +1068,7 @@ bool OmxDecoder::ProcessCachedData(int64_t aOffset, bool aWaitForCompletion)
nsAutoArrayPtr<char> buffer(new char[bufferLength]);
nsresult rv = mResource->ReadFromCache(buffer.get(), aOffset, bufferLength);
NS_ENSURE_SUCCESS(rv, false);
NS_ENSURE_SUCCESS(rv, -1);
nsRefPtr<OmxDecoderNotifyDataArrivedRunnable> runnable(
new OmxDecoderNotifyDataArrivedRunnable(this,
@ -1051,11 +1078,11 @@ bool OmxDecoder::ProcessCachedData(int64_t aOffset, bool aWaitForCompletion)
resourceLength));
rv = NS_DispatchToMainThread(runnable.get());
NS_ENSURE_SUCCESS(rv, false);
NS_ENSURE_SUCCESS(rv, -1);
if (aWaitForCompletion) {
runnable->WaitForCompletion();
}
return true;
return resourceLength - aOffset - bufferLength;
}

View File

@ -238,7 +238,7 @@ public:
// Called on ALooper thread.
void onMessageReceived(const sp<AMessage> &msg);
bool ProcessCachedData(int64_t aOffset, bool aWaitForCompletion);
int64_t ProcessCachedData(int64_t aOffset, bool aWaitForCompletion);
};
}