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

Commit 179652ee authored by Andy Hung's avatar Andy Hung
Browse files

NuPlayer: Add audio sink buffer configuration

Property media.stagefright.audio.sink (in milliseconds)
Also change the default buffer size for PCM playback to 500 ms.

Bug: 21198655
Change-Id: I5781288f59bf08fbecd9263a26c919570b58be0f
parent a7f03353
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -114,7 +114,8 @@ public:
                void *cookie = NULL,
                audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
                const audio_offload_info_t *offloadInfo = NULL,
                bool doNotReconnect = false) = 0;
                bool doNotReconnect = false,
                uint32_t suggestedFrameCount = 0) = 0;

        virtual status_t    start() = 0;

+23 −13
Original line number Diff line number Diff line
@@ -1482,20 +1482,11 @@ status_t MediaPlayerService::AudioOutput::open(
        AudioCallback cb, void *cookie,
        audio_output_flags_t flags,
        const audio_offload_info_t *offloadInfo,
        bool doNotReconnect)
        bool doNotReconnect,
        uint32_t suggestedFrameCount)
{
    mCallback = cb;
    mCallbackCookie = cookie;

    // Check argument "bufferCount" against the mininum buffer count
    if (bufferCount < mMinBufferCount) {
        ALOGD("bufferCount (%d) is too small and increased to %d", bufferCount, mMinBufferCount);
        bufferCount = mMinBufferCount;

    }
    ALOGV("open(%u, %d, 0x%x, 0x%x, %d, %d 0x%x)", sampleRate, channelCount, channelMask,
                format, bufferCount, mSessionId, flags);
    size_t frameCount;

    // offloading is only supported in callback mode for now.
    // offloadInfo must be present if offload flag is set
@@ -1504,20 +1495,36 @@ status_t MediaPlayerService::AudioOutput::open(
        return BAD_VALUE;
    }

    // compute frame count for the AudioTrack internal buffer
    size_t frameCount;
    if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
        frameCount = 0; // AudioTrack will get frame count from AudioFlinger
    } else {
        // try to estimate the buffer processing fetch size from AudioFlinger.
        // framesPerBuffer is approximate and generally correct, except when it's not :-).
        uint32_t afSampleRate;
        size_t afFrameCount;

        if (AudioSystem::getOutputFrameCount(&afFrameCount, mStreamType) != NO_ERROR) {
            return NO_INIT;
        }
        if (AudioSystem::getOutputSamplingRate(&afSampleRate, mStreamType) != NO_ERROR) {
            return NO_INIT;
        }
        const size_t framesPerBuffer =
                (unsigned long long)sampleRate * afFrameCount / afSampleRate;

        frameCount = (sampleRate*afFrameCount*bufferCount)/afSampleRate;
        if (bufferCount == 0) {
            // use suggestedFrameCount
            bufferCount = (suggestedFrameCount + framesPerBuffer - 1) / framesPerBuffer;
        }
        // Check argument bufferCount against the mininum buffer count
        if (bufferCount != 0 && bufferCount < mMinBufferCount) {
            ALOGV("bufferCount (%d) increased to %d", bufferCount, mMinBufferCount);
            bufferCount = mMinBufferCount;
        }
        // if frameCount is 0, then AudioTrack will get frame count from AudioFlinger
        // which will be the minimum size permitted.
        frameCount = bufferCount * framesPerBuffer;
    }

    if (channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER) {
@@ -1528,6 +1535,9 @@ status_t MediaPlayerService::AudioOutput::open(
        }
    }

    mCallback = cb;
    mCallbackCookie = cookie;

    // Check whether we can recycle the track
    bool reuse = false;
    bool bothOffloaded = false;
+2 −1
Original line number Diff line number Diff line
@@ -98,7 +98,8 @@ class MediaPlayerService : public BnMediaPlayerService
                AudioCallback cb, void *cookie,
                audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
                const audio_offload_info_t *offloadInfo = NULL,
                bool doNotReconnect = false);
                bool doNotReconnect = false,
                uint32_t suggestedFrameCount = 0);

        virtual status_t        start();
        virtual ssize_t         write(const void* buffer, size_t size, bool blocking = true);
+18 −3
Original line number Diff line number Diff line
@@ -48,6 +48,9 @@ namespace android {
   #Use audio callbacks for PCM data
   adb shell setprop media.stagefright.audio.cbk 1

   #Set size of buffers for pcm audio sink in msec (example: 1000 msec)
   adb shell setprop media.stagefright.audio.sink 1000

 * These configurations take effect for the next track played (not the current track).
 */

@@ -55,6 +58,11 @@ static inline bool getUseAudioCallbackSetting() {
    return property_get_bool("media.stagefright.audio.cbk", false /* default_value */);
}

static inline int32_t getAudioSinkPcmMsSetting() {
    return property_get_int32(
            "media.stagefright.audio.sink", 500 /* default_value */);
}

// Maximum time in paused state when offloading audio decompression. When elapsed, the AudioSink
// is closed to allow the audio DSP to power down.
static const int64_t kOffloadPauseMaxUs = 10000000ll;
@@ -1636,7 +1644,7 @@ status_t NuPlayer::Renderer::onOpenAudioSink(
                    numChannels,
                    (audio_channel_mask_t)channelMask,
                    audioFormat,
                    8 /* bufferCount */,
                    0 /* bufferCount - unused */,
                    &NuPlayer::Renderer::AudioSinkCallback,
                    this,
                    (audio_output_flags_t)offloadFlags,
@@ -1691,17 +1699,24 @@ status_t NuPlayer::Renderer::onOpenAudioSink(
        // Note: It is possible to set up the callback, but not use it to send audio data.
        // This requires a fix in AudioSink to explicitly specify the transfer mode.
        mUseAudioCallback = getUseAudioCallbackSetting();

        // Compute the desired buffer size.
        // For callback mode, the amount of time before wakeup is about half the buffer size.
        const uint32_t frameCount =
                (unsigned long long)sampleRate * getAudioSinkPcmMsSetting() / 1000;

        status_t err = mAudioSink->open(
                    sampleRate,
                    numChannels,
                    (audio_channel_mask_t)channelMask,
                    AUDIO_FORMAT_PCM_16_BIT,
                    8 /* bufferCount */,
                    0 /* bufferCount - unused */,
                    mUseAudioCallback ? &NuPlayer::Renderer::AudioSinkCallback : NULL,
                    mUseAudioCallback ? this : NULL,
                    (audio_output_flags_t)pcmFlags,
                    NULL,
                    true /* doNotReconnect */);
                    true /* doNotReconnect */,
                    frameCount);
        if (err == OK) {
            err = mAudioSink->setPlaybackRate(mPlaybackSettings);
        }