Skip to content

Commit

Permalink
Change Pipewire frame capture
Browse files Browse the repository at this point in the history
  • Loading branch information
awawa-dev committed Oct 23, 2023
1 parent db4b07a commit 939cc29
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 26 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ if (DEFAULT_PIPEWIRE)
message( WARNING "QT dbus library is required for PipeWire/Portal support" )
SET ( DEFAULT_PIPEWIRE OFF )
else()

pkg_check_modules(PIPEWIRE libpipewire-0.3)
if(NOT PIPEWIRE_FOUND OR NOT PIPEWIRE_INCLUDE_DIRS OR NOT PIPEWIRE_LIBRARIES)
message( WARNING "Pipewire >= 3.0 not found (did you install libpipewire-0.3-dev?). Disabling support for PipeWire software grabber.")
Expand Down
62 changes: 36 additions & 26 deletions sources/grabber/pipewire/PipewireHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@ PipewireHandler::PipewireHandler() :
connect(this, &PipewireHandler::onStateChangedSignal, this, &PipewireHandler::onStateChanged);
connect(this, &PipewireHandler::onProcessFrameSignal, this, &PipewireHandler::onProcessFrame);
connect(this, &PipewireHandler::onCoreErrorSignal, this, &PipewireHandler::onCoreError);


_image.isError = true;
_image.data = nullptr;
}

QString PipewireHandler::getToken()
Expand Down Expand Up @@ -243,6 +245,12 @@ void PipewireHandler::closeSession()
for (supportedDmaFormat& supVal : _supportedDmaFormatsList)
supVal.hasDma = false;

if (_image.data != nullptr)
{
free(_image.data);
_image.data = nullptr;
}

if (_version > 0)
{
std::cout << "Pipewire: driver is closed now" << std::endl;
Expand Down Expand Up @@ -668,36 +676,42 @@ void PipewireHandler::onParamsChanged(uint32_t id, const struct spa_pod* param)

void PipewireHandler::onProcessFrame()
{
if (_hasFrame)
if (_image.data == nullptr)
{
struct pw_buffer* newFrame;
if ((newFrame = pw_stream_dequeue_buffer(_pwStream)) != nullptr)
pw_stream_queue_buffer(_pwStream, newFrame);
captureFrame();
_hasFrame = (_image.data != nullptr);
}

_hasFrame = true;
};

void PipewireHandler::grabFrame()
{
if (_image.data != nullptr)
{
_callback(_image);

free(_image.data);
_image.data = nullptr;
}
}

void PipewireHandler::captureFrame()
{
struct pw_buffer* newFrame = nullptr;
struct pw_buffer* dequeueFrame = nullptr;
uint8_t* mappedMemory = nullptr;
uint8_t* frameBuffer = nullptr;
PipewireImage image;
uint8_t* frameBuffer = nullptr;

if (_pwStream == nullptr)
return;

_hasFrame = false;

image.width = _frameWidth;
image.height = _frameHeight;
image.isOrderRgb = _frameOrderRgb;
image.version = getVersion();
image.isError = hasError();
image.stride = 0;
image.data = nullptr;
_image.width = _frameWidth;
_image.height = _frameHeight;
_image.isOrderRgb = _frameOrderRgb;
_image.version = getVersion();
_image.isError = hasError();
_image.stride = 0;

while ((dequeueFrame = pw_stream_dequeue_buffer(_pwStream)) != nullptr)
{
Expand Down Expand Up @@ -816,7 +830,7 @@ void PipewireHandler::grabFrame()
if (!_infoUpdated)
printf("PipewireEGL: succesfully rendered the DMA texture\n");

image.data = frameBuffer;
_image.data = frameBuffer;
}

break;
Expand All @@ -837,7 +851,7 @@ void PipewireHandler::grabFrame()
}
else
{
image.stride = newFrame->buffer->datas->chunk->stride;
_image.stride = newFrame->buffer->datas->chunk->stride;

if (newFrame->buffer->datas->type == SPA_DATA_MemFd)
{
Expand All @@ -852,26 +866,22 @@ void PipewireHandler::grabFrame()
}
else
{
image.data = mappedMemory;
_image.data = (uint8_t*) malloc(_image.stride * _frameHeight);
memcpy(_image.data, mappedMemory, _image.stride * _frameHeight);
}
}
else if (newFrame->buffer->datas->type == SPA_DATA_MemPtr)
{
image.data = static_cast<uint8_t*>(newFrame->buffer->datas[0].data);
_image.data = (uint8_t*) malloc(_image.stride * _frameHeight);
memcpy(_image.data, static_cast<uint8_t*>(newFrame->buffer->datas[0].data), _image.stride * _frameHeight);
}
}
}

// forward the frame
_callback(image);

// clean up
if (mappedMemory != nullptr)
munmap(mappedMemory, newFrame->buffer->datas->maxsize + newFrame->buffer->datas->mapoffset);

if (frameBuffer != nullptr)
free(frameBuffer);

if (newFrame != nullptr)
pw_stream_queue_buffer(_pwStream, newFrame);

Expand Down
2 changes: 2 additions & 0 deletions sources/grabber/pipewire/PipewireHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ public Q_SLOTS:
pw_stream* createCapturingStream();
QString getSessionToken();
QString getRequestToken();
void captureFrame();

pipewire_callback_func _callback;
QString _sessionHandle;
Expand Down Expand Up @@ -149,6 +150,7 @@ public Q_SLOTS:
int64_t _frameDrmFormat;
int64_t _frameDrmModifier;
QTimer _timer;
PipewireImage _image;

#ifdef ENABLE_PIPEWIRE_EGL
eglGetProcAddressFun eglGetProcAddress = nullptr;
Expand Down

0 comments on commit 939cc29

Please sign in to comment.