diff options
| author | Android (Google) Code Review <android-gerrit@google.com> | 2009-10-23 11:42:41 -0400 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2009-10-23 11:42:41 -0400 |
| commit | e84729002102622b40bd6efddffb76909615c12a (patch) | |
| tree | c229350c2ca260179a2b9dd87a566dbdece3dea6 | |
| parent | 1f64ffe2e486b5a0d0c77487bdb612ee46ed7ead (diff) | |
| parent | e13526ad926bfee99778a4f21ea5e4f8a6c8984f (diff) | |
| download | frameworks_base-e84729002102622b40bd6efddffb76909615c12a.zip frameworks_base-e84729002102622b40bd6efddffb76909615c12a.tar.gz frameworks_base-e84729002102622b40bd6efddffb76909615c12a.tar.bz2 | |
Merge change Ie13526ad into eclair-mr2
* changes:
Prefer software decoders over hardware for thumbnail extraction.
| -rw-r--r-- | include/media/stagefright/OMXCodec.h | 14 | ||||
| -rw-r--r-- | media/libmediaplayerservice/StagefrightMetadataRetriever.cpp | 3 | ||||
| -rw-r--r-- | media/libstagefright/OMXCodec.cpp | 146 |
3 files changed, 124 insertions, 39 deletions
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h index dfc902e..d0f4f17 100644 --- a/include/media/stagefright/OMXCodec.h +++ b/include/media/stagefright/OMXCodec.h @@ -30,11 +30,15 @@ struct OMXCodecObserver; struct OMXCodec : public MediaSource, public MediaBufferObserver { + enum CreationFlags { + kPreferSoftwareCodecs = 1, + }; static sp<OMXCodec> Create( const sp<IOMX> &omx, const sp<MetaData> &meta, bool createEncoder, const sp<MediaSource> &source, - const char *matchComponentName = NULL); + const char *matchComponentName = NULL, + uint32_t flags = 0); static void setComponentRole( const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder, @@ -207,6 +211,14 @@ private: void dumpPortStatus(OMX_U32 portIndex); + static uint32_t getComponentQuirks(const char *componentName); + + static void findMatchingCodecs( + const char *mime, + bool createEncoder, const char *matchComponentName, + uint32_t flags, + Vector<String8> *matchingCodecs); + OMXCodec(const OMXCodec &); OMXCodec &operator=(const OMXCodec &); }; diff --git a/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp index 5ac59c8..fced87b 100644 --- a/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp +++ b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp @@ -122,7 +122,8 @@ VideoFrame *StagefrightMetadataRetriever::captureFrame() { sp<MediaSource> decoder = OMXCodec::Create( - mClient.interface(), meta, false, source); + mClient.interface(), meta, false, source, + NULL, OMXCodec::kPreferSoftwareCodecs); if (decoder.get() == NULL) { LOGE("unable to instantiate video decoder."); diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index f8c0bda..e0f9563 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -172,49 +172,35 @@ static void InitOMXParams(T *params) { params->nVersion.s.nStep = 0; } -// static -sp<OMXCodec> OMXCodec::Create( - const sp<IOMX> &omx, - const sp<MetaData> &meta, bool createEncoder, - const sp<MediaSource> &source, - const char *matchComponentName) { - const char *mime; - bool success = meta->findCString(kKeyMIMEType, &mime); - CHECK(success); - - const char *componentName = NULL; - sp<OMXCodecObserver> observer = new OMXCodecObserver; - IOMX::node_id node = 0; - for (int index = 0;; ++index) { - if (createEncoder) { - componentName = GetCodec( - kEncoderInfo, sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]), - mime, index); - } else { - componentName = GetCodec( - kDecoderInfo, sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]), - mime, index); - } +static bool IsSoftwareCodec(const char *componentName) { + if (!strncmp("OMX.PV.", componentName, 7)) { + return true; + } - if (!componentName) { - return NULL; - } + return false; +} - // If a specific codec is requested, skip the non-matching ones. - if (matchComponentName && strcmp(componentName, matchComponentName)) { - continue; - } +static int CompareSoftwareCodecsFirst( + const String8 *elem1, const String8 *elem2) { + bool isSoftwareCodec1 = IsSoftwareCodec(elem1->string()); + bool isSoftwareCodec2 = IsSoftwareCodec(elem2->string()); - LOGV("Attempting to allocate OMX node '%s'", componentName); + if (isSoftwareCodec1) { + if (isSoftwareCodec2) { return 0; } + return -1; + } - status_t err = omx->allocateNode(componentName, observer, &node); - if (err == OK) { - LOGV("Successfully allocated OMX node '%s'", componentName); - break; - } + if (isSoftwareCodec2) { + return 1; } + return 0; +} + +// static +uint32_t OMXCodec::getComponentQuirks(const char *componentName) { uint32_t quirks = 0; + if (!strcmp(componentName, "OMX.PV.avcdec")) { quirks |= kWantsNALFragments; } @@ -244,8 +230,94 @@ sp<OMXCodec> OMXCodec::Create( quirks |= kRequiresAllocateBufferOnOutputPorts; } + return quirks; +} + +// static +void OMXCodec::findMatchingCodecs( + const char *mime, + bool createEncoder, const char *matchComponentName, + uint32_t flags, + Vector<String8> *matchingCodecs) { + matchingCodecs->clear(); + + for (int index = 0;; ++index) { + const char *componentName; + + if (createEncoder) { + componentName = GetCodec( + kEncoderInfo, + sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]), + mime, index); + } else { + componentName = GetCodec( + kDecoderInfo, + sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]), + mime, index); + } + + if (!componentName) { + break; + } + + // If a specific codec is requested, skip the non-matching ones. + if (matchComponentName && strcmp(componentName, matchComponentName)) { + continue; + } + + matchingCodecs->push(String8(componentName)); + } + + if (flags & kPreferSoftwareCodecs) { + matchingCodecs->sort(CompareSoftwareCodecsFirst); + } +} + +// static +sp<OMXCodec> OMXCodec::Create( + const sp<IOMX> &omx, + const sp<MetaData> &meta, bool createEncoder, + const sp<MediaSource> &source, + const char *matchComponentName, + uint32_t flags) { + const char *mime; + bool success = meta->findCString(kKeyMIMEType, &mime); + CHECK(success); + + Vector<String8> matchingCodecs; + findMatchingCodecs( + mime, createEncoder, matchComponentName, flags, &matchingCodecs); + + if (matchingCodecs.isEmpty()) { + return NULL; + } + + sp<OMXCodecObserver> observer = new OMXCodecObserver; + IOMX::node_id node = 0; + success = false; + + const char *componentName; + for (size_t i = 0; i < matchingCodecs.size(); ++i) { + componentName = matchingCodecs[i].string(); + + LOGV("Attempting to allocate OMX node '%s'", componentName); + + status_t err = omx->allocateNode(componentName, observer, &node); + if (err == OK) { + LOGV("Successfully allocated OMX node '%s'", componentName); + + success = true; + break; + } + } + + if (!success) { + return NULL; + } + sp<OMXCodec> codec = new OMXCodec( - omx, node, quirks, createEncoder, mime, componentName, + omx, node, getComponentQuirks(componentName), + createEncoder, mime, componentName, source); observer->setCodec(codec); |
