mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 924678: Stop MP3 parser if decoder got cleared, r=doublec
If the decoder has been cleaned up, there is no point in further parsing the MP3 file. This patch makes the I/O logic stop in that case. The patch also fixes a bug where the beginning of an MP3 chunk was parsed multiple times if the chunk is larger than 4 GiB. --HG-- extra : rebase_source : d247ed3995991d362c51a0666274e9de3b90b7d2
This commit is contained in:
parent
568572011d
commit
ba40fab0c9
@ -62,8 +62,8 @@ private:
|
||||
};
|
||||
|
||||
// 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
|
||||
// content to find its duration. Reading files of 100 MiB or more can
|
||||
// delay the player app noticably, so the file is read and decoded in
|
||||
// smaller chunks.
|
||||
//
|
||||
// We first read on the decode thread, but parsing must be done on the
|
||||
@ -79,7 +79,9 @@ private:
|
||||
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, uint64_t aFullLength)
|
||||
: mOmxDecoder(aOmxDecoder),
|
||||
mBuffer(aBuffer),
|
||||
mLength(aLength),
|
||||
@ -96,24 +98,7 @@ public:
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
|
||||
const char* buffer = mBuffer.get();
|
||||
|
||||
while (mLength) {
|
||||
uint32_t length = std::min<uint64_t>(mLength, UINT32_MAX);
|
||||
mOmxDecoder->NotifyDataArrived(mBuffer.get(), mLength, mOffset);
|
||||
|
||||
buffer += length;
|
||||
mLength -= length;
|
||||
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));
|
||||
}
|
||||
|
||||
NotifyDataArrived();
|
||||
Completed();
|
||||
|
||||
return NS_OK;
|
||||
@ -130,6 +115,32 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void NotifyDataArrived()
|
||||
{
|
||||
const char* buffer = mBuffer.get();
|
||||
|
||||
while (mLength) {
|
||||
uint32_t length = std::min<uint64_t>(mLength, UINT32_MAX);
|
||||
bool success = mOmxDecoder->NotifyDataArrived(buffer, mLength,
|
||||
mOffset);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
|
||||
buffer += length;
|
||||
mLength -= length;
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
// Call this function at the end of Run() to notify waiting
|
||||
// threads.
|
||||
void Completed()
|
||||
@ -633,10 +644,10 @@ void OmxDecoder::ReleaseDecoder()
|
||||
mDecoder = nullptr;
|
||||
}
|
||||
|
||||
void OmxDecoder::NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset)
|
||||
bool OmxDecoder::NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset)
|
||||
{
|
||||
if (!mAudioTrack.get() || !mIsMp3 || !mMP3FrameParser.IsMP3() || !mDecoder) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
mMP3FrameParser.Parse(aBuffer, aLength, aOffset);
|
||||
@ -650,6 +661,8 @@ void OmxDecoder::NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
mDecoder->UpdateEstimatedMediaDuration(mDurationUs);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OmxDecoder::ReleaseVideoBuffer() {
|
||||
|
@ -183,7 +183,7 @@ public:
|
||||
|
||||
void ReleaseDecoder();
|
||||
|
||||
void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset);
|
||||
bool NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset);
|
||||
|
||||
void GetDuration(int64_t *durationUs) {
|
||||
*durationUs = mDurationUs;
|
||||
|
Loading…
Reference in New Issue
Block a user