Merge change Ie13526ad into eclair-mr2

* changes:
  Prefer software decoders over hardware for thumbnail extraction.
This commit is contained in:
Android (Google) Code Review
2009-10-23 11:42:41 -04:00
3 changed files with 128 additions and 43 deletions

View File

@@ -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 &);
};

View File

@@ -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.");

View File

@@ -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);
}
if (!componentName) {
return NULL;
}
// If a specific codec is requested, skip the non-matching ones.
if (matchComponentName && strcmp(componentName, matchComponentName)) {
continue;
}
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);
break;
}
static bool IsSoftwareCodec(const char *componentName) {
if (!strncmp("OMX.PV.", componentName, 7)) {
return true;
}
return false;
}
static int CompareSoftwareCodecsFirst(
const String8 *elem1, const String8 *elem2) {
bool isSoftwareCodec1 = IsSoftwareCodec(elem1->string());
bool isSoftwareCodec2 = IsSoftwareCodec(elem2->string());
if (isSoftwareCodec1) {
if (isSoftwareCodec2) { return 0; }
return -1;
}
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);