summaryrefslogtreecommitdiffstats
path: root/media/libstagefright
diff options
context:
space:
mode:
authorAndroid (Google) Code Review <android-gerrit@google.com>2009-10-23 11:42:41 -0400
committerAndroid (Google) Code Review <android-gerrit@google.com>2009-10-23 11:42:41 -0400
commite84729002102622b40bd6efddffb76909615c12a (patch)
treec229350c2ca260179a2b9dd87a566dbdece3dea6 /media/libstagefright
parent1f64ffe2e486b5a0d0c77487bdb612ee46ed7ead (diff)
parente13526ad926bfee99778a4f21ea5e4f8a6c8984f (diff)
downloadframeworks_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.
Diffstat (limited to 'media/libstagefright')
-rw-r--r--media/libstagefright/OMXCodec.cpp146
1 files changed, 109 insertions, 37 deletions
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);