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

Commit cede28e2 authored by Lajos Molnar's avatar Lajos Molnar Committed by Android (Google) Code Review
Browse files

Merge "stagefright: add runtime debug support" into lmp-mr1-dev

parents 97e6ca1a f296e2b2
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -80,6 +80,36 @@ MAKE_COMPARATOR(GT,>)
            __FILE__ ":" LITERAL_TO_STRING(__LINE__)            \
                " Should not be here.");

struct ADebug {
    enum Level {
        kDebugNone,             // no debug
        kDebugLifeCycle,        // lifecycle events: creation/deletion
        kDebugState,            // commands and events
        kDebugConfig,           // configuration
        kDebugInternalState,    // internal state changes
        kDebugAll,              // all
        kDebugMax = kDebugAll,

    };

    // parse the property or string to get the debug level for a component name
    // string format is:
    // <level>[:<glob>][,<level>[:<glob>]...]
    // - <level> is 0-5 corresponding to ADebug::Level
    // - <glob> is used to match component name case insensitively, if omitted, it
    //   matches all components
    // - string is read left-to-right, and the last matching level is returned, or
    //   the def if no terms matched
    static Level GetDebugLevelFromProperty(
            const char *name, const char *propertyName, Level def = kDebugNone);
    static Level GetDebugLevelFromString(
            const char *name, const char *value, Level def = kDebugNone);

    // remove redundant segments of a codec name, and return a newly allocated
    // string suitable for debugging
    static char *GetDebugName(const char *name);
};

}  // namespace android

#endif  // A_DEBUG_H_
+36 −0
Original line number Diff line number Diff line
/*
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef A_STRING_UTILS_H_
#define A_STRING_UTILS_H_

#include <stdlib.h>

namespace android {

struct AStringUtils {
    // similar to strncmp or strcasecmp, but case sensitivity is parametric
    static int Compare(const char *a, const char *b, size_t len, bool ignoreCase);

    // matches a string (str) to a glob pattern that supports:
    //    * - matches any number of characters
    static bool MatchesGlob(
            const char *glob, size_t globLen, const char *str, size_t strLen, bool ignoreCase);
};

}  // namespace android

#endif  // A_STRING_UTILS_H_
+55 −270
Original line number Diff line number Diff line
@@ -47,10 +47,11 @@
#include <media/stagefright/SkipCutBuffer.h>
#include <utils/Vector.h>

#include <OMX_Audio.h>
#include <OMX_AudioExt.h>
#include <OMX_Component.h>
#include <OMX_IndexExt.h>
#include <OMX_VideoExt.h>
#include <OMX_AsString.h>

#include "include/avc_utils.h"

@@ -4078,220 +4079,6 @@ void OMXCodec::signalBufferReturned(MediaBuffer *buffer) {
    CHECK(!"should not be here.");
}

static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) {
    static const char *kNames[] = {
        "OMX_IMAGE_CodingUnused",
        "OMX_IMAGE_CodingAutoDetect",
        "OMX_IMAGE_CodingJPEG",
        "OMX_IMAGE_CodingJPEG2K",
        "OMX_IMAGE_CodingEXIF",
        "OMX_IMAGE_CodingTIFF",
        "OMX_IMAGE_CodingGIF",
        "OMX_IMAGE_CodingPNG",
        "OMX_IMAGE_CodingLZW",
        "OMX_IMAGE_CodingBMP",
    };

    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);

    if (type < 0 || (size_t)type >= numNames) {
        return "UNKNOWN";
    } else {
        return kNames[type];
    }
}

static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) {
    static const char *kNames[] = {
        "OMX_COLOR_FormatUnused",
        "OMX_COLOR_FormatMonochrome",
        "OMX_COLOR_Format8bitRGB332",
        "OMX_COLOR_Format12bitRGB444",
        "OMX_COLOR_Format16bitARGB4444",
        "OMX_COLOR_Format16bitARGB1555",
        "OMX_COLOR_Format16bitRGB565",
        "OMX_COLOR_Format16bitBGR565",
        "OMX_COLOR_Format18bitRGB666",
        "OMX_COLOR_Format18bitARGB1665",
        "OMX_COLOR_Format19bitARGB1666",
        "OMX_COLOR_Format24bitRGB888",
        "OMX_COLOR_Format24bitBGR888",
        "OMX_COLOR_Format24bitARGB1887",
        "OMX_COLOR_Format25bitARGB1888",
        "OMX_COLOR_Format32bitBGRA8888",
        "OMX_COLOR_Format32bitARGB8888",
        "OMX_COLOR_FormatYUV411Planar",
        "OMX_COLOR_FormatYUV411PackedPlanar",
        "OMX_COLOR_FormatYUV420Planar",
        "OMX_COLOR_FormatYUV420PackedPlanar",
        "OMX_COLOR_FormatYUV420SemiPlanar",
        "OMX_COLOR_FormatYUV422Planar",
        "OMX_COLOR_FormatYUV422PackedPlanar",
        "OMX_COLOR_FormatYUV422SemiPlanar",
        "OMX_COLOR_FormatYCbYCr",
        "OMX_COLOR_FormatYCrYCb",
        "OMX_COLOR_FormatCbYCrY",
        "OMX_COLOR_FormatCrYCbY",
        "OMX_COLOR_FormatYUV444Interleaved",
        "OMX_COLOR_FormatRawBayer8bit",
        "OMX_COLOR_FormatRawBayer10bit",
        "OMX_COLOR_FormatRawBayer8bitcompressed",
        "OMX_COLOR_FormatL2",
        "OMX_COLOR_FormatL4",
        "OMX_COLOR_FormatL8",
        "OMX_COLOR_FormatL16",
        "OMX_COLOR_FormatL24",
        "OMX_COLOR_FormatL32",
        "OMX_COLOR_FormatYUV420PackedSemiPlanar",
        "OMX_COLOR_FormatYUV422PackedSemiPlanar",
        "OMX_COLOR_Format18BitBGR666",
        "OMX_COLOR_Format24BitARGB6666",
        "OMX_COLOR_Format24BitABGR6666",
    };

    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);

    if (type == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
        return "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar";
    } else if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) {
        return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar";
    } else if (type < 0 || (size_t)type >= numNames) {
        return "UNKNOWN";
    } else {
        return kNames[type];
    }
}

static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) {
    static const char *kNames[] = {
        "OMX_VIDEO_CodingUnused",
        "OMX_VIDEO_CodingAutoDetect",
        "OMX_VIDEO_CodingMPEG2",
        "OMX_VIDEO_CodingH263",
        "OMX_VIDEO_CodingMPEG4",
        "OMX_VIDEO_CodingWMV",
        "OMX_VIDEO_CodingRV",
        "OMX_VIDEO_CodingAVC",
        "OMX_VIDEO_CodingMJPEG",
    };

    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);

    if (type < 0 || (size_t)type >= numNames) {
        return "UNKNOWN";
    } else {
        return kNames[type];
    }
}

static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) {
    static const char *kNames[] = {
        "OMX_AUDIO_CodingUnused",
        "OMX_AUDIO_CodingAutoDetect",
        "OMX_AUDIO_CodingPCM",
        "OMX_AUDIO_CodingADPCM",
        "OMX_AUDIO_CodingAMR",
        "OMX_AUDIO_CodingGSMFR",
        "OMX_AUDIO_CodingGSMEFR",
        "OMX_AUDIO_CodingGSMHR",
        "OMX_AUDIO_CodingPDCFR",
        "OMX_AUDIO_CodingPDCEFR",
        "OMX_AUDIO_CodingPDCHR",
        "OMX_AUDIO_CodingTDMAFR",
        "OMX_AUDIO_CodingTDMAEFR",
        "OMX_AUDIO_CodingQCELP8",
        "OMX_AUDIO_CodingQCELP13",
        "OMX_AUDIO_CodingEVRC",
        "OMX_AUDIO_CodingSMV",
        "OMX_AUDIO_CodingG711",
        "OMX_AUDIO_CodingG723",
        "OMX_AUDIO_CodingG726",
        "OMX_AUDIO_CodingG729",
        "OMX_AUDIO_CodingAAC",
        "OMX_AUDIO_CodingMP3",
        "OMX_AUDIO_CodingSBC",
        "OMX_AUDIO_CodingVORBIS",
        "OMX_AUDIO_CodingOPUS",
        "OMX_AUDIO_CodingWMA",
        "OMX_AUDIO_CodingRA",
        "OMX_AUDIO_CodingMIDI",
    };

    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);

    if (type < 0 || (size_t)type >= numNames) {
        return "UNKNOWN";
    } else {
        return kNames[type];
    }
}

static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) {
    static const char *kNames[] = {
        "OMX_AUDIO_PCMModeLinear",
        "OMX_AUDIO_PCMModeALaw",
        "OMX_AUDIO_PCMModeMULaw",
    };

    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);

    if (type < 0 || (size_t)type >= numNames) {
        return "UNKNOWN";
    } else {
        return kNames[type];
    }
}

static const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) {
    static const char *kNames[] = {
        "OMX_AUDIO_AMRBandModeUnused",
        "OMX_AUDIO_AMRBandModeNB0",
        "OMX_AUDIO_AMRBandModeNB1",
        "OMX_AUDIO_AMRBandModeNB2",
        "OMX_AUDIO_AMRBandModeNB3",
        "OMX_AUDIO_AMRBandModeNB4",
        "OMX_AUDIO_AMRBandModeNB5",
        "OMX_AUDIO_AMRBandModeNB6",
        "OMX_AUDIO_AMRBandModeNB7",
        "OMX_AUDIO_AMRBandModeWB0",
        "OMX_AUDIO_AMRBandModeWB1",
        "OMX_AUDIO_AMRBandModeWB2",
        "OMX_AUDIO_AMRBandModeWB3",
        "OMX_AUDIO_AMRBandModeWB4",
        "OMX_AUDIO_AMRBandModeWB5",
        "OMX_AUDIO_AMRBandModeWB6",
        "OMX_AUDIO_AMRBandModeWB7",
        "OMX_AUDIO_AMRBandModeWB8",
    };

    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);

    if (type < 0 || (size_t)type >= numNames) {
        return "UNKNOWN";
    } else {
        return kNames[type];
    }
}

static const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) {
    static const char *kNames[] = {
        "OMX_AUDIO_AMRFrameFormatConformance",
        "OMX_AUDIO_AMRFrameFormatIF1",
        "OMX_AUDIO_AMRFrameFormatIF2",
        "OMX_AUDIO_AMRFrameFormatFSF",
        "OMX_AUDIO_AMRFrameFormatRTPPayload",
        "OMX_AUDIO_AMRFrameFormatITU",
    };

    size_t numNames = sizeof(kNames) / sizeof(kNames[0]);

    if (type < 0 || (size_t)type >= numNames) {
        return "UNKNOWN";
    } else {
        return kNames[type];
    }
}

void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
    OMX_PARAM_PORTDEFINITIONTYPE def;
    InitOMXParams(&def);
@@ -4322,10 +4109,10 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
            printf("  nStride = %" PRIu32 "\n", imageDef->nStride);

            printf("  eCompressionFormat = %s\n",
                   imageCompressionFormatString(imageDef->eCompressionFormat));
                   asString(imageDef->eCompressionFormat));

            printf("  eColorFormat = %s\n",
                   colorFormatString(imageDef->eColorFormat));
                   asString(imageDef->eColorFormat));

            break;
        }
@@ -4341,10 +4128,10 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
            printf("  nStride = %" PRIu32 "\n", videoDef->nStride);

            printf("  eCompressionFormat = %s\n",
                   videoCompressionFormatString(videoDef->eCompressionFormat));
                   asString(videoDef->eCompressionFormat));

            printf("  eColorFormat = %s\n",
                   colorFormatString(videoDef->eColorFormat));
                   asString(videoDef->eColorFormat));

            break;
        }
@@ -4356,7 +4143,7 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
            printf("\n");
            printf("  // Audio\n");
            printf("  eEncoding = %s\n",
                   audioCodingTypeString(audioDef->eEncoding));
                   asString(audioDef->eEncoding));

            if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) {
                OMX_AUDIO_PARAM_PCMMODETYPE params;
@@ -4376,7 +4163,7 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
                       params.eNumData == OMX_NumericalDataSigned
                        ? "signed" : "unsigned");

                printf("  ePCMMode = %s\n", audioPCMModeString(params.ePCMMode));
                printf("  ePCMMode = %s\n", asString(params.ePCMMode));
            } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) {
                OMX_AUDIO_PARAM_AMRTYPE amr;
                InitOMXParams(&amr);
@@ -4388,9 +4175,9 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {

                printf("  nChannels = %" PRIu32 "\n", amr.nChannels);
                printf("  eAMRBandMode = %s\n",
                        amrBandModeString(amr.eAMRBandMode));
                        asString(amr.eAMRBandMode));
                printf("  eAMRFrameFormat = %s\n",
                        amrFrameFormatString(amr.eAMRFrameFormat));
                        asString(amr.eAMRFrameFormat));
            }

            break;
@@ -4699,12 +4486,7 @@ status_t QueryCodec(
        const char *componentName, const char *mime,
        bool isEncoder,
        CodecCapabilities *caps) {
    if (strncmp(componentName, "OMX.", 4)) {
        // Not an OpenMax component but a software codec.
        caps->mFlags = 0;
        caps->mComponentName = componentName;
        return OK;
    }
    bool isVideo = !strncasecmp(mime, "video/", 6);

    sp<OMXCodecObserver> observer = new OMXCodecObserver;
    IOMX::node_id node;
@@ -4719,6 +4501,8 @@ status_t QueryCodec(
    caps->mFlags = 0;
    caps->mComponentName = componentName;

    // NOTE: OMX does not provide a way to query AAC profile support
    if (isVideo) {
        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
        InitOMXParams(&param);

@@ -4770,8 +4554,9 @@ status_t QueryCodec(
            }
            caps->mColorFormats.push(portFormat.eColorFormat);
        }
    }

    if (!isEncoder && !strncmp(mime, "video/", 6)) {
    if (isVideo && !isEncoder) {
        if (omx->storeMetaDataInBuffers(
                    node, 1 /* port index */, OMX_TRUE) == OK ||
            omx->prepareForAdaptivePlayback(
+117 −0
Original line number Diff line number Diff line
/*
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <errno.h>
#include <stdlib.h>
#include <ctype.h>

#define LOG_TAG "ADebug"
#include <utils/Log.h>
#include <utils/misc.h>

#include <cutils/properties.h>

#include <ADebug.h>
#include <AStringUtils.h>
#include <AUtils.h>

namespace android {

//static
ADebug::Level ADebug::GetDebugLevelFromString(
        const char *name, const char *value, ADebug::Level def) {
    // split on ,
    const char *next = value, *current;
    const unsigned long maxLevel = (unsigned long)kDebugMax;
    while (next != NULL) {
        current = next;
        next = strchr(current, ',');
        if (next != NULL) {
            ++next;  // pass ,
        }

        while (isspace(*current)) {
            ++current;
        }
        // check for :
        char *colon = strchr(current, ':');

        // get level
        char *end;
        errno = 0;  // strtoul does not clear errno, but it can be set for any return value
        unsigned long level = strtoul(current, &end, 10);
        while (isspace(*end)) {
            ++end;
        }
        if (errno != 0 || end == current || (end != colon && *end != '\0' && end != next)) {
            // invalid level - skip
            continue;
        }
        if (colon != NULL) {
            // check if pattern matches
            do {  // skip colon and spaces
                ++colon;
            } while (isspace(*colon));
            size_t globLen = (next == NULL ? strlen(colon) : (next - 1 - colon));
            while (globLen > 0 && isspace(colon[globLen - 1])) {
                --globLen;  // trim glob
            }

            if (!AStringUtils::MatchesGlob(
                    colon, globLen, name, strlen(name), true /* ignoreCase */)) {
                continue;
            }
        }

        // update debug level
        def = (Level)min(level, maxLevel);
    }
    return def;
}

//static
ADebug::Level ADebug::GetDebugLevelFromProperty(
        const char *name, const char *propertyName, ADebug::Level def) {
    char value[PROPERTY_VALUE_MAX];
    if (property_get(propertyName, value, NULL)) {
        return GetDebugLevelFromString(name, value, def);
    }
    return def;
}

//static
char *ADebug::GetDebugName(const char *name) {
    char *debugName = strdup(name);
    const char *terms[] = { "omx", "video", "audio" };
    for (size_t i = 0; i < NELEM(terms) && debugName != NULL; i++) {
        const char *term = terms[i];
        const size_t len = strlen(term);
        char *match = strcasestr(debugName, term);
        if (match != NULL && (match == debugName || match[-1] == '.'
                || match[len] == '.' || match[len] == '\0')) {
            char *src = match + len;
            if (match == debugName || match[-1] == '.') {
                src += (*src == '.');  // remove trailing or double .
            }
            memmove(match, src, debugName + strlen(debugName) - src + 1);
        }
    }

    return debugName;
}

}  // namespace android
+77 −0
Original line number Diff line number Diff line
/*
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <string.h>
#include <AStringUtils.h>

namespace android {

// static
int AStringUtils::Compare(const char *a, const char *b, size_t len, bool ignoreCase) {
    // this method relies on a trailing '\0' if a or b are shorter than len
    return ignoreCase ? strncasecmp(a, b, len) : strncmp(a, b, len);
}

// static
bool AStringUtils::MatchesGlob(
        const char *glob, size_t globLen, const char *str, size_t strLen, bool ignoreCase) {
    // this method does not assume a trailing '\0'
    size_t ix = 0, globIx = 0;

    // pattern must match until first '*'
    while (globIx < globLen && glob[globIx] != '*') {
        ++globIx;
    }
    if (strLen < globIx || Compare(str, glob, globIx /* len */, ignoreCase)) {
        return false;
    }
    ix = globIx;

    // process by * separated sections
    while (globIx < globLen) {
        ++globIx;
        size_t start = globIx;
        while (globIx < globLen && glob[globIx] != '*') {
            ++globIx;
        }
        size_t len = globIx - start;
        const char *pattern = glob + start;

        if (globIx == globLen) {
            // last pattern must match tail
            if (ix + len > strLen) {
                return false;
            }
            const char *tail = str + strLen - len;
            return !Compare(tail, pattern, len, ignoreCase);
        }
        // progress after first occurrence of pattern
        while (ix + len <= strLen && Compare(str + ix, pattern, len, ignoreCase)) {
            ++ix;
        }
        if (ix + len > strLen) {
            return false;
        }
        ix += len;
        // we will loop around as globIx < globLen
    }

    // we only get here if there were no * in the pattern
    return ix == strLen;
}

}  // namespace android
Loading