Merge "Fix warning: Potential leak of memory pointed to by 'device'"
diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp
index 91f9fc7..6ed9a43 100644
--- a/media/libeffects/visualizer/EffectVisualizer.cpp
+++ b/media/libeffects/visualizer/EffectVisualizer.cpp
@@ -604,7 +604,7 @@
*replySize < (sizeof(int32_t) * MEASUREMENT_COUNT)) {
ALOGV("VISUALIZER_CMD_MEASURE() error *replySize %" PRIu32
" < (sizeof(int32_t) * MEASUREMENT_COUNT) %" PRIu32, *replySize,
- sizeof(int32_t) * MEASUREMENT_COUNT);
+ uint32_t(sizeof(int32_t)) * MEASUREMENT_COUNT);
android_errorWriteLog(0x534e4554, "30229821");
return -EINVAL;
}
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index cdb0a7b..a748b46 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -884,7 +884,10 @@
case OUTPUT_FORMAT_RTP_AVP:
case OUTPUT_FORMAT_MPEG2TS:
{
- status = mWriter->start();
+ sp<MetaData> meta = new MetaData;
+ int64_t startTimeUs = systemTime() / 1000;
+ meta->setInt64(kKeyTime, startTimeUs);
+ status = mWriter->start(meta.get());
break;
}
diff --git a/media/libstagefright/MPEG2TSWriter.cpp b/media/libstagefright/MPEG2TSWriter.cpp
index 931b280..b83b0a0 100644
--- a/media/libstagefright/MPEG2TSWriter.cpp
+++ b/media/libstagefright/MPEG2TSWriter.cpp
@@ -37,7 +37,7 @@
struct MPEG2TSWriter::SourceInfo : public AHandler {
explicit SourceInfo(const sp<IMediaSource> &source);
- void start(const sp<AMessage> ¬ify);
+ void start(const sp<AMessage> ¬ify, const sp<MetaData> ¶ms);
void stop();
unsigned streamType() const;
@@ -75,7 +75,7 @@
sp<ABuffer> mAACCodecSpecificData;
- sp<ABuffer> mAACBuffer;
+ sp<ABuffer> mBuffer;
sp<ABuffer> mLastAccessUnit;
bool mEOSReceived;
@@ -85,10 +85,8 @@
void extractCodecSpecificData();
- bool appendAACFrames(MediaBuffer *buffer);
- bool flushAACFrames();
-
- void postAVCFrame(MediaBuffer *buffer);
+ void appendAACFrames(MediaBuffer *buffer);
+ void appendAVCFrame(MediaBuffer *buffer);
DISALLOW_EVIL_CONSTRUCTORS(SourceInfo);
};
@@ -129,13 +127,14 @@
return mContinuityCounter;
}
-void MPEG2TSWriter::SourceInfo::start(const sp<AMessage> ¬ify) {
+void MPEG2TSWriter::SourceInfo::start(const sp<AMessage> ¬ify, const sp<MetaData> ¶ms) {
mLooper->registerHandler(this);
mLooper->start();
-
mNotify = notify;
- (new AMessage(kWhatStart, this))->post();
+ sp<AMessage> msg = new AMessage(kWhatStart, this);
+ msg->setObject("meta", params);
+ msg->post();
}
void MPEG2TSWriter::SourceInfo::stop() {
@@ -250,56 +249,51 @@
notify->post();
}
-void MPEG2TSWriter::SourceInfo::postAVCFrame(MediaBuffer *buffer) {
+void MPEG2TSWriter::SourceInfo::appendAVCFrame(MediaBuffer *buffer) {
sp<AMessage> notify = mNotify->dup();
notify->setInt32("what", kNotifyBuffer);
- sp<ABuffer> copy =
- new ABuffer(buffer->range_length());
- memcpy(copy->data(),
+ if (mBuffer == NULL || buffer->range_length() > mBuffer->capacity()) {
+ mBuffer = new ABuffer(buffer->range_length());
+ }
+ mBuffer->setRange(0, 0);
+
+ memcpy(mBuffer->data(),
(const uint8_t *)buffer->data()
+ buffer->range_offset(),
buffer->range_length());
int64_t timeUs;
CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
- copy->meta()->setInt64("timeUs", timeUs);
+ mBuffer->meta()->setInt64("timeUs", timeUs);
int32_t isSync;
if (buffer->meta_data()->findInt32(kKeyIsSyncFrame, &isSync)
&& isSync != 0) {
- copy->meta()->setInt32("isSync", true);
+ mBuffer->meta()->setInt32("isSync", true);
}
- notify->setBuffer("buffer", copy);
+ mBuffer->setRange(0, buffer->range_length());
+
+ notify->setBuffer("buffer", mBuffer);
notify->post();
}
-bool MPEG2TSWriter::SourceInfo::appendAACFrames(MediaBuffer *buffer) {
- bool accessUnitPosted = false;
+void MPEG2TSWriter::SourceInfo::appendAACFrames(MediaBuffer *buffer) {
+ sp<AMessage> notify = mNotify->dup();
+ notify->setInt32("what", kNotifyBuffer);
- if (mAACBuffer != NULL
- && mAACBuffer->size() + 7 + buffer->range_length()
- > mAACBuffer->capacity()) {
- accessUnitPosted = flushAACFrames();
+ if (mBuffer == NULL || 7 + buffer->range_length() > mBuffer->capacity()) {
+ mBuffer = new ABuffer(7 + buffer->range_length());
}
- if (mAACBuffer == NULL) {
- size_t alloc = 4096;
- if (buffer->range_length() + 7 > alloc) {
- alloc = 7 + buffer->range_length();
- }
+ int64_t timeUs;
+ CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
- mAACBuffer = new ABuffer(alloc);
+ mBuffer->meta()->setInt64("timeUs", timeUs);
+ mBuffer->meta()->setInt32("isSync", true);
- int64_t timeUs;
- CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
-
- mAACBuffer->meta()->setInt64("timeUs", timeUs);
- mAACBuffer->meta()->setInt32("isSync", true);
-
- mAACBuffer->setRange(0, 0);
- }
+ mBuffer->setRange(0, 0);
const uint8_t *codec_specific_data = mAACCodecSpecificData->data();
@@ -312,7 +306,7 @@
unsigned channel_configuration =
(codec_specific_data[1] >> 3) & 0x0f;
- uint8_t *ptr = mAACBuffer->data() + mAACBuffer->size();
+ uint8_t *ptr = mBuffer->data() + mBuffer->size();
const uint32_t aac_frame_length = buffer->range_length() + 7;
@@ -340,24 +334,10 @@
ptr += buffer->range_length();
- mAACBuffer->setRange(0, ptr - mAACBuffer->data());
+ mBuffer->setRange(0, ptr - mBuffer->data());
- return accessUnitPosted;
-}
-
-bool MPEG2TSWriter::SourceInfo::flushAACFrames() {
- if (mAACBuffer == NULL) {
- return false;
- }
-
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kNotifyBuffer);
- notify->setBuffer("buffer", mAACBuffer);
+ notify->setBuffer("buffer", mBuffer);
notify->post();
-
- mAACBuffer.clear();
-
- return true;
}
void MPEG2TSWriter::SourceInfo::readMore() {
@@ -368,7 +348,10 @@
switch (msg->what()) {
case kWhatStart:
{
- status_t err = mSource->start();
+ sp<RefBase> obj;
+ CHECK(msg->findObject("meta", &obj));
+ MetaData *params = static_cast<MetaData *>(obj.get());
+ status_t err = mSource->start(params);
if (err != OK) {
sp<AMessage> notify = mNotify->dup();
notify->setInt32("what", kNotifyStartFailed);
@@ -376,6 +359,7 @@
break;
}
+ // Extract CSD from config format.
extractCodecSpecificData();
readMore();
@@ -388,10 +372,6 @@
status_t err = mSource->read(&buffer);
if (err != OK && err != INFO_FORMAT_CHANGED) {
- if (mStreamType == 0x0f) {
- flushAACFrames();
- }
-
sp<AMessage> notify = mNotify->dup();
notify->setInt32("what", kNotifyReachedEOS);
notify->setInt32("status", err);
@@ -401,23 +381,20 @@
if (err == OK) {
if (mStreamType == 0x0f && mAACCodecSpecificData == NULL) {
- // The first buffer contains codec specific data.
-
+ // The first audio buffer must contain CSD if not received yet.
CHECK_GE(buffer->range_length(), 2u);
-
mAACCodecSpecificData = new ABuffer(buffer->range_length());
memcpy(mAACCodecSpecificData->data(),
(const uint8_t *)buffer->data()
+ buffer->range_offset(),
buffer->range_length());
+ readMore();
} else if (buffer->range_length() > 0) {
if (mStreamType == 0x0f) {
- if (!appendAACFrames(buffer)) {
- msg->post();
- }
+ appendAACFrames(buffer);
} else {
- postAVCFrame(buffer);
+ appendAVCFrame(buffer);
}
} else {
readMore();
@@ -452,7 +429,6 @@
int64_t timeUs;
CHECK(mLastAccessUnit->meta()->findInt64("timeUs", &timeUs));
-
return timeUs;
}
@@ -542,7 +518,7 @@
return OK;
}
-status_t MPEG2TSWriter::start(MetaData * /* param */) {
+status_t MPEG2TSWriter::start(MetaData *param ) {
CHECK(!mStarted);
mStarted = true;
@@ -556,7 +532,7 @@
notify->setInt32("source-index", i);
- mSources.editItemAt(i)->start(notify);
+ mSources.editItemAt(i)->start(notify, param);
}
return OK;
@@ -594,13 +570,13 @@
{
int32_t sourceIndex;
CHECK(msg->findInt32("source-index", &sourceIndex));
+ sp<SourceInfo> source = mSources.editItemAt(sourceIndex);
int32_t what;
CHECK(msg->findInt32("what", &what));
if (what == SourceInfo::kNotifyReachedEOS
|| what == SourceInfo::kNotifyStartFailed) {
- sp<SourceInfo> source = mSources.editItemAt(sourceIndex);
source->setEOSReceived();
sp<ABuffer> buffer = source->lastAccessUnit();
@@ -615,6 +591,7 @@
} else if (what == SourceInfo::kNotifyBuffer) {
sp<ABuffer> buffer;
CHECK(msg->findBuffer("buffer", &buffer));
+ CHECK(source->lastAccessUnit() == NULL);
int32_t oob;
if (msg->findInt32("oob", &oob) && oob) {
@@ -635,15 +612,10 @@
// Rinse, repeat.
// If we don't have data on any track we don't write
// anything just yet.
-
- sp<SourceInfo> source = mSources.editItemAt(sourceIndex);
-
- CHECK(source->lastAccessUnit() == NULL);
source->setLastAccessUnit(buffer);
ALOGV("lastAccessUnitTimeUs[%d] = %.2f secs",
- sourceIndex, source->lastAccessUnitTimeUs() / 1E6);
-
+ sourceIndex, source->lastAccessUnitTimeUs() / 1E6);
int64_t minTimeUs = -1;
size_t minIndex = 0;
@@ -665,15 +637,14 @@
}
if (minTimeUs < 0) {
- ALOGV("not a all tracks have valid data.");
+ ALOGV("not all tracks have valid data.");
break;
}
ALOGV("writing access unit at time %.2f secs (index %zu)",
- minTimeUs / 1E6, minIndex);
+ minTimeUs / 1E6, minIndex);
source = mSources.editItemAt(minIndex);
-
buffer = source->lastAccessUnit();
source->setLastAccessUnit(NULL);
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
index 030c505..137a924 100644
--- a/media/libstagefright/MediaCodecSource.cpp
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -906,6 +906,7 @@
}
mbuf->meta_data()->setInt64(kKeyTime, timeUs);
} else {
+ mbuf->meta_data()->setInt64(kKeyTime, 0ll);
mbuf->meta_data()->setInt32(kKeyIsCodecConfig, true);
}
if (flags & MediaCodec::BUFFER_FLAG_SYNCFRAME) {
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index b863d67..844479e 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -701,6 +701,10 @@
}
mPayloadStarted = true;
+ // There should be at most 2 elements in |mPesStartOffsets|.
+ while (mPesStartOffsets.size() >= 2) {
+ mPesStartOffsets.erase(mPesStartOffsets.begin());
+ }
mPesStartOffsets.push_back(offset);
}
@@ -1104,15 +1108,20 @@
mSource->queueAccessUnit(accessUnit);
}
- if ((event != NULL) && !found && mQueue->getFormat() != NULL) {
+ // Every access unit has a pesStartOffset queued in |mPesStartOffsets|.
+ off64_t pesStartOffset = -1;
+ if (!mPesStartOffsets.empty()) {
+ pesStartOffset = *mPesStartOffsets.begin();
+ mPesStartOffsets.erase(mPesStartOffsets.begin());
+ }
+
+ if (pesStartOffset >= 0 && (event != NULL) && !found && mQueue->getFormat() != NULL) {
int32_t sync = 0;
if (accessUnit->meta()->findInt32("isSync", &sync) && sync) {
int64_t timeUs;
if (accessUnit->meta()->findInt64("timeUs", &timeUs)) {
found = true;
- off64_t pesStartOffset = *mPesStartOffsets.begin();
event->init(pesStartOffset, mSource, timeUs);
- mPesStartOffsets.erase(mPesStartOffsets.begin());
}
}
}
diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp
index bd89a51..7301193 100644
--- a/media/mtp/MtpDevice.cpp
+++ b/media/mtp/MtpDevice.cpp
@@ -220,7 +220,9 @@
mTransactionID(0),
mReceivedResponse(false),
mProcessingEvent(false),
- mCurrentEventHandle(0)
+ mCurrentEventHandle(0),
+ mLastSendObjectInfoTransactionID(0),
+ mLastSendObjectInfoObjectHandle(0)
{
mRequestIn1 = usb_request_new(device, ep_in);
mRequestIn2 = usb_request_new(device, ep_in);
@@ -490,6 +492,8 @@
if (sendRequest(MTP_OPERATION_SEND_OBJECT_INFO) && sendData()) {
MtpResponseCode ret = readResponse();
if (ret == MTP_RESPONSE_OK) {
+ mLastSendObjectInfoTransactionID = mRequest.getTransactionID();
+ mLastSendObjectInfoObjectHandle = mResponse.getParameter(3);
info->mStorageID = mResponse.getParameter(1);
info->mParent = mResponse.getParameter(2);
info->mHandle = mResponse.getParameter(3);
@@ -502,9 +506,14 @@
bool MtpDevice::sendObject(MtpObjectHandle handle, int size, int srcFD) {
Mutex::Autolock autoLock(mMutex);
+ if (mLastSendObjectInfoTransactionID + 1 != mTransactionID ||
+ mLastSendObjectInfoObjectHandle != handle) {
+ ALOGE("A sendObject request must follow the sendObjectInfo request.");
+ return false;
+ }
+
int remaining = size;
mRequest.reset();
- mRequest.setParameter(1, handle);
bool error = false;
if (sendRequest(MTP_OPERATION_SEND_OBJECT)) {
// send data header
diff --git a/media/mtp/MtpDevice.h b/media/mtp/MtpDevice.h
index c034c13..88f245f 100644
--- a/media/mtp/MtpDevice.h
+++ b/media/mtp/MtpDevice.h
@@ -62,6 +62,10 @@
bool mProcessingEvent;
int mCurrentEventHandle;
+ // to check if a sendObject request follows the last sendObjectInfo request.
+ MtpTransactionID mLastSendObjectInfoTransactionID;
+ MtpObjectHandle mLastSendObjectInfoObjectHandle;
+
// to ensure only one MTP transaction at a time
Mutex mMutex;
Mutex mEventMutex;