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

Commit b29438ef authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

audiohal: Re-implement stream read and write using FMQ

Result: no hwbinder calls due read / write session.

Added IStream.close method for explicitly freeing up of resources
consumed by the stream before automatic server objects reaping
gets to it.

Test: make, perform Loopback RTT, check traces
Bug: 30222631
Change-Id: I678559f6ef30026685df787cd2ba7c2ee449ed27
parent 4a412790
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -279,4 +279,16 @@ interface IStream {
     */
    getMmapPosition()
            generates (Result retval, MmapPosition position);

    /*
     * Called by the framework to deinitialize the stream and free up
     * all the currently allocated resources. It is recommended to close
     * the stream on the client side as soon as it is becomes unused.
     *
     * @return retval OK in case the success.
     *                NOT_SUPPORTED if called on IStream instead of input or
     *                              output stream interface.
     *                INVALID_STATE if the stream was already closed.
     */
    close() generates (Result retval);
};
+37 −8
Original line number Diff line number Diff line
@@ -41,16 +41,45 @@ interface IStreamIn extends IStream {
    setGain(float gain) generates (Result retval);

    /*
     * Read audio buffer in from driver. If at least one frame was read prior to
     * the error, 'read' must return that byte count and then return an error
     * in the subsequent call.
     * Data structure passed back to the client via status message queue
     * of 'read' operation.
     *
     * @param size maximum amount of bytes to read.
     * @return retval operation completion status.
     * @return data audio data.
     * Possible values of 'retval' field:
     *  - OK, read operation was successful;
     *  - INVALID_ARGUMENTS, stream was not configured properly;
     *  - INVALID_STATE, stream is in a state that doesn't allow reads.
     */
    struct ReadStatus {
        Result retval;
        uint64_t read;
    };

    /*
     * Set up required transports for receiving audio buffers from the driver.
     *
     * The transport consists of two message queues: one is used for passing
     * audio data from the driver to the client, another is used for reporting
     * read operation status (amount of bytes actually read or error code),
     * see ReadStatus structure definition.
     *
     * @param frameSize the size of a single frame, in bytes.
     * @param framesCount the number of frames in a buffer.
     * @param threadPriority priority of the thread that performs reads.
     * @return retval OK if both message queues were created successfully.
     *                INVALID_STATE if the method was already called.
     *                INVALID_ARGUMENTS if there was a problem setting up
     *                                  the queues.
     * @return dataMQ a message queue used for passing audio data in the format
     *                specified at the stream opening.
     * @return statusMQ a message queue used for passing status from the driver
     *                  using ReadStatus structures.
     */
    // TODO(mnaganov): Replace with FMQ version.
    read(uint64_t size) generates (Result retval, vec<uint8_t> data);
    prepareForReading(
            uint32_t frameSize, uint32_t framesCount,
            ThreadPriority threadPriority)
    generates (
            Result retval,
            fmq_sync<uint8_t> dataMQ, fmq_sync<ReadStatus> statusMQ);

    /*
     * Return the amount of input frames lost in the audio driver since the last
+41 −18
Original line number Diff line number Diff line
@@ -44,25 +44,48 @@ interface IStreamOut extends IStream {
    setVolume(float left, float right) generates (Result retval);

    /*
     * Write audio buffer to driver. On success, sets 'retval' to 'OK', and
     * returns number of bytes written. If at least one frame was written
     * successfully prior to the error, it is suggested that the driver return
     * that successful (short) byte count and then return an error in the
     * subsequent call.
     *
     * If 'setCallback' has previously been called to enable non-blocking mode
     * then 'write' is not allowed to block. It must write only the number of
     * bytes that currently fit in the driver/hardware buffer and then return
     * this byte count. If this is less than the requested write size the
     * callback function must be called when more space is available in the
     * driver/hardware buffer.
     *
     * @param data audio data.
     * @return retval operation completion status.
     * @return written number of bytes written.
     * Data structure passed back to the client via status message queue
     * of 'write' operation.
     *
     * Possible values of 'retval' field:
     *  - OK, write operation was successful;
     *  - INVALID_ARGUMENTS, stream was not configured properly;
     *  - INVALID_STATE, stream is in a state that doesn't allow writes.
     */
    struct WriteStatus {
        Result retval;
        uint64_t written;
        uint64_t frames;    // presentation position
        TimeSpec timeStamp; // presentation position
    };

    /*
     * Set up required transports for passing audio buffers to the driver.
     *
     * The transport consists of two message queues: one is used for passing
     * audio data from the client to the driver, another is used for reporting
     * write operation status (amount of bytes actually written or error code),
     * and the presentation position immediately after the write, see
     * WriteStatus structure definition.
     *
     * @param frameSize the size of a single frame, in bytes.
     * @param framesCount the number of frames in a buffer.
     * @param threadPriority priority of the thread that performs writes.
     * @return retval OK if both message queues were created successfully.
     *                INVALID_STATE if the method was already called.
     *                INVALID_ARGUMENTS if there was a problem setting up
     *                                  the queues.
     * @return dataMQ a message queue used for passing audio data in the format
     *                specified at the stream opening.
     * @return statusMQ a message queue used for passing status from the driver
     *                  using WriteStatus structures.
     */
    // TODO(mnaganov): Replace with FMQ version.
    write(vec<uint8_t> data) generates (Result retval, uint64_t written);
    prepareForWriting(
            uint32_t frameSize, uint32_t framesCount,
            ThreadPriority threadPriority)
    generates (
            Result retval,
            fmq_sync<uint8_t> dataMQ, fmq_sync<WriteStatus> statusMQ);

    /*
     * Return the number of audio frames written by the audio DSP to DAC since
+6 −3
Original line number Diff line number Diff line
@@ -30,13 +30,16 @@ LOCAL_SRC_FILES := \
    StreamOut.cpp \

LOCAL_SHARED_LIBRARIES := \
    libbase \
    libcutils \
    libfmq \
    libhardware \
    libhidlbase \
    libhidltransport \
    libhwbinder \
    libcutils \
    libutils \
    libhardware \
    liblog \
    libmediautils \
    libutils \
    android.hardware.audio@2.0 \
    android.hardware.audio.common@2.0 \
    android.hardware.audio.common@2.0-util \
+4 −0
Original line number Diff line number Diff line
@@ -253,6 +253,10 @@ Return<void> Stream::getMmapPosition(getMmapPosition_cb _hidl_cb) {
    return Void();
}

Return<Result> Stream::close()  {
    return Result::NOT_SUPPORTED;
}

} // namespace implementation
}  // namespace V2_0
}  // namespace audio
Loading