Merge "HDCP: buffer over flow check" into mnc-dev
diff --git a/include/media/IResourceManagerClient.h b/include/media/IResourceManagerClient.h
index 3587aea..aa0cd88 100644
--- a/include/media/IResourceManagerClient.h
+++ b/include/media/IResourceManagerClient.h
@@ -18,6 +18,7 @@
#define ANDROID_IRESOURCEMANAGERCLIENT_H
#include <utils/RefBase.h>
+#include <utils/String8.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
@@ -29,6 +30,7 @@
DECLARE_META_INTERFACE(ResourceManagerClient);
virtual bool reclaimResource() = 0;
+ virtual String8 getName() = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/media/MediaResource.h b/include/media/MediaResource.h
index 0b57c84..20f2cad 100644
--- a/include/media/MediaResource.h
+++ b/include/media/MediaResource.h
@@ -25,6 +25,8 @@
extern const char kResourceSecureCodec[];
extern const char kResourceNonSecureCodec[];
+extern const char kResourceAudioCodec[];
+extern const char kResourceVideoCodec[];
extern const char kResourceGraphicMemory[];
class MediaResource {
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index a8d0fcb..c14e6c0 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -192,6 +192,7 @@
List<sp<AMessage> > mDeferredQueue;
bool mSentFormat;
+ bool mIsVideo;
bool mIsEncoder;
bool mUseMetadataOnEncoderOutput;
bool mShutdownInProgress;
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index f2b21c9..d89e4c7 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -351,7 +351,7 @@
bool isExecuting() const;
uint64_t getGraphicBufferSize();
- void addResource(const char *type, uint64_t value);
+ void addResource(const String8 &type, const String8 &subtype, uint64_t value);
/* called to get the last codec error when the sticky flag is set.
* if no such codec error is found, returns UNKNOWN_ERROR.
diff --git a/media/libmedia/IResourceManagerClient.cpp b/media/libmedia/IResourceManagerClient.cpp
index 6fa56fc..b3f56e8 100644
--- a/media/libmedia/IResourceManagerClient.cpp
+++ b/media/libmedia/IResourceManagerClient.cpp
@@ -25,6 +25,7 @@
enum {
RECLAIM_RESOURCE = IBinder::FIRST_CALL_TRANSACTION,
+ GET_NAME,
};
class BpResourceManagerClient: public BpInterface<IResourceManagerClient>
@@ -46,6 +47,19 @@
}
return ret;
}
+
+ virtual String8 getName() {
+ Parcel data, reply;
+ data.writeInterfaceToken(IResourceManagerClient::getInterfaceDescriptor());
+
+ String8 ret;
+ status_t status = remote()->transact(GET_NAME, data, &reply);
+ if (status == NO_ERROR) {
+ ret = reply.readString8();
+ }
+ return ret;
+ }
+
};
IMPLEMENT_META_INTERFACE(ResourceManagerClient, "android.media.IResourceManagerClient");
@@ -62,6 +76,12 @@
reply->writeInt32(ret);
return NO_ERROR;
} break;
+ case GET_NAME: {
+ CHECK_INTERFACE(IResourceManagerClient, data, reply);
+ String8 ret = getName();
+ reply->writeString8(ret);
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libmedia/MediaResource.cpp b/media/libmedia/MediaResource.cpp
index eea2c43..40ec0cb 100644
--- a/media/libmedia/MediaResource.cpp
+++ b/media/libmedia/MediaResource.cpp
@@ -23,6 +23,8 @@
const char kResourceSecureCodec[] = "secure-codec";
const char kResourceNonSecureCodec[] = "non-secure-codec";
+const char kResourceAudioCodec[] = "audio-codec";
+const char kResourceVideoCodec[] = "video-codec";
const char kResourceGraphicMemory[] = "graphic-memory";
MediaResource::MediaResource() : mValue(0) {}
diff --git a/media/libmediaplayerservice/Drm.cpp b/media/libmediaplayerservice/Drm.cpp
index 8ca8769..d55482d 100644
--- a/media/libmediaplayerservice/Drm.cpp
+++ b/media/libmediaplayerservice/Drm.cpp
@@ -52,6 +52,7 @@
KeyedVector<Vector<uint8_t>, String8> Drm::mUUIDToLibraryPathMap;
KeyedVector<String8, wp<SharedLibrary> > Drm::mLibraryPathToOpenLibraryMap;
Mutex Drm::mMapLock;
+Mutex Drm::mLock;
static bool operator<(const Vector<uint8_t> &lhs, const Vector<uint8_t> &rhs) {
if (lhs.size() < rhs.size()) {
diff --git a/media/libmediaplayerservice/Drm.h b/media/libmediaplayerservice/Drm.h
index c4013b8..056723c 100644
--- a/media/libmediaplayerservice/Drm.h
+++ b/media/libmediaplayerservice/Drm.h
@@ -143,7 +143,7 @@
virtual void binderDied(const wp<IBinder> &the_late_who);
private:
- mutable Mutex mLock;
+ static Mutex mLock;
status_t mInitCheck;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index a028b01..b670d68 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -634,6 +634,17 @@
if (mRenderer != NULL) {
mRenderer->setPlaybackRate(mPlaybackRate);
}
+
+ if (mVideoDecoder != NULL) {
+ sp<MetaData> meta = getFileMeta();
+ int32_t rate;
+ if (meta != NULL && meta->findInt32(kKeyFrameRate, &rate) && rate > 0) {
+ sp<AMessage> params = new AMessage();
+ params->setFloat("operating-rate", rate * mPlaybackRate);
+ mVideoDecoder->setParameters(params);
+ }
+ }
+
break;
}
@@ -1249,6 +1260,8 @@
return -EWOULDBLOCK;
}
+ format->setInt32("priority", 0 /* realtime */);
+
if (!audio) {
AString mime;
CHECK(format->findString("mime", &mime));
@@ -1265,6 +1278,12 @@
if (mSourceFlags & Source::FLAG_PROTECTED) {
format->setInt32("protected", true);
}
+
+ sp<MetaData> meta = getFileMeta();
+ int32_t rate;
+ if (meta != NULL && meta->findInt32(kKeyFrameRate, &rate) && rate > 0) {
+ format->setFloat("operating-rate", rate * mPlaybackRate);
+ }
}
if (audio) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index acc9ef5..3c4d695 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -252,6 +252,14 @@
mResumePending = false;
}
+void NuPlayer::Decoder::onSetParameters(const sp<AMessage> ¶ms) {
+ if (mCodec == NULL) {
+ ALOGW("onSetParameters called before codec is created.");
+ return;
+ }
+ mCodec->setParameters(params);
+}
+
void NuPlayer::Decoder::onSetRenderer(const sp<Renderer> &renderer) {
bool hadNoRenderer = (mRenderer == NULL);
mRenderer = renderer;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
index 9f0ef1b5..dd84620 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
@@ -40,6 +40,7 @@
virtual void onMessageReceived(const sp<AMessage> &msg);
virtual void onConfigure(const sp<AMessage> &format);
+ virtual void onSetParameters(const sp<AMessage> ¶ms);
virtual void onSetRenderer(const sp<Renderer> &renderer);
virtual void onGetInputBuffers(Vector<sp<ABuffer> > *dstBuffers);
virtual void onResume(bool notifyComplete);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp
index 36b41ec..9d509bf 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp
@@ -70,6 +70,12 @@
mDecoderLooper->registerHandler(this);
}
+void NuPlayer::DecoderBase::setParameters(const sp<AMessage> ¶ms) {
+ sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
+ msg->setMessage("params", params);
+ msg->post();
+}
+
void NuPlayer::DecoderBase::setRenderer(const sp<Renderer> &renderer) {
sp<AMessage> msg = new AMessage(kWhatSetRenderer, this);
msg->setObject("renderer", renderer);
@@ -123,6 +129,14 @@
break;
}
+ case kWhatSetParameters:
+ {
+ sp<AMessage> params;
+ CHECK(msg->findMessage("params", ¶ms));
+ onSetParameters(params);
+ break;
+ }
+
case kWhatSetRenderer:
{
sp<RefBase> obj;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h
index 262f5d5..b52e7f7 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h
@@ -33,6 +33,7 @@
void configure(const sp<AMessage> &format);
void init();
+ void setParameters(const sp<AMessage> ¶ms);
void setRenderer(const sp<Renderer> &renderer);
@@ -62,6 +63,7 @@
virtual void onMessageReceived(const sp<AMessage> &msg);
virtual void onConfigure(const sp<AMessage> &format) = 0;
+ virtual void onSetParameters(const sp<AMessage> ¶ms) = 0;
virtual void onSetRenderer(const sp<Renderer> &renderer) = 0;
virtual void onGetInputBuffers(Vector<sp<ABuffer> > *dstBuffers) = 0;
virtual void onResume(bool notifyComplete) = 0;
@@ -78,6 +80,7 @@
private:
enum {
kWhatConfigure = 'conf',
+ kWhatSetParameters = 'setP',
kWhatSetRenderer = 'setR',
kWhatGetInputBuffers = 'gInB',
kWhatRequestInputBuffers = 'reqB',
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
index fdb9039..d7b070e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
@@ -88,6 +88,10 @@
}
}
+void NuPlayer::DecoderPassThrough::onSetParameters(const sp<AMessage> &/*params*/) {
+ ALOGW("onSetParameters() called unexpectedly");
+}
+
void NuPlayer::DecoderPassThrough::onSetRenderer(
const sp<Renderer> &renderer) {
// renderer can't be changed during offloading
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h
index b7dcb8d..2f6df2c 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h
@@ -40,6 +40,7 @@
virtual void onMessageReceived(const sp<AMessage> &msg);
virtual void onConfigure(const sp<AMessage> &format);
+ virtual void onSetParameters(const sp<AMessage> ¶ms);
virtual void onSetRenderer(const sp<Renderer> &renderer);
virtual void onGetInputBuffers(Vector<sp<ABuffer> > *dstBuffers);
virtual void onResume(bool notifyComplete);
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index da22f11..c7df5a0 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -405,6 +405,7 @@
: mQuirks(0),
mNode(0),
mSentFormat(false),
+ mIsVideo(false),
mIsEncoder(false),
mUseMetadataOnEncoderOutput(false),
mShutdownInProgress(false),
@@ -1186,6 +1187,7 @@
mIsEncoder = encoder;
+
status_t err = setComponentRole(encoder /* isEncoder */, mime);
if (err != OK) {
@@ -1244,6 +1246,7 @@
// sps/pps to idr frames, since in metadata mode the bitstream is in an
// opaque handle, to which we don't have access.
int32_t video = !strncasecmp(mime, "video/", 6);
+ mIsVideo = video;
if (encoder && video) {
OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
&& msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
@@ -5684,6 +5687,15 @@
}
}
+ float rate;
+ if (params->findFloat("operating-rate", &rate) && rate > 0) {
+ status_t err = setOperatingRate(rate, mIsVideo);
+ if (err != OK) {
+ ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
+ return err;
+ }
+ }
+
return OK;
}
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 96b22c0..aa0d2e6 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -79,6 +79,21 @@
return (err == OK);
}
+ virtual String8 getName() {
+ String8 ret;
+ sp<MediaCodec> codec = mMediaCodec.promote();
+ if (codec == NULL) {
+ // codec is already gone.
+ return ret;
+ }
+
+ AString name;
+ if (codec->getName(&name) == OK) {
+ ret.setTo(name.c_str());
+ }
+ return ret;
+ }
+
protected:
virtual ~ResourceManagerClient() {}
@@ -419,7 +434,8 @@
status_t err;
Vector<MediaResource> resources;
const char *type = secureCodec ? kResourceSecureCodec : kResourceNonSecureCodec;
- resources.push_back(MediaResource(String8(type), 1));
+ const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
+ resources.push_back(MediaResource(String8(type), String8(subtype), 1));
for (int i = 0; i <= kMaxRetry; ++i) {
if (i > 0) {
// Don't try to reclaim resource for the first time.
@@ -477,7 +493,8 @@
Vector<MediaResource> resources;
const char *type = (mFlags & kFlagIsSecure) ?
kResourceSecureCodec : kResourceNonSecureCodec;
- resources.push_back(MediaResource(String8(type), 1));
+ const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
+ resources.push_back(MediaResource(String8(type), String8(subtype), 1));
// Don't know the buffer size at this point, but it's fine to use 1 because
// the reclaimResource call doesn't consider the requester's buffer size for now.
resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1));
@@ -542,9 +559,9 @@
return size;
}
-void MediaCodec::addResource(const char *type, uint64_t value) {
+void MediaCodec::addResource(const String8 &type, const String8 &subtype, uint64_t value) {
Vector<MediaResource> resources;
- resources.push_back(MediaResource(String8(type), value));
+ resources.push_back(MediaResource(type, subtype, value));
mResourceManagerService->addResource(
getCallingPid(), getId(mResourceManagerClient), mResourceManagerClient, resources);
}
@@ -556,7 +573,8 @@
Vector<MediaResource> resources;
const char *type = (mFlags & kFlagIsSecure) ?
kResourceSecureCodec : kResourceNonSecureCodec;
- resources.push_back(MediaResource(String8(type), 1));
+ const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
+ resources.push_back(MediaResource(String8(type), String8(subtype), 1));
// Don't know the buffer size at this point, but it's fine to use 1 because
// the reclaimResource call doesn't consider the requester's buffer size for now.
resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1));
@@ -1168,7 +1186,9 @@
mFlags &= ~kFlagIsSecure;
resourceType = String8(kResourceNonSecureCodec);
}
- addResource(resourceType, 1);
+
+ const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
+ addResource(resourceType, String8(subtype), 1);
(new AMessage)->postReply(mReplyID);
break;
@@ -1282,7 +1302,11 @@
// allocating input buffers, so this is a good
// indication that now all buffers are allocated.
if (mIsVideo) {
- addResource(kResourceGraphicMemory, getGraphicBufferSize());
+ String8 subtype;
+ addResource(
+ String8(kResourceGraphicMemory),
+ subtype,
+ getGraphicBufferSize());
}
setState(STARTED);
(new AMessage)->postReply(mReplyID);
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp
index 0712bf0..ddca437 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.cpp
+++ b/media/libstagefright/matroska/MatroskaExtractor.cpp
@@ -941,7 +941,10 @@
const mkvparser::VideoTrack *vtrack =
static_cast<const mkvparser::VideoTrack *>(track);
- if (!strcmp("V_MPEG4/ISO/AVC", codecID)) {
+ if (codecID == NULL) {
+ ALOGW("unknown codecID is not supported.");
+ continue;
+ } else if (!strcmp("V_MPEG4/ISO/AVC", codecID)) {
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
meta->setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize);
} else if (!strcmp("V_MPEG4/ISO/ASP", codecID)) {
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 01f2b61..ba3fcaf 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1420,6 +1420,13 @@
}
if (inputDesc->mRefCount == 0) {
+ // if input maps to a dynamic policy with an activity listener, notify of state change
+ if ((inputDesc->mPolicyMix != NULL)
+ && ((inputDesc->mPolicyMix->mFlags & MIX_FLAG_NOTIFY_ACTIVITY) != 0)) {
+ mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mRegistrationId,
+ MIX_STATE_MIXING);
+ }
+
if (mInputs.activeInputsCount() == 0) {
SoundTrigger::setCaptureState(true);
}
@@ -1473,6 +1480,12 @@
inputDesc->mRefCount--;
if (inputDesc->mRefCount == 0) {
+ // if input maps to a dynamic policy with an activity listener, notify of state change
+ if ((inputDesc->mPolicyMix != NULL)
+ && ((inputDesc->mPolicyMix->mFlags & MIX_FLAG_NOTIFY_ACTIVITY) != 0)) {
+ mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mRegistrationId,
+ MIX_STATE_IDLE);
+ }
// automatically disable the remote submix output when input is stopped if not
// used by a policy mix of type MIX_TYPE_RECORDERS
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 75a69ed..17aac4e 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -88,6 +88,51 @@
return infos.editItemAt(infos.size() - 1);
}
+status_t ResourceManagerService::dump(int fd, const Vector<String16>& args) {
+ Mutex::Autolock lock(mLock);
+
+ String8 result;
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+
+ snprintf(buffer, SIZE, "ResourceManagerService: %p\n", this);
+ result.append(buffer);
+ result.append(" Policies:\n");
+ snprintf(buffer, SIZE, " SupportsMultipleSecureCodecs: %d\n", mSupportsMultipleSecureCodecs);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " SupportsSecureWithNonSecureCodec: %d\n", mSupportsSecureWithNonSecureCodec);
+ result.append(buffer);
+
+ snprintf(buffer, SIZE, " Processes:\n");
+ result.append(buffer);
+ for (size_t i = 0; i < mMap.size(); ++i) {
+ snprintf(buffer, SIZE, " Pid: %d\n", mMap.keyAt(i));
+ result.append(buffer);
+
+ const ResourceInfos &infos = mMap.valueAt(i);
+ for (size_t j = 0; j < infos.size(); ++j) {
+ snprintf(buffer, SIZE, " Client:\n");
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Id: %lld\n", (long long)infos[j].clientId);
+ result.append(buffer);
+
+ snprintf(buffer, SIZE, " Name: %s\n", infos[j].client->getName().string());
+ result.append(buffer);
+
+ Vector<MediaResource> resources = infos[j].resources;
+ snprintf(buffer, SIZE, " Resources:\n");
+ result.append(buffer);
+ for (size_t k = 0; k < resources.size(); ++k) {
+ snprintf(buffer, SIZE, " %s\n", resources[k].toString().string());
+ result.append(buffer);
+ }
+ }
+ }
+
+ write(fd, result.string(), result.size());
+ return OK;
+}
+
ResourceManagerService::ResourceManagerService()
: mProcessInfo(new ProcessInfo()),
mSupportsMultipleSecureCodecs(true),
diff --git a/services/mediaresourcemanager/ResourceManagerService.h b/services/mediaresourcemanager/ResourceManagerService.h
index 2ed9bf8..0c3d694 100644
--- a/services/mediaresourcemanager/ResourceManagerService.h
+++ b/services/mediaresourcemanager/ResourceManagerService.h
@@ -48,6 +48,8 @@
public:
static char const *getServiceName() { return "media.resource_manager"; }
+ virtual status_t dump(int fd, const Vector<String16>& args);
+
ResourceManagerService();
ResourceManagerService(sp<ProcessInfoInterface> processInfo);
diff --git a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
index 48d1395..bccc7fa 100644
--- a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
+++ b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
@@ -55,6 +55,10 @@
return true;
}
+ virtual String8 getName() {
+ return String8("test_client");
+ }
+
bool reclaimed() const {
return mReclaimed;
}