am e8472900: Merge change Ie13526ad into eclair-mr2
Merge commit 'e84729002102622b40bd6efddffb76909615c12a' into eclair-mr2-plus-aosp * commit 'e84729002102622b40bd6efddffb76909615c12a': Prefer software decoders over hardware for thumbnail extraction.
This commit is contained in:
@@ -30,11 +30,15 @@ struct OMXCodecObserver;
|
|||||||
|
|
||||||
struct OMXCodec : public MediaSource,
|
struct OMXCodec : public MediaSource,
|
||||||
public MediaBufferObserver {
|
public MediaBufferObserver {
|
||||||
|
enum CreationFlags {
|
||||||
|
kPreferSoftwareCodecs = 1,
|
||||||
|
};
|
||||||
static sp<OMXCodec> Create(
|
static sp<OMXCodec> Create(
|
||||||
const sp<IOMX> &omx,
|
const sp<IOMX> &omx,
|
||||||
const sp<MetaData> &meta, bool createEncoder,
|
const sp<MetaData> &meta, bool createEncoder,
|
||||||
const sp<MediaSource> &source,
|
const sp<MediaSource> &source,
|
||||||
const char *matchComponentName = NULL);
|
const char *matchComponentName = NULL,
|
||||||
|
uint32_t flags = 0);
|
||||||
|
|
||||||
static void setComponentRole(
|
static void setComponentRole(
|
||||||
const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder,
|
const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder,
|
||||||
@@ -207,6 +211,14 @@ private:
|
|||||||
|
|
||||||
void dumpPortStatus(OMX_U32 portIndex);
|
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(const OMXCodec &);
|
||||||
OMXCodec &operator=(const OMXCodec &);
|
OMXCodec &operator=(const OMXCodec &);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -122,7 +122,8 @@ VideoFrame *StagefrightMetadataRetriever::captureFrame() {
|
|||||||
|
|
||||||
sp<MediaSource> decoder =
|
sp<MediaSource> decoder =
|
||||||
OMXCodec::Create(
|
OMXCodec::Create(
|
||||||
mClient.interface(), meta, false, source);
|
mClient.interface(), meta, false, source,
|
||||||
|
NULL, OMXCodec::kPreferSoftwareCodecs);
|
||||||
|
|
||||||
if (decoder.get() == NULL) {
|
if (decoder.get() == NULL) {
|
||||||
LOGE("unable to instantiate video decoder.");
|
LOGE("unable to instantiate video decoder.");
|
||||||
|
|||||||
@@ -172,49 +172,35 @@ static void InitOMXParams(T *params) {
|
|||||||
params->nVersion.s.nStep = 0;
|
params->nVersion.s.nStep = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
// static
|
||||||
sp<OMXCodec> OMXCodec::Create(
|
uint32_t OMXCodec::getComponentQuirks(const char *componentName) {
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t quirks = 0;
|
uint32_t quirks = 0;
|
||||||
|
|
||||||
if (!strcmp(componentName, "OMX.PV.avcdec")) {
|
if (!strcmp(componentName, "OMX.PV.avcdec")) {
|
||||||
quirks |= kWantsNALFragments;
|
quirks |= kWantsNALFragments;
|
||||||
}
|
}
|
||||||
@@ -244,8 +230,94 @@ sp<OMXCodec> OMXCodec::Create(
|
|||||||
quirks |= kRequiresAllocateBufferOnOutputPorts;
|
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(
|
sp<OMXCodec> codec = new OMXCodec(
|
||||||
omx, node, quirks, createEncoder, mime, componentName,
|
omx, node, getComponentQuirks(componentName),
|
||||||
|
createEncoder, mime, componentName,
|
||||||
source);
|
source);
|
||||||
|
|
||||||
observer->setCodec(codec);
|
observer->setCodec(codec);
|
||||||
|
|||||||
Reference in New Issue
Block a user