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

Commit 54d22a98 authored by Xin Li's avatar Xin Li Committed by Android (Google) Code Review
Browse files

Merge "Merge sc-qpr1-dev-plus-aosp-without-vendor@7810918" into stage-aosp-master

parents f7a6e155 c948a7c8
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