diff --git a/content/media/omx/OmxDecoder.cpp b/content/media/omx/OmxDecoder.cpp index 5ce86774dcb..1d53cde4f76 100644 --- a/content/media/omx/OmxDecoder.cpp +++ b/content/media/omx/OmxDecoder.cpp @@ -41,6 +41,25 @@ using namespace mozilla; namespace mozilla { +class ReleaseOmxDecoderRunnable : public nsRunnable +{ +public: + ReleaseOmxDecoderRunnable(const android::sp& aOmxDecoder) + : mOmxDecoder(aOmxDecoder) + { + } + + NS_METHOD Run() MOZ_OVERRIDE + { + MOZ_ASSERT(NS_IsMainThread()); + mOmxDecoder = nullptr; // release OmxDecoder + return NS_OK; + } + +private: + android::sp 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(resourceLength-aOffset, sReadSize); @@ -1041,7 +1068,7 @@ bool OmxDecoder::ProcessCachedData(int64_t aOffset, bool aWaitForCompletion) nsAutoArrayPtr buffer(new char[bufferLength]); nsresult rv = mResource->ReadFromCache(buffer.get(), aOffset, bufferLength); - NS_ENSURE_SUCCESS(rv, false); + NS_ENSURE_SUCCESS(rv, -1); nsRefPtr 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; } diff --git a/content/media/omx/OmxDecoder.h b/content/media/omx/OmxDecoder.h index b0e7ce3b91c..96b55c068cd 100644 --- a/content/media/omx/OmxDecoder.h +++ b/content/media/omx/OmxDecoder.h @@ -238,7 +238,7 @@ public: // Called on ALooper thread. void onMessageReceived(const sp &msg); - bool ProcessCachedData(int64_t aOffset, bool aWaitForCompletion); + int64_t ProcessCachedData(int64_t aOffset, bool aWaitForCompletion); }; }