The Usage of BufferQueue in one process

//#include <iostream>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/Binder.h>
#include <binder/IBinder.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/IServiceManager.h>

#include <iostream>
#include <array>
#include <limits>
#include <set>
#include <unordered_map>

#include <functional>
#include <memory>
#include <ostream>
#include <string>
#include <vector>
#include <map>
#include <optional>
#include <optional>

#include <chrono>
#include <mutex>
#include <thread>

#include <android/gui/IDisplayEventConnection.h>
#include <android/gui/ISurfaceComposer.h>
#include <binder/ProcessState.h>
#include <gui/BufferItemConsumer.h>
#include <gui/IProducerListener.h>
#include <gui/ISurfaceComposer.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/SyncScreenCaptureListener.h>
#include <inttypes.h>
#include <private/gui/ComposerService.h>
#include <private/gui/ComposerServiceAIDL.h>
#include <sys/types.h>
#include <ui/BufferQueueDefs.h>
#include <ui/DisplayMode.h>
#include <ui/Rect.h>
#include <utils/Errors.h>
#include <utils/String8.h>
#include <limits>
#include <thread>
#include "ColorUtils.h"
#include "MockConsumer.h"
#include <utils/Log.h>

//
typedef uint8_t u8;
typedef int32_t u32;

#include <iostream>
#include <chrono>
#include <thread>

#include <android/gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/SurfaceControl.h>
#include <gui/Surface.h>
#include <ui/Rect.h>

#include <gui/IConsumerListener.h>

using namespace android;

static const uint32_t TEST_DATA = 123456;

const uint32_t DEFAULT_WIDTH = 1;

const uint32_t DEFAULT_HEIGHT = 1;

// Default format before setDefaultBufferFormat is called
const PixelFormat DEFAULT_FORMAT = HAL_PIXEL_FORMAT_RGBA_8888;

// Default transform hint before setTransformHint is called
//const uint32_t DEFAULT_TRANSFORM_HINT = 0;

// TODO: Make these constants in header
//const int DEFAULT_CONSUMER_USAGE_BITS = 0;

#define TEST_PRODUCER_USAGE_BITS (0)

// Parameters for a generic "valid" input for queueBuffer.
const int64_t QUEUE_BUFFER_INPUT_TIMESTAMP = 1384888611;
const bool QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP = false;
const android_dataspace QUEUE_BUFFER_INPUT_DATASPACE = HAL_DATASPACE_UNKNOWN;
const Rect QUEUE_BUFFER_INPUT_RECT = Rect(DEFAULT_WIDTH, DEFAULT_HEIGHT);
const int QUEUE_BUFFER_INPUT_SCALING_MODE = 0;
const int QUEUE_BUFFER_INPUT_TRANSFORM = 0;
const sp<Fence> QUEUE_BUFFER_INPUT_FENCE = Fence::NO_FENCE;
const uint32_t QUEUE_BUFFER_INPUT_STICKY_TRANSFORM = 0;
const bool QUEUE_BUFFER_INPUT_GET_TIMESTAMPS = 0;
const int QUEUE_BUFFER_INPUT_SLOT = -1;

// Builder pattern to slightly vary *almost* correct input
// -- avoids copying and pasting

struct QueueBufferInputBuilder {
    QueueBufferInputBuilder() {
        timestamp = QUEUE_BUFFER_INPUT_TIMESTAMP;
        isAutoTimestamp = QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP;
        dataSpace = QUEUE_BUFFER_INPUT_DATASPACE;
        crop = QUEUE_BUFFER_INPUT_RECT;
        scalingMode = QUEUE_BUFFER_INPUT_SCALING_MODE;
        transform = QUEUE_BUFFER_INPUT_TRANSFORM;
        fence = QUEUE_BUFFER_INPUT_FENCE;
        stickyTransform = QUEUE_BUFFER_INPUT_STICKY_TRANSFORM;
        getTimestamps = QUEUE_BUFFER_INPUT_GET_TIMESTAMPS;
        slot = QUEUE_BUFFER_INPUT_SLOT;
    }

    IGraphicBufferProducer::QueueBufferInput build() {
        return IGraphicBufferProducer::QueueBufferInput(
                timestamp,
                isAutoTimestamp,
                dataSpace,
                crop,
                scalingMode,
                transform,
                fence,
                stickyTransform,
                getTimestamps,
                slot);
    }

private:
    int64_t timestamp;
    bool isAutoTimestamp;
    android_dataspace dataSpace;
    Rect crop;
    int scalingMode;
    uint32_t transform;
    sp<Fence> fence;
    uint32_t stickyTransform;
    bool getTimestamps;
    int slot;

};

// Create a generic "valid" input for queueBuffer
// -- uses the default buffer format, width, etc.
static IGraphicBufferProducer::QueueBufferInput CreateBufferInput() {
    return QueueBufferInputBuilder().build();
}


int main() {
    sp<IGraphicBufferProducer> mProducer;
    sp<IGraphicBufferConsumer> mConsumer;

    const String16 PRODUCER_NAME = String16("BQTestProducer1");
    const String16 CONSUMER_NAME = String16("BQTestConsumer1");

//    pid_t forkPid = fork();

//    if (forkPid == -1) {
//        std::cout << "fork error" << std::endl;
//        return -1;
//    }

//    if (forkPid == 0) {
    // Child process
    sp<IGraphicBufferProducer> producer;
    sp<IGraphicBufferConsumer> consumer;
    BufferQueue::createBufferQueue(&producer, &consumer);
    sp<IServiceManager> serviceManager = defaultServiceManager();
    serviceManager->addService(PRODUCER_NAME, IInterface::asBinder(producer));
    serviceManager->addService(CONSUMER_NAME, IInterface::asBinder(consumer));
    ProcessState::self()->startThreadPool();
//        IPCThreadState::self()->joinThreadPool();
//        LOG_ALWAYS_FATAL("Shouldn't be here");
//    }

//    sp<IServiceManager> serviceManager = defaultServiceManager();
    sp<IBinder> binderProducer =
            serviceManager->getService(PRODUCER_NAME);
    mProducer = interface_cast<IGraphicBufferProducer>(binderProducer);
    sp<IBinder> binderConsumer =
            serviceManager->getService(CONSUMER_NAME);
    mConsumer = interface_cast<IGraphicBufferConsumer>(binderConsumer);

    sp<MockConsumer> mc(new MockConsumer);
//
    mConsumer->consumerConnect(mc, false);
//

    IGraphicBufferProducer::QueueBufferOutput output;
//    ASSERT_EQ(OK,
    auto ret = mProducer->connect(nullptr, NATIVE_WINDOW_API_CPU, false, &output);

    if (ret != NO_ERROR) {
        std::cout << "mProducer->connect fails:" << statusToString(ret) << std::endl;
        return ret;
    }

    int slot = -1;
    sp<Fence> fence;
    sp<GraphicBuffer> buffer;

    ret = mProducer->dequeueBuffer(&slot, &fence, DEFAULT_WIDTH, DEFAULT_HEIGHT,
                                   DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS,
                                   nullptr, nullptr);

    if (ret < 0) {
        std::cout << "mProducer->dequeueBuffer  fails: " << ret << std::endl;
        return ret;
    }

    if (slot == -1) {
        std::cout << "slot is -1" << ret << std::endl;
        return -1;
    }

    ret = mProducer->requestBuffer(slot, &buffer);
    if (buffer == nullptr) {
        std::cout << "mProducer->requestBuffer fails " << ret << std::endl;
        return -1;
    }

    uint32_t *dataIn;

    ret = buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
                       reinterpret_cast<void **>(&dataIn));

    if (ret != OK) {
        std::cout << "buffer->lock fails" << std::endl;
        return ret;
    }

    *dataIn = TEST_DATA;
    ret = buffer->unlock();

    if (ret != OK) {
        std::cout << "unlock fails" << std::endl;
        return ret;
    }

    std::cout << "slot is:" << slot << std::endl;

    IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
    IGraphicBufferProducer::QueueBufferOutput output2;
    ret = mProducer->queueBuffer(slot, input, &output2);

    if (ret != NO_ERROR) {
        std::cout << "queueBuffer fails: " << statusToString(ret) << std::endl;
        return ret;
    }

    BufferItem item;
    ret = mConsumer->acquireBuffer(&item, 0);
//
    if (ret != OK) {
        std::cout << "acquireBuffer fails:" << statusToString(ret) << std::endl;
        return ret;
    }

    uint32_t *dataOut;
    ret = item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
                                    reinterpret_cast<void **>(&dataOut));

    if (ret != OK) {
        std::cout << "item.mGraphicBuffer->lock fails" << std::endl;
        return ret;
    }

    if (*dataOut != TEST_DATA) {
        std::cout << "dataOut!=TEST_DATA" << std::endl;
        return -1;
    } else {
        std::cout << *dataOut << std::endl;
    }

    ret = item.mGraphicBuffer->unlock();

    if (ret != OK) {
        std::cout << "unlock fails" << std::endl;
        return ret;
    }
    std::cout << "OK" << std::endl;
    IPCThreadState::self()->joinThreadPool();
    return 0;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值