diff options
Diffstat (limited to 'media')
-rw-r--r-- | media/libmedia/AudioRecord.cpp | 12 | ||||
-rw-r--r-- | media/libmedia/AudioTrack.cpp | 30 | ||||
-rw-r--r-- | media/libmedia/mediaplayer.cpp | 1 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.cpp | 25 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.h | 2 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 6 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp | 6 | ||||
-rw-r--r-- | media/libstagefright/ACodec.cpp | 5 | ||||
-rwxr-xr-x | media/libstagefright/MPEG4Extractor.cpp | 9 | ||||
-rw-r--r-- | media/libstagefright/Utils.cpp | 98 | ||||
-rw-r--r-- | media/libstagefright/httplive/LiveSession.cpp | 11 |
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) { |