summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/libmedia/IAudioPolicyService.cpp22
-rw-r--r--media/libmediaplayerservice/nuplayer/GenericSource.cpp43
-rw-r--r--media/libmediaplayerservice/nuplayer/GenericSource.h4
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp74
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.h2
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerSource.h2
-rw-r--r--media/libstagefright/ESDS.cpp6
-rw-r--r--media/libstagefright/SampleTable.cpp9
-rw-r--r--services/audiopolicy/AudioPolicyManager.cpp8
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());
}