set image raw data buffer to QMediaPlayer - qt

I want to get a screen shot of the widget application and then set its raw data buffer to QMeidaPlayer with setMedia(). What I have done so far is to receive the image, SAVE it, and then read from it. However, I would like to ask you how to read raw data directly without saving it into media player:
QPixmap originalPixmap = QPixmap::grabWidget(this);
QImage *image = new QImage(originalPixmap.toImage());
QByteArray ba;
QBuffer buffer(&ba);
buffer.setBuffer(&ba);
buffer.open(QIODevice::WriteOnly);
image->save(&buffer); // writes image into ba in PNG format
image->save(image Path);
mediaPlayer.setMedia(QUrl::fromLocalFile(image path)); //I want this to read from raw data
mediaPlayer.play();
I want this to take the minimum CPU usage. However, saving and reading from file consumes lots of CPU,47%.
Cheers,
Update: I tested the program with this code snippet as well. But it does not draw the buffer contents on video widget.
QBuffer *buffer = new QBuffer(image_ba);
QMediaContent media;
mediaPlayer.setMedia(media, buffer);
mediaPlayer.play();
Any ideas how I can resolve this to input image raw data to video widget?

here's how you can do it:
QPixmap originalPixmap = QPixmap::grabWidget(this);
QBuffer *buffer = new QBuffer(); // make sure that your buffer has the same life span as your media player, or otherwise the media player would try to read data from non-existing buffer. (the setMedia() and play() methods are non-blocking)
buffer.open(QIODevice::ReadWrite);
originalPixmap.save(buffer, "PNG"); // can be any other format, not just PNG
mediaPlayer.setMedia(QUrl(), buffer);
mediaPlayer.play();

Related

QT QVideoFrame memcpy zero-copy alternative

I get raw video data from the V4L2 driver using VIDIOC_DQBUF and I want to render this frames in qt using QVideoFrame as described here: https://blog.katastros.com/a?ID=9f708708-c5b3-4cb3-bbce-400cc8b8000c
This code works well but has huge performance issues.
Here is the problematik code part when doing this:
QVideoFrame f(size, QSize(width, height), width, QVideoFrame::Format_YUV420P);
if (f.map(QAbstractVideoBuffer::WriteOnly)) {
memcpy(f.bits(), data, size);
f.setStartTime(0);
f.unmap();
emit newFrameAvailable(f);
}
The memcpy operation for my 4K video reduces the framerate from 35fps to 5fps on my arm based embedded system.
This constructor is supposed to constructs a video frame from a buffer with the given pixel format and size in pixels. However I cannot find any example of this:
QVideoFrame::QVideoFrame(QAbstractVideoBuffer *buffer, const QSize &size, QVideoFrame::PixelFormat format)
I just need to pass valid buffer to QVideoFrame. I don't need to map or unmap the QVideoFrame. Like this:
unsigned char * pBuffer = get_pointer_to_a_frame();
QVideoFrame frame((QAbstractVideoBuffer *) pBuffer, QSize(width, height), QVideoFrame::Format_YUV420P);
frame.setStartTime(0);
emit newFrameAvailable(frame);
Any zero-copy QVideoFrame usage will wellcome.

Play video using QMediaplayer from buffer and append buffer while the video playing

I tried to play video from a buffer and append the buffer while playing so the two or more videos play after each other without any delay as they are one video, I tried to use the QMediaPlaylist and append the list during run time, it worked but there is a Noticeable delay between the videos I use this code in the play button
void MainWindow::on_pushButton_2_clicked()
{
player = new QMediaPlayer(this);
QFile file("D:/video/first.mp4");
file.open(QIODevice::ReadOnly);
arr = new QByteArray();
arr->append(file.readAll());
file.close();
buffer = new QBuffer(arr);
buffer->open(QIODevice::ReadWrite);
player->setVideoOutput(ui->widget);
player->setMedia(QMediaContent(), buffer);
player->play();
}
and a button to append the second video during the runtime which is here I make many different trys
void MainWindow::on_pushButton_3_clicked()
{
QFile file("D:/video/second.mp4");
file.open(QIODevice::ReadOnly);
QByteArray temp = file.readAll();
//arr->append(temp, temp.size()); //first to append the QByteArray did not work
buffer->write(temp.data(), temp.size()); //second write to the buffer but not work
file.close();
qDebug() << "Appeneded";
}
first one which is append the array but it did not work, same as when i set the buffer to ReadWrite flage and its the same result, the result is that only the first video is played and it stop,
so can you help me to make this work? what i did wrong in my code let the second video not run smoothly after first video and this is the result i want.

Convert jpeg image to thumbnail image in Qt

A QImage needs to be finally shown as a thumbnail image in a QLabel. In between it's serialized in QByteArray and sent over the network. So, can we convert the QImage to QByteArray for thumbnail? Basically I want to avoid the QImage::scale() method as it's quite CPU consuming.
Like QImage converted to a QByteArray which will hold data for thumbnail images.
On this case you cannot avoid QImage::scale. Why do you want?
This is the answer to your question how to save QImage to QByteArray.
QFile file(imagePath);
if (file.open(QIODevice::ReadOnly)) {
QByteArray bytes;
QImage img;
img = img.fromData(file.readAll());
img = img.scaled(200, 100, Qt::IgnoreAspectRatio, Qt::FastTransformation);
SetLabelImage(img);
QBuffer buffer(&bytes);
img.save(&buffer, "PNG");
}

Qt - Cannot export QImage to 16bit bmp

I have created a simple application and I need export from pixmap to the 16-bit bmp image. I have several pixmap items so I have the for loop like this where I first create QImage and convert it to Format_RGB16:
for(QList<image_handler * >::iterator it=imageItems->begin(); it!=imageItems->end(); it++)
{
...
// image_handler inherits QPixmap
QFile export_image(path+"/img_"+code+".bmp");
QImage export_img = (*it)->toImage().convertToFormat(QImage::Format_RGB16);
export_img.save(&export_image, "BMP");
...
}
where image_handler is my custom QPixmap. Images are exported at path given, with correct filename. However when I look at properties of file (in windows) I can see that image depth is 24-bit. Unfortunately I need them to be 16-bit.
What I am doing wrong here? Or is this a bug in Qt? Then how can I export 16-bit bmps from pixmap?
Turns out, that Qt forcibly converts image, before saving it to bmp.
qt-src/src/gui/image/qbmphandler.cpp:777:
bool QBmpHandler::write(const QImage &img)
{
QImage image;
switch (img.format()) {
case QImage::Format_ARGB8565_Premultiplied:
case QImage::Format_ARGB8555_Premultiplied:
case QImage::Format_ARGB6666_Premultiplied:
case QImage::Format_ARGB4444_Premultiplied:
image = img.convertToFormat(QImage::Format_ARGB32);
break;
case QImage::Format_RGB16:
case QImage::Format_RGB888:
case QImage::Format_RGB666:
case QImage::Format_RGB555:
case QImage::Format_RGB444:
image = img.convertToFormat(QImage::Format_RGB32);
break;
default:
image = img;
}
...
So, if you need to save bmp 16bit, you'll have to do it manually, filling header and using QImage::bits() and QImage::byteCount().

Display image from raw bitmap file to bmp file

I am trying to create a QT application which will display a image (bmp) from a raw bitmap file. The raw bitmap file is of .panel file format. Its in RGB565 format.
How do we use/convert the raw bitmap (img.panel) into a bmp file, so I can use it Qimage.
QFile file("/usr/bitmap.bmp");
if (!file.open(QFile::ReadOnly))
return 0;
QByteArray array = file.readAll();
QImage image((const uchar*)array.data(), h_bitmap, v_bitmap, QImage::Format_RGB16);
image.save("/usr/test_qimg_16.bmp","BMP");
image = image.convertToFormat(QImage::Format_RGB16);
image.load("/usr/test_qimg_16.bmp");
QPixmap pixmap;
This is the image I get after this operation.
http://tinypic.com/r/kb4pd4/8
But I am expecting something like this :
http://tinypic.com/r/dptpq1/8
Thank you.
Any help is appreciated.

Resources