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

Commit 0c4a97e6 authored by Andy Hung's avatar Andy Hung Committed by Android (Google) Code Review
Browse files

Merge "NuPlayer: Reserve buffer for 8x max speed" into nyc-dev

parents 24f66c69 ff874dc9
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -201,6 +201,10 @@ public:
                           binder to AudioFlinger.
                           It will return an error instead.  The application will recreate
                           the track based on offloading or different channel configuration, etc.
     * maxRequiredSpeed:   For PCM tracks, this creates an appropriate buffer size that will allow
     *                     maxRequiredSpeed playback. Values less than 1.0f and greater than
     *                     AUDIO_TIMESTRETCH_SPEED_MAX will be clamped.  For non-PCM tracks
     *                     and direct or offloaded tracks, this parameter is ignored.
     * threadCanCallJava:  Not present in parameter list, and so is fixed at false.
     */

@@ -219,7 +223,8 @@ public:
                                    int uid = -1,
                                    pid_t pid = -1,
                                    const audio_attributes_t* pAttributes = NULL,
                                    bool doNotReconnect = false);
                                    bool doNotReconnect = false,
                                    float maxRequiredSpeed = 1.0f);

    /* Creates an audio track and registers it with AudioFlinger.
     * With this constructor, the track is configured for static buffer mode.
@@ -248,7 +253,8 @@ public:
                                    int uid = -1,
                                    pid_t pid = -1,
                                    const audio_attributes_t* pAttributes = NULL,
                                    bool doNotReconnect = false);
                                    bool doNotReconnect = false,
                                    float maxRequiredSpeed = 1.0f);

    /* Terminates the AudioTrack and unregisters it from AudioFlinger.
     * Also destroys all resources associated with the AudioTrack.
@@ -293,7 +299,8 @@ public:
                            int uid = -1,
                            pid_t pid = -1,
                            const audio_attributes_t* pAttributes = NULL,
                            bool doNotReconnect = false);
                            bool doNotReconnect = false,
                            float maxRequiredSpeed = 1.0f);

    /* Result of constructing the AudioTrack. This must be checked for successful initialization
     * before using any AudioTrack API (except for set()), because using
@@ -920,6 +927,7 @@ protected:
    mutable uint32_t        mSampleRate;            // mutable because getSampleRate() can update it
    uint32_t                mOriginalSampleRate;
    AudioPlaybackRate       mPlaybackRate;
    float                   mMaxRequiredSpeed;      // use PCM buffer size to allow this speed

    // Corresponds to current IAudioTrack, value is reported back by AudioFlinger to the client.
    // This allocated buffer size is maintained by the proxy.
+23 −7
Original line number Diff line number Diff line
@@ -191,7 +191,8 @@ AudioTrack::AudioTrack(
        int uid,
        pid_t pid,
        const audio_attributes_t* pAttributes,
        bool doNotReconnect)
        bool doNotReconnect,
        float maxRequiredSpeed)
    : mStatus(NO_INIT),
      mState(STATE_STOPPED),
      mPreviousPriority(ANDROID_PRIORITY_NORMAL),
@@ -202,7 +203,7 @@ AudioTrack::AudioTrack(
    mStatus = set(streamType, sampleRate, format, channelMask,
            frameCount, flags, cbf, user, notificationFrames,
            0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType,
            offloadInfo, uid, pid, pAttributes, doNotReconnect);
            offloadInfo, uid, pid, pAttributes, doNotReconnect, maxRequiredSpeed);
}

AudioTrack::AudioTrack(
@@ -221,7 +222,8 @@ AudioTrack::AudioTrack(
        int uid,
        pid_t pid,
        const audio_attributes_t* pAttributes,
        bool doNotReconnect)
        bool doNotReconnect,
        float maxRequiredSpeed)
    : mStatus(NO_INIT),
      mState(STATE_STOPPED),
      mPreviousPriority(ANDROID_PRIORITY_NORMAL),
@@ -232,7 +234,7 @@ AudioTrack::AudioTrack(
    mStatus = set(streamType, sampleRate, format, channelMask,
            0 /*frameCount*/, flags, cbf, user, notificationFrames,
            sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo,
            uid, pid, pAttributes, doNotReconnect);
            uid, pid, pAttributes, doNotReconnect, maxRequiredSpeed);
}

AudioTrack::~AudioTrack()
@@ -281,7 +283,8 @@ status_t AudioTrack::set(
        int uid,
        pid_t pid,
        const audio_attributes_t* pAttributes,
        bool doNotReconnect)
        bool doNotReconnect,
        float maxRequiredSpeed)
{
    ALOGV("set(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
          "flags #%x, notificationFrames %u, sessionId %d, transferType %d, uid %d, pid %d",
@@ -422,6 +425,8 @@ status_t AudioTrack::set(
    mSampleRate = sampleRate;
    mOriginalSampleRate = sampleRate;
    mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
    // 1.0 <= mMaxRequiredSpeed <= AUDIO_TIMESTRETCH_SPEED_MAX
    mMaxRequiredSpeed = min(max(maxRequiredSpeed, 1.0f), AUDIO_TIMESTRETCH_SPEED_MAX);

    // Make copy of input parameter offloadInfo so that in the future:
    //  (a) createTrack_l doesn't need it as an input parameter
@@ -824,6 +829,9 @@ status_t AudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate)
    if (mFlags & AUDIO_OUTPUT_FLAG_FAST) {
        return INVALID_OPERATION;
    }

    ALOGV("setPlaybackRate (input): mSampleRate:%u  mSpeed:%f  mPitch:%f",
            mSampleRate, playbackRate.mSpeed, playbackRate.mPitch);
    // pitch is emulated by adjusting speed and sampleRate
    const uint32_t effectiveRate = adjustSampleRate(mSampleRate, playbackRate.mPitch);
    const float effectiveSpeed = adjustSpeed(playbackRate.mSpeed, playbackRate.mPitch);
@@ -832,12 +840,18 @@ status_t AudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate)
    playbackRateTemp.mSpeed = effectiveSpeed;
    playbackRateTemp.mPitch = effectivePitch;

    ALOGV("setPlaybackRate (effective): mSampleRate:%u  mSpeed:%f  mPitch:%f",
            effectiveRate, effectiveSpeed, effectivePitch);

    if (!isAudioPlaybackRateValid(playbackRateTemp)) {
        ALOGV("setPlaybackRate(%f, %f) failed (effective rate out of bounds)",
                playbackRate.mSpeed, playbackRate.mPitch);
        return BAD_VALUE;
    }
    // Check if the buffer size is compatible.
    if (!isSampleRateSpeedAllowed_l(effectiveRate, effectiveSpeed)) {
        ALOGV("setPlaybackRate(%f, %f) failed", playbackRate.mSpeed, playbackRate.mPitch);
        ALOGV("setPlaybackRate(%f, %f) failed (buffer size)",
                playbackRate.mSpeed, playbackRate.mPitch);
        return BAD_VALUE;
    }

@@ -1293,9 +1307,11 @@ status_t AudioTrack::createTrack_l()

        if ((mFlags & AUDIO_OUTPUT_FLAG_FAST) == 0) {
            // for normal tracks precompute the frame count based on speed.
            const float speed = !isPurePcmData_l() || isOffloadedOrDirect_l() ? 1.0f :
                            max(mMaxRequiredSpeed, mPlaybackRate.mSpeed);
            const size_t minFrameCount = calculateMinFrameCount(
                    mAfLatency, mAfFrameCount, mAfSampleRate, mSampleRate,
                    mPlaybackRate.mSpeed);
                    speed);
            if (frameCount < minFrameCount) {
                frameCount = minFrameCount;
            }
+12 −1
Original line number Diff line number Diff line
@@ -94,6 +94,8 @@ using android::Parcel;
// Max number of entries in the filter.
const int kMaxFilterSize = 64;  // I pulled that out of thin air.

const float kMaxRequiredSpeed = 8.0f; // for PCM tracks allow up to 8x speedup.

// FIXME: Move all the metadata related function in the Metadata.cpp


@@ -1749,6 +1751,14 @@ status_t MediaPlayerService::AudioOutput::open(
                    mAttributes,
                    doNotReconnect);
        } else {
            // TODO: Due to buffer memory concerns, we use a max target playback speed
            // based on mPlaybackRate at the time of open (instead of kMaxRequiredSpeed),
            // also clamping the target speed to 1.0 <= targetSpeed <= kMaxRequiredSpeed.
            const float targetSpeed =
                    std::min(std::max(mPlaybackRate.mSpeed, 1.0f), kMaxRequiredSpeed);
            ALOGW_IF(targetSpeed != mPlaybackRate.mSpeed,
                    "track target speed:%f clamped from playback speed:%f",
                    targetSpeed, mPlaybackRate.mSpeed);
            t = new AudioTrack(
                    mStreamType,
                    sampleRate,
@@ -1765,7 +1775,8 @@ status_t MediaPlayerService::AudioOutput::open(
                    mUid,
                    mPid,
                    mAttributes,
                    doNotReconnect);
                    doNotReconnect,
                    targetSpeed);
        }

        if ((t == 0) || (t->initCheck() != NO_ERROR)) {
+4 −3
Original line number Diff line number Diff line
@@ -1883,6 +1883,10 @@ status_t NuPlayer::Renderer::onOpenAudioSink(
        // NuPlayer a chance to switch from non-offload mode to offload mode.
        // So we only set doNotReconnect when there's no video.
        const bool doNotReconnect = !hasVideo;

        // We should always be able to set our playback settings if the sink is closed.
        LOG_ALWAYS_FATAL_IF(mAudioSink->setPlaybackRate(mPlaybackSettings) != OK,
                "onOpenAudioSink: can't set playback rate on closed sink");
        status_t err = mAudioSink->open(
                    sampleRate,
                    numChannels,
@@ -1895,9 +1899,6 @@ status_t NuPlayer::Renderer::onOpenAudioSink(
                    NULL,
                    doNotReconnect,
                    frameCount);
        if (err == OK) {
            err = mAudioSink->setPlaybackRate(mPlaybackSettings);
        }
        if (err != OK) {
            ALOGW("openAudioSink: non offloaded open failed status: %d", err);
            mAudioSink->close();