diff options
-rw-r--r-- | media/libmedia/IAudioPolicyService.cpp | 22 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/GenericSource.cpp | 43 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/GenericSource.h | 4 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 74 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayer.h | 2 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerSource.h | 2 | ||||
-rw-r--r-- | media/libstagefright/ESDS.cpp | 6 | ||||
-rw-r--r-- | media/libstagefright/SampleTable.cpp | 9 | ||||
-rw-r--r-- | services/audiopolicy/AudioPolicyManager.cpp | 8 |
9 files changed, 149 insertions, 21 deletions
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp index dbc7a9e..cfb28a9 100644 --- a/media/libmedia/IAudioPolicyService.cpp +++ b/media/libmedia/IAudioPolicyService.cpp @@ -73,6 +73,8 @@ enum { REGISTER_POLICY_MIXES, }; +#define MAX_ITEMS_PER_LIST 1024 + class BpAudioPolicyService : public BpInterface<IAudioPolicyService> { public: @@ -1054,10 +1056,18 @@ status_t BnAudioPolicyService::onTransact( audio_port_role_t role = (audio_port_role_t)data.readInt32(); audio_port_type_t type = (audio_port_type_t)data.readInt32(); unsigned int numPortsReq = data.readInt32(); + if (numPortsReq > MAX_ITEMS_PER_LIST) { + numPortsReq = MAX_ITEMS_PER_LIST; + } unsigned int numPorts = numPortsReq; - unsigned int generation; struct audio_port *ports = (struct audio_port *)calloc(numPortsReq, sizeof(struct audio_port)); + if (ports == NULL) { + reply->writeInt32(NO_MEMORY); + reply->writeInt32(0); + return NO_ERROR; + } + unsigned int generation; status_t status = listAudioPorts(role, type, &numPorts, ports, &generation); reply->writeInt32(status); reply->writeInt32(numPorts); @@ -1111,11 +1121,19 @@ status_t BnAudioPolicyService::onTransact( case LIST_AUDIO_PATCHES: { CHECK_INTERFACE(IAudioPolicyService, data, reply); unsigned int numPatchesReq = data.readInt32(); + if (numPatchesReq > MAX_ITEMS_PER_LIST) { + numPatchesReq = MAX_ITEMS_PER_LIST; + } unsigned int numPatches = numPatchesReq; - unsigned int generation; struct audio_patch *patches = (struct audio_patch *)calloc(numPatchesReq, sizeof(struct audio_patch)); + if (patches == NULL) { + reply->writeInt32(NO_MEMORY); + reply->writeInt32(0); + return NO_ERROR; + } + unsigned int generation; status_t status = listAudioPatches(&numPatches, patches, &generation); reply->writeInt32(status); reply->writeInt32(numPatches); diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index 9b446b8..1b2fc5e 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp +++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp @@ -262,6 +262,12 @@ status_t NuPlayer::GenericSource::initFromDataSource() { } } + mBitrate = totalBitrate; + + return OK; +} + +status_t NuPlayer::GenericSource::startSources() { // Start the selected A/V tracks now before we start buffering. // Widevine sources might re-initialize crypto when starting, if we delay // this to start(), all data buffered during prepare would be wasted. @@ -276,8 +282,6 @@ status_t NuPlayer::GenericSource::initFromDataSource() { return UNKNOWN_ERROR; } - mBitrate = totalBitrate; - return OK; } @@ -423,6 +427,32 @@ void NuPlayer::GenericSource::onPrepareAsync() { | FLAG_CAN_SEEK_FORWARD | FLAG_CAN_SEEK); + if (mIsSecure) { + // secure decoders must be instantiated before starting widevine source + sp<AMessage> reply = new AMessage(kWhatSecureDecodersInstantiated, id()); + notifyInstantiateSecureDecoders(reply); + } else { + finishPrepareAsync(); + } +} + +void NuPlayer::GenericSource::onSecureDecodersInstantiated(status_t err) { + if (err != OK) { + ALOGE("Failed to instantiate secure decoders!"); + notifyPreparedAndCleanup(err); + return; + } + finishPrepareAsync(); +} + +void NuPlayer::GenericSource::finishPrepareAsync() { + status_t err = startSources(); + if (err != OK) { + ALOGE("Failed to init start data source!"); + notifyPreparedAndCleanup(err); + return; + } + if (mIsStreaming) { mPrepareBuffering = true; @@ -441,6 +471,7 @@ void NuPlayer::GenericSource::notifyPreparedAndCleanup(status_t err) { mDataSource.clear(); mCachedSource.clear(); mHttpSource.clear(); + mBitrate = -1; cancelPollBuffering(); } @@ -870,6 +901,14 @@ void NuPlayer::GenericSource::onMessageReceived(const sp<AMessage> &msg) { break; } + case kWhatSecureDecodersInstantiated: + { + int32_t err; + CHECK(msg->findInt32("err", &err)); + onSecureDecodersInstantiated(err); + break; + } + case kWhatStopWidevine: { // mStopRead is only used for Widevine to prevent the video source diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h index 385d73a..2d73ea9 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.h +++ b/media/libmediaplayerservice/nuplayer/GenericSource.h @@ -96,6 +96,7 @@ private: kWhatStopWidevine, kWhatStart, kWhatResume, + kWhatSecureDecodersInstantiated, }; struct Track { @@ -161,6 +162,9 @@ private: status_t prefillCacheIfNecessary(); void notifyPreparedAndCleanup(status_t err); + void onSecureDecodersInstantiated(status_t err); + void finishPrepareAsync(); + status_t startSources(); void onGetFormatMeta(sp<AMessage> msg) const; sp<MetaData> doGetFormatMeta(bool audio) const; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index fb8dbce..aeea204 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -1004,22 +1004,40 @@ void NuPlayer::onResume() { } } -void NuPlayer::onStart() { - mOffloadAudio = false; - mAudioEOS = false; - mVideoEOS = false; - mStarted = true; +status_t NuPlayer::onInstantiateSecureDecoders() { + status_t err; + if (!(mSourceFlags & Source::FLAG_SECURE)) { + return BAD_TYPE; + } - /* instantiate decoders now for secure playback */ - if (mSourceFlags & Source::FLAG_SECURE) { - if (mNativeWindow != NULL) { - instantiateDecoder(false, &mVideoDecoder); + if (mRenderer != NULL) { + ALOGE("renderer should not be set when instantiating secure decoders"); + return UNKNOWN_ERROR; + } + + // TRICKY: We rely on mRenderer being null, so that decoder does not start requesting + // data on instantiation. + if (mNativeWindow != NULL) { + err = instantiateDecoder(false, &mVideoDecoder); + if (err != OK) { + return err; } + } - if (mAudioSink != NULL) { - instantiateDecoder(true, &mAudioDecoder); + if (mAudioSink != NULL) { + err = instantiateDecoder(true, &mAudioDecoder); + if (err != OK) { + return err; } } + return OK; +} + +void NuPlayer::onStart() { + mOffloadAudio = false; + mAudioEOS = false; + mVideoEOS = false; + mStarted = true; mSource->start(); @@ -1371,7 +1389,7 @@ void NuPlayer::flushDecoder(bool audio, bool needShutdown) { FlushStatus newStatus = needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER; - mFlushComplete[audio][false /* isDecoder */] = false; + mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL); mFlushComplete[audio][true /* isDecoder */] = false; if (audio) { ALOGE_IF(mFlushingAudio != NONE, @@ -1656,6 +1674,23 @@ void NuPlayer::onSourceNotify(const sp<AMessage> &msg) { CHECK(msg->findInt32("what", &what)); switch (what) { + case Source::kWhatInstantiateSecureDecoders: + { + if (mSource == NULL) { + // This is a stale notification from a source that was + // asynchronously preparing when the client called reset(). + // We handled the reset, the source is gone. + break; + } + + sp<AMessage> reply; + CHECK(msg->findMessage("reply", &reply)); + status_t err = onInstantiateSecureDecoders(); + reply->setInt32("err", err); + reply->post(); + break; + } + case Source::kWhatPrepared: { if (mSource == NULL) { @@ -1668,6 +1703,14 @@ void NuPlayer::onSourceNotify(const sp<AMessage> &msg) { int32_t err; CHECK(msg->findInt32("err", &err)); + if (err != OK) { + // shut down potential secure codecs in case client never calls reset + mDeferredActions.push_back( + new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */, + FLUSH_CMD_SHUTDOWN /* video */)); + processDeferredActions(); + } + sp<NuPlayerDriver> driver = mDriver.promote(); if (driver != NULL) { // notify duration first, so that it's definitely set when @@ -1952,6 +1995,13 @@ void NuPlayer::Source::notifyPrepared(status_t err) { notify->post(); } +void NuPlayer::Source::notifyInstantiateSecureDecoders(const sp<AMessage> &reply) { + sp<AMessage> notify = dupNotify(); + notify->setInt32("what", kWhatInstantiateSecureDecoders); + notify->setMessage("reply", reply); + notify->post(); +} + void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) { TRESPASS(); } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h index 57eaf74..30ede1a 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -201,6 +201,8 @@ private: status_t instantiateDecoder(bool audio, sp<DecoderBase> *decoder); + status_t onInstantiateSecureDecoders(); + void updateVideoSize( const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat = NULL); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h index 5a8beb1..d9f14a2 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h @@ -55,6 +55,7 @@ struct NuPlayer::Source : public AHandler { kWhatTimedTextData, kWhatQueueDecoderShutdown, kWhatDrmNoLicense, + kWhatInstantiateSecureDecoders, }; // The provides message is used to notify the player about various @@ -125,6 +126,7 @@ protected: void notifyFlagsChanged(uint32_t flags); void notifyVideoSizeChanged(const sp<AMessage> &format = NULL); + void notifyInstantiateSecureDecoders(const sp<AMessage> &reply); void notifyPrepared(status_t err = OK); private: diff --git a/media/libstagefright/ESDS.cpp b/media/libstagefright/ESDS.cpp index 427bf7b..8fbb57c 100644 --- a/media/libstagefright/ESDS.cpp +++ b/media/libstagefright/ESDS.cpp @@ -136,6 +136,8 @@ status_t ESDS::parseESDescriptor(size_t offset, size_t size) { --size; if (streamDependenceFlag) { + if (size < 2) + return ERROR_MALFORMED; offset += 2; size -= 2; } @@ -145,11 +147,15 @@ status_t ESDS::parseESDescriptor(size_t offset, size_t size) { return ERROR_MALFORMED; } unsigned URLlength = mData[offset]; + if (URLlength >= size) + return ERROR_MALFORMED; offset += URLlength + 1; size -= URLlength + 1; } if (OCRstreamFlag) { + if (size < 2) + return ERROR_MALFORMED; offset += 2; size -= 2; diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp index bdd6d56..6030236 100644 --- a/media/libstagefright/SampleTable.cpp +++ b/media/libstagefright/SampleTable.cpp @@ -230,6 +230,9 @@ status_t SampleTable::setSampleToChunkParams( return ERROR_MALFORMED; } + if (SIZE_MAX / sizeof(SampleToChunkEntry) <= mNumSampleToChunkOffsets) + return ERROR_OUT_OF_RANGE; + mSampleToChunkEntries = new SampleToChunkEntry[mNumSampleToChunkOffsets]; @@ -330,7 +333,7 @@ status_t SampleTable::setTimeToSampleParams( } mTimeToSampleCount = U32_AT(&header[4]); - uint64_t allocSize = mTimeToSampleCount * 2 * sizeof(uint32_t); + uint64_t allocSize = mTimeToSampleCount * 2 * (uint64_t)sizeof(uint32_t); if (allocSize > SIZE_MAX) { return ERROR_OUT_OF_RANGE; } @@ -376,7 +379,7 @@ status_t SampleTable::setCompositionTimeToSampleParams( } mNumCompositionTimeDeltaEntries = numEntries; - uint64_t allocSize = numEntries * 2 * sizeof(uint32_t); + uint64_t allocSize = numEntries * 2 * (uint64_t)sizeof(uint32_t); if (allocSize > SIZE_MAX) { return ERROR_OUT_OF_RANGE; } @@ -426,7 +429,7 @@ status_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) ALOGV("Table of sync samples is empty or has only a single entry!"); } - uint64_t allocSize = mNumSyncSamples * sizeof(uint32_t); + uint64_t allocSize = mNumSyncSamples * (uint64_t)sizeof(uint32_t); if (allocSize > SIZE_MAX) { return ERROR_OUT_OF_RANGE; } diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp index 7f27659..6ebd0ed 100644 --- a/services/audiopolicy/AudioPolicyManager.cpp +++ b/services/audiopolicy/AudioPolicyManager.cpp @@ -7635,10 +7635,14 @@ AudioPolicyManager::DeviceVector AudioPolicyManager::DeviceVector::getDevicesFro audio_devices_t type) const { DeviceVector devices; + bool isOutput = audio_is_output_devices(type); + type &= ~AUDIO_DEVICE_BIT_IN; for (size_t i = 0; (i < size()) && (type != AUDIO_DEVICE_NONE); i++) { - if (itemAt(i)->mDeviceType & type & ~AUDIO_DEVICE_BIT_IN) { + bool curIsOutput = audio_is_output_devices(itemAt(i)->mDeviceType); + audio_devices_t curType = itemAt(i)->mDeviceType & ~AUDIO_DEVICE_BIT_IN; + if ((isOutput == curIsOutput) && ((type & curType) != 0)) { devices.add(itemAt(i)); - type &= ~itemAt(i)->mDeviceType; + type &= ~curType; ALOGV("DeviceVector::getDevicesFromType() for type %x found %p", itemAt(i)->mDeviceType, itemAt(i).get()); } |