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

Commit 7f83e10c authored by Andreas Huber's avatar Andreas Huber Committed by Android (Google) Code Review
Browse files

Merge "Properly handle errors during the codec configuration phase, attempt to...

Merge "Properly handle errors during the codec configuration phase, attempt to revert to next available (likely software-) codec if configuration fails."
parents 52c6c108 2a09c7e0
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -167,7 +167,7 @@ private:
    status_t setupMPEG4EncoderParameters();
    status_t setupAVCEncoderParameters();

    void setVideoOutputFormat(
    status_t setVideoOutputFormat(
            const char *mime, OMX_U32 width, OMX_U32 height);

    void setImageOutputFormat(
@@ -220,6 +220,8 @@ private:

    void dumpPortStatus(OMX_U32 portIndex);

    status_t configureCodec(const sp<MetaData> &meta);

    static uint32_t getComponentQuirks(const char *componentName);

    static void findMatchingCodecs(
+64 −44
Original line number Diff line number Diff line
@@ -366,7 +366,6 @@ sp<MediaSource> OMXCodec::Create(

    sp<OMXCodecObserver> observer = new OMXCodecObserver;
    IOMX::node_id node = 0;
    success = false;

    const char *componentName;
    for (size_t i = 0; i < matchingCodecs.size(); ++i) {
@@ -389,15 +388,6 @@ sp<MediaSource> OMXCodec::Create(
        if (err == OK) {
            LOGV("Successfully allocated OMX node '%s'", componentName);

            success = true;
            break;
        }
    }

    if (!success) {
        return NULL;
    }

            sp<OMXCodec> codec = new OMXCodec(
                    omx, node, getComponentQuirks(componentName),
                    createEncoder, mime, componentName,
@@ -405,6 +395,20 @@ sp<MediaSource> OMXCodec::Create(

            observer->setCodec(codec);

            err = codec->configureCodec(meta);

            if (err == OK) {
                return codec;
            }

            LOGV("Failed to configure codec '%s'", componentName);
        }
    }

    return NULL;
}

status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
    uint32_t type;
    const void *data;
    size_t size;
@@ -417,7 +421,7 @@ sp<MediaSource> OMXCodec::Create(
        esds.getCodecSpecificInfo(
                &codec_specific_data, &codec_specific_data_size);

        codec->addCodecSpecificData(
        addCodecSpecificData(
                codec_specific_data, codec_specific_data_size);
    } else if (meta->findData(kKeyAVCC, &type, &data, &size)) {
        // Parse the AVCDecoderConfigurationRecord
@@ -453,7 +457,7 @@ sp<MediaSource> OMXCodec::Create(

            CHECK(size >= length);

            codec->addCodecSpecificData(ptr, length);
            addCodecSpecificData(ptr, length);

            ptr += length;
            size -= length;
@@ -473,7 +477,7 @@ sp<MediaSource> OMXCodec::Create(

            CHECK(size >= length);

            codec->addCodecSpecificData(ptr, length);
            addCodecSpecificData(ptr, length);

            ptr += length;
            size -= length;
@@ -482,44 +486,49 @@ sp<MediaSource> OMXCodec::Create(
        LOGV("AVC profile = %d (%s), level = %d",
             (int)profile, AVCProfileToString(profile), (int)level / 10);

        if (!strcmp(componentName, "OMX.TI.Video.Decoder")
        if (!strcmp(mComponentName, "OMX.TI.Video.Decoder")
            && (profile != kAVCProfileBaseline || level > 39)) {
            // This stream exceeds the decoder's capabilities. The decoder
            // does not handle this gracefully and would clobber the heap
            // and wreak havoc instead...

            LOGE("Profile and/or level exceed the decoder's capabilities.");
            return NULL;
            return ERROR_UNSUPPORTED;
        }
    }

    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) {
        codec->setAMRFormat(false /* isWAMR */);
    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mMIME)) {
        setAMRFormat(false /* isWAMR */);
    }
    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
        codec->setAMRFormat(true /* isWAMR */);
    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mMIME)) {
        setAMRFormat(true /* isWAMR */);
    }
    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mMIME)) {
        int32_t numChannels, sampleRate;
        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));

        codec->setAACFormat(numChannels, sampleRate);
        setAACFormat(numChannels, sampleRate);
    }
    if (!strncasecmp(mime, "video/", 6)) {
    if (!strncasecmp(mMIME, "video/", 6)) {
        int32_t width, height;
        bool success = meta->findInt32(kKeyWidth, &width);
        success = success && meta->findInt32(kKeyHeight, &height);
        CHECK(success);

        if (createEncoder) {
            codec->setVideoInputFormat(mime, width, height);
        if (mIsEncoder) {
            setVideoInputFormat(mMIME, width, height);
        } else {
            codec->setVideoOutputFormat(mime, width, height);
            status_t err = setVideoOutputFormat(
                    mMIME, width, height);

            if (err != OK) {
                return err;
            }
        }
    }
    if (!strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_JPEG)
        && !strcmp(componentName, "OMX.TI.JPEG.decode")) {
    if (!strcasecmp(mMIME, MEDIA_MIMETYPE_IMAGE_JPEG)
        && !strcmp(mComponentName, "OMX.TI.JPEG.decode")) {
        OMX_COLOR_FORMATTYPE format =
            OMX_COLOR_Format32bitARGB8888;
            // OMX_COLOR_FormatYUV420PackedPlanar;
@@ -537,23 +546,23 @@ sp<MediaSource> OMXCodec::Create(
        CHECK(success);
        CHECK(compressedSize > 0);

        codec->setImageOutputFormat(format, width, height);
        codec->setJPEGInputFormat(width, height, (OMX_U32)compressedSize);
        setImageOutputFormat(format, width, height);
        setJPEGInputFormat(width, height, (OMX_U32)compressedSize);
    }

    int32_t maxInputSize;
    if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
        codec->setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize);
        setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize);
    }

    if (!strcmp(componentName, "OMX.TI.AMR.encode")
        || !strcmp(componentName, "OMX.TI.WBAMR.encode")) {
        codec->setMinBufferSize(kPortIndexOutput, 8192);  // XXX
    if (!strcmp(mComponentName, "OMX.TI.AMR.encode")
        || !strcmp(mComponentName, "OMX.TI.WBAMR.encode")) {
        setMinBufferSize(kPortIndexOutput, 8192);  // XXX
    }

    codec->initOutputFormat(meta);
    initOutputFormat(meta);

    return codec;
    return OK;
}

void OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) {
@@ -902,7 +911,7 @@ status_t OMXCodec::setupAVCEncoderParameters() {
    return OK;
}

void OMXCodec::setVideoOutputFormat(
status_t OMXCodec::setVideoOutputFormat(
        const char *mime, OMX_U32 width, OMX_U32 height) {
    CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height);

@@ -918,9 +927,13 @@ void OMXCodec::setVideoOutputFormat(
        CHECK(!"Should not be here. Not a supported video mime type.");
    }

    setVideoPortFormatType(
    status_t err = setVideoPortFormatType(
            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);

    if (err != OK) {
        return err;
    }

#if 1
    {
        OMX_VIDEO_PARAM_PORTFORMATTYPE format;
@@ -944,7 +957,10 @@ void OMXCodec::setVideoOutputFormat(
        err = mOMX->setParameter(
                mNode, OMX_IndexParamVideoPortFormat,
                &format, sizeof(format));
        CHECK_EQ(err, OK);

        if (err != OK) {
            return err;
        }
    }
#endif

@@ -954,7 +970,7 @@ void OMXCodec::setVideoOutputFormat(

    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;

    status_t err = mOMX->getParameter(
    err = mOMX->getParameter(
            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));

    CHECK_EQ(err, OK);
@@ -977,7 +993,10 @@ void OMXCodec::setVideoOutputFormat(

    err = mOMX->setParameter(
            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    CHECK_EQ(err, OK);

    if (err != OK) {
        return err;
    }

    ////////////////////////////////////////////////////////////////////////////

@@ -999,7 +1018,8 @@ void OMXCodec::setVideoOutputFormat(

    err = mOMX->setParameter(
            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    CHECK_EQ(err, OK);

    return err;
}

OMXCodec::OMXCodec(
+9 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@

#include <binder/IMemory.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaErrors.h>

namespace android {

@@ -105,7 +106,14 @@ OMX::node_id OMXNodeInstance::nodeID() {
}

static status_t StatusFromOMXError(OMX_ERRORTYPE err) {
    return (err == OMX_ErrorNone) ? OK : UNKNOWN_ERROR;
    switch (err) {
        case OMX_ErrorNone:
            return OK;
        case OMX_ErrorUnsupportedSetting:
            return ERROR_UNSUPPORTED;
        default:
            return UNKNOWN_ERROR;
    }
}

status_t OMXNodeInstance::freeNode(OMXMaster *master) {