mirror of
https://invent.kde.org/network/krfb
synced 2024-07-01 07:24:29 +00:00
pipewire: Support cursors
This commit is contained in:
parent
775d3c7a97
commit
61d464676c
|
@ -175,6 +175,10 @@ private:
|
|||
// sanity indicator
|
||||
bool isValid = true;
|
||||
|
||||
QImage cursorTexture;
|
||||
QPoint cursorPosition;
|
||||
QPoint cursorHotspot;
|
||||
|
||||
#if HAVE_DMA_BUF
|
||||
struct EGLStruct {
|
||||
QList<QByteArray> extensions;
|
||||
|
@ -556,6 +560,10 @@ void PWFrameBuffer::Private::onStreamStateChanged(void *data, pw_stream_state /*
|
|||
}
|
||||
}
|
||||
|
||||
#define CURSOR_BPP 4
|
||||
#define CURSOR_META_SIZE(w,h) (sizeof(struct spa_meta_cursor) + \
|
||||
sizeof(struct spa_meta_bitmap) + w * h * CURSOR_BPP)
|
||||
|
||||
/**
|
||||
* @brief PWFrameBuffer::Private::onStreamFormatChanged - being executed after stream is set to active
|
||||
* and after setup has been requested to connect to it. The actual video format is being negotiated here.
|
||||
|
@ -583,7 +591,6 @@ void PWFrameBuffer::Private::onStreamParamChanged(void *data, uint32_t id, const
|
|||
auto builder = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
||||
|
||||
// setup buffers and meta header for new format
|
||||
const struct spa_pod *params[3];
|
||||
|
||||
#if HAVE_DMA_BUF
|
||||
const auto bufferTypes = d->m_eglInitialized ? (1 << SPA_DATA_DmaBuf) | (1 << SPA_DATA_MemFd) | (1 << SPA_DATA_MemPtr) :
|
||||
|
@ -592,23 +599,31 @@ void PWFrameBuffer::Private::onStreamParamChanged(void *data, uint32_t id, const
|
|||
const auto bufferTypes = (1 << SPA_DATA_MemFd) | (1 << SPA_DATA_MemPtr);
|
||||
#endif /* HAVE_DMA_BUF */
|
||||
|
||||
params[0] = reinterpret_cast<spa_pod *>(spa_pod_builder_add_object(&builder,
|
||||
QVector<const struct spa_pod *> params = {
|
||||
reinterpret_cast<spa_pod *>(spa_pod_builder_add_object(&builder,
|
||||
SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers,
|
||||
SPA_PARAM_BUFFERS_size, SPA_POD_Int(size),
|
||||
SPA_PARAM_BUFFERS_stride, SPA_POD_Int(stride),
|
||||
SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(8, 1, 32),
|
||||
SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(1),
|
||||
SPA_PARAM_BUFFERS_align, SPA_POD_Int(16),
|
||||
SPA_PARAM_BUFFERS_dataType, SPA_POD_CHOICE_FLAGS_Int(bufferTypes)));
|
||||
params[1] = reinterpret_cast<spa_pod *>(spa_pod_builder_add_object(&builder,
|
||||
SPA_PARAM_BUFFERS_dataType, SPA_POD_CHOICE_FLAGS_Int(bufferTypes))),
|
||||
reinterpret_cast<spa_pod *>(spa_pod_builder_add_object(&builder,
|
||||
SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta,
|
||||
SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header),
|
||||
SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_header))));
|
||||
params[2] = reinterpret_cast<spa_pod*>(spa_pod_builder_add_object(&builder,
|
||||
SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_header)))),
|
||||
reinterpret_cast<spa_pod*>(spa_pod_builder_add_object(&builder,
|
||||
SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, SPA_PARAM_META_type,
|
||||
SPA_POD_Id(SPA_META_VideoCrop), SPA_PARAM_META_size,
|
||||
SPA_POD_Int(sizeof(struct spa_meta_region))));
|
||||
pw_stream_update_params(d->pwStream, params, 3);
|
||||
SPA_POD_Int(sizeof(struct spa_meta_region)))),
|
||||
reinterpret_cast<spa_pod*>(spa_pod_builder_add_object ( &builder,
|
||||
SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta,
|
||||
SPA_PARAM_META_type, SPA_POD_Id (SPA_META_Cursor),
|
||||
SPA_PARAM_META_size, SPA_POD_CHOICE_RANGE_Int (CURSOR_META_SIZE (64, 64),
|
||||
CURSOR_META_SIZE (1, 1),
|
||||
CURSOR_META_SIZE (1024, 1024)))),
|
||||
};
|
||||
pw_stream_update_params(d->pwStream, params.data(), params.size());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -642,6 +657,13 @@ void PWFrameBuffer::Private::onStreamProcess(void *data)
|
|||
pw_stream_queue_buffer(d->pwStream, buffer);
|
||||
}
|
||||
|
||||
static QImage::Format spaToQImageFormat(quint32 format)
|
||||
{
|
||||
return format == SPA_VIDEO_FORMAT_BGR ? QImage::Format_BGR888
|
||||
: format == SPA_VIDEO_FORMAT_RGBx ? QImage::Format_RGBX8888
|
||||
: QImage::Format_RGB32;
|
||||
}
|
||||
|
||||
void PWFrameBuffer::Private::handleFrame(pw_buffer *pwBuffer)
|
||||
{
|
||||
auto spaBuffer = pwBuffer->buffer;
|
||||
|
@ -751,6 +773,28 @@ void PWFrameBuffer::Private::handleFrame(pw_buffer *pwBuffer)
|
|||
}
|
||||
#endif /* HAVE_DMA_BUF */
|
||||
|
||||
|
||||
// process cursor
|
||||
{
|
||||
struct spa_meta_cursor *cursor = static_cast<struct spa_meta_cursor*>(spa_buffer_find_meta_data (spaBuffer, SPA_META_Cursor, sizeof (*cursor)));
|
||||
if (spa_meta_cursor_is_valid (cursor)) {
|
||||
struct spa_meta_bitmap *bitmap = nullptr;
|
||||
|
||||
if (cursor->bitmap_offset)
|
||||
bitmap = SPA_MEMBER (cursor, cursor->bitmap_offset, struct spa_meta_bitmap);
|
||||
|
||||
if (bitmap && bitmap->size.width > 0 && bitmap->size.height > 0) {
|
||||
const uint8_t *bitmap_data;
|
||||
|
||||
bitmap_data = SPA_MEMBER (bitmap, bitmap->offset, uint8_t);
|
||||
cursorHotspot = { cursor->hotspot.x, cursor->hotspot.y };
|
||||
cursorTexture = QImage(bitmap_data, bitmap->size.width, bitmap->size.height, bitmap->stride, spaToQImageFormat(bitmap->format));
|
||||
}
|
||||
|
||||
cursorPosition = QPoint{ cursor->position.x, cursor->position.y };
|
||||
}
|
||||
}
|
||||
|
||||
struct spa_meta_region* videoMetadata =
|
||||
static_cast<struct spa_meta_region*>(spa_buffer_find_meta_data(
|
||||
spaBuffer, SPA_META_VideoCrop, sizeof(*videoMetadata)));
|
||||
|
@ -828,11 +872,7 @@ void PWFrameBuffer::Private::handleFrame(pw_buffer *pwBuffer)
|
|||
}
|
||||
|
||||
if (videoFormat->format != SPA_VIDEO_FORMAT_RGB) {
|
||||
const QImage::Format format = videoFormat->format == SPA_VIDEO_FORMAT_BGR ? QImage::Format_BGR888
|
||||
: videoFormat->format == SPA_VIDEO_FORMAT_RGBx ? QImage::Format_RGBX8888
|
||||
: QImage::Format_RGB32;
|
||||
|
||||
QImage img((uchar*) q->fb, videoSize.width(), videoSize.height(), dstStride, format);
|
||||
QImage img((uchar*) q->fb, videoSize.width(), videoSize.height(), dstStride, spaToQImageFormat(videoFormat->format));
|
||||
img.convertTo(QImage::Format_RGB888);
|
||||
}
|
||||
|
||||
|
@ -1002,3 +1042,8 @@ bool PWFrameBuffer::isValid() const
|
|||
{
|
||||
return d->isValid;
|
||||
}
|
||||
|
||||
QPoint PWFrameBuffer::cursorPosition()
|
||||
{
|
||||
return d->cursorPosition;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ public:
|
|||
void getServerFormat(rfbPixelFormat &format) override;
|
||||
void startMonitor() override;
|
||||
void stopMonitor() override;
|
||||
QPoint cursorPosition() override;
|
||||
|
||||
QVariant customProperty(const QString &property) const override;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user