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

Commit ac14ed7b authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Speed up SniffMidi() by parsing the initial bytes of the header" into main am: 92949994

parents c88b5bce 92949994
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -73,3 +73,21 @@ cc_defaults {
        ],
    },
}

aconfig_declarations {
    name: "android.media.extractor.flags-aconfig",
    package: "com.android.media.extractor.flags",
    container: "com.android.media",
    srcs: ["extractor.aconfig"],
}

cc_aconfig_library {
    name: "android.media.extractor.flags-aconfig-cc",
    aconfig_declarations: "android.media.extractor.flags-aconfig",
    host_supported: true,
    min_sdk_version: "29",
    apex_available: [
        "//apex_available:platform",
        "com.android.media",
    ],
}
+13 −0
Original line number Diff line number Diff line
# Media Extractor flags.
#
# !!! Please add flags in alphabetical order. !!!
package: "com.android.media.extractor.flags"
container: "com.android.media"

flag {
    name: "extractor_sniff_midi_optimizations"
    is_exported: true
    namespace: "media_extractor"
    description: "Enable SniffMidi optimizations."
    bug: "359920208"
}
+7 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ package {
    // to get the below license kinds:
    //   SPDX-license-identifier-Apache-2.0
    default_applicable_licenses: ["frameworks_av_license"],
    default_team: "trendy_team_android_media_solutions_playback",
}

cc_defaults {
@@ -302,12 +303,18 @@ cc_fuzz {
    ],

    static_libs: [
        "android.media.extractor.flags-aconfig-cc",
        "libaconfig_storage_read_api_cc",
        "libsonivox",
        "libmedia_midiiowrapper",
        "libmidiextractor",
        "libwatchdog",
    ],

    shared_libs: [
        "server_configurable_flags",
    ],

    dictionary: "midi_extractor_fuzzer.dict",

    host_supported: true,
+3 −0
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@ cc_library {
    ],

    static_libs: [
        "android.media.extractor.flags-aconfig-cc",
        "libaconfig_storage_read_api_cc",
        "libmedia_midiiowrapper",
        "libsonivoxwithoutjet",
        "libstagefright_foundation",
@@ -40,6 +42,7 @@ cc_library {

    shared_libs: [
        "libbase",
        "server_configurable_flags",
    ],

    host_supported: true,
+131 −3
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@

#include "MidiExtractor.h"

#include <com_android_media_extractor_flags.h>
#include <media/MidiIoWrapper.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaBufferGroup.h>
@@ -323,10 +324,97 @@ media_status_t MidiExtractor::getMetaData(AMediaFormat *meta)
    return AMediaFormat_copy(meta, mFileMetadata);
}

// Sniffer
static bool startsWith(const uint8_t *buf, size_t size, const char *pattern, size_t patternSize) {
    if (size < patternSize) {
        return false;
    }
    return (memcmp(buf, pattern, patternSize) == 0);
}

bool SniffMidi(CDataSource *source, float *confidence)
{
static bool isValidMThd(const uint8_t *buf, size_t size) {
    return startsWith(buf, size, "MThd", 4);
}

static bool isValidXmf(const uint8_t *buf, size_t size) {
    return startsWith(buf, size, "XMF_", 4);
}

static bool isValidImelody(const uint8_t *buf, size_t size) {
    return startsWith(buf, size, "BEGIN:IMELODY", 13);
}

static bool isValidRtttl(const uint8_t *buf, size_t size) {
    #define RTTTL_MAX_TITLE_LEN 32
    // rtttl starts with the following:
    // <title>:<type>=<value>
    //
    // Where:
    // - <title>: Up to 32 characters
    // - <type>: Single character indicating:
    //     'd' for duration
    //     'o' for octave
    //     'b' for beats per minute
    // - <value>: Corresponding value for the type
    if (size < 4) {
        return false;
    }
    for (size_t i = 0; i < RTTTL_MAX_TITLE_LEN && i < size; i++) {
        if (buf[i] == ':') {
            if (i < (size - 3) && buf[i + 2] == '=') {
                return true;
            }
            break;
        }
    }
    return false;
}

static bool isValidOta(const uint8_t *buf, size_t size) {
    #define OTA_RINGTONE 0x25
    #define OTA_SOUND 0x1d
    #define OTA_UNICODE 0x22

    // ota starts with the following:
    // <cmdLen><cmd1><cmd2>..<cmdN>
    //
    // Where:
    // - <cmdLen>: Single character command length
    // - <cmd1>: Single character (OTA_RINGTONE << 1)
    // - <cmd2>: Single character (OTA_SOUND << 1) or (OTA_UNICODE << 1)
    //           and so on with last cmd being (0x1d << 1)

    if (size < 3) {
        return false;
    }

    uint8_t cmdLen = buf[0];
    if (cmdLen < 2) {
        return false;
    }

    if ((buf[1] >> 1) != OTA_RINGTONE) {
        return false;
    }
    cmdLen--;

    size_t i = 2;
    while(cmdLen && i < size) {
        switch(buf[i] >> 1) {
            case OTA_SOUND:
                return true;
            case OTA_UNICODE:
                break;
            default:
                return false;
        }
        cmdLen--;
        i++;
    }

    return false;
}

bool SniffMidiLegacy(CDataSource *source, float *confidence) {
    MidiEngine p(source, NULL, NULL);
    if (p.initCheck() == OK) {
        *confidence = 0.8;
@@ -335,7 +423,47 @@ bool SniffMidi(CDataSource *source, float *confidence)
    }
    ALOGV("SniffMidi: no");
    return false;
}

bool SniffMidiEfficiently(CDataSource *source, float *confidence) {
    uint8_t header[128];
    int filled = source->readAt(source->handle, 0, header, sizeof(header));

    if (isValidMThd(header, filled)) {
        *confidence = 0.80;
        ALOGV("SniffMidi: yes, MThd");
        return true;
    }
    if (isValidXmf(header, filled)) {
        *confidence = 0.80;
        ALOGV("SniffMidi: yes, XMF_");
        return true;
    }
    if (isValidImelody(header, filled)) {
        *confidence = 0.80;
        ALOGV("SniffMidi: yes, imelody");
        return true;
    }
    if (isValidRtttl(header, filled)) {
        *confidence = 0.80;
        ALOGV("SniffMidi: yes, rtttl");
        return true;
    }
    if (isValidOta(header, filled)) {
        *confidence = 0.80;
        ALOGV("SniffMidi: yes, ota");
        return true;
    }
    ALOGV("SniffMidi: no");
    return false;
}

// Sniffer
bool SniffMidi(CDataSource *source, float *confidence) {
    if(com::android::media::extractor::flags::extractor_sniff_midi_optimizations()) {
        return SniffMidiEfficiently(source, confidence);
    }
    return SniffMidiLegacy(source, confidence);
}

static const char *extensions[] = {