Merge "Fix a memory leak in the Forward Lock plugin. For bug 4770217."
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index c37b4f8..458f1b6 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -37,7 +37,7 @@
using namespace android;
-static void writeDecrptHandleToParcelData(
+static void writeDecryptHandleToParcelData(
const DecryptHandle* handle, Parcel* data) {
data->writeInt32(handle->decryptId);
data->writeString8(handle->mimeType);
@@ -46,14 +46,14 @@
int size = handle->copyControlVector.size();
data->writeInt32(size);
- for(int i = 0; i < size; i++) {
+ for (int i = 0; i < size; i++) {
data->writeInt32(handle->copyControlVector.keyAt(i));
data->writeInt32(handle->copyControlVector.valueAt(i));
}
size = handle->extendedData.size();
data->writeInt32(size);
- for(int i = 0; i < size; i++) {
+ for (int i = 0; i < size; i++) {
data->writeString8(handle->extendedData.keyAt(i));
data->writeString8(handle->extendedData.valueAt(i));
}
@@ -77,14 +77,14 @@
handle->status = data.readInt32();
int size = data.readInt32();
- for (int i = 0; i < size; i ++) {
+ for (int i = 0; i < size; i++) {
DrmCopyControl key = (DrmCopyControl)data.readInt32();
int value = data.readInt32();
handle->copyControlVector.add(key, value);
}
size = data.readInt32();
- for (int i = 0; i < size; i ++) {
+ for (int i = 0; i < size; i++) {
String8 key = data.readString8();
String8 value = data.readString8();
handle->extendedData.add(key, value);
@@ -416,7 +416,7 @@
data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
data.writeInt32(uniqueId);
- writeDecrptHandleToParcelData(decryptHandle, &data);
+ writeDecryptHandleToParcelData(decryptHandle, &data);
data.writeInt32(action);
data.writeInt32(static_cast< int>(reserve));
@@ -433,7 +433,7 @@
data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
data.writeInt32(uniqueId);
- writeDecrptHandleToParcelData(decryptHandle, &data);
+ writeDecryptHandleToParcelData(decryptHandle, &data);
data.writeInt32(playbackStatus);
data.writeInt64(position);
@@ -646,7 +646,7 @@
data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
data.writeInt32(uniqueId);
- writeDecrptHandleToParcelData(decryptHandle, &data);
+ writeDecryptHandleToParcelData(decryptHandle, &data);
remote()->transact(CLOSE_DECRYPT_SESSION, data, &reply);
@@ -662,7 +662,7 @@
data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
data.writeInt32(uniqueId);
- writeDecrptHandleToParcelData(decryptHandle, &data);
+ writeDecryptHandleToParcelData(decryptHandle, &data);
data.writeInt32(decryptUnitId);
@@ -682,7 +682,7 @@
data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
data.writeInt32(uniqueId);
- writeDecrptHandleToParcelData(decryptHandle, &data);
+ writeDecryptHandleToParcelData(decryptHandle, &data);
data.writeInt32(decryptUnitId);
data.writeInt32((*decBuffer)->length);
@@ -715,7 +715,7 @@
data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
data.writeInt32(uniqueId);
- writeDecrptHandleToParcelData(decryptHandle, &data);
+ writeDecryptHandleToParcelData(decryptHandle, &data);
data.writeInt32(decryptUnitId);
@@ -733,7 +733,7 @@
data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
data.writeInt32(uniqueId);
- writeDecrptHandleToParcelData(decryptHandle, &data);
+ writeDecryptHandleToParcelData(decryptHandle, &data);
data.writeInt32(numBytes);
data.writeInt64(offset);
@@ -1244,7 +1244,7 @@
= openDecryptSession(uniqueId, fd, data.readInt64(), data.readInt64());
if (NULL != handle) {
- writeDecrptHandleToParcelData(handle, reply);
+ writeDecryptHandleToParcelData(handle, reply);
clearDecryptHandle(handle);
delete handle; handle = NULL;
}
@@ -1262,7 +1262,7 @@
DecryptHandle* handle = openDecryptSession(uniqueId, uri.string());
if (NULL != handle) {
- writeDecrptHandleToParcelData(handle, reply);
+ writeDecryptHandleToParcelData(handle, reply);
clearDecryptHandle(handle);
delete handle; handle = NULL;
diff --git a/drm/libdrmframework/include/PlugInManager.h b/drm/libdrmframework/include/PlugInManager.h
index 8029138..7bb143f 100644
--- a/drm/libdrmframework/include/PlugInManager.h
+++ b/drm/libdrmframework/include/PlugInManager.h
@@ -202,7 +202,7 @@
Vector<String8> getPlugInPathList(const String8& rsDirPath) {
Vector<String8> fileList;
DIR* pDir = opendir(rsDirPath.string());
- struct dirent* pEntry = new dirent();
+ struct dirent* pEntry;
while (NULL != pDir && NULL != (pEntry = readdir(pDir))) {
if (!isPlugIn(pEntry)) {
@@ -219,8 +219,6 @@
if (NULL != pDir) {
closedir(pDir);
}
- delete pEntry;
- pEntry = NULL;
return fileList;
}
diff --git a/media/libeffects/factory/EffectsFactory.c b/media/libeffects/factory/EffectsFactory.c
index b0e8585..a3e76d9 100644
--- a/media/libeffects/factory/EffectsFactory.c
+++ b/media/libeffects/factory/EffectsFactory.c
@@ -257,7 +257,7 @@
}
// create effect in library
- l->desc->create_effect(uuid, sessionId, ioId, &itfe);
+ ret = l->desc->create_effect(uuid, sessionId, ioId, &itfe);
if (ret != 0) {
LOGW("EffectCreate() library %s: could not create fx %s, error %d", l->name, d->name, ret);
goto exit;
diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp
index 9f1b3d6..7c2200e 100644
--- a/media/libmedia/ToneGenerator.cpp
+++ b/media/libmedia/ToneGenerator.cpp
@@ -21,7 +21,6 @@
#include <stdio.h>
#include <math.h>
#include <utils/Log.h>
-#include <sys/resource.h>
#include <utils/RefBase.h>
#include <utils/Timers.h>
#include <cutils/properties.h>
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
index 06fb103..d574ea3 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
@@ -21,7 +21,6 @@
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/resource.h>
#include <dirent.h>
#include <unistd.h>
diff --git a/media/libstagefright/AACWriter.cpp b/media/libstagefright/AACWriter.cpp
index 8413208..d133e91 100644
--- a/media/libstagefright/AACWriter.cpp
+++ b/media/libstagefright/AACWriter.cpp
@@ -27,7 +27,6 @@
#include <media/stagefright/MetaData.h>
#include <media/mediarecorder.h>
#include <sys/prctl.h>
-#include <sys/resource.h>
#include <fcntl.h>
namespace android {
diff --git a/media/libstagefright/AMRWriter.cpp b/media/libstagefright/AMRWriter.cpp
index b10d52c..6436071 100644
--- a/media/libstagefright/AMRWriter.cpp
+++ b/media/libstagefright/AMRWriter.cpp
@@ -23,7 +23,6 @@
#include <media/stagefright/MetaData.h>
#include <media/mediarecorder.h>
#include <sys/prctl.h>
-#include <sys/resource.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 28add18..58f6699 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -22,7 +22,6 @@
#include <pthread.h>
#include <sys/prctl.h>
-#include <sys/resource.h>
#include <media/stagefright/MPEG4Writer.h>
#include <media/stagefright/MediaBuffer.h>
@@ -1975,7 +1974,17 @@
int64_t previousPausedDurationUs = 0;
int64_t timestampUs = 0;
int64_t cttsDeltaTimeUs = 0;
+ bool hasBFrames = false;
+#if 1
+ // XXX: Samsung's video encoder's output buffer timestamp
+ // is not correct. see bug 4724339
+ char value[PROPERTY_VALUE_MAX];
+ if (property_get("rw.media.record.hasb", value, NULL) &&
+ (!strcasecmp(value, "true") || !strcasecmp(value, "1"))) {
+ hasBFrames = true;
+ }
+#endif
if (mIsAudio) {
prctl(PR_SET_NAME, (unsigned long)"AudioTrackEncoding", 0, 0, 0);
} else {
@@ -2118,7 +2127,7 @@
timestampUs -= previousPausedDurationUs;
CHECK(timestampUs >= 0);
- if (!mIsAudio) {
+ if (!mIsAudio && hasBFrames) {
/*
* Composition time: timestampUs
* Decoding time: decodingTimeUs
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index c4fcc79..bb8a8be 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1983,7 +1983,14 @@
int64_t OMXCodec::retrieveDecodingTimeUs(bool isCodecSpecific) {
CHECK(mIsEncoder);
- CHECK(!mDecodingTimeList.empty());
+
+ if (mDecodingTimeList.empty()) {
+ CHECK(mNoMoreOutputData);
+ // No corresponding input frame available.
+ // This could happen when EOS is reached.
+ return 0;
+ }
+
List<int64_t>::iterator it = mDecodingTimeList.begin();
int64_t timeUs = *it;
@@ -2152,11 +2159,6 @@
buffer->meta_data()->setInt32(kKeyIsUnreadable, true);
}
- if (mIsEncoder) {
- int64_t decodingTimeUs = retrieveDecodingTimeUs(isCodecSpecific);
- buffer->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs);
- }
-
buffer->meta_data()->setPointer(
kKeyPlatformPrivate,
msg.u.extended_buffer_data.platform_private);
@@ -2170,6 +2172,11 @@
mNoMoreOutputData = true;
}
+ if (mIsEncoder) {
+ int64_t decodingTimeUs = retrieveDecodingTimeUs(isCodecSpecific);
+ buffer->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs);
+ }
+
if (mTargetTimeUs >= 0) {
CHECK(msg.u.extended_buffer_data.timestamp <= mTargetTimeUs);
diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp
index 1560b8e..29e6907 100644
--- a/media/libstagefright/OggExtractor.cpp
+++ b/media/libstagefright/OggExtractor.cpp
@@ -730,8 +730,9 @@
off64_t size;
if (mSource->getSize(&size) == OK) {
uint64_t bps = approxBitrate();
-
- mMeta->setInt64(kKeyDuration, size * 8000000ll / bps);
+ if (bps != 0) {
+ mMeta->setInt64(kKeyDuration, size * 8000000ll / bps);
+ }
}
break;
}
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index eb135ab..a8a094e 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -416,12 +416,16 @@
uint32_t delta = mTimeToSample[2 * i + 1];
for (uint32_t j = 0; j < n; ++j) {
- CHECK(sampleIndex < mNumSampleSizes);
+ if (sampleIndex < mNumSampleSizes) {
+ // Technically this should always be the case if the file
+ // is well-formed, but you know... there's (gasp) malformed
+ // content out there.
- mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex;
+ mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex;
- mSampleTimeEntries[sampleIndex].mCompositionTime =
- sampleTime + getCompositionTimeOffset(sampleIndex);
+ mSampleTimeEntries[sampleIndex].mCompositionTime =
+ sampleTime + getCompositionTimeOffset(sampleIndex);
+ }
++sampleIndex;
sampleTime += delta;
diff --git a/media/libstagefright/TimedEventQueue.cpp b/media/libstagefright/TimedEventQueue.cpp
index a08eb7b..100d8a3 100644
--- a/media/libstagefright/TimedEventQueue.cpp
+++ b/media/libstagefright/TimedEventQueue.cpp
@@ -30,7 +30,6 @@
#include <sys/prctl.h>
#include <sys/time.h>
-#include <sys/resource.h>
#include <media/stagefright/MediaDebug.h>
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC.cpp b/media/libstagefright/codecs/aacdec/SoftAAC.cpp
index 7ce6128..bbd6dbb 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC.cpp
@@ -367,7 +367,15 @@
inHeader->nFilledLen -= mConfig->inputBufferUsedLength;
inHeader->nOffset += mConfig->inputBufferUsedLength;
} else {
+ LOGW("AAC decoder returned error %d, substituting silence",
+ decoderErr);
+
memset(outHeader->pBuffer + outHeader->nOffset, 0, numOutBytes);
+
+ // Discard input buffer.
+ inHeader->nFilledLen = 0;
+
+ // fall through
}
if (mUpsamplingFactor == 2) {
diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
index e9ce719..7e83163 100644
--- a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
+++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
@@ -117,11 +117,27 @@
addPort(def);
}
+static int GetCPUCoreCount() {
+ int cpuCoreCount = 1;
+#if defined(_SC_NPROCESSORS_ONLN)
+ cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
+#else
+ // _SC_NPROC_ONLN must be defined...
+ cpuCoreCount = sysconf(_SC_NPROC_ONLN);
+#endif
+ CHECK(cpuCoreCount >= 1);
+ LOGV("Number of CPU cores: %d", cpuCoreCount);
+ return cpuCoreCount;
+}
+
status_t SoftVPX::initDecoder() {
mCtx = new vpx_codec_ctx_t;
vpx_codec_err_t vpx_err;
+ vpx_codec_dec_cfg_t cfg;
+ memset(&cfg, 0, sizeof(vpx_codec_dec_cfg_t));
+ cfg.threads = GetCPUCoreCount();
if ((vpx_err = vpx_codec_dec_init(
- (vpx_codec_ctx_t *)mCtx, &vpx_codec_vp8_dx_algo, NULL, 0))) {
+ (vpx_codec_ctx_t *)mCtx, &vpx_codec_vp8_dx_algo, &cfg, 0))) {
LOGE("on2 decoder failed to initialize. (%d)", vpx_err);
return UNKNOWN_ERROR;
}
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 012d9ad..165683e 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -296,6 +296,8 @@
new M3UParser(url, buffer->data(), buffer->size());
if (playlist->initCheck() != OK) {
+ LOGE("failed to parse .m3u8 playlist");
+
return NULL;
}
diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp
index 2eb180a..765f795 100644
--- a/media/libstagefright/httplive/M3UParser.cpp
+++ b/media/libstagefright/httplive/M3UParser.cpp
@@ -179,7 +179,7 @@
if (mIsVariantPlaylist) {
return ERROR_MALFORMED;
}
- err = parseMetaData(line, &itemMeta, "duration");
+ err = parseMetaDataDuration(line, &itemMeta, "durationUs");
} else if (line.startsWith("#EXT-X-DISCONTINUITY")) {
if (mIsVariantPlaylist) {
return ERROR_MALFORMED;
@@ -203,9 +203,9 @@
if (!line.startsWith("#")) {
if (!mIsVariantPlaylist) {
- int32_t durationSecs;
+ int64_t durationUs;
if (itemMeta == NULL
- || !itemMeta->findInt32("duration", &durationSecs)) {
+ || !itemMeta->findInt64("durationUs", &durationUs)) {
return ERROR_MALFORMED;
}
}
@@ -252,6 +252,30 @@
}
// static
+status_t M3UParser::parseMetaDataDuration(
+ const AString &line, sp<AMessage> *meta, const char *key) {
+ ssize_t colonPos = line.find(":");
+
+ if (colonPos < 0) {
+ return ERROR_MALFORMED;
+ }
+
+ double x;
+ status_t err = ParseDouble(line.c_str() + colonPos + 1, &x);
+
+ if (err != OK) {
+ return err;
+ }
+
+ if (meta->get() == NULL) {
+ *meta = new AMessage;
+ }
+ (*meta)->setInt64(key, (int64_t)x * 1E6);
+
+ return OK;
+}
+
+// static
status_t M3UParser::parseStreamInf(
const AString &line, sp<AMessage> *meta) {
ssize_t colonPos = line.find(":");
@@ -412,4 +436,18 @@
return OK;
}
+// static
+status_t M3UParser::ParseDouble(const char *s, double *x) {
+ char *end;
+ double dval = strtod(s, &end);
+
+ if (end == s || (*end != '\0' && *end != ',')) {
+ return ERROR_MALFORMED;
+ }
+
+ *x = dval;
+
+ return OK;
+}
+
} // namespace android
diff --git a/media/libstagefright/include/M3UParser.h b/media/libstagefright/include/M3UParser.h
index 63895b4..478582d 100644
--- a/media/libstagefright/include/M3UParser.h
+++ b/media/libstagefright/include/M3UParser.h
@@ -63,6 +63,9 @@
static status_t parseMetaData(
const AString &line, sp<AMessage> *meta, const char *key);
+ static status_t parseMetaDataDuration(
+ const AString &line, sp<AMessage> *meta, const char *key);
+
static status_t parseStreamInf(
const AString &line, sp<AMessage> *meta);
@@ -70,6 +73,7 @@
const AString &line, sp<AMessage> *meta, const AString &baseURI);
static status_t ParseInt32(const char *s, int32_t *x);
+ static status_t ParseDouble(const char *s, double *x);
DISALLOW_EVIL_CONSTRUCTORS(M3UParser);
};
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 14968e8..d23aa3a 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -21,7 +21,6 @@
#include <dlfcn.h>
#include <sys/prctl.h>
-#include <sys/resource.h>
#include "../include/OMX.h"
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 4a8fd3e..bc04e8c 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -95,10 +95,11 @@
MTP_EVENT_STORE_REMOVED,
};
-MtpServer::MtpServer(int fd, MtpDatabase* database,
+MtpServer::MtpServer(int fd, MtpDatabase* database, bool ptp,
int fileGroup, int filePerm, int directoryPerm)
: mFD(fd),
mDatabase(database),
+ mPtp(ptp),
mFileGroup(fileGroup),
mFilePermission(filePerm),
mDirectoryPermission(directoryPerm),
@@ -426,9 +427,20 @@
// fill in device info
mData.putUInt16(MTP_STANDARD_VERSION);
- mData.putUInt32(6); // MTP Vendor Extension ID
+ if (mPtp) {
+ mData.putUInt32(0);
+ } else {
+ // MTP Vendor Extension ID
+ mData.putUInt32(6);
+ }
mData.putUInt16(MTP_STANDARD_VERSION);
- string.set("microsoft.com: 1.0; android.com: 1.0;");
+ if (mPtp) {
+ // no extensions
+ string.set("");
+ } else {
+ // MTP extensions
+ string.set("microsoft.com: 1.0; android.com: 1.0;");
+ }
mData.putString(string); // MTP Extensions
mData.putUInt16(0); //Functional Mode
mData.putAUInt16(kSupportedOperationCodes,
@@ -533,12 +545,10 @@
MtpStorageID storageID = mRequest.getParameter(1); // 0xFFFFFFFF for all storage
MtpObjectFormat format = mRequest.getParameter(2); // 0 for all formats
MtpObjectHandle parent = mRequest.getParameter(3); // 0xFFFFFFFF for objects with no parent
- // 0x00000000 for all objects?
+ // 0x00000000 for all objects
if (!hasStorage(storageID))
return MTP_RESPONSE_INVALID_STORAGE_ID;
- if (parent == 0xFFFFFFFF)
- parent = 0;
MtpObjectHandleList* handles = mDatabase->getObjectList(storageID, format, parent);
mData.putAUInt32(handles);
@@ -552,11 +562,9 @@
MtpStorageID storageID = mRequest.getParameter(1); // 0xFFFFFFFF for all storage
MtpObjectFormat format = mRequest.getParameter(2); // 0 for all formats
MtpObjectHandle parent = mRequest.getParameter(3); // 0xFFFFFFFF for objects with no parent
- // 0x00000000 for all objects?
+ // 0x00000000 for all objects
if (!hasStorage(storageID))
return MTP_RESPONSE_INVALID_STORAGE_ID;
- if (parent == 0xFFFFFFFF)
- parent = 0;
int count = mDatabase->getNumObjects(storageID, format, parent);
if (count >= 0) {
diff --git a/media/mtp/MtpServer.h b/media/mtp/MtpServer.h
index 859a18e..dfa8258 100644
--- a/media/mtp/MtpServer.h
+++ b/media/mtp/MtpServer.h
@@ -39,6 +39,9 @@
MtpDatabase* mDatabase;
+ // appear as a PTP device
+ bool mPtp;
+
// group to own new files and folders
int mFileGroup;
// permissions for new files and directories
@@ -87,7 +90,7 @@
Vector<ObjectEdit*> mObjectEditList;
public:
- MtpServer(int fd, MtpDatabase* database,
+ MtpServer(int fd, MtpDatabase* database, bool ptp,
int fileGroup, int filePerm, int directoryPerm);
virtual ~MtpServer();
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 1e8c30b..a011ae2 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -147,6 +147,14 @@
return NULL;
}
+ char value[PROPERTY_VALUE_MAX];
+ property_get("sys.secpolicy.camera.disabled", value, "0");
+ if (strcmp(value, "1") == 0) {
+ // Camera is disabled by DevicePolicyManager.
+ LOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
+ return NULL;
+ }
+
Mutex::Autolock lock(mServiceLock);
if (mClient[cameraId] != 0) {
client = mClient[cameraId].promote();