Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e8472900 authored by Android (Google) Code Review's avatar Android (Google) Code Review
Browse files

Merge change Ie13526ad into eclair-mr2

* changes:
  Prefer software decoders over hardware for thumbnail extraction.
parents 1f64ffe2 e13526ad
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -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 &);
};
+2 −1
Original line number Diff line number Diff line
@@ -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.");
+109 −37
Original line number Diff line number Diff line
@@ -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);