am 4269757f: am 9697dd11: am 14cf4f0f: am c7a58efa: am def6aff8: am 1c4549c3: am 84a131f2: am 39ab7cea: am 88aa97ea: am 3ce29384: libstagefright: fix possible overflow in amrwbenc.
* commit '4269757fa363e4ce93da44723dca1f09e8d83f71':
libstagefright: fix possible overflow in amrwbenc.
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 7dc9be7..27a2934 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -1521,7 +1521,8 @@
queueDiscontinuityIfNeeded(seeking, formatChange, trackType, track);
sp<ABuffer> buffer = mediaBufferToABuffer(
- mbuf, trackType, seekTimeUs, actualTimeUs);
+ mbuf, trackType, seekTimeUs,
+ numBuffers == 0 ? actualTimeUs : NULL);
track->mPackets->queueAccessUnit(buffer);
formatChange = false;
seeking = false;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 2e0d0d3..116e8be 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -110,6 +110,7 @@
mVideoRenderingStarted(false),
mVideoRenderingStartGeneration(0),
mAudioRenderingStartGeneration(0),
+ mLastAudioMediaTimeUs(-1),
mAudioOffloadPauseTimeoutGeneration(0),
mAudioTornDown(false),
mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER),
@@ -845,6 +846,7 @@
postEOSDelayUs = getPendingAudioPlayoutDurationUs(ALooper::GetNowUs());
}
notifyEOS(true /* audio */, entry->mFinalResult, postEOSDelayUs);
+ mLastAudioMediaTimeUs = getDurationUsIfPlayedAtSampleRate(mNumFramesWritten);
mAudioQueue.erase(mAudioQueue.begin());
entry = NULL;
@@ -1081,10 +1083,10 @@
int64_t nowUs = -1;
int64_t realTimeUs;
+ int64_t mediaTimeUs = -1;
if (mFlags & FLAG_REAL_TIME) {
CHECK(entry->mBuffer->meta()->findInt64("timeUs", &realTimeUs));
} else {
- int64_t mediaTimeUs;
CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
nowUs = ALooper::GetNowUs();
@@ -1109,6 +1111,14 @@
ALOGV("rendering video at media time %.2f secs",
(mFlags & FLAG_REAL_TIME ? realTimeUs :
mediaUs) / 1E6);
+
+ if (!(mFlags & FLAG_REAL_TIME)
+ && mLastAudioMediaTimeUs != -1
+ && mediaTimeUs > mLastAudioMediaTimeUs) {
+ // If audio ends before video, video continues to drive media clock.
+ // Also smooth out videos >= 10fps.
+ mMediaClock->updateMaxTimeMedia(mediaTimeUs + 100000);
+ }
}
} else {
setVideoLateByUs(0);
@@ -1295,6 +1305,7 @@
if (audio) {
notifyComplete = mNotifyCompleteAudio;
mNotifyCompleteAudio = false;
+ mLastAudioMediaTimeUs = -1;
} else {
notifyComplete = mNotifyCompleteVideo;
mNotifyCompleteVideo = false;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index 3e65649..58bf121 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -176,7 +176,8 @@
int32_t mVideoRenderingStartGeneration;
int32_t mAudioRenderingStartGeneration;
- int64_t mLastPositionUpdateUs;
+ // the media timestamp of last audio sample right before EOS.
+ int64_t mLastAudioMediaTimeUs;
int32_t mAudioOffloadPauseTimeoutGeneration;
bool mAudioTornDown;
diff --git a/media/libnbaio/SourceAudioBufferProvider.cpp b/media/libnbaio/SourceAudioBufferProvider.cpp
index e21ef48..04c42c9 100644
--- a/media/libnbaio/SourceAudioBufferProvider.cpp
+++ b/media/libnbaio/SourceAudioBufferProvider.cpp
@@ -61,20 +61,30 @@
// do we need to reallocate?
if (buffer->frameCount > mSize) {
free(mAllocated);
- mAllocated = malloc(buffer->frameCount * mFrameSize);
+ // Android convention is to _not_ check the return value of malloc and friends.
+ // But in this case the calloc() can also fail due to integer overflow,
+ // so we check and recover.
+ mAllocated = calloc(buffer->frameCount, mFrameSize);
+ if (mAllocated == NULL) {
+ mSize = 0;
+ goto fail;
+ }
mSize = buffer->frameCount;
}
- // read from source
- ssize_t actual = mSource->read(mAllocated, buffer->frameCount, pts);
- if (actual > 0) {
- ALOG_ASSERT((size_t) actual <= buffer->frameCount);
- mOffset = 0;
- mRemaining = actual;
- buffer->raw = mAllocated;
- buffer->frameCount = actual;
- mGetCount = actual;
- return OK;
+ {
+ // read from source
+ ssize_t actual = mSource->read(mAllocated, buffer->frameCount, pts);
+ if (actual > 0) {
+ ALOG_ASSERT((size_t) actual <= buffer->frameCount);
+ mOffset = 0;
+ mRemaining = actual;
+ buffer->raw = mAllocated;
+ buffer->frameCount = actual;
+ mGetCount = actual;
+ return OK;
+ }
}
+fail:
buffer->raw = NULL;
buffer->frameCount = 0;
mGetCount = 0;
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index fb654b8..5b3947e 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -1321,7 +1321,8 @@
}
bool stale = false;
- for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
+ for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
+ i--;
BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
if (info->mGraphicBuffer != NULL &&
@@ -1364,7 +1365,8 @@
// get oldest undequeued buffer
BufferInfo *oldest = NULL;
- for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
+ for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
+ i--;
BufferInfo *info =
&mBuffers[kPortIndexOutput].editItemAt(i);
if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
diff --git a/media/libstagefright/DataURISource.cpp b/media/libstagefright/DataURISource.cpp
index 2c39314..2a61c3a 100644
--- a/media/libstagefright/DataURISource.cpp
+++ b/media/libstagefright/DataURISource.cpp
@@ -42,7 +42,8 @@
AString encoded(commaPos + 1);
// Strip CR and LF...
- for (size_t i = encoded.size(); i-- > 0;) {
+ for (size_t i = encoded.size(); i > 0;) {
+ i--;
if (encoded.c_str()[i] == '\r' || encoded.c_str()[i] == '\n') {
encoded.erase(i, 1);
}
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 96aa808..ef72bd4 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -2643,7 +2643,8 @@
status_t stickyErr = OK;
- for (size_t i = buffers->size(); i-- > 0;) {
+ for (size_t i = buffers->size(); i > 0;) {
+ i--;
BufferInfo *info = &buffers->editItemAt(i);
if (onlyThoseWeOwn && info->mStatus == OWNED_BY_COMPONENT) {
diff --git a/media/libstagefright/foundation/ANetworkSession.cpp b/media/libstagefright/foundation/ANetworkSession.cpp
index b230400..4bcb1f6 100644
--- a/media/libstagefright/foundation/ANetworkSession.cpp
+++ b/media/libstagefright/foundation/ANetworkSession.cpp
@@ -1318,7 +1318,8 @@
List<sp<Session> > sessionsToAdd;
- for (size_t i = mSessions.size(); res > 0 && i-- > 0;) {
+ for (size_t i = mSessions.size(); res > 0 && i > 0;) {
+ i--;
const sp<Session> &session = mSessions.valueAt(i);
int s = session->socket();
@@ -1409,4 +1410,3 @@
}
} // namespace android
-
diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp
index 72d832e..1f345fb 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -1628,7 +1628,8 @@
if (mSegmentFirstPTS < 0ll) {
// get the smallest first PTS from all streams present in this parser
- for (size_t i = mPacketSources.size(); i-- > 0;) {
+ for (size_t i = mPacketSources.size(); i > 0;) {
+ i--;
const LiveSession::StreamType stream = mPacketSources.keyAt(i);
if (stream == LiveSession::STREAMTYPE_SUBTITLES) {
ALOGE("MPEG2 Transport streams do not contain subtitles.");
@@ -1683,7 +1684,8 @@
}
status_t err = OK;
- for (size_t i = mPacketSources.size(); i-- > 0;) {
+ for (size_t i = mPacketSources.size(); i > 0;) {
+ i--;
sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i);
const LiveSession::StreamType stream = mPacketSources.keyAt(i);
@@ -1807,7 +1809,8 @@
}
if (err != OK) {
- for (size_t i = mPacketSources.size(); i-- > 0;) {
+ for (size_t i = mPacketSources.size(); i > 0;) {
+ i--;
sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i);
packetSource->clear();
}
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index e3c3e80..f9a9c4c 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -509,7 +509,7 @@
mLastRecoveredPTS = static_cast<int64_t>(PTS_33bit);
} else {
mLastRecoveredPTS = static_cast<int64_t>(
- ((mLastRecoveredPTS - PTS_33bit + 0x100000000ll)
+ ((mLastRecoveredPTS - static_cast<int64_t>(PTS_33bit) + 0x100000000ll)
& 0xfffffffe00000000ull) | PTS_33bit);
// We start from 0, but recovered PTS could be slightly below 0.
// Clamp it to 0 as rest of the pipeline doesn't take negative pts.
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 9f1c5d8..85668f7 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -1589,7 +1589,8 @@
void OMXNodeInstance::freeActiveBuffers() {
// Make sure to count down here, as freeBuffer will in turn remove
// the active buffer from the vector...
- for (size_t i = mActiveBuffers.size(); i--;) {
+ for (size_t i = mActiveBuffers.size(); i > 0;) {
+ i--;
freeBuffer(mActiveBuffers[i].mPortIndex, mActiveBuffers[i].mID);
}
}
diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp
index 3eafd6f..887f0ec 100644
--- a/media/mtp/MtpDevice.cpp
+++ b/media/mtp/MtpDevice.cpp
@@ -698,6 +698,14 @@
fchmod(fd, perm);
umask(mask);
+ bool result = readObject(handle, fd);
+ ::close(fd);
+ return result;
+}
+
+bool MtpDevice::readObject(MtpObjectHandle handle, int fd) {
+ ALOGD("readObject: %d", fd);
+
Mutex::Autolock autoLock(mMutex);
bool result = false;
@@ -779,7 +787,6 @@
}
fail:
- ::close(fd);
return result;
}
diff --git a/media/mtp/MtpDevice.h b/media/mtp/MtpDevice.h
index 9b0acbf..ef29f1b 100644
--- a/media/mtp/MtpDevice.h
+++ b/media/mtp/MtpDevice.h
@@ -101,6 +101,7 @@
size_t objectSize, void* clientData);
bool readObject(MtpObjectHandle handle, const char* destPath, int group,
int perm);
+ bool readObject(MtpObjectHandle handle, int fd);
private:
bool sendRequest(MtpOperationCode operation);
diff --git a/media/ndk/NdkMediaExtractor.cpp b/media/ndk/NdkMediaExtractor.cpp
index 0ecd64f..b869c54 100644
--- a/media/ndk/NdkMediaExtractor.cpp
+++ b/media/ndk/NdkMediaExtractor.cpp
@@ -243,15 +243,27 @@
while (len > 0) {
numentries++;
+ if (len < 16) {
+ ALOGE("invalid PSSH data");
+ return NULL;
+ }
// skip uuid
data += 16;
len -= 16;
// get data length
+ if (len < 4) {
+ ALOGE("invalid PSSH data");
+ return NULL;
+ }
uint32_t datalen = *((uint32_t*)data);
data += 4;
len -= 4;
+ if (len < datalen) {
+ ALOGE("invalid PSSH data");
+ return NULL;
+ }
// skip the data
data += datalen;
len -= datalen;
@@ -265,6 +277,10 @@
// extra pointer for each entry, and an extra size_t for the entire PsshInfo.
size_t newsize = buffer->size() - (sizeof(uint32_t) * numentries) + sizeof(size_t)
+ ((sizeof(void*) + sizeof(size_t)) * numentries);
+ if (newsize <= buffer->size()) {
+ ALOGE("invalid PSSH data");
+ return NULL;
+ }
ex->mPsshBuf = new ABuffer(newsize);
ex->mPsshBuf->setRange(0, newsize);