Backed out changeset 909cddbd5af9 (bug 831224)

This commit is contained in:
Ed Morley 2013-08-08 09:59:42 -07:00
parent da742ab0b7
commit 7d5f2c1626
2 changed files with 43 additions and 84 deletions

View File

@ -40,50 +40,22 @@ using namespace mozilla;
namespace mozilla {
class OmxDecoderProcessCachedDataTask : public Task
{
public:
OmxDecoderProcessCachedDataTask(android::OmxDecoder* aOmxDecoder, int64_t aOffset)
: mOmxDecoder(aOmxDecoder),
mOffset(aOffset)
{ }
void Run()
{
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(mOmxDecoder.get());
mOmxDecoder->ProcessCachedData(mOffset, false);
}
private:
android::sp<android::OmxDecoder> mOmxDecoder;
int64_t mOffset;
};
// When loading an MP3 stream from a file, we need to parse the file's
// content to find its duration. Reading files of 100 Mib or more can
// delay the player app noticably, so the file os read and decoded in
// smaller chunks.
// content to find its duration. We must do this from within the decode
// thread, but parsing itself must be done in the main thread.
//
// We first read on the decode thread, but parsing must be done on the
// main thread. After we read the file's initial MiBs in the decode
// thread, an instance of this class is scheduled to the main thread for
// parsing the MP3 stream. The decode thread waits until it has finished.
//
// If there is more data available from the file, the runnable dispatches
// a task to the IO thread for retrieving the next chunk of data, and
// the IO task dispatches a runnable to the main thread for parsing the
// data. This goes on until all of the MP3 file has been parsed.
// After we read the file's content in the decode thread, an instance
// of this class is scheduled to the main thread for parsing the MP3
// stream. We then wait until it has returned.
class OmxDecoderNotifyDataArrivedRunnable : public nsRunnable
{
public:
OmxDecoderNotifyDataArrivedRunnable(android::OmxDecoder* aOmxDecoder, const char* aBuffer, uint64_t aLength, int64_t aOffset, uint64_t aFullLength)
OmxDecoderNotifyDataArrivedRunnable(android::OmxDecoder* aOmxDecoder, const char* aBuffer, uint64_t aLength, int64_t aOffset)
: mOmxDecoder(aOmxDecoder),
mBuffer(aBuffer),
mLength(aLength),
mOffset(aOffset),
mFullLength(aFullLength),
mCompletedMonitor("OmxDecoderNotifyDataArrived.mCompleted"),
mCompleted(false)
{
@ -106,13 +78,6 @@ public:
mOffset += length;
}
if (mOffset < mFullLength) {
// We cannot read data in the main thread because it
// might block for too long. Instead we post an IO task
// to the IO thread if there is more data available.
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new OmxDecoderProcessCachedDataTask(mOmxDecoder.get(), mOffset));
}
Completed();
return NS_OK;
@ -128,6 +93,8 @@ public:
}
}
static nsresult ProcessCachedData(android::OmxDecoder* aOmxDecoder);
private:
// Call this function at the end of Run() to notify waiting
// threads.
@ -143,12 +110,43 @@ private:
nsAutoArrayPtr<const char> mBuffer;
uint64_t mLength;
int64_t mOffset;
uint64_t mFullLength;
Monitor mCompletedMonitor;
bool mCompleted;
};
nsresult OmxDecoderNotifyDataArrivedRunnable::ProcessCachedData(android::OmxDecoder* aOmxDecoder)
{
MOZ_ASSERT(aOmxDecoder);
NS_ASSERTION(!NS_IsMainThread(), "Should not be on main thread.");
MediaResource* resource = aOmxDecoder->GetResource();
MOZ_ASSERT(resource);
int64_t length = resource->GetCachedDataEnd(0);
NS_ENSURE_TRUE(length >= 0, NS_ERROR_UNEXPECTED);
if (!length) {
return NS_OK; // Cache is empty, nothing to do
}
nsAutoArrayPtr<char> buffer(new char[length]);
nsresult rv = resource->ReadFromCache(buffer.get(), 0, length);
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<OmxDecoderNotifyDataArrivedRunnable> runnable(
new OmxDecoderNotifyDataArrivedRunnable(aOmxDecoder, buffer.forget(), length, 0));
rv = NS_DispatchToMainThread(runnable.get());
NS_ENSURE_SUCCESS(rv, rv);
runnable->WaitForCompletion();
return NS_OK;
}
namespace layers {
VideoGraphicBuffer::VideoGraphicBuffer(const android::wp<android::OmxDecoder> aOmxDecoder,
@ -396,7 +394,9 @@ 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)) {
nsresult rv = OmxDecoderNotifyDataArrivedRunnable::ProcessCachedData(this);
if (rv == NS_OK) {
durationUs = mMP3FrameParser.GetDuration();
if (durationUs > totalDurationUs) {
totalDurationUs = durationUs;
@ -992,43 +992,3 @@ void OmxDecoder::ReleaseAllPendingVideoBuffersLocked()
releasingVideoBuffers.clear();
}
bool OmxDecoder::ProcessCachedData(int64_t aOffset, bool aWaitForCompletion)
{
// We read data in chunks of 8 MiB. We can reduce this
// value if media, such as sdcards, is too slow.
static const int64_t sReadSize = 8 * 1024 * 1024;
NS_ASSERTION(!NS_IsMainThread(), "Should not be on main thread.");
MOZ_ASSERT(mResource);
int64_t resourceLength = mResource->GetCachedDataEnd(0);
NS_ENSURE_TRUE(resourceLength >= 0, false);
if (aOffset >= resourceLength) {
return true; // Cache is empty, nothing to do
}
int64_t bufferLength = std::min<int64_t>(resourceLength-aOffset, sReadSize);
nsAutoArrayPtr<char> buffer(new char[bufferLength]);
nsresult rv = mResource->ReadFromCache(buffer.get(), aOffset, bufferLength);
NS_ENSURE_SUCCESS(rv, false);
nsRefPtr<OmxDecoderNotifyDataArrivedRunnable> runnable(
new OmxDecoderNotifyDataArrivedRunnable(this,
buffer.forget(),
bufferLength,
aOffset,
resourceLength));
rv = NS_DispatchToMainThread(runnable.get());
NS_ENSURE_SUCCESS(rv, false);
if (aWaitForCompletion) {
runnable->WaitForCompletion();
}
return true;
}

View File

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