Error when trying to access frames from multithreading video capturing - multithreading

I am using ltbb to stream from two cameras. ltbb creates two threads(because of two cameras) for simultaneous streaming from two cameras. It makes use of concurrent queues for fetching frames. The following code snippet displays frames:
while (waitKey(20) != 27)
{
//Retrieve frames from each camera capture thread
vector<Mat> iMats(capture_source.size());
for (int i = 0; i < capture_source.size(); i++)
{
Mat frame;
//Pop frame from queue and check if the frame is valid
if (cam.frame_queue[i]->try_pop(frame))
{
//Show frame on Highgui window
// IMats.push_back(frame);
iMats[i] = frame;
imshow(label[i], frame);
}
} // end of for - loop
int x = opencv_tri(iMats);
}
The problem is when I am doing iMats[i] = frame and pass it to other function, It's giving me an error. It works fine when I comment iMats and stop calling opencv_tri(iMats).
Error: Segmentation fault (core dumped)
Link to opencv_tri: opencv_tri.cpp
Can anyone please explain and help me to fix this?

Unfortunatly I can't comment.
I think your vector is empty, therefor you can not access the [i]'th element.
vector<Mat> iMats(capture_source.size());
This creates an empty Vector with capture_source.size() elements.

I did not go through the whole opencv_tri function that you linked, but I spot the possible error.
you have the following
for(int i = 0;i<imats.size();i+=2)
{
...
Mat imgATest = imats[i];
Mat imgBTest = imats[i+1];
when i is in imats.size()-1 it will try to access:
Mat imgBTest = imats[i+1];
This is an out of bounds. since i+1 is imats.size()
You have to loop up to imats.size()-1
for(int i = 0;i<imats.size()-1;i+=2)
{
this way it will not try to access the wrong value

Related

error says vulkan queue waiting on semaphore that has no way to be signaled (actually will be signaled)

I have read these two similar questions:
Vulkan queue waiting on semaphore that has no way to be signaled
vkQueuePresentKHR validation bug
The first one is caused by signaling semaphore A and waiting on semaphore B; The second one is caused by present before submit. However, my case is quite different. When the program runs, the validation layer will throw error:
--> Validation Error: [ VUID-vkQueuePresentKHR-pWaitSemaphores-03268 ]
Object 0: handle = 0x14e37396870, name = queueGCT, type = VK_OBJECT_TYPE_QUEUE;
Object 1: handle = 0x2b424a0000000034, name = swapchainWrittenSemaphore:1, type = VK_OBJECT_TYPE_SEMAPHORE; |
MessageID = 0x251f8f7a |
vkQueuePresentKHR: Queue VkQueue 0x14e37396870[queueGCT] is waiting on
pWaitSemaphores[0] (VkSemaphore 0x2b424a0000000034[swapchainWrittenSemaphore:1]) that has no way to be signaled.
According to the message, the error is most likely caused by a semaphore that will never be signaled. However, this is weird.In my case, the swapchain creates 3 entries and has 3 somaphore pairs (readSemaphore[0,1,2] and writeSemaphore[0,1,2]). My program is like:
// Main loop
while (!glfwWindowShouldClose(...)) {
// ...
prepareFrame();
// create command buffer and record commands ...
vkBeginCommandBuffer(cmdBuf, &beginInfo);
// -- ray tracing...
// -- post processing...
vkEndCommandBuffer(cmdBuf);
submitFrame();
}
In the prepareFrame(), the swapchain vkAcquireNextImageKHR and will signal readSemaphore[cur_loop % 3] when preparing is done.
In the submitFrame(), the program first vkQueueSubmit which waits on readSemaphore[cur_loop % 3] and will signal writeSemaphore[cur_loop %3] when queue is done. Then the program vkQueuePresentKHR which waits on writeSemaphore[cur_loop %3]. The code can be found in nvpro_core's swapchain_vk.h/cpp and appbase_vk.h/cpp.
The error will only be trigered When the loop goes through the 2nd (or 3rd) time and the triger point is submitFrame()::present()::vkQueuePresentKHR(). It is weird because the 1st loop and 2nd/3rd loop do the same thing but there is no problem with the 1st loop. I debugged the code and found that the waitSemaphore writtenSemphore[1]enter image description here in vkQueuePresentKHR() should have been signaled by vkQueueSubmit() in submitFrame().
In visual studio debugger, semaphoreWrite = 0x2b424a0000000034 and written = 0x2b424a0000000034. The image can referred here:
vkQueueSubmit signals semaphoreWrite and vkQueuePresentKHR waits on written. They are the same semaphore.
The strangest thing is that this bug seems to be related to my raytracing shader code. When I comment the raytracing procedure in main loop, the program runs fine. If the raytracing procedure is preserved, simple shader code like generating a uv coordinate at the output image will not cause problem, while computing hit distance will.
// writing uv coordinate, works fine
// ---------------------------------
// ray generation
void main()
{
const ivec2 resolution = imageSize(image);
const ivec2 pixel = ivec2(gl_LaunchIDEXT.xy);
if((pixel.x >= resolution.x) || (pixel.y >= resolution.y))
{
return;
}
vec4 color = vec4(pixel.x / float(resolution.x),
pixel.y / float(resolution.y),
0.0, 0.0);
imageStore(image, pixel, color);
}
// close hit
void main() {}
// writing depth, works fine
// ---------------------------------
// ray generation
traceRayEXT(topLevelAS, // acceleration structure
rayFlags, // rayFlags
0xFF, // cullMask
0, // sbtRecordOffset
0, // sbtRecordStride
0, // missIndex
origin.xyz, // ray origin
tMin, // ray min range
direction.xyz, // ray direction
tMax, // ray max range
0 // payload (location = 0)
);
imageStore(image, ivec2(gl_LaunchIDEXT.xy), vec4(payload.radiance, 1.0));
// close hit
void main() {
payload.radiance = vec3(gl_HitTEXT);
}
However, made a small adjustment, the error will occur:
// close hit
void main() {
payload.radiance = vec3(gl_HitTEXT/100.0);
// or any other operation to gl_HitTEXT
// or
// float x = gl_HitTEXT * 2;
// payload.radiance = vec3(x);
}
Could anyone please help me? Thanks in advance!
Some code here.
Solved. Finally, I found that only ray generation shader was added to the shader group when creating shader binding table. That is, close hit shader and ray miss shader were missing.

UWP no error but can not display my screen

I am writing an uwp program, you may treat it as a drawing segments program:
It is only allow to draw segments horizontal or vertical.
a new segment must start at an old segment's vertex, and there are two situation not allowed in this program:
1.overlap.
2.intersection.
Here is my code to judge if two segments are cross over each other,Here is my code :
(I use a for loop to select all of segments I have already created, "line[]" stored all the segments I have already created and "ln" stored a random new segment, it will add the new segment to "line[]" if no erro occurs)
for (int l = 0; l < i - 1; l++)
{
if (ln.getY1() == ln.getY()&&line[l].getX()==line[l].getX1())
{
if(line[l].getX()>=Math.Min(ln.getX(),ln.getX1())&&line[l].getX()<=Math.Max(ln.getX(), ln.getX1())&&ln.getY()>=Math.Min(line[l].getY(),line[l].getY1())&&ln.getY()<= Math.Max(line[l].getY(), line[l].getY1()))
{
sameIslandCount++;
}
}
else if (ln.getX1() == ln.getX()&&line[l].getY()==line[l].getY1())
{
if(ln.getX()>=Math.Min(line[l].getX(),line[l].getX1())&&ln.getX()<=Math.Max(line[l].getX(), line[l].getX1())&&line[l].getY()>=Math.Min(ln.getY(),ln.getY1())&& line[l].getY() <= Math.Max(ln.getY(), ln.getY1()))
{
sameIslandCount++;
}
}
}
but when I test this program, it stuck in this screen:
but if I delete all the equal symbol, the program can run successfully. Can anyone tell me how to improve? sorry about my English, hope you can understand what I mean:p

Filling QGraphicsScene with items in thread

I have the thread where the worker object is running infinite cycle. Here I have the following code that I would like it to read coordinates from list and place QGraphicsEllipseItem on these coordinates. The list can be updated by another thread, so I protect it by mutex. But sometimes the size of list may grow up so I would like to create new QGraphicsEllipse items for it if needed.
int meter_to_pixel_ratio = 20;
int x_pixel, y_pixel;
int i;
forever {
visualizationDataMutex->lock();
while(ellipseList->count()<visualizationData->count())
{
qDebug() << "Creating new visual item...";
ellipseList->append(new QGraphicsEllipseItem(0.0, 0.0, 10.0, 10.0));
ellipseList->last()->setVisible(false);
visualizationScene->addItem(ellipseList->last());
}
for(i=0; i<visualizationData->count(); i++)
{
x_pixel = meter_to_pixel_ratio*visualizationData->at(i)->x();
y_pixel = meter_to_pixel_ratio*visualizationData->at(i)->y();
ellipseList->at(i)->setPos(x_pixel, y_pixel);
ellipseList->at(i)->setBrush(QBrush(*visualizationColor->at(i)));
if(!ellipseList->at(i)->isVisible()) ellipseList->at(i)->setVisible(true);
}
visualizationDataMutex->unlock();
// repaint scene
visualizationScene->update();
QThread::msleep(100);
}
The problem I have is, that when I try to run the program I´ll obtain a runtime error. Tried to qDebug() the ellipseList->count() and seems to have the exactly same number of elements as needed (as visualizationData->count()). When commented these three lines:
//ellipseList->at(i)->setPos(x_pixel, y_pixel);
//ellipseList->at(i)->setBrush(QBrush(*visualizationColor->at(i)));
//if(!ellipseList->at(i)->isVisible()) ellipseList->at(i)->setVisible(true);
program can run without crashing. I do not understand why is this happening since there is no other function working with QGraphicsView/QGraphicsScene. (QGraphicsView was added from Qt Designer environment into mainwindow).

C# - Matrix Printing Incorrectly on a Separate Thread

I'm currently making a Console Application game, and am working on the multiplayer version.
When I am receiving packets, I create a new thread to handle the packets, in order to return to the ReceiveFrom command as soon as possible.
The newly created thread should reprint the whole Matrix, using the new information it got regarding the changes in the matrix (it should print the Matrix with updated player positions).
The problem is, when the Print method is called on the new thread, it is badly performed. It prints the matrix very inaccurately, and many characters of the matrix are just in a mess on the Console Screen.
Here are the methods:
void Receive()
{
while (true)
{
byte[] msg = new byte[1024];
client.Receive(msg);
Thread handle = new Thread(() => HandleInput(msg));
handle.Start();
}
}
void HandleInput(byte[] msgX)
{
string data = Encoding.ASCII.GetString(msgX);
data = data.Replace("\0", "");
if (data.Contains('*') || data.Contains('\0') || data.Contains(' ')) // Move Packet (moving objects in a matrice)
{
// for example, a move packet can be: '*'!12!10
char ToMove = char.Parse(data.Split('!')[0]);
int X = int.Parse(data.Split('!')[1]);
int Y = int.Parse(data.Split('!')[2]);
grid[X, Y] = ToMove;
Print();
}
}
void Print() // print a 20x50 matrix
{
Console.Clear();
for (int y = 0; y < 52; y++)
{
Console.Write('-');
}
Console.WriteLine();
for (int i = 0; i < 20; i++)
{
Console.Write('|');
for (int j = 0; j < 50; j++)
{
Console.Write(grid[i,j]);
}
Console.WriteLine('|');
}
for (int x = 0; x < 52; x++)
{
Console.Write('-');
}
}
But, when I tried to treat the input and print the matrix on the same thread of the Receive method, it worked fine. The problem printing it only came when I printed the matrix on a separate thread.
So why does this happen? Why can't a separate thread just print the matrix correctly?
You create a new thread for every received kilobyte, but those threads are not guaranteed to start running in sequence, to wait one another, nor to finish running in sequence.
There is also no guarantee that network client will receive all needed bytes in one call of Receive method. It may happen in one, but it may happen in several calls. It may also happen that two Send methods from the other side of the connection are merged into one message. All that is guaranteed in network communication is the ordering of the bytes in the stream, and nothing else.
Your next question will probably be "so how do I make it work"? I can't do the job for you, but this is in general how I would do it:
Read chunk of bytes from the stream and store it in some buffer.
Check in the loop for existence of a complete message in the buffer. If there is such a message remove that message from the buffer, and process the message. I would process it in the same thread, and only if there are problems with that approach I would consider additional threads (or rather just one additional thread to whom I would be sending all the messages).
Repeat the loop until all complete messages are removed from the buffer, and continue reading the stream.

How to read large number of files using multiple threads,help me please!

in my application there is a small part of function,in which it will read files to get some information,the number of filecount would be utleast 50,So I thought of implementing threading.Say if the user is giving 50 files,I wanted to separate it as 5 *10, 5 thread should be created,so that each thread can handle 10 files which can speed up the process.And also from the below code you can see that some variables are common.I read some articles about threading and I am aware that only one thread should access a variable/contorl at a me(CCriticalStiuation can be used for that).For me as a beginner,I am finding hard to imlplement what I have learned about threading.Somebody please give me some idea with code shown below..thanks in advance
file read function://
void CMyClass::GetWorkFilesInfo(CStringArray& dataFilesArray,CString* dataFilesB,
int* check,DWORD noOfFiles,LPWSTR path)
{
CString cFilePath;
int cIndex =0;
int exceptionInd = 0;
wchar_t** filesForWork = new wchar_t*[noOfFiles];
int tempCheck;
int localIndex =0;
for(int index = 0;index < noOfFiles; index++)
{
tempCheck = *(check + index);
if(tempCheck == NOCHECKBOX)
{
*(filesForWork+cIndex) = new TCHAR[MAX_PATH];
wcscpy(*(filesForWork+cIndex),*(dataFilesB +index));
cIndex++;
}
else//CHECKED or UNCHECKED
{
dataFilesArray.Add(*(dataFilesB+index));
*(check + localIndex) = *(check + index);
localIndex++;
}
}
WorkFiles(&cFilePath,dataFilesArray,filesForWork,
path,
cIndex);
dataFilesArray.Add(cFilePath);
*(check + localIndex) = CHECKED;
}
I think you would be better off having just one thread to read all the files. The context switch between the threads together with the synchronization issues is really not worth the price in your example. The hard drive is one resource so imagine all five threads taking turns moving the hard drive read heads to various positions on the hard drive == not very effective.

Resources