mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-09-10 03:53:23 +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()) {
|
||||
auto fo = std::make_unique<FrameObject>();
|
||||
fo->videoFrame = std::make_unique<QVideoFrame>(frameFormat);
|
||||
qDebug() << "Create new QVideoFrame " << frameFormat.frameSize();
|
||||
framesObjects_.emplace(id, std::move(fo));
|
||||
} else {
|
||||
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;
|
||||
return;
|
||||
}
|
||||
auto frame = avModel_.getRendererFrame(id);
|
||||
std::memcpy(videoFrame->bits(0), frame.ptr, frame.size);
|
||||
auto srcFrame = avModel_.getRendererFrame(id);
|
||||
if (srcFrame.ptr != nullptr and srcFrame.size > 0) {
|
||||
copyUnaligned(videoFrame, srcFrame);
|
||||
}
|
||||
}
|
||||
if (videoFrame->isMapped()) {
|
||||
videoFrame->unmap();
|
||||
|
@ -206,3 +210,34 @@ VideoProvider::onRendererStopped(const QString& id)
|
|||
}
|
||||
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);
|
||||
|
||||
private:
|
||||
void copyUnaligned(QVideoFrame* dst, const video::Frame& src);
|
||||
AVModel& avModel_;
|
||||
|
||||
struct FrameObject
|
||||
|
|
Loading…
Add table
Reference in a new issue