mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-09-10 12:03:18 +02:00
SHM: Fix copy from shared memory to QVideoFrame
Frames in shared memory have no specific line alignment (i.e. stride = width), as opposed to the QVideoFrame, so the copy need to be done accordingly. Gitlab: #721 Change-Id: Id6576e55c5742a4e99d603feb4bc78f4d2be1ff0
This commit is contained in:
parent
6d3ae747bc
commit
6f1945af48
2 changed files with 38 additions and 2 deletions
|
@ -111,9 +111,11 @@ VideoProvider::onRendererStarted(const QString& id)
|
||||||
if (it == framesObjects_.end()) {
|
if (it == framesObjects_.end()) {
|
||||||
auto fo = std::make_unique<FrameObject>();
|
auto fo = std::make_unique<FrameObject>();
|
||||||
fo->videoFrame = std::make_unique<QVideoFrame>(frameFormat);
|
fo->videoFrame = std::make_unique<QVideoFrame>(frameFormat);
|
||||||
|
qDebug() << "Create new QVideoFrame " << frameFormat.frameSize();
|
||||||
framesObjects_.emplace(id, std::move(fo));
|
framesObjects_.emplace(id, std::move(fo));
|
||||||
} else {
|
} else {
|
||||||
it->second->videoFrame.reset(new QVideoFrame(frameFormat));
|
it->second->videoFrame.reset(new QVideoFrame(frameFormat));
|
||||||
|
qDebug() << "QVideoFrame reset to " << frameFormat.frameSize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,8 +176,10 @@ VideoProvider::onFrameUpdated(const QString& id)
|
||||||
qWarning() << "QVideoFrame can't be mapped" << id;
|
qWarning() << "QVideoFrame can't be mapped" << id;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto frame = avModel_.getRendererFrame(id);
|
auto srcFrame = avModel_.getRendererFrame(id);
|
||||||
std::memcpy(videoFrame->bits(0), frame.ptr, frame.size);
|
if (srcFrame.ptr != nullptr and srcFrame.size > 0) {
|
||||||
|
copyUnaligned(videoFrame, srcFrame);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (videoFrame->isMapped()) {
|
if (videoFrame->isMapped()) {
|
||||||
videoFrame->unmap();
|
videoFrame->unmap();
|
||||||
|
@ -206,3 +210,34 @@ VideoProvider::onRendererStopped(const QString& id)
|
||||||
}
|
}
|
||||||
it->second->videoFrame.reset();
|
it->second->videoFrame.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
VideoProvider::copyUnaligned(QVideoFrame* dst, const video::Frame& src)
|
||||||
|
{
|
||||||
|
// Copy from a frame residing in the shared memory.
|
||||||
|
// Frames in shared memory have no specific line alignment
|
||||||
|
// (i.e. stride = width), as opposed to QVideoFrame frames,
|
||||||
|
// so the copy need to be done accordingly.
|
||||||
|
|
||||||
|
// This helper only handles RGBA and BGRA pixel formats, so the
|
||||||
|
// following constraints must apply.
|
||||||
|
assert(dst->pixelFormat() == QVideoFrameFormat::Format_RGBA8888
|
||||||
|
or dst->pixelFormat() == QVideoFrameFormat::Format_BGRA8888);
|
||||||
|
assert(dst->planeCount() == 1);
|
||||||
|
|
||||||
|
const int BYTES_PER_PIXEL = 4;
|
||||||
|
|
||||||
|
// The provided source must be valid.
|
||||||
|
assert(src.ptr != nullptr and src.size > 0);
|
||||||
|
if (dst->width() * dst->height() * BYTES_PER_PIXEL != src.size) {
|
||||||
|
qCritical() << "Size mismatch. Actual " << src.size << " Expected "
|
||||||
|
<< dst->width() * dst->height() * BYTES_PER_PIXEL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int row = 0; row < dst->height(); row++) {
|
||||||
|
auto dstPtr = dst->bits(0) + row * dst->bytesPerLine(0);
|
||||||
|
auto srcPtr = src.ptr + row * dst->width() * BYTES_PER_PIXEL;
|
||||||
|
std::memcpy(dstPtr, srcPtr, dst->width() * BYTES_PER_PIXEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ private Q_SLOTS:
|
||||||
void onRendererStopped(const QString& id);
|
void onRendererStopped(const QString& id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void copyUnaligned(QVideoFrame* dst, const video::Frame& src);
|
||||||
AVModel& avModel_;
|
AVModel& avModel_;
|
||||||
|
|
||||||
struct FrameObject
|
struct FrameObject
|
||||||
|
|
Loading…
Add table
Reference in a new issue