summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
Diffstat (limited to 'media')
-rw-r--r--media/libmedia/AudioRecord.cpp12
-rw-r--r--media/libmedia/AudioTrack.cpp30
-rw-r--r--media/libmedia/mediaplayer.cpp1
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp25
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h2
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp6
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp6
-rw-r--r--media/libstagefright/ACodec.cpp5
-rwxr-xr-xmedia/libstagefright/MPEG4Extractor.cpp9
-rw-r--r--media/libstagefright/Utils.cpp98
-rw-r--r--media/libstagefright/httplive/LiveSession.cpp11
11 files changed, 153 insertions, 52 deletions
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 3868f13..011b31f 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -1235,11 +1235,15 @@ void AudioRecord::AudioRecordThread::resume()
void AudioRecord::AudioRecordThread::wake()
{
AutoMutex _l(mMyLock);
- if (!mPaused && mPausedInt && mPausedNs > 0) {
- // audio record is active and internally paused with timeout.
+ if (!mPaused) {
+ // wake() might be called while servicing a callback - ignore the next
+ // pause time and call processAudioBuffer.
mIgnoreNextPausedInt = true;
- mPausedInt = false;
- mMyCond.signal();
+ if (mPausedInt && mPausedNs > 0) {
+ // audio record is active and internally paused with timeout.
+ mPausedInt = false;
+ mMyCond.signal();
+ }
}
}
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index ab720c6..7befe5d 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -483,7 +483,6 @@ status_t AudioTrack::set(
mMarkerReached = false;
mNewPosition = 0;
mUpdatePeriod = 0;
- mServer = 0;
mPosition = 0;
mReleased = 0;
mStartUs = 0;
@@ -1389,6 +1388,9 @@ status_t AudioTrack::createTrack_l()
mReqFrameCount = frameCount;
}
+ // reset server position to 0 as we have new cblk.
+ mServer = 0;
+
// update proxy
if (mSharedBuffer == 0) {
mStaticProxy.clear();
@@ -2109,15 +2111,13 @@ status_t AudioTrack::restoreTrack_l(const char *from)
// If a new IAudioTrack cannot be created, the previous (dead) instance will be left intact.
status_t result = createTrack_l();
- // take the frames that will be lost by track recreation into account in saved position
- // For streaming tracks, this is the amount we obtained from the user/client
- // (not the number actually consumed at the server - those are already lost).
- (void) updateAndGetPosition_l();
- if (mStaticProxy == 0) {
- mPosition = mReleased;
- }
-
if (result == NO_ERROR) {
+ // take the frames that will be lost by track recreation into account in saved position
+ // For streaming tracks, this is the amount we obtained from the user/client
+ // (not the number actually consumed at the server - those are already lost).
+ if (mStaticProxy == 0) {
+ mPosition = mReleased;
+ }
// Continue playback from last known position and restore loop.
if (mStaticProxy != 0) {
if (loopCount != 0) {
@@ -2551,11 +2551,15 @@ void AudioTrack::AudioTrackThread::resume()
void AudioTrack::AudioTrackThread::wake()
{
AutoMutex _l(mMyLock);
- if (!mPaused && mPausedInt && mPausedNs > 0) {
- // audio track is active and internally paused with timeout.
+ if (!mPaused) {
+ // wake() might be called while servicing a callback - ignore the next
+ // pause time and call processAudioBuffer.
mIgnoreNextPausedInt = true;
- mPausedInt = false;
- mMyCond.signal();
+ if (mPausedInt && mPausedNs > 0) {
+ // audio track is active and internally paused with timeout.
+ mPausedInt = false;
+ mMyCond.signal();
+ }
}
}
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index c215abf..502ab2d 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -574,6 +574,7 @@ status_t MediaPlayer::reset_l()
ALOGE("reset() failed with return code (%d)", ret);
mCurrentState = MEDIA_PLAYER_STATE_ERROR;
} else {
+ mPlayer->disconnect();
mCurrentState = MEDIA_PLAYER_IDLE;
}
// setDataSource has to be called again to create a
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index d49ba93..56521a2 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -655,6 +655,7 @@ sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre(
}
if (!p->hardwareOutput()) {
+ Mutex::Autolock l(mLock);
mAudioOutput = new AudioOutput(mAudioSessionId, IPCThreadState::self()->getCallingUid(),
mPid, mAudioAttributes);
static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
@@ -1101,6 +1102,9 @@ status_t MediaPlayerService::Client::setAudioAttributes_l(const Parcel &parcel)
{
if (mAudioAttributes != NULL) { free(mAudioAttributes); }
mAudioAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
+ if (mAudioAttributes == NULL) {
+ return NO_MEMORY;
+ }
unmarshallAudioAttributes(parcel, mAudioAttributes);
ALOGV("setAudioAttributes_l() usage=%d content=%d flags=0x%x tags=%s",
@@ -1337,7 +1341,6 @@ MediaPlayerService::AudioOutput::AudioOutput(int sessionId, int uid, int pid,
mCallbackData(NULL),
mBytesWritten(0),
mStreamType(AUDIO_STREAM_MUSIC),
- mAttributes(attr),
mLeftVolume(1.0),
mRightVolume(1.0),
mPlaybackRate(AUDIO_PLAYBACK_RATE_DEFAULT),
@@ -1353,7 +1356,13 @@ MediaPlayerService::AudioOutput::AudioOutput(int sessionId, int uid, int pid,
{
ALOGV("AudioOutput(%d)", sessionId);
if (attr != NULL) {
- mStreamType = audio_attributes_to_stream_type(attr);
+ mAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
+ if (mAttributes != NULL) {
+ memcpy(mAttributes, attr, sizeof(audio_attributes_t));
+ mStreamType = audio_attributes_to_stream_type(attr);
+ }
+ } else {
+ mAttributes = NULL;
}
setMinBufferCount();
@@ -1362,6 +1371,7 @@ MediaPlayerService::AudioOutput::AudioOutput(int sessionId, int uid, int pid,
MediaPlayerService::AudioOutput::~AudioOutput()
{
close();
+ free(mAttributes);
delete mCallbackData;
}
@@ -1468,14 +1478,21 @@ String8 MediaPlayerService::AudioOutput::getParameters(const String8& keys)
void MediaPlayerService::AudioOutput::setAudioAttributes(const audio_attributes_t * attributes) {
Mutex::Autolock lock(mLock);
- mAttributes = attributes;
- if (attributes != NULL) {
+ if (attributes == NULL) {
+ free(mAttributes);
+ mAttributes = NULL;
+ } else {
+ if (mAttributes == NULL) {
+ mAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
+ }
+ memcpy(mAttributes, attributes, sizeof(audio_attributes_t));
mStreamType = audio_attributes_to_stream_type(attributes);
}
}
void MediaPlayerService::AudioOutput::setAudioStreamType(audio_stream_type_t streamType)
{
+ Mutex::Autolock lock(mLock);
// do not allow direct stream type modification if attributes have been set
if (mAttributes == NULL) {
mStreamType = streamType;
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 1c32597..60d4617 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -142,7 +142,7 @@ class MediaPlayerService : public BnMediaPlayerService
CallbackData * mCallbackData;
uint64_t mBytesWritten;
audio_stream_type_t mStreamType;
- const audio_attributes_t *mAttributes;
+ audio_attributes_t * mAttributes;
float mLeftVolume;
float mRightVolume;
AudioPlaybackRate mPlaybackRate;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 8e3e460..bfdb1ad 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -1474,8 +1474,10 @@ void NuPlayer::determineAudioModeChange() {
sp<AMessage> format = mSource->getFormat(true /*audio*/);
tryOpenAudioSinkForOffload(format, hasVideo);
} else {
- mRenderer->signalDisableOffloadAudio();
- mOffloadAudio = false;
+ if (mOffloadAudio) {
+ mRenderer->signalDisableOffloadAudio();
+ mOffloadAudio = false;
+ }
}
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 767417b..e9f3799 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -1422,12 +1422,18 @@ void NuPlayer::Renderer::onDisableOffloadAudio() {
Mutex::Autolock autoLock(mLock);
mFlags &= ~FLAG_OFFLOAD_AUDIO;
++mAudioDrainGeneration;
+ if (mAudioRenderingStartGeneration != -1) {
+ prepareForMediaRenderingStart_l();
+ }
}
void NuPlayer::Renderer::onEnableOffloadAudio() {
Mutex::Autolock autoLock(mLock);
mFlags |= FLAG_OFFLOAD_AUDIO;
++mAudioDrainGeneration;
+ if (mAudioRenderingStartGeneration != -1) {
+ prepareForMediaRenderingStart_l();
+ }
}
void NuPlayer::Renderer::onPause() {
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 4e1f094..e904c49 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -668,8 +668,7 @@ status_t ACodec::handleSetSurface(const sp<Surface> &surface) {
return err;
}
- int ignoredFlags = (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER
- | GRALLOC_USAGE_EXTERNAL_DISP);
+ int ignoredFlags = kVideoGrallocUsage;
// New output surface is not allowed to add new usage flag except ignored ones.
if ((usageBits & ~(mNativeWindowUsageBits | ignoredFlags)) != 0) {
ALOGW("cannot change usage from %#x to %#x", mNativeWindowUsageBits, usageBits);
@@ -905,7 +904,7 @@ status_t ACodec::setupNativeWindowSizeFormatAndUsage(
usage |= GRALLOC_USAGE_PROTECTED;
}
- usage |= GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP;
+ usage |= kVideoGrallocUsage;
*finalUsage = usage;
ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 26b07d4..0b07717 100755
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -3587,8 +3587,17 @@ status_t MPEG4Source::parseSampleAuxiliaryInformationOffsets(
int ivlength;
CHECK(mFormat->findInt32(kKeyCryptoDefaultIVSize, &ivlength));
+ // only 0, 8 and 16 byte initialization vectors are supported
+ if (ivlength != 0 && ivlength != 8 && ivlength != 16) {
+ ALOGW("unsupported IV length: %d", ivlength);
+ return ERROR_MALFORMED;
+ }
// read CencSampleAuxiliaryDataFormats
for (size_t i = 0; i < mCurrentSampleInfoCount; i++) {
+ if (i >= mCurrentSamples.size()) {
+ ALOGW("too few samples");
+ break;
+ }
Sample *smpl = &mCurrentSamples.editItemAt(i);
memset(smpl->iv, 0, 16);
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 6828b54..f0a7277 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -70,6 +70,23 @@ uint64_t hton64(uint64_t x) {
return ((uint64_t)htonl(x & 0xffffffff) << 32) | htonl(x >> 32);
}
+static status_t copyNALUToABuffer(sp<ABuffer> *buffer, const uint8_t *ptr, size_t length) {
+ if (((*buffer)->size() + 4 + length) > ((*buffer)->capacity() - (*buffer)->offset())) {
+ sp<ABuffer> tmpBuffer = new (std::nothrow) ABuffer((*buffer)->size() + 4 + length + 1024);
+ if (tmpBuffer.get() == NULL || tmpBuffer->base() == NULL) {
+ return NO_MEMORY;
+ }
+ memcpy(tmpBuffer->data(), (*buffer)->data(), (*buffer)->size());
+ tmpBuffer->setRange(0, (*buffer)->size());
+ (*buffer) = tmpBuffer;
+ }
+
+ memcpy((*buffer)->data() + (*buffer)->size(), "\x00\x00\x00\x01", 4);
+ memcpy((*buffer)->data() + (*buffer)->size() + 4, ptr, length);
+ (*buffer)->setRange((*buffer)->offset(), (*buffer)->size() + 4 + length);
+ return OK;
+}
+
status_t convertMetaDataToMessage(
const sp<MetaData> &meta, sp<AMessage> *format) {
format->clear();
@@ -214,7 +231,10 @@ status_t convertMetaDataToMessage(
ptr += 6;
size -= 6;
- sp<ABuffer> buffer = new ABuffer(1024);
+ sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
+ if (buffer.get() == NULL || buffer->base() == NULL) {
+ return NO_MEMORY;
+ }
buffer->setRange(0, 0);
for (size_t i = 0; i < numSeqParameterSets; ++i) {
@@ -224,11 +244,13 @@ status_t convertMetaDataToMessage(
ptr += 2;
size -= 2;
- CHECK(size >= length);
-
- memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
- memcpy(buffer->data() + buffer->size() + 4, ptr, length);
- buffer->setRange(0, buffer->size() + 4 + length);
+ if (size < length) {
+ return BAD_VALUE;
+ }
+ status_t err = copyNALUToABuffer(&buffer, ptr, length);
+ if (err != OK) {
+ return err;
+ }
ptr += length;
size -= length;
@@ -239,7 +261,10 @@ status_t convertMetaDataToMessage(
msg->setBuffer("csd-0", buffer);
- buffer = new ABuffer(1024);
+ buffer = new (std::nothrow) ABuffer(1024);
+ if (buffer.get() == NULL || buffer->base() == NULL) {
+ return NO_MEMORY;
+ }
buffer->setRange(0, 0);
CHECK(size >= 1);
@@ -254,11 +279,13 @@ status_t convertMetaDataToMessage(
ptr += 2;
size -= 2;
- CHECK(size >= length);
-
- memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
- memcpy(buffer->data() + buffer->size() + 4, ptr, length);
- buffer->setRange(0, buffer->size() + 4 + length);
+ if (size < length) {
+ return BAD_VALUE;
+ }
+ status_t err = copyNALUToABuffer(&buffer, ptr, length);
+ if (err != OK) {
+ return err;
+ }
ptr += length;
size -= length;
@@ -283,7 +310,10 @@ status_t convertMetaDataToMessage(
size -= 1;
size_t j = 0, i = 0;
- sp<ABuffer> buffer = new ABuffer(1024);
+ sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
+ if (buffer.get() == NULL || buffer->base() == NULL) {
+ return NO_MEMORY;
+ }
buffer->setRange(0, 0);
for (i = 0; i < numofArrays; i++) {
@@ -303,11 +333,13 @@ status_t convertMetaDataToMessage(
ptr += 2;
size -= 2;
- CHECK(size >= length);
-
- memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
- memcpy(buffer->data() + buffer->size() + 4, ptr, length);
- buffer->setRange(0, buffer->size() + 4 + length);
+ if (size < length) {
+ return BAD_VALUE;
+ }
+ status_t err = copyNALUToABuffer(&buffer, ptr, length);
+ if (err != OK) {
+ return err;
+ }
ptr += length;
size -= length;
@@ -326,7 +358,10 @@ status_t convertMetaDataToMessage(
esds.getCodecSpecificInfo(
&codec_specific_data, &codec_specific_data_size);
- sp<ABuffer> buffer = new ABuffer(codec_specific_data_size);
+ sp<ABuffer> buffer = new (std::nothrow) ABuffer(codec_specific_data_size);
+ if (buffer.get() == NULL || buffer->base() == NULL) {
+ return NO_MEMORY;
+ }
memcpy(buffer->data(), codec_specific_data,
codec_specific_data_size);
@@ -335,7 +370,10 @@ status_t convertMetaDataToMessage(
buffer->meta()->setInt64("timeUs", 0);
msg->setBuffer("csd-0", buffer);
} else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
- sp<ABuffer> buffer = new ABuffer(size);
+ sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
+ if (buffer.get() == NULL || buffer->base() == NULL) {
+ return NO_MEMORY;
+ }
memcpy(buffer->data(), data, size);
buffer->meta()->setInt32("csd", true);
@@ -346,14 +384,20 @@ status_t convertMetaDataToMessage(
return -EINVAL;
}
- buffer = new ABuffer(size);
+ buffer = new (std::nothrow) ABuffer(size);
+ if (buffer.get() == NULL || buffer->base() == NULL) {
+ return NO_MEMORY;
+ }
memcpy(buffer->data(), data, size);
buffer->meta()->setInt32("csd", true);
buffer->meta()->setInt64("timeUs", 0);
msg->setBuffer("csd-1", buffer);
} else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) {
- sp<ABuffer> buffer = new ABuffer(size);
+ sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
+ if (buffer.get() == NULL || buffer->base() == NULL) {
+ return NO_MEMORY;
+ }
memcpy(buffer->data(), data, size);
buffer->meta()->setInt32("csd", true);
@@ -364,7 +408,10 @@ status_t convertMetaDataToMessage(
return -EINVAL;
}
- buffer = new ABuffer(size);
+ buffer = new (std::nothrow) ABuffer(size);
+ if (buffer.get() == NULL || buffer->base() == NULL) {
+ return NO_MEMORY;
+ }
memcpy(buffer->data(), data, size);
buffer->meta()->setInt32("csd", true);
@@ -375,7 +422,10 @@ status_t convertMetaDataToMessage(
return -EINVAL;
}
- buffer = new ABuffer(size);
+ buffer = new (std::nothrow) ABuffer(size);
+ if (buffer.get() == NULL || buffer->base() == NULL) {
+ return NO_MEMORY;
+ }
memcpy(buffer->data(), data, size);
buffer->meta()->setInt32("csd", true);
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 2fc5135..1557401 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -1657,7 +1657,16 @@ void LiveSession::onChangeConfiguration2(const sp<AMessage> &msg) {
mLastDequeuedTimeUs = timeUs;
for (size_t i = 0; i < mPacketSources.size(); i++) {
- mPacketSources.editValueAt(i)->clear();
+ sp<AnotherPacketSource> packetSource = mPacketSources.editValueAt(i);
+ sp<MetaData> format = packetSource->getFormat();
+ packetSource->clear();
+ // Set a tentative format here such that HTTPLiveSource will always have
+ // a format available when NuPlayer queries. Without an available video
+ // format when setting a surface NuPlayer might disable video decoding
+ // altogether. The tentative format will be overwritten by the
+ // authoritative (and possibly same) format once content from the new
+ // position is dequeued.
+ packetSource->setFormat(format);
}
for (size_t i = 0; i < kMaxStreams; ++i) {