QImage to QVideoFrame Conversion access violation issue
-
QVideoFrameFormat format(image.size(), QVideoFrameFormat::pixelFormatFromImageFormat(image.format()));
QVideoFrame frame(format);
if (!frame.isValid()) {
qDebug() << "Error: Invalid video frame format";
// Handle error
} else {
if (!frame.map(QVideoFrame::ReadWrite)) {
qDebug() << "Error: Failed to map video frame";
// Handle error
} else {
// Check if mapping succeeded
qDebug() << "Video frame mapped successfully";// Perform memcpy for each plane const int planeCount = frame.planeCount(); for (int plane = 0; plane < planeCount; ++plane) { uchar* frameBits = frame.bits(plane); uchar* imgBits = image.bits(); const int planeBytes = frame.mappedBytes(plane); // Check if sizes match for this plane if (frameBits && imgBits && planeBytes >= 0) { memcpy(frameBits, imgBits, planeBytes); qDebug() << "Memcpy for plane" << plane << "completed successfully"; } else { qDebug() << "Error: Invalid pointer(s) or plane size"; // Handle error } } // Unmap the frame after memcpy frame.unmap(); } }
This is my code for the conversion from QImage to QVideoFrame but am facing access violation issue due to this(memcpy(frameBits, imgBits, planeBytes)) I think so. How can I solve this issue?
-
@iSolve_Tech said in QImage to QVideoFrame Conversion access violation issue:
I think so.
You think so or did you run in debugger to validate this assumption?
How does stack trace look like after the crash? -
@iSolve_Tech Then check what you pass to memcpy: are both dest/src pointers valid? Is dest pointing to a memory chunk same size or bigger than src?
-
@iSolve_Tech
Some minor points:
First, this line will make a deep copy of the image data, which is a waste.uchar* imgBits = image.bits();
So it is better to add
const
.Second, since
QImage
does not support multiple planes, there will always be only plane 0.Then the important point, have you tried print
qDebug() << planeBytes << image.sizeInBytes();
You probably will see
planeBytes
is not same asimage.sizeInBytes()
That's what I suppose whymemcpy
would have access violation, the data size inQVideoFrame
is aligned and maybe bigger thanQImage
. So what you should do is copy data line by line.I modified your code to
QVideoFrameFormat format(image.size(), QVideoFrameFormat::pixelFormatFromImageFormat(image.format())); QVideoFrame frame(format); if (!frame.isValid() || frame.planeCount() <= 0) { qDebug() << "Error: Invalid video frame format"; // Handle error } else { if (!frame.map(QVideoFrame::ReadWrite)) { qDebug() << "Error: Failed to map video frame"; // Handle error } else { // Check if mapping succeeded qDebug() << "Video frame mapped successfully"; uchar* frameBits = frame.bits(0); const uchar* imgBits = image.constBits(); const int planeBytes = frame.mappedBytes(0); // Check if sizes match for this plane if (frameBits && imgBits && planeBytes >= 0) { const int lineBytesFrame = frame.bytesPerLine(0); const int lineBytesImage = image.bytesPerLine(); const int imageHeight = image.height(); for(int line = 0; line < imageHeight; line++){ // Perform memcpy for each line //you can add error handling here since memcpy_s can return errors memcpy_s(frameBits, lineBytesFrame, imgBits, lineBytesImage); frameBits += lineBytesFrame; imgBits += lineBytesImage; } qDebug() << "Memcpy completed successfully"; } else { qDebug() << "Error: Invalid pointer(s) or plane size"; // Handle error } // Unmap the frame after memcpy frame.unmap(); }
-
@Bonnie Thanks you so much for your time I will modify the code you provide and will check .
-
@Bonnie QVideoFrameFormat format(image.size(), QVideoFrameFormat::pixelFormatFromImageFormat(image.format()));
QVideoFrame frame(format);
if (!frame.isValid() || frame.planeCount() <= 0) {
qDebug() << "Error: Invalid video frame format";
// Handle error
} else {
if (!frame.map(QVideoFrame::ReadWrite)) {
qDebug() << "Error: Failed to map video frame";
// Handle error
} else {
// Check if mapping succeeded
qDebug() << "Video frame mapped successfully";
uchar* frameBits = frame.bits(0);
const uchar* imgBits = image.constBits();
const int planeBytes = frame.mappedBytes(0);// Check if sizes match for this plane if (frameBits && imgBits && planeBytes >= 0) { const int lineBytesFrame = frame.bytesPerLine(0); const int lineBytesImage = image.bytesPerLine(); const int imageHeight = image.height(); for(int line = 0; line < imageHeight; line++){ // srinadh // Perform memcpy for each line memcpy(frameBits, imgBits, lineBytesImage); } qDebug() << "Memcpy completed successfully"; } else { qDebug() << "Error: Invalid pointer(s) or plane size"; // Handle error } // Unmap the frame after memcpy frame.unmap(); } } Buffer updatedFrame = Buffer(frame); updatedFrame.copyTsFrom(newFrame); updatedFrame.setUnmodifiedVideoFrame(newFrame.videoFrame()); newFrame = updatedFrame; qDebug() << "image processed";
this memcopy is working fine in iOS and Windows but in android after am converting the image to frame I can able to see black screen
-
@Bonnie Can you please give me some idea regarding the issue in android ?
am getting this error - freeAllBuffers: 1 buffers were freed while being dequeued!
-
@iSolve_Tech Hi,
From old memories, I think that on Android, it's an OpenGL texture and you have to handle it accordingly.
-
@iSolve_Tech Sorry I don't develop on android, also this seems not related to this topic.
-
@SGaist Thanks for your reply will check in that way