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

Commit 25e5f8a2 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 5586686 from a4d3cbef to qt-c2f2-release

Change-Id: I6c292120948c546806bf1dfef95f256cd88b1fbd
parents c8a454d9 a4d3cbef
Loading
Loading
Loading
Loading
+88 −9
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@
#define LOG_TAG "C2SoftVpxDec"
#include <log/log.h>

#include <algorithm>

#include <media/stagefright/foundation/AUtils.h>
#include <media/stagefright/foundation/MediaDefs.h>

@@ -303,13 +305,43 @@ private:
#endif
};

C2SoftVpxDec::ConverterThread::ConverterThread(
        const std::shared_ptr<Mutexed<ConversionQueue>> &queue)
    : Thread(false), mQueue(queue) {}

bool C2SoftVpxDec::ConverterThread::threadLoop() {
    Mutexed<ConversionQueue>::Locked queue(*mQueue);
    if (queue->entries.empty()) {
        queue.waitForCondition(queue->cond);
        if (queue->entries.empty()) {
            return true;
        }
    }
    std::function<void()> convert = queue->entries.front();
    queue->entries.pop_front();
    if (!queue->entries.empty()) {
        queue->cond.signal();
    }
    queue.unlock();

    convert();

    queue.lock();
    if (--queue->numPending == 0u) {
        queue->cond.broadcast();
    }
    return true;
}

C2SoftVpxDec::C2SoftVpxDec(
        const char *name,
        c2_node_id_t id,
        const std::shared_ptr<IntfImpl> &intfImpl)
    : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
      mIntf(intfImpl),
      mCodecCtx(nullptr) {
      mCodecCtx(nullptr),
      mCoreCount(1),
      mQueue(new Mutexed<ConversionQueue>) {
}

C2SoftVpxDec::~C2SoftVpxDec() {
@@ -399,7 +431,7 @@ status_t C2SoftVpxDec::initDecoder() {

    vpx_codec_dec_cfg_t cfg;
    memset(&cfg, 0, sizeof(vpx_codec_dec_cfg_t));
    cfg.threads = GetCPUCoreCount();
    cfg.threads = mCoreCount = GetCPUCoreCount();

    vpx_codec_flags_t flags;
    memset(&flags, 0, sizeof(vpx_codec_flags_t));
@@ -413,6 +445,18 @@ status_t C2SoftVpxDec::initDecoder() {
        return UNKNOWN_ERROR;
    }

    if (mMode == MODE_VP9) {
        using namespace std::string_literals;
        for (int i = 0; i < mCoreCount; ++i) {
            sp<ConverterThread> thread(new ConverterThread(mQueue));
            mConverterThreads.push_back(thread);
            if (thread->run(("vp9conv #"s + std::to_string(i)).c_str(),
                            ANDROID_PRIORITY_AUDIO) != OK) {
                return UNKNOWN_ERROR;
            }
        }
    }

    return OK;
}

@@ -422,6 +466,21 @@ status_t C2SoftVpxDec::destroyDecoder() {
        delete mCodecCtx;
        mCodecCtx = nullptr;
    }
    bool running = true;
    for (const sp<ConverterThread> &thread : mConverterThreads) {
        thread->requestExit();
    }
    while (running) {
        mQueue->lock()->cond.broadcast();
        running = false;
        for (const sp<ConverterThread> &thread : mConverterThreads) {
            if (thread->isRunning()) {
                running = true;
                break;
            }
        }
    }
    mConverterThreads.clear();

    return OK;
}
@@ -759,10 +818,30 @@ bool C2SoftVpxDec::outputBuffer(
        const uint16_t *srcV = (const uint16_t *)img->planes[VPX_PLANE_V];

        if (format == HAL_PIXEL_FORMAT_RGBA_1010102) {
            convertYUV420Planar16ToY410((uint32_t *)dst, srcY, srcU, srcV, srcYStride / 2,
                                    srcUStride / 2, srcVStride / 2,
                                    dstYStride / sizeof(uint32_t),
                                    mWidth, mHeight);
            Mutexed<ConversionQueue>::Locked queue(*mQueue);
            size_t i = 0;
            constexpr size_t kHeight = 64;
            for (; i < mHeight; i += kHeight) {
                queue->entries.push_back(
                        [dst, srcY, srcU, srcV,
                         srcYStride, srcUStride, srcVStride, dstYStride,
                         width = mWidth, height = std::min(mHeight - i, kHeight)] {
                            convertYUV420Planar16ToY410(
                                    (uint32_t *)dst, srcY, srcU, srcV, srcYStride / 2,
                                    srcUStride / 2, srcVStride / 2, dstYStride / sizeof(uint32_t),
                                    width, height);
                        });
                srcY += srcYStride / 2 * kHeight;
                srcU += srcUStride / 2 * (kHeight / 2);
                srcV += srcVStride / 2 * (kHeight / 2);
                dst += dstYStride * kHeight;
            }
            CHECK_EQ(0u, queue->numPending);
            queue->numPending = queue->entries.size();
            while (queue->numPending > 0) {
                queue->cond.signal();
                queue.waitForCondition(queue->cond);
            }
        } else {
            convertYUV420Planar16ToYUV420Planar(dst, srcY, srcU, srcV, srcYStride / 2,
                                                srcUStride / 2, srcVStride / 2,
+22 −0
Original line number Diff line number Diff line
@@ -50,6 +50,19 @@ struct C2SoftVpxDec : public SimpleC2Component {
        MODE_VP9,
    } mMode;

    struct ConversionQueue;

    class ConverterThread : public Thread {
    public:
        explicit ConverterThread(
                const std::shared_ptr<Mutexed<ConversionQueue>> &queue);
        ~ConverterThread() override = default;
        bool threadLoop() override;

    private:
        std::shared_ptr<Mutexed<ConversionQueue>> mQueue;
    };

    std::shared_ptr<IntfImpl> mIntf;
    vpx_codec_ctx_t *mCodecCtx;
    bool mFrameParallelMode;  // Frame parallel is only supported by VP9 decoder.
@@ -59,6 +72,15 @@ struct C2SoftVpxDec : public SimpleC2Component {
    bool mSignalledOutputEos;
    bool mSignalledError;

    int mCoreCount;
    struct ConversionQueue {
        std::list<std::function<void()>> entries;
        Condition cond;
        size_t numPending{0u};
    };
    std::shared_ptr<Mutexed<ConversionQueue>> mQueue;
    std::vector<sp<ConverterThread>> mConverterThreads;

    status_t initDecoder();
    status_t destroyDecoder();
    void finishWork(uint64_t index, const std::unique_ptr<C2Work> &work,
+61 −23
Original line number Diff line number Diff line
@@ -4401,11 +4401,12 @@ status_t Camera3Device::HalInterface::configureStreams(const camera_metadata_t *

status_t Camera3Device::HalInterface::wrapAsHidlRequest(camera3_capture_request_t* request,
        /*out*/device::V3_2::CaptureRequest* captureRequest,
        /*out*/std::vector<native_handle_t*>* handlesCreated) {
        /*out*/std::vector<native_handle_t*>* handlesCreated,
        /*out*/std::vector<std::pair<int32_t, int32_t>>* inflightBuffers) {
    ATRACE_CALL();
    if (captureRequest == nullptr || handlesCreated == nullptr) {
        ALOGE("%s: captureRequest (%p) and handlesCreated (%p) must not be null",
                __FUNCTION__, captureRequest, handlesCreated);
    if (captureRequest == nullptr || handlesCreated == nullptr || inflightBuffers == nullptr) {
        ALOGE("%s: captureRequest (%p), handlesCreated (%p), and inflightBuffers(%p) "
                "must not be null", __FUNCTION__, captureRequest, handlesCreated, inflightBuffers);
        return BAD_VALUE;
    }

@@ -4435,8 +4436,8 @@ status_t Camera3Device::HalInterface::wrapAsHidlRequest(camera3_capture_request_
            captureRequest->inputBuffer.releaseFence = nullptr;

            pushInflightBufferLocked(captureRequest->frameNumber, streamId,
                    request->input_buffer->buffer,
                    request->input_buffer->acquire_fence);
                    request->input_buffer->buffer);
            inflightBuffers->push_back(std::make_pair(captureRequest->frameNumber, streamId));
        } else {
            captureRequest->inputBuffer.streamId = -1;
            captureRequest->inputBuffer.bufferId = BUFFER_ID_NO_BUFFER;
@@ -4475,14 +4476,31 @@ status_t Camera3Device::HalInterface::wrapAsHidlRequest(camera3_capture_request_

            // Output buffers are empty when using HAL buffer manager
            if (!mUseHalBufManager) {
                pushInflightBufferLocked(captureRequest->frameNumber, streamId,
                        src->buffer, src->acquire_fence);
                pushInflightBufferLocked(captureRequest->frameNumber, streamId, src->buffer);
                inflightBuffers->push_back(std::make_pair(captureRequest->frameNumber, streamId));
            }
        }
    }
    return OK;
}

void Camera3Device::HalInterface::cleanupNativeHandles(
        std::vector<native_handle_t*> *handles, bool closeFd) {
    if (handles == nullptr) {
        return;
    }
    if (closeFd) {
        for (auto& handle : *handles) {
            native_handle_close(handle);
        }
    }
    for (auto& handle : *handles) {
        native_handle_delete(handle);
    }
    handles->clear();
    return;
}

status_t Camera3Device::HalInterface::processBatchCaptureRequests(
        std::vector<camera3_capture_request_t*>& requests,/*out*/uint32_t* numRequestProcessed) {
    ATRACE_NAME("CameraHal::processBatchCaptureRequests");
@@ -4503,17 +4521,20 @@ status_t Camera3Device::HalInterface::processBatchCaptureRequests(
        captureRequests.resize(batchSize);
    }
    std::vector<native_handle_t*> handlesCreated;
    std::vector<std::pair<int32_t, int32_t>> inflightBuffers;

    status_t res = OK;
    for (size_t i = 0; i < batchSize; i++) {
        if (hidlSession_3_4 != nullptr) {
            res = wrapAsHidlRequest(requests[i], /*out*/&captureRequests_3_4[i].v3_2,
                    /*out*/&handlesCreated);
                    /*out*/&handlesCreated, /*out*/&inflightBuffers);
        } else {
            res = wrapAsHidlRequest(requests[i],
                    /*out*/&captureRequests[i], /*out*/&handlesCreated);
            res = wrapAsHidlRequest(requests[i], /*out*/&captureRequests[i],
                    /*out*/&handlesCreated, /*out*/&inflightBuffers);
        }
        if (res != OK) {
            popInflightBuffers(inflightBuffers);
            cleanupNativeHandles(&handlesCreated);
            return res;
        }
    }
@@ -4610,18 +4631,30 @@ status_t Camera3Device::HalInterface::processBatchCaptureRequests(
    }
    if (!err.isOk()) {
        ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
        return DEAD_OBJECT;
        status = common::V1_0::Status::CAMERA_DISCONNECTED;
    }

    if (status == common::V1_0::Status::OK && *numRequestProcessed != batchSize) {
        ALOGE("%s: processCaptureRequest returns OK but processed %d/%zu requests",
                __FUNCTION__, *numRequestProcessed, batchSize);
        status = common::V1_0::Status::INTERNAL_ERROR;
    }

    for (auto& handle : handlesCreated) {
        native_handle_delete(handle);
    res = CameraProviderManager::mapToStatusT(status);
    if (res == OK) {
        if (mHidlSession->isRemote()) {
            // Only close acquire fence FDs when the HIDL transaction succeeds (so the FDs have been
            // sent to camera HAL processes)
            cleanupNativeHandles(&handlesCreated, /*closeFd*/true);
        } else {
            // In passthrough mode the FDs are now owned by HAL
            cleanupNativeHandles(&handlesCreated);
        }
    return CameraProviderManager::mapToStatusT(status);
    } else {
        popInflightBuffers(inflightBuffers);
        cleanupNativeHandles(&handlesCreated);
    }
    return res;
}

status_t Camera3Device::HalInterface::flush() {
@@ -4703,10 +4736,9 @@ void Camera3Device::HalInterface::getInflightRequestBufferKeys(
}

status_t Camera3Device::HalInterface::pushInflightBufferLocked(
        int32_t frameNumber, int32_t streamId, buffer_handle_t *buffer, int acquireFence) {
        int32_t frameNumber, int32_t streamId, buffer_handle_t *buffer) {
    uint64_t key = static_cast<uint64_t>(frameNumber) << 32 | static_cast<uint64_t>(streamId);
    auto pair = std::make_pair(buffer, acquireFence);
    mInflightBufferMap[key] = pair;
    mInflightBufferMap[key] = buffer;
    return OK;
}

@@ -4718,16 +4750,22 @@ status_t Camera3Device::HalInterface::popInflightBuffer(
    uint64_t key = static_cast<uint64_t>(frameNumber) << 32 | static_cast<uint64_t>(streamId);
    auto it = mInflightBufferMap.find(key);
    if (it == mInflightBufferMap.end()) return NAME_NOT_FOUND;
    auto pair = it->second;
    *buffer = pair.first;
    int acquireFence = pair.second;
    if (acquireFence > 0) {
        ::close(acquireFence);
    if (buffer != nullptr) {
        *buffer = it->second;
    }
    mInflightBufferMap.erase(it);
    return OK;
}

void Camera3Device::HalInterface::popInflightBuffers(
        const std::vector<std::pair<int32_t, int32_t>>& buffers) {
    for (const auto& pair : buffers) {
        int32_t frameNumber = pair.first;
        int32_t streamId = pair.second;
        popInflightBuffer(frameNumber, streamId, nullptr);
    }
}

status_t Camera3Device::HalInterface::pushInflightRequestBuffer(
        uint64_t bufferId, buffer_handle_t* buf, int32_t streamId) {
    std::lock_guard<std::mutex> lock(mRequestedBuffersLock);
+12 −4
Original line number Diff line number Diff line
@@ -358,13 +358,21 @@ class Camera3Device :
        // Do not free input camera3_capture_request_t before output HIDL request
        status_t wrapAsHidlRequest(camera3_capture_request_t* in,
                /*out*/hardware::camera::device::V3_2::CaptureRequest* out,
                /*out*/std::vector<native_handle_t*>* handlesCreated);
                /*out*/std::vector<native_handle_t*>* handlesCreated,
                /*out*/std::vector<std::pair<int32_t, int32_t>>* inflightBuffers);

        status_t pushInflightBufferLocked(int32_t frameNumber, int32_t streamId,
                buffer_handle_t *buffer, int acquireFence);
                buffer_handle_t *buffer);

        // Pop inflight buffers based on pairs of (frameNumber,streamId)
        void popInflightBuffers(const std::vector<std::pair<int32_t, int32_t>>& buffers);

        // Cache of buffer handles keyed off (frameNumber << 32 | streamId)
        // value is a pair of (buffer_handle_t*, acquire_fence FD)
        std::unordered_map<uint64_t, std::pair<buffer_handle_t*, int>> mInflightBufferMap;
        std::unordered_map<uint64_t, buffer_handle_t*> mInflightBufferMap;

        // Delete and optionally close native handles and clear the input vector afterward
        static void cleanupNativeHandles(
                std::vector<native_handle_t*> *handles, bool closeFd = false);

        struct BufferHasher {
            size_t operator()(const buffer_handle_t& buf) const {