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

Commit fdb3c07d authored by Phil Burk's avatar Phil Burk
Browse files

AudioTrack: support ENCODING_IEC61937



Set DIRECT flag.
Use audio_has_proportional_frames() instead of audio_is_linear_pcm()
where appropriate.

Bug: 24541671
Bug: 20891646
Bug: 26373761
Change-Id: Ia32036b18683b084d6c9887593df87397ea0afd9
Signed-off-by: default avatarPhil Burk <philburk@google.com>
parent 3ea4f828
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -363,6 +363,8 @@ status_t AudioTrack::set(
    // these below should probably come from the audioFlinger too...
    if (format == AUDIO_FORMAT_DEFAULT) {
        format = AUDIO_FORMAT_PCM_16_BIT;
    } else if (format == AUDIO_FORMAT_IEC61937) { // HDMI pass-through?
        mAttributes.flags |= AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO;
    }

    // validate parameters
@@ -398,13 +400,13 @@ status_t AudioTrack::set(
    }

    if (flags & AUDIO_OUTPUT_FLAG_DIRECT) {
        if (audio_is_linear_pcm(format)) {
        if (audio_has_proportional_frames(format)) {
            mFrameSize = channelCount * audio_bytes_per_sample(format);
        } else {
            mFrameSize = sizeof(uint8_t);
        }
    } else {
        ALOG_ASSERT(audio_is_linear_pcm(format));
        ALOG_ASSERT(audio_has_proportional_frames(format));
        mFrameSize = channelCount * audio_bytes_per_sample(format);
        // createTrack will return an error if PCM format is not supported by server,
        // so no need to check for specific PCM formats here
@@ -1221,7 +1223,7 @@ status_t AudioTrack::createTrack_l()
    mNotificationFramesAct = mNotificationFramesReq;

    size_t frameCount = mReqFrameCount;
    if (!audio_is_linear_pcm(mFormat)) {
    if (!audio_has_proportional_frames(mFormat)) {

        if (mSharedBuffer != 0) {
            // Same comment as below about ignoring frameCount parameter for set()
@@ -1944,7 +1946,7 @@ nsecs_t AudioTrack::processAudioBuffer()
            return NS_NEVER;
        }

        if (mRetryOnPartialBuffer && audio_is_linear_pcm(mFormat)) {
        if (mRetryOnPartialBuffer && audio_has_proportional_frames(mFormat)) {
            mRetryOnPartialBuffer = false;
            if (avail < mRemainingFrames) {
                if (ns > 0) { // account for obtain time
@@ -1990,7 +1992,7 @@ nsecs_t AudioTrack::processAudioBuffer()
            // buffer size and skip the loop entirely.

            nsecs_t myns;
            if (audio_is_linear_pcm(mFormat)) {
            if (audio_has_proportional_frames(mFormat)) {
                // time to wait based on buffer occupancy
                const nsecs_t datans = mRemainingFrames <= avail ? 0 :
                        framesToNanoseconds(mRemainingFrames - avail, sampleRate, speed);
+3 −2
Original line number Diff line number Diff line
@@ -107,7 +107,7 @@ static const nsecs_t kMinGlobalEffectEnabletimeNs = seconds(7200);
// ----------------------------------------------------------------------------

const char *formatToString(audio_format_t format) {
    switch (format & AUDIO_FORMAT_MAIN_MASK) {
    switch (audio_get_main_format(format)) {
    case AUDIO_FORMAT_PCM:
        switch (format) {
        case AUDIO_FORMAT_PCM_16_BIT: return "pcm16";
@@ -130,6 +130,7 @@ const char *formatToString(audio_format_t format) {
    case AUDIO_FORMAT_OPUS: return "opus";
    case AUDIO_FORMAT_AC3: return "ac-3";
    case AUDIO_FORMAT_E_AC3: return "e-ac-3";
    case AUDIO_FORMAT_IEC61937: return "iec61937";
    default:
        break;
    }
@@ -1162,7 +1163,7 @@ size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t form
        return 0;
    }
    if ((sampleRate == 0) ||
            !audio_is_valid_format(format) || !audio_is_linear_pcm(format) ||
            !audio_is_valid_format(format) || !audio_has_proportional_frames(format) ||
            !audio_is_input_channel(channelMask)) {
        return 0;
    }
+1 −1
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ status_t AudioHwDevice::openOutputStream(
            status);

        // If the data is encoded then try again using wrapped PCM.
        bool wrapperNeeded = !audio_is_linear_pcm(originalConfig.format)
        bool wrapperNeeded = !audio_has_proportional_frames(originalConfig.format)
                && ((flags & AUDIO_OUTPUT_FLAG_DIRECT) != 0)
                && ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0);

+28 −7
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ AudioStreamOut::AudioStreamOut(AudioHwDevice *dev, audio_output_flags_t flags)
        , mFramesWrittenAtStandby(0)
        , mRenderPosition(0)
        , mRateMultiplier(1)
        , mHalFormatIsLinearPcm(false)
        , mHalFormatHasProportionalFrames(false)
        , mHalFrameSize(0)
{
}
@@ -96,7 +96,7 @@ status_t AudioStreamOut::getPresentationPosition(uint64_t *frames, struct timesp

    // Adjust for standby using HAL rate frames.
    // Only apply this correction if the HAL is getting PCM frames.
    if (mHalFormatIsLinearPcm) {
    if (mHalFormatHasProportionalFrames) {
        uint64_t adjustedPosition = (halPosition <= mFramesWrittenAtStandby) ?
                0 : (halPosition - mFramesWrittenAtStandby);
        // Scale from HAL sample rate to application rate.
@@ -116,16 +116,21 @@ status_t AudioStreamOut::open(
        const char *address)
{
    audio_stream_out_t *outStream;

    audio_output_flags_t customFlags = (config->format == AUDIO_FORMAT_IEC61937)
                ? (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)
                : flags;

    int status = hwDev()->open_output_stream(
            hwDev(),
            handle,
            devices,
            flags,
            customFlags,
            config,
            &outStream,
            address);
    ALOGV("AudioStreamOut::open(), HAL open_output_stream returned "
            " %p, sampleRate %d, Format %#x, "
    ALOGV("AudioStreamOut::open(), HAL returned "
            " stream %p, sampleRate %d, Format %#x, "
            "channelMask %#x, status %d",
            outStream,
            config->sample_rate,
@@ -133,10 +138,26 @@ status_t AudioStreamOut::open(
            config->channel_mask,
            status);

    // Some HALs may not recognize AUDIO_FORMAT_IEC61937. But if we declare
    // it as PCM then it will probably work.
    if (status != NO_ERROR && config->format == AUDIO_FORMAT_IEC61937) {
        struct audio_config customConfig = *config;
        customConfig.format = AUDIO_FORMAT_PCM_16_BIT;

        status = hwDev()->open_output_stream(
                hwDev(),
                handle,
                devices,
                customFlags,
                &customConfig,
                &outStream,
                address);
        ALOGV("AudioStreamOut::open(), treat IEC61937 as PCM, status = %d", status);
    }

    if (status == NO_ERROR) {
        stream = outStream;
        mHalFormatIsLinearPcm = audio_is_linear_pcm(config->format);
        ALOGI("AudioStreamOut::open(), mHalFormatIsLinearPcm = %d", (int)mHalFormatIsLinearPcm);
        mHalFormatHasProportionalFrames = audio_has_proportional_frames(config->format);
        mHalFrameSize = audio_stream_out_frame_size(stream);
    }

+1 −1
Original line number Diff line number Diff line
@@ -106,7 +106,7 @@ protected:
    uint64_t             mFramesWrittenAtStandby;
    uint64_t             mRenderPosition; // reset by flush or standby
    int                  mRateMultiplier;
    bool                 mHalFormatIsLinearPcm;
    bool                 mHalFormatHasProportionalFrames;
    size_t               mHalFrameSize;
};

Loading