diff options
-rw-r--r-- | media/libavextensions/stagefright/AVExtensions.h | 3 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/GenericSource.cpp | 29 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/GenericSource.h | 1 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp | 9 | ||||
-rw-r--r-- | media/libstagefright/Android.mk | 6 | ||||
-rw-r--r-- | media/libstagefright/MPEG4Writer.cpp | 30 | ||||
-rw-r--r-- | media/libstagefright/MediaCodec.cpp | 2 | ||||
-rw-r--r-- | media/libstagefright/MediaCodecSource.cpp | 2 | ||||
-rw-r--r-- | services/camera/libcameraservice/CameraFlashlight.cpp | 12 | ||||
-rw-r--r-- | services/camera/libcameraservice/CameraService.cpp | 14 | ||||
-rw-r--r-- | services/camera/libcameraservice/CameraService.h | 5 |
11 files changed, 84 insertions, 29 deletions
diff --git a/media/libavextensions/stagefright/AVExtensions.h b/media/libavextensions/stagefright/AVExtensions.h index 891c7f8..0b70c08 100644 --- a/media/libavextensions/stagefright/AVExtensions.h +++ b/media/libavextensions/stagefright/AVExtensions.h @@ -160,6 +160,9 @@ struct AVUtils { virtual bool useQCHWEncoder(const sp<AMessage> &, AString &) { return false; } + virtual bool canDeferRelease(const sp<MetaData> &/*meta*/) { return false; } + virtual void setDeferRelease(sp<MetaData> &/*meta*/) {} + struct HEVCMuxer { virtual bool reassembleHEVCCSD(const AString &mime, sp<ABuffer> csd0, sp<MetaData> &meta); diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index 5c68e81..ee0310e 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp +++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp @@ -128,6 +128,7 @@ status_t NuPlayer::GenericSource::setDataSource( status_t NuPlayer::GenericSource::setDataSource(const sp<DataSource>& source) { resetDataSource(); + Mutex::Autolock _l(mSourceLock); mDataSource = source; return OK; } @@ -155,7 +156,12 @@ status_t NuPlayer::GenericSource::initFromDataSource() { return UNKNOWN_ERROR; } } else if (mIsStreaming) { - if (!mDataSource->sniff(&mimeType, &confidence, &dummy)) { + sp<DataSource> dataSource; + { + Mutex::Autolock _l(mSourceLock); + dataSource = mDataSource; + } + if (!dataSource->sniff(&mimeType, &confidence, &dummy)) { return UNKNOWN_ERROR; } isWidevineStreaming = !strcasecmp( @@ -380,6 +386,7 @@ void NuPlayer::GenericSource::onPrepareAsync() { } } + Mutex::Autolock _l(mSourceLock); mDataSource = DataSource::CreateFromURI( mHTTPService, uri, &mUriHeaders, &contentType, static_cast<HTTPBase *>(mHttpSource.get()), @@ -387,6 +394,7 @@ void NuPlayer::GenericSource::onPrepareAsync() { } else { mIsWidevine = false; + Mutex::Autolock _l(mSourceLock); mDataSource = new FileSource(mFd, mOffset, mLength); mFd = -1; } @@ -477,6 +485,7 @@ void NuPlayer::GenericSource::finishPrepareAsync() { void NuPlayer::GenericSource::notifyPreparedAndCleanup(status_t err) { if (err != OK) { + Mutex::Autolock _l(mSourceLock); mDataSource.clear(); mCachedSource.clear(); mHttpSource.clear(); @@ -532,13 +541,21 @@ void NuPlayer::GenericSource::resume() { } void NuPlayer::GenericSource::disconnect() { - if (mDataSource != NULL) { + + sp<DataSource> dataSource; + sp<DataSource> httpSource; + { + Mutex::Autolock _l(mSourceLock); + dataSource = mDataSource; + httpSource = mHttpSource; + } + if (dataSource != NULL) { // disconnect data source - if (mDataSource->flags() & DataSource::kIsCachingDataSource) { - static_cast<NuCachedSource2 *>(mDataSource.get())->disconnect(); + if (dataSource->flags() & DataSource::kIsCachingDataSource) { + static_cast<NuCachedSource2 *>(dataSource.get())->disconnect(); } - } else if (mHttpSource != NULL) { - static_cast<HTTPBase *>(mHttpSource.get())->disconnect(); + } else if (httpSource != NULL) { + static_cast<HTTPBase *>(httpSource.get())->disconnect(); } } diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h index ebc1fdc..c1d6e3e 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.h +++ b/media/libmediaplayerservice/nuplayer/GenericSource.h @@ -137,6 +137,7 @@ protected: int64_t mOffset; int64_t mLength; + Mutex mSourceLock; sp<DataSource> mDataSource; sp<NuCachedSource2> mCachedSource; sp<DataSource> mHttpSource; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp index 997920b..0bffafe 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp @@ -364,7 +364,14 @@ void NuPlayer::Decoder::onResume(bool notifyComplete) { if (notifyComplete) { mResumePending = true; } - mCodec->start(); + + if (mCodec != NULL) { + mCodec->start(); + } else { + ALOGW("Decoder %s onResume without a valid codec object", + mComponentName.c_str()); + handleError(NO_INIT); + } } void NuPlayer::Decoder::doFlush(bool notifyComplete) { diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk index 03e7e46..b2729af 100644 --- a/media/libstagefright/Android.mk +++ b/media/libstagefright/Android.mk @@ -137,6 +137,12 @@ ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT))) LOCAL_CFLAGS += -DENABLE_STAGEFRIGHT_EXPERIMENTS endif +ifeq ($(call is-vendor-board-platform,QCOM),true) +ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_FLAC_DECODER)),true) + LOCAL_CFLAGS += -DQTI_FLAC_DECODER +endif +endif + LOCAL_CLANG := true LOCAL_MODULE:= libstagefright diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp index 94f40b4..8dfc54c 100644 --- a/media/libstagefright/MPEG4Writer.cpp +++ b/media/libstagefright/MPEG4Writer.cpp @@ -2231,7 +2231,9 @@ status_t MPEG4Writer::Track::threadEntry() { MediaBuffer *buffer; const char *trackName = mIsAudio ? "Audio" : "Video"; while (!mDone && (err = mSource->read(&buffer)) == OK) { - if (buffer->range_length() == 0) { + if (buffer == NULL) { + continue; + } else if (buffer->range_length() == 0) { buffer->release(); buffer = NULL; ++nZeroLengthFrames; @@ -2284,15 +2286,23 @@ status_t MPEG4Writer::Track::threadEntry() { continue; } - // Make a deep copy of the MediaBuffer and Metadata and release - // the original as soon as we can - MediaBuffer *copy = new MediaBuffer(buffer->range_length()); - memcpy(copy->data(), (uint8_t *)buffer->data() + buffer->range_offset(), - buffer->range_length()); - copy->set_range(0, buffer->range_length()); - meta_data = new MetaData(*buffer->meta_data().get()); - buffer->release(); - buffer = NULL; + MediaBuffer *copy = NULL; + // Check if the upstream source hints it is OK to hold on to the + // buffer without releasing immediately and avoid cloning the buffer + if (AVUtils::get()->canDeferRelease(buffer->meta_data())) { + copy = buffer; + meta_data = new MetaData(*buffer->meta_data().get()); + } else { + // Make a deep copy of the MediaBuffer and Metadata and release + // the original as soon as we can + copy = new MediaBuffer(buffer->range_length()); + memcpy(copy->data(), (uint8_t *)buffer->data() + buffer->range_offset(), + buffer->range_length()); + copy->set_range(0, buffer->range_length()); + meta_data = new MetaData(*buffer->meta_data().get()); + buffer->release(); + buffer = NULL; + } if (mIsAvc || mIsHEVC) StripStartcode(copy); diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp index 3ae2056..c77d366 100644 --- a/media/libstagefright/MediaCodec.cpp +++ b/media/libstagefright/MediaCodec.cpp @@ -871,6 +871,8 @@ status_t MediaCodec::getBufferAndFormat( } *format = info.mFormat; } + } else { + return BAD_INDEX; } return OK; } diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp index dbd9cb0..925be14 100644 --- a/media/libstagefright/MediaCodecSource.cpp +++ b/media/libstagefright/MediaCodecSource.cpp @@ -759,6 +759,8 @@ void MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) { MediaBuffer *mbuf = new MediaBuffer(outbuf->size()); memcpy(mbuf->data(), outbuf->data(), outbuf->size()); + sp<MetaData> meta = mbuf->meta_data(); + AVUtils::get()->setDeferRelease(meta); if (!(flags & MediaCodec::BUFFER_FLAG_CODECCONFIG)) { if (mIsVideo) { diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp index 280bb9d..fd23ef9 100644 --- a/services/camera/libcameraservice/CameraFlashlight.cpp +++ b/services/camera/libcameraservice/CameraFlashlight.cpp @@ -99,7 +99,8 @@ status_t CameraFlashlight::createFlashlightControl(const String8& cameraId) { status_t CameraFlashlight::setTorchMode(const String8& cameraId, bool enabled) { if (!mFlashlightMapInitialized) { - ALOGE("%s: findFlashUnits() must be called before this method."); + ALOGE("%s: findFlashUnits() must be called before this method.", + __FUNCTION__); return NO_INIT; } @@ -200,7 +201,8 @@ bool CameraFlashlight::hasFlashUnit(const String8& cameraId) { bool CameraFlashlight::hasFlashUnitLocked(const String8& cameraId) { if (!mFlashlightMapInitialized) { - ALOGE("%s: findFlashUnits() must be called before this method."); + ALOGE("%s: findFlashUnits() must be called before this method.", + __FUNCTION__); return false; } @@ -219,7 +221,8 @@ status_t CameraFlashlight::prepareDeviceOpen(const String8& cameraId) { Mutex::Autolock l(mLock); if (!mFlashlightMapInitialized) { - ALOGE("%s: findFlashUnits() must be called before this method."); + ALOGE("%s: findFlashUnits() must be called before this method.", + __FUNCTION__); return NO_INIT; } @@ -256,7 +259,8 @@ status_t CameraFlashlight::deviceClosed(const String8& cameraId) { Mutex::Autolock l(mLock); if (!mFlashlightMapInitialized) { - ALOGE("%s: findFlashUnits() must be called before this method."); + ALOGE("%s: findFlashUnits() must be called before this method.", + __FUNCTION__); return NO_INIT; } diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 9a1101a..e4f792d 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -935,6 +935,16 @@ void CameraService::finishConnectLocked(const sp<BasicClient>& client, LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, clients not evicted properly", __FUNCTION__); } + + // And register a death notification for the client callback. Do + // this last to avoid Binder policy where a nested Binder + // transaction might be pre-empted to service the client death + // notification if the client process dies before linkToDeath is + // invoked. + sp<IBinder> remoteCallback = client->getRemote(); + if (remoteCallback != nullptr) { + remoteCallback->linkToDeath(this); + } } status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clientPid, @@ -1874,11 +1884,9 @@ CameraService::BasicClient::~BasicClient() { void CameraService::BasicClient::disconnect() { if (mDisconnected) { - ALOGE("%s: Disconnect called on already disconnected client for device %d", __FUNCTION__, - mCameraId); return; } - mDisconnected = true;; + mDisconnected = true; mCameraService->removeByClient(this); mCameraService->logDisconnected(String8::format("%d", mCameraId), mClientPid, diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index b56c161..b29317e 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -861,11 +861,6 @@ status_t CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String return ret; } - sp<IBinder> remoteCallback = client->getRemote(); - if (remoteCallback != nullptr) { - remoteCallback->linkToDeath(this); - } - // Update shim paremeters for legacy clients if (effectiveApiLevel == API_1) { // Assume we have always received a Client subclass for API1 |