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

Commit dc2c50ba authored by Glenn Kasten's avatar Glenn Kasten
Browse files

Make max fast tracks configurable using a property

ro.audio.max_fast_tracks

Rename the currently configured maximum number of fast tracks
from FastMixerState::kMaxFastTracks to FastMixerState::sMaxFastTracks.

There is no guarantee that the CPU will be able to handle
the configured number of fast tracks.

Bug: 27564141
Change-Id: If9af226d839b226503488c3cb20a4bb8950b429d
parent ecd0a41d
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ FastMixer::FastMixer() : FastThread(),
    mSinkChannelMask = audio_channel_out_mask_from_count(mSinkChannelCount);

    unsigned i;
    for (i = 0; i < FastMixerState::kMaxFastTracks; ++i) {
    for (i = 0; i < FastMixerState::sMaxFastTracks; ++i) {
        mFastTrackNames[i] = -1;
        mGenerations[i] = 0;
    }
@@ -187,7 +187,7 @@ void FastMixer::onStateChange()
            // FIXME new may block for unbounded time at internal mutex of the heap
            //       implementation; it would be better to have normal mixer allocate for us
            //       to avoid blocking here and to prevent possible priority inversion
            mMixer = new AudioMixer(frameCount, mSampleRate, FastMixerState::kMaxFastTracks);
            mMixer = new AudioMixer(frameCount, mSampleRate, FastMixerState::sMaxFastTracks);
            const size_t mixerFrameSize = mSinkChannelCount
                    * audio_bytes_per_sample(mMixerBufferFormat);
            mMixerBufferSize = mixerFrameSize * frameCount;
@@ -214,7 +214,7 @@ void FastMixer::onStateChange()
        }
        mMixerBufferState = UNDEFINED;
#if !LOG_NDEBUG
        for (unsigned i = 0; i < FastMixerState::kMaxFastTracks; ++i) {
        for (unsigned i = 0; i < FastMixerState::sMaxFastTracks; ++i) {
            mFastTrackNames[i] = -1;
        }
#endif
+3 −3
Original line number Diff line number Diff line
@@ -166,10 +166,10 @@ void FastMixerDumpState::dump(int fd) const
    // Instead we always display all tracks, with an indication
    // of whether we think the track is active.
    uint32_t trackMask = mTrackMask;
    dprintf(fd, "  Fast tracks: kMaxFastTracks=%u activeMask=%#x\n",
            FastMixerState::kMaxFastTracks, trackMask);
    dprintf(fd, "  Fast tracks: sMaxFastTracks=%u activeMask=%#x\n",
            FastMixerState::sMaxFastTracks, trackMask);
    dprintf(fd, "  Index Active Full Partial Empty  Recent Ready\n");
    for (uint32_t i = 0; i < FastMixerState::kMaxFastTracks; ++i, trackMask >>= 1) {
    for (uint32_t i = 0; i < FastMixerState::sMaxFastTracks; ++i, trackMask >>= 1) {
        bool isActive = trackMask & 1;
        const FastTrackDump *ftDump = &mTracks[i];
        const FastTrackUnderruns& underruns = ftDump->mUnderruns;
+25 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
 * limitations under the License.
 */

#include <cutils/properties.h>
#include "FastMixerState.h"

namespace android {
@@ -33,12 +34,22 @@ FastMixerState::FastMixerState() : FastThreadState(),
    mFastTracksGen(0), mTrackMask(0), mOutputSink(NULL), mOutputSinkGen(0),
    mFrameCount(0), mTeeSink(NULL)
{
    int ok = pthread_once(&sMaxFastTracksOnce, sMaxFastTracksInit);
    if (ok != 0) {
        ALOGE("%s pthread_once failed: %d", __func__, ok);
    }
}

FastMixerState::~FastMixerState()
{
}

// static
unsigned FastMixerState::sMaxFastTracks = kDefaultFastTracks;

// static
pthread_once_t FastMixerState::sMaxFastTracksOnce = PTHREAD_ONCE_INIT;

// static
const char *FastMixerState::commandToString(Command command)
{
@@ -54,4 +65,18 @@ const char *FastMixerState::commandToString(Command command)
    LOG_ALWAYS_FATAL("%s", __func__);
}

// static
void FastMixerState::sMaxFastTracksInit()
{
    char value[PROPERTY_VALUE_MAX];
    if (property_get("ro.audio.max_fast_tracks", value, NULL) > 0) {
        char *endptr;
        unsigned long ul = strtoul(value, &endptr, 0);
        if (*endptr == '\0' && kMinFastTracks <= ul && ul <= kMaxFastTracks) {
            sMaxFastTracks = (unsigned) ul;
        }
    }
    ALOGI("sMaxFastTracks = %u", sMaxFastTracks);
}

}   // namespace android
+11 −1
Original line number Diff line number Diff line
@@ -54,7 +54,13 @@ struct FastMixerState : FastThreadState {
                FastMixerState();
    /*virtual*/ ~FastMixerState();

    static const unsigned kMaxFastTracks = 8;   // must be between 2 and 32 inclusive
    // These are the minimum, maximum, and default values for maximum number of fast tracks
    static const unsigned kMinFastTracks = 2;
    static const unsigned kMaxFastTracks = 32;
    static const unsigned kDefaultFastTracks = 8;

    static unsigned sMaxFastTracks;             // Configured maximum number of fast tracks
    static pthread_once_t sMaxFastTracksOnce;   // Protects initializer for sMaxFastTracks

    // all pointer fields use raw pointers; objects are owned and ref-counted by the normal mixer
    FastTrack   mFastTracks[kMaxFastTracks];
@@ -76,6 +82,10 @@ struct FastMixerState : FastThreadState {

    // never returns NULL; asserts if command is invalid
    static const char *commandToString(Command command);

    // initialize sMaxFastTracks
    static void sMaxFastTracksInit();

};  // struct FastMixerState

}   // namespace android
+3 −3
Original line number Diff line number Diff line
@@ -1602,7 +1602,7 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge
        mSignalPending(false),
        mScreenState(AudioFlinger::mScreenState),
        // index 0 is reserved for normal mixer's submix
        mFastTrackAvailMask(((1 << FastMixerState::kMaxFastTracks) - 1) & ~1),
        mFastTrackAvailMask(((1 << FastMixerState::sMaxFastTracks) - 1) & ~1),
        mHwSupportsPause(false), mHwPaused(false), mFlushPending(false)
{
    snprintf(mThreadName, kThreadNameLength, "AudioOut_%X", id);
@@ -2103,7 +2103,7 @@ void AudioFlinger::PlaybackThread::removeTrack_l(const sp<Track>& track)
    track->mName = -1;
    if (track->isFastTrack()) {
        int index = track->mFastIndex;
        ALOG_ASSERT(0 < index && index < (int)FastMixerState::kMaxFastTracks);
        ALOG_ASSERT(0 < index && index < (int)FastMixerState::sMaxFastTracks);
        ALOG_ASSERT(!(mFastTrackAvailMask & (1 << index)));
        mFastTrackAvailMask |= 1 << index;
        // redundant as track is about to be destroyed, for dumpsys only
@@ -3859,7 +3859,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
            // at the identical fast mixer slot within the same normal mix cycle,
            // is impossible because the slot isn't marked available until the end of each cycle.
            int j = track->mFastIndex;
            ALOG_ASSERT(0 < j && j < (int)FastMixerState::kMaxFastTracks);
            ALOG_ASSERT(0 < j && j < (int)FastMixerState::sMaxFastTracks);
            ALOG_ASSERT(!(mFastTrackAvailMask & (1 << j)));
            FastTrack *fastTrack = &state->mFastTracks[j];

Loading