From 6ff58f04f78886b07c72c0118eb71a78d08f5651 Mon Sep 17 00:00:00 2001 From: Lajos Molnar Date: Mon, 11 Aug 2014 16:46:15 -0700 Subject: MediaCodecList: handle errors gracefully Handle missing OMX codecs, and codecs that do not load. Fix NULL dereference when initializing codec with no type. Bug: 16907578 Bug: 16905025 Change-Id: I5d103db36ebb029d1aab03222bf6e9324beb1566 --- include/media/MediaCodecInfo.h | 1 + media/libmedia/MediaCodecInfo.cpp | 8 ++++++++ media/libstagefright/MediaCodecList.cpp | 26 +++++++++++++++++++++----- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/include/media/MediaCodecInfo.h b/include/media/MediaCodecInfo.h index 29315ce..fc340c8 100644 --- a/include/media/MediaCodecInfo.h +++ b/include/media/MediaCodecInfo.h @@ -107,6 +107,7 @@ private: status_t initializeCapabilities(const CodecCapabilities &caps); void addDetail(const AString &key, const AString &value); void addFeature(const AString &key, int32_t value); + void removeMime(const char *mime); void complete(); DISALLOW_EVIL_CONSTRUCTORS(MediaCodecInfo); diff --git a/media/libmedia/MediaCodecInfo.cpp b/media/libmedia/MediaCodecInfo.cpp index 7900eae..8f47292 100644 --- a/media/libmedia/MediaCodecInfo.cpp +++ b/media/libmedia/MediaCodecInfo.cpp @@ -206,6 +206,14 @@ status_t MediaCodecInfo::addMime(const char *mime) { return OK; } +void MediaCodecInfo::removeMime(const char *mime) { + ssize_t ix = getCapabilityIndex(mime); + if (ix >= 0) { + mCaps.removeItemsAt(ix); + // mCurrentCaps will be removed when completed + } +} + status_t MediaCodecInfo::initializeCapabilities(const CodecCapabilities &caps) { mCurrentCaps->mProfileLevels.clear(); mCurrentCaps->mColorFormats.clear(); diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp index 7f8b7f5..2f2a0b3 100644 --- a/media/libstagefright/MediaCodecList.cpp +++ b/media/libstagefright/MediaCodecList.cpp @@ -482,11 +482,21 @@ status_t MediaCodecList::addMediaCodecFromAttributes( } mCurrentInfo = new MediaCodecInfo(name, encoder, type); - mCodecInfos.push_back(mCurrentInfo); - return initializeCapabilities(type); + // The next step involves trying to load the codec, which may + // fail. Only list the codec if this succeeds. + // However, keep mCurrentInfo object around until parsing + // of full codec info is completed. + if (initializeCapabilities(type) == OK) { + mCodecInfos.push_back(mCurrentInfo); + } + return OK; } status_t MediaCodecList::initializeCapabilities(const char *type) { + if (type == NULL) { + return OK; + } + ALOGV("initializeCapabilities %s:%s", mCurrentInfo->mName.c_str(), type); @@ -553,10 +563,16 @@ status_t MediaCodecList::addTypeFromAttributes(const char **attrs) { } status_t ret = mCurrentInfo->addMime(name); - if (ret == OK) { - ret = initializeCapabilities(name); + if (ret != OK) { + return ret; } - return ret; + + // The next step involves trying to load the codec, which may + // fail. Handle this gracefully (by not reporting such mime). + if (initializeCapabilities(name) != OK) { + mCurrentInfo->removeMime(name); + } + return OK; } // legacy method for non-advanced codecs -- cgit v1.1