Great questions. 9.3fps is the theoretical max at 1280x1024 YUYV based on image size and USB isochronous bandwidth (24 MBytes/s). If you are seeing less than that, likely it is because your vision algorithm runs slower.
The jevois::Timer class was created specifically for your needs. It will measure the actual processing speed of your algo. In many modules, we start the timer measurement period just as we have receive the video frame from the sensor, and we end it as we send off the results frame to USB. The time this takes (converted to fps) is what you see at the bottom of the video for many modules, next to the CPU load, temperature, and MHz. Each time you see that info at the bottom left of the video, it is coming from a Timer that measures algo performance (not camera sensor frames/s).
So, if you see that DemoArUco runs at less than 9.3fps according to what is displayed at the bottom left of the video, then your speed is limited by the algo (at that resolution).
The fps reported at the bottom left is precisely to help you decide how fast your algo can run at a given resolution, and how you can optimize your video mapping. For example, say you run DemoArUco at 320x240@30fps setting, and you see a report of 48fps at the bottom left of the video, that means that your algorithm could run at up to 48fps. Because there is a bit of overhead with grabbing video and sending it over USB, you might then want to adjust your video mapping to 320x240@45fps or so. Hence there is no chicken and egg problem with this method. Note that python algorithms will require more margin (maybe from 48fps to 40fps) as the timer is started after the camera frame is converted to numpy format, and stopped before it is converted back from numpy to raw data for USB, and those two conversions take a bit of time.
To experiment with different output sizes with rescaling on the fly, try the python version of the aruco module, as described here: http://jevois.org/tutorials/ProgrammerInvHello.html towards the end of the tutorial. It is the same core algorithm (C++ aruco implementation of opencv). In there, out.sendCv() will take care of any rescaling and pixel type conversion, so you can experiment with a bunch of different mappings using that code.
To change the C++ code, you need to install the jevois SDK, see here: http://jevois.org/tutorials/ProgrammerSetup.html
Finally, regarding the 26.3fps vs 30fps, this is a simple estimate that assumes no buffering (while we actually do allow for some buffering in JeVois now), which goes like this:
If your sensor runs at 30fps, you get a frame every 33.33ms.
If your algo runs at 26.3fps, you need 38ms to process one frame.
The camera sensor has a fixed clock and it just outputs one frame after the other with no delay or pause. So, you end up with this (again, assuming no buffering):
at t=0, frame 1 is done capturing and is sent to processing.
at t=33.33ms frame 2 is done capturing but processing of frame 1 takes 38ms so it still is ongoing, hence we miss frame 2 and the camera sensor starts capturing frame 3.
at t=38ms processing is done but frame 2 was dropped and frame 3 is not ready yet, we have to wait until frame 3 is completely captured, that will be at t=66.66ms.
and so on, we basically end up dropping every other frame and processing at 15fps, with lots of idle CPU as we wait for the next frame after we barely missed the previous one. But if you program the camera sensor for slightly below 26.3fps, you should be able to be done processing one frame just before the next frame arrives, and you will not drop frames.
Finally note that at 1280x1024 with USB output, significant time is spent just creating the video output and sending it over USB. So you may also want to try running the algo with no USB output (only serial messages). The C++ version can do it. See this new tutorial for adding this capability to the python version: http://jevois.org/tutorials/UserHeadless.html and first you need to implement processNoUSB() in your python module, see http://jevois.org/doc/ProgrammerPython.html and http://jevois.org/doc/ModulePythonTutorial.html for more about processNoUSB()