When I try recording videos by OpenCV, The grab thread got 210 frames from my camera with 1280*1024 resolution per second, however, the write thread can only process about 35 frames per second. Is there any way to improve the writing speed?
The following code is the run function of the writing thread, I have confirmed that the write function makes the queue buildup.
void recordThread::run(){
int count=0;
cv::Mat mat,tmp;
while (runFlag){
if(que->size()>0){
mat = this->que->dequeue();
count+=1;
if(count%100==0){
qDebug()<<count<<que->size();
}
cv::cvtColor(mat,tmp,cv::COLOR_RGB2BGR);
outputVideo<<tmp;
free(mat.data);
}
}
}
Related
I have an Qt based OpenGLES2.0 application, where I want to capture the FPS.
my application draw same geometry for 16 times and then try to know the FPS.
How can I make sure glDrawElements() has finished its job ?
I want to get the correct FPS.
Is there any way to make the glDrawElements()synchronous or Pooling the glDrawElements() complete?
define a Timer object in application window/widget class.
QTime frameTime;
Start the timer in initializeGL.
frameTime.start();
in PaintGL
paintGL ()
{
draw_your_geometry();
++frameCount;
if (frameTime.elapsed() >= 1000)
{
double fps = frameCount / ((double)frameTime.elapsed()/1000.0);
}
}
I would like to have a bit of code executed (like toggling a flag variable),
after a completion of UART transmission issued by Serial.write(buf, len).
I tried several things to no success. Could someone suggest what would be the best way?
Thanks.
m
According to the code on the Arduino repository (you can see it here, particularly the HardwareSerial, Stream and Print classes) the Serial class functions are not blocking: they use an internal buffer which is emptied by the ISR.
Looking at the code, you have two possibilities.
The first and easiest one is to use the built-in Serial.flush function. This function waits for the uC to complete the sending and returns only when everything has been sent.
The second way is to mimic the flush behavior; this is what you need if you don't want the program to stop (i.e. perform other tasks) and just check if the board is sending data or not. If bit UDRIE0 (register UCSR0B) is set then the library has some data in its queue. At the end, however, you have to wait for the final byte to be sent, so you also have to check that bit TXC0(register UCSR0A) is cleared.
To implement and test this, I wrote this simple program:
unsigned long thisMillis = -1;
unsigned long lastMillis = -1;
char mybuffer[256];
void setup() {
Serial.begin(9600);
}
bool isSending()
{
return bit_is_set(UCSR0B, UDRIE0) || bit_is_clear(UCSR0A, TXC0);
}
void loop() {
int printed = snprintf(mybuffer, 256, "time: %lu\r\n", millis());
Serial.write(mybuffer, printed);
// Just enable ONE of the following methods
//Serial.flush();
//while(isSending());
lastMillis = millis();
}
Then I simulated it.
When neither the flush nor the while are enabled, the board buffers the string until it can. Then, when the buffer becomes full, starts waiting for some chars to go away before filling it again. Consequently we will see a lot of strings in the first milliseconds, then almost equally spaced strings (when the buffer is full). And in fact the output of the program is this one:
time: 0
time: 0
time: 1
time: 1
time: 1
time: 1
time: 2
time: 2
time: 7
time: 17
time: 27
When, however, we uncomment the Serial.flush function, the loop will wait for all the data to get out of the uC before looping again. This leads to equally spaced timestamps just from the beginning, and in fact this is the output
time: 0
time: 9
time: 19
time: 29
time: 39
time: 51
When enabling the while loop the behavior is exactly the same:
time: 0
time: 9
time: 19
time: 29
time: 39
time: 51
So, summing up: if you want to wait for the board to send just go with Serial.flush(); if you want to just test it (and then do something else) test the two bits reported above.
Try this:
void setup() {
Serial.begin(9600);
_SFR_BYTE(UCSR0B) |= _BV(TXCIE0); //Enable TXCIE0 interrupts
Serial.print("When UART finishes to send this text, it will call the routine ISR(USART0_TX_vect) ");
}
void loop() {
}
ISR(USART1_TX_vect)
{
//do whatever you want, but as quick as you can.
}
My application involves run myfuns() in a serial time execution. It calls dothings(...), which has a object instances and others passing to it. This function involves a loop each does a breadth-first search and it is really time consuming. I have used OpenMP for the loop and it speed up just a little bit, not good enough. I am thinking of using MPI parallelism to get more processes to work on, but not sure how to use it in an efficient way for this portion of code embedded deep inside a sequential code.
void dothings (object obji...) {
std::vector retvec;
for (i = 0; i < somenumber; i++) {
/* this function involves breadth first search using std:queue */
retval = compute(obji, i);
retvec.push_back(retval);
}
}
/* myfuns() gets called in a sequential manner */
void myfuns() {
dothings(objectInstance,...)
}
I am trying to create a list of files on my SD card this is easy enough to do once but the moment I run the program more than once the list become either shortened or the program say there is no files at all.
To make this as easy as possible I am using the SD example that comes with the arduino SD library and just putting the setup part ( that would normally run once ) in the loop part.
Heres what I have with that.
#include <SD.h>
File root;
void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.print("Initializing SD card...");
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
// Note that even if it's not used as the CS pin, the hardware SS pin
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
// or the SD library functions will not work.
pinMode(10, OUTPUT);
if (!SD.begin(10)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
}
void loop()
{
Serial.println("hit any key then enter to run the list");
while(!Serial.available())
{;}
Serial.read();
root = SD.open("/");
printDirectory(root, 0);
Serial.println("done!");
// nothing happens after setup finishes.
}
void printDirectory(File dir, int numTabs) {
while(true) {
File entry = dir.openNextFile();
if (! entry) {
// no more files
//Serial.println("**nomorefiles**");
break;
}
for (uint8_t i=0; i<numTabs; i++) {
Serial.print('\t');
}
Serial.print(entry.name());
if (entry.isDirectory()) {
Serial.println("/");
printDirectory(entry, numTabs+1);
} else {
// files have sizes, directories do not
Serial.print("\t\t");
Serial.println(entry.size(), DEC);
}
}
}
But then I get this weird output after running it
Initializing SD card...initialization done.
hit any key then enter to run the list
HFBVYRG.TXT 7
THBVFG.TXT 7
WAZXDSQ.TXT 7
QAZXSW.TXT 21
WSXZAQ.TXT 7
1478523.TXT 7
QWSDFRE.TXT 7
ZXCVBNM.TXT 7
MKOLIJY.TXT 7
done!
hit any key then enter to run the list
HFBVYRG.TXT 7
THBVFG.TXT 7
WAZXDSQ.TXT 7
QAZXSW.TXT 21
WSXZAQ.TXT 7
1478523.TXT 7
QWSDFRE.TXT 7
ZXCVBNM.TXT 7
MKOLIJY.TXT 7
done!
hit any key then enter to run the list
HFBVYRG.TXT 7
THBVFG.TXT 7
WAZXDSQ.TXT 7
QAZXSW.TXT 21
done!
hit any key then enter to run the list
done!
hit any key then enter to run the list
done!
hit any key then enter to run the list
done!
hit any key then enter to run the list
////////////////////////////////////////////////////////////////////////////////////
as you can see it gets shorter and shorter then just stops altogether.
Does anyone have any ideas why ?
I have tried playing around with pointers and closing and reopening the file but I have come up with nothing.
Any ideas would be greatly appreciated.
No good can come from mismatched open()'s and close()'s. You open the root directory every pass through the loop:
root = SD.open("/");
but never
root.close();
First, fix this error and also check that when you open the root that you succeed before trying to print a listing:
root = SD.open("/");
if(root) {
printDirectory(root, 0);
Serial.println("done!");
root.close();
}
else {
Serial.println("failed to open directory");
}
Second, close the files that are opened in the directory walk
void printDirectory(File dir, int numTabs) {
while(true) {
File entry = dir.openNextFile();
...
entry.close();
}
return;
}
Lastly, consider not blocking in the loop(). Other things can happen outside your loop() and they will be blocked indefinitely depending on how long you wait to hit a key. A more typical code pattern is to spin wildly through the loop() as opposed to blocking waiting for user input. For example:
boolean bNeedPrompt = true;
void loop() {
// Show the prompt once, then mark as displayed so that text does not
// continuously scroll on the screen
if(bNeedPrompt) {
Serial.println("hit any key then enter to run the list");
bNeedPrompt = false;
}
if(Serial.available()) {
Serial.read();
// do action
// set flag so that prompt will display again
bNeedPrompt = true;
}
return;
}
jdr5ca's answer addresses a lot of the problems with your setup - by not closing files you are going to be leaking resources which won't end well. It is particularly important on such a low memory setup as the Arduino, which has only 2k RAM for the original chips, so worth bearing in mind throughout your code.
Short answer for your remaining question: it won't be entirely predictable, but low memory is likely the cause of your problem. Read on for more details.
I've had some similar experiences with the SD library recently, though not with such an obvious cause. I found that if the free memory on my system got below about 500 bytes (a quarter of the total RAM) then the SD library starts to behave very oddly when trying to list directories.
I saw similar things to you, for example:
list entries under root directory and find two sub-directories
list entries in one of those sub-directories, worked fine
list entries under root directory and now I find only one sub-directory! The one I had listed the contents of has vanished!
I could still list the contents of the sub-directory fine, ie. it is still there!
resetting the Arduino and starting again gave the same results, again showing that the files were still present on SD card
I think all of this comes down to SD library being both quite memory hungry (#include SD.h uses up 500 bytes off the bat!), and not handling low memory errors particularly obviously.
So if things are acting strangely then:
check your memory usage (see eg. freeRam() from http://playground.arduino.cc/Code/AvailableMemory)
reduce your memory usage where ever possible. In rough order:
remove libraries you don't need
get rid of any hard coded strings that you don't need (eg. in calls to Serial.print())
for hard coded strings you do need make them as short as possible, and store them in flash (eg. Serial.print(F("String in flash"));) rather than RAM
you can't stick format strings (eg. for snprintf) in flash currently, so avoid using those and just build up the output manually (it is more long handed but saves memory)
make sure you are using appropriate variable types everywhere (ie. the smallest sized type that will suit your purposes) - especially important if you have any arrays, for obvious reasons!
For those unfamiliar, the following is Peterson's algorithm used for process coordination:
int No_Of_Processes; // Number of processes
int turn; // Whose turn is it?
int interested[No_Of_Processes]; // All values initially FALSE
void enter_region(int process) {
int other; // number of the other process
other = 1 - process; // the opposite process
interested[process] = TRUE; // this process is interested
turn = process; // set flag
while(turn == process && interested[other] == TRUE); // wait
}
void leave_region(int process) {
interested[process] = FALSE; // process leaves critical region
}
My question is, can this algorithm give rise to deadlock?
No, there is no deadlock possible.
The only place you are waiting is while loop. And the process variables is not shared between threads and they are different, but turn variable is shared. So it's impossible to get true condition for turn == process for more then one thread in every single moment.
But anyway your solution is not correct at all, the Peterson's algorithm is only for two concurrent threads, not for any No_Of_Processes like in your code.
In original algorithm for N processes deadlocks are possible link.