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

Commit b6838ad8 authored by Xin Li's avatar Xin Li Committed by Gerrit Code Review
Browse files

Merge "Merge Android 12 QPR1"

parents 98fc7f6f 86c55d53
Loading
Loading
Loading
Loading
+83 −0
Original line number Diff line number Diff line
@@ -53,6 +53,83 @@ namespace android {
//EL_FIXME 20 seconds may not be enough and must be reconciled with new obtainBuffer implementation
#define MAX_RUN_OFFLOADED_TIMEOUT_MS 20000 // assuming up to a maximum of 20 seconds of offloaded

// for audio_track_cblk_t::mState, to match TrackBase.h
static inline constexpr int CBLK_STATE_IDLE = 0;
static inline constexpr int CBLK_STATE_PAUSING = 7;

/**
 * MirroredVariable is a local variable which simultaneously updates
 * a mirrored storage location.  This is useful for server side variables
 * where a local copy is kept, but a client visible copy is offered through shared memory.
 *
 * We use std::atomic as the default container class to access this memory.
 */
template <typename T, template <typename> class Container = std::atomic>
class MirroredVariable {
    template <typename C>
    struct Constraints {
        // If setMirror is used with a different type U != T passed in,
        // as a general rule, the Container must issue a memcpy to read or write
        // (or its equivalent) to avoid possible strict aliasing issues.
        // The memcpy also avoids gaps in structs and alignment issues with different types.
        static constexpr bool ok_ = false;  // Containers must specify constraints.
    };
    template <typename X>
    struct Constraints<std::atomic<X>> {
        // Atomics force read and write to memory.
        static constexpr bool ok = std::is_same_v<X, T> ||
                (std::atomic<X>::is_always_lock_free                   // no additional locking
                && sizeof(std::atomic<X>) == sizeof(X)                 // layout identical to X.
                && (std::is_arithmetic_v<X> || std::is_enum_v<X>));    // No gaps in the layout.
    };

static_assert(Constraints<Container<T>>::ok);
public:
    explicit MirroredVariable(const T& t) : t_{t} {}

    // implicit conversion operator
    operator T() const {
        return t_;
    }

    MirroredVariable& operator=(const T& t) {
        t_ = t;
        if (mirror_ != nullptr) {
            *mirror_ = t;
        }
        return *this;
    }

    template <typename U>
    void setMirror(Container<U> *other_mirror) {
        // Much of the concern is with T != U, however there are additional concerns
        // when storage uses shared memory between processes.  For atomics, it must be
        // lock free.
        static_assert(sizeof(U) == sizeof(T));
        static_assert(alignof(U) == alignof(T));
        static_assert(Constraints<Container<U>>::ok);
        static_assert(sizeof(Container<U>) == sizeof(Container<T>));
        static_assert(alignof(Container<U>) == alignof(Container<T>));
        auto mirror = reinterpret_cast<Container<T>*>(other_mirror);
        if (mirror_ != mirror) {
            mirror_ = mirror;
            if (mirror != nullptr) {
                *mirror = t_;
            }
        }
    }

    void clear() {
        mirror_ = nullptr;
    }

    MirroredVariable& operator&() const = delete;

protected:
    T t_{};
    Container<T>* mirror_ = nullptr;
};

struct AudioTrackSharedStreaming {
    // similar to NBAIO MonoPipe
    // in continuously incrementing frame units, take modulo buffer size, which must be a power of 2
@@ -188,6 +265,8 @@ public:

    volatile    int32_t     mFlags;         // combinations of CBLK_*

                std::atomic<int32_t>  mState; // current TrackBase state.

public:
                union {
                    AudioTrackSharedStreaming   mStreaming;
@@ -198,6 +277,9 @@ public:
                // Cache line boundary (32 bytes)
};

// TODO: ensure standard layout.
// static_assert(std::is_standard_layout_v<audio_track_cblk_t>);

// ----------------------------------------------------------------------------

// Proxy for shared memory control block, to isolate callers from needing to know the details.
@@ -323,6 +405,7 @@ public:
        return mEpoch;
    }

    int32_t getState() const { return mCblk->mState; }
    uint32_t      getBufferSizeInFrames() const { return mBufferSizeInFrames; }
    // See documentation for AudioTrack::setBufferSizeInFrames()
    uint32_t      setBufferSizeInFrames(uint32_t requestedSize);
+3 −5
Original line number Diff line number Diff line
@@ -287,6 +287,7 @@ c2_status_t C2SoftAacDec::onStop() {
    mOutputDelayRingBufferWritePos = 0;
    mOutputDelayRingBufferReadPos = 0;
    mOutputDelayRingBufferFilled = 0;
    mOutputDelayRingBuffer.reset();
    mBuffersInfo.clear();

    status_t status = UNKNOWN_ERROR;
@@ -308,10 +309,7 @@ void C2SoftAacDec::onRelease() {
        aacDecoder_Close(mAACDecoder);
        mAACDecoder = nullptr;
    }
    if (mOutputDelayRingBuffer) {
        delete[] mOutputDelayRingBuffer;
        mOutputDelayRingBuffer = nullptr;
    }
    mOutputDelayRingBuffer.reset();
}

status_t C2SoftAacDec::initDecoder() {
@@ -327,7 +325,7 @@ status_t C2SoftAacDec::initDecoder() {

    mOutputDelayCompensated = 0;
    mOutputDelayRingBufferSize = 2048 * MAX_CHANNEL_COUNT * kNumDelayBlocksMax;
    mOutputDelayRingBuffer = new short[mOutputDelayRingBufferSize];
    mOutputDelayRingBuffer.reset(new short[mOutputDelayRingBufferSize]);
    mOutputDelayRingBufferWritePos = 0;
    mOutputDelayRingBufferReadPos = 0;
    mOutputDelayRingBufferFilled = 0;
+1 −1
Original line number Diff line number Diff line
@@ -93,7 +93,7 @@ private:
    bool mEndOfOutput;
    int32_t mOutputDelayCompensated;
    int32_t mOutputDelayRingBufferSize;
    short *mOutputDelayRingBuffer;
    std::unique_ptr<short[]> mOutputDelayRingBuffer;
    int32_t mOutputDelayRingBufferWritePos;
    int32_t mOutputDelayRingBufferReadPos;
    int32_t mOutputDelayRingBufferFilled;
+1 −1
Original line number Diff line number Diff line
@@ -413,7 +413,7 @@ void C2SoftMP3::process(
        mConfig->inputBufferCurrentLength = (inSize - inPos);
        mConfig->inputBufferMaxLength = 0;
        mConfig->inputBufferUsedLength = 0;
        mConfig->outputFrameSize = (calOutSize - outSize);
        mConfig->outputFrameSize = (calOutSize - outSize) / sizeof(int16_t);
        mConfig->pOutputBuffer = reinterpret_cast<int16_t *> (wView.data() + outSize);

        ERROR_CODE decoderErr;
+26 −7
Original line number Diff line number Diff line
@@ -1579,15 +1579,36 @@ status_t CCodec::setupInputSurface(const std::shared_ptr<InputSurfaceWrapper> &s
    // we are now using surface - apply default color aspects to input format - as well as
    // get dataspace
    bool inputFormatChanged = config->updateFormats(Config::IS_INPUT);
    ALOGD("input format %s to %s",
            inputFormatChanged ? "changed" : "unchanged",
            config->mInputFormat->debugString().c_str());

    // configure dataspace
    static_assert(sizeof(int32_t) == sizeof(android_dataspace), "dataspace size mismatch");
    android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
    (void)config->mInputFormat->findInt32("android._dataspace", (int32_t*)&dataSpace);

    // The output format contains app-configured color aspects, and the input format
    // has the default color aspects. Use the default for the unspecified params.
    ColorAspects inputColorAspects, colorAspects;
    getColorAspectsFromFormat(config->mOutputFormat, colorAspects);
    getColorAspectsFromFormat(config->mInputFormat, inputColorAspects);
    if (colorAspects.mRange == ColorAspects::RangeUnspecified) {
        colorAspects.mRange = inputColorAspects.mRange;
    }
    if (colorAspects.mPrimaries == ColorAspects::PrimariesUnspecified) {
        colorAspects.mPrimaries = inputColorAspects.mPrimaries;
    }
    if (colorAspects.mTransfer == ColorAspects::TransferUnspecified) {
        colorAspects.mTransfer = inputColorAspects.mTransfer;
    }
    if (colorAspects.mMatrixCoeffs == ColorAspects::MatrixUnspecified) {
        colorAspects.mMatrixCoeffs = inputColorAspects.mMatrixCoeffs;
    }
    android_dataspace dataSpace = getDataSpaceForColorAspects(
            colorAspects, /* mayExtend = */ false);
    surface->setDataSpace(dataSpace);
    setColorAspectsIntoFormat(colorAspects, config->mInputFormat, /* force = */ true);
    config->mInputFormat->setInt32("android._dataspace", int32_t(dataSpace));

    ALOGD("input format %s to %s",
            inputFormatChanged ? "changed" : "unchanged",
            config->mInputFormat->debugString().c_str());

    status_t err = mChannel->setInputSurface(surface);
    if (err != OK) {
@@ -2286,8 +2307,6 @@ void CCodec::onMessageReceived(const sp<AMessage> &msg) {
                            const C2ConstGraphicBlock &block = blocks[0];
                            updates.emplace_back(new C2StreamCropRectInfo::output(
                                    stream, block.crop()));
                            updates.emplace_back(new C2StreamPictureSizeInfo::output(
                                    stream, block.crop().width, block.crop().height));
                        }
                        ++stream;
                    }
Loading