QSharedMemory not the same size - qt

QSharedMemory is changing sizes on me.
create:
...
int size = buffer->size();
qDebug() << "buffer->size()" << size << "points" << points->size() << "share name" << sharedMemoryName;
if (!m_sharedMemory->create(size)) {
qCritical() << tr("Unable to create shared memory segment.");
return;
}
m_sharedMemory->lock();
char *to = (char*)m_sharedMemory->data();
memcpy(to, buffer->data(), qMin(m_sharedMemory->size(), size));
m_sharedMemory->unlock();
read:
QSharedMemory sharedMemory(sharedMemoryName);
if (!sharedMemory.attach(QSharedMemory::AccessMode::ReadOnly)) {
qCritical() << "Unable to attach to shared memory segment.";
return nullptr;
}
qDebug() << sharedMemoryName << sharedMemory.size();
Not the same size.
when create the size is 658824
when read the size is 659456
ok - sounds crazy now, but I run the read multiple times and all the sudden the size was correct. Then I restarted everything (same size on create) and the error came back.
edit:
I just realized that the size of the QSharedMemory is not necessarily then same as the QBuffer
memcpy(to, buffer->data(), qMin(m_sharedMemory->size(), size));
why is that and how can I know "on the other side" the correct size (without making an ugly workaround)
edit 2:
I may found it. looks like QSharedMemory reserves the memory in 4096 blocks.
solution for me is to check the QByteArray for empty
if(in.at(i) == QChar(0))
break;

Related

CL_OUT_OF_HOST_MEMORY when using CL_MEM_USE_HOST_PTR to create buffer

I was previously allocating a buffer using the iterator method of the opencl 1.2 wrapper. However for performance reasons I have tried to provide a host pointer to the memory already allocated. However when specifying a buffer with this I get a CL_OUT_OF_HOST_MEMORY error on clCreateBuffer call.
This code previously worked when I had my memory allocated as std::vector and provided the buffer with the iterator method e.g
std::vector<int> mem;
mem.resize( 256*256*256, 0);
_d_currentmap= cl::Buffer(*_context,
mem.begin(), mem.end(), false);
_d_currentmap is created and doesn't throw any errors. I actually create two buffers of the same size.
Following this intel article, I am trying to migrate to a zero copy paradigm as I am deploying intel HD graphics which shares mem with the cpu
First I initialise memory that is to be shared, _map1 and _map2 are initilised.:
int size = 256*256*256;
int* _map1 = (int*)aligned_alloc(4096, sizeof(int)*size);
int* _map2 = (int*)aligned_alloc(4096, sizeof(int)*size);
memset((void*)_map1, 0, size*sizeof(int));
memset((void*)_map2, 0, size*sizeof(int));
I then want to swap between these objects alternatively:
int size = 256*256*256*sizeof(int);
int* currptr, newptr;
switch( newmapnumber)
{
case 1:
memset(_map1, 0, size);
newptr= _map1;
currptr= _map2;
break;
case 2:
memset(_map2, 0, size);
newptr =_map2;
currptr =_map1;
break;
}
_mapSeq++;
try{
cl::CommandQueue queue(*_context, CL_QUEUE_PROFILING_ENABLE);
_d_newmap = cl::Buffer(*_context, CL_MEM_USE_HOST_PTR | CL_MEM_READ_WRITE, size*sizeof(int),(void*) newptr);
_d_currentmap = cl::Buffer(*_context, CL_MEM_USE_HOST_PTR | CL_MEM_READ_WRITE, size*sizeof(int), (void*)currptr);
queue.finish();
}
catch (cl::Error err) {
std::cout << "Exception\n";
std::cerr
<< "ERROR: "
<< err.what()
<< "("
<< err.err()
<< ")"
<< std::endl;
exit(1);
}
This will return
Exception
ERROR: clCreateBuffer(-6)
Which is a CL_OUT_OF_HOST_MEMORY error as defined in cl.h
Okay, no-one would have got this, as I didn't add the key piece of information. The int size changed in value between the two blocks.
As shown in the top code block
int size = 256*256*256;
however in the bottom block I specified a local variable size (for use in the cl::Buffer declarations) to be
int size=256*256*256*sizeof(int);
Thus in the declaration of the buffer I am multiplying size by sizeof(int) again:
_d_newmap = cl::Buffer(*_context, CL_MEM_USE_HOST_PTR | CL_MEM_READ_WRITE, size*sizeof(int),(void*) newptr);
causing buffer overwrites and a bunch of other grief.

QAudioBuffer providing different data of the same song in different computers

I'm creating a music player for PC. I want to visualize the FFT of the song. I've crated an entire class that buffers 1024 points of data does the FFT and displays it (this is handled by another class). My program was developed in my laptop which uses Debian Testing x64. My work pc uses Centos 7 x64. When I compiled my program (both use Qt 5.7.0) on my work PC the FFT visualization was garbage. Snooping into my code I found that the sample type provided by QAudioBuffer from QAudioProbe was Signed (in my work PC) while it was float in my Laptop. Here is the code that is called whenever QAudioProbe emits that data has been buffered:
void SpectrumController::setAudioBuffer(QAudioBuffer buffer){
// Used to momentarily stop the process.
if (!enableBuffering) return;
// Only process stereo frames
if (buffer.format().channelCount() != 2) return;
if (buffer.format().sampleType() == QAudioFormat::SignedInt){
//qWarning() << "Signed";
QAudioBuffer::S16S *data = buffer.data<QAudioBuffer::S16S>();
bufferData(data,buffer.frameCount());
}
else if (buffer.format().sampleType() == QAudioFormat::UnSignedInt){
//qWarning() << "Unsigned";
QAudioBuffer::S16U *data = buffer.data<QAudioBuffer::S16U>();
bufferData(data,buffer.frameCount());
}
else if(buffer.format().sampleType() == QAudioFormat::Float){
//qWarning() << "Float";
QAudioBuffer::S32F *data = buffer.data<QAudioBuffer::S32F>();
bufferData(data,buffer.frameCount());
}
}
template<typename T>
void SpectrumController::bufferData(T *data, qint32 N){
for (qint32 i = 0; i < N; i++){
//if (qAbs(data[i].left) > largest){largest = qAbs(data[i].left); qDebug() << "Largest" << largest;}
//currentBuffer << ((qreal)data[i].left/(largest));
//qWarning() << "Added data" << currentBuffer.last();
currentBuffer << data[i].left;
if (datcounter < 100000){
*writer << data[i].left;
*writer << "\n";
datcounter++;
}
else if (writeFile->isOpen()){
qWarning() << "Closed file";
writeFile->close();
}
if (currentBuffer.size() == FFT_SIZE){
dataBuffer << currentBuffer;
currentBuffer.clear();
if (!isRunning) run();
}
What I ended up doing is writing, to a file, the first 100.000 points of data gathered by both my laptop and my work PC in order to plot them.
This is what I've got
What I think is that difference is in the base system's handling of the the mp3, which, in turn, is what Qt uses. I think is gstreamer. Centos uses a much older version. The plot on the right corresponds to my laptop while the plot on the left corresponds to my work pc.
Any ideas on how to fix this? Or am I just stuck with no way of accessising the raw audio data correctly?
UPDATE:
Even though this is not a Fix or anything like that, the data in the other channel (data[i].right) did have more appropiate data. I'm using the right channnel, for now.

QImageReader::text() does not work properly

I need to read image description (QImage::text()) without reading whole image. I used QImageReader, but its behaviour is very strange. It does not return text() or textKeys() but QImage does.
Example code:
QImageReader imageReader(filename,0);
QImage image;
bool ok=imageReader.read(&image);
qDebug() << "KEYS_READER: " << imageReader.textKeys() << "\n";
qDebug() << "KEYS_IMAGE: " << image.textKeys() << "\n";
When I try to load data from image which has one text key it prints in the debug window:
KEYS: ()
KEYS0: ("UVFI")
But I need to retrieve keys without reading the whole image data.

If I reuse a QProcess variable, can there be leftover data in the stdout/stderr channels?

I have the following scenario:
QProcess*p;
// later
p->start();
//later
p->terminate(); // there might be unread data in stdout
//later
p->start();
I read the process stdout. After I call p->start() the second time, could there still be unread data left in the stdout buffers from the first p->start()? That would be a problem for me. Do I need to flush the buffers or something?
Okay, I've checked the sources. The QProcess::start() method explicitly clears both output buffers, so it should be okay, at least in this sense:
void QProcess::start(const QString &program, const QStringList &arguments, OpenMode mode)
{
Q_D(QProcess);
if (d->processState != NotRunning) {
qWarning("QProcess::start: Process is already running");
return;
}
#if defined QPROCESS_DEBUG
qDebug() << "QProcess::start(" << program << "," << arguments << "," << mode << ")";
#endif
d->outputReadBuffer.clear();
d->errorReadBuffer.clear();
I still think it's a bad style to reuse the same object, though.

QList memory deallocation

I'm trying to free memory after using QList, but it doesn't seem to work properly.
Here's my code:
QList<double> * myList;
myList = new QList<double>;
double myNumber;
cout << "CP1" << endl;
getchar(); // checkpoint 1
for (int i=0; i<1000000; i++)
{
myNumber = i;
myList->append(myNumber);
cout << myList->size() << endl;
}
cout << "CP2!" << endl;
getchar(); // checkpoint 2
for (int i=999999; i>0; i--)
{
myList->removeLast();
cout << myList->size() << endl;
}
cout << "CP3!" << endl;
getchar(); // checkpoint 3
delete myList;
cout << "CP4!" << endl;
getchar(); // checkpoint 4
Memory usage:
CP1: 460k
CP2:19996k
CP3:19996k
CP4:16088k
So it looks like despite removing of elements and deleting myList still large part of memory is being used. I believe there is a way to handle it but I can't find it.
Thanks in advance for any help.
Pawel
Memory manager is not required to release the memory your program has allocated. There are no problems in your deallocation.
QList is an array based list. The array expands automatically, but does not shrink automatically. Removing elements from the list does not affect the size of the array.
To trim the array down to the actual size, create a new QList and add the contents to it. Then delete the original list.
Unfortunately looks like there is no convenience method to do this, like the List.TrimExcess() in .NET.

Resources