Skip to content
Snippets Groups Projects
Commit 6f1945af authored by Mohamed Chibani's avatar Mohamed Chibani Committed by Sébastien Blin
Browse files

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
parent 6d3ae747
No related branches found
No related tags found
No related merge requests found
......@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment