Data Readout (Video Streaming)
Different camera may have different readout method. There is two basic readout method. One is for video streaming and another is for single frame capture.
Video Streaming:
For the QHY5II series, QHY5III series, QHY COLDMOS camera. There is the video streaming mode. In this mode, the camera will send the data continuously to the computer if there is USB read request from computer. If there is no request,or computer cpu is slow or busy and cause the read speed slower than the input data rate, the camera will still running but it will cause the data buffer in the camera get full. And then the data send from sensor to the buffer will be lost . But sensor will not stop running, it is still keeping on running. This will cause the frame is not holonomy. This frame should be regards a bad frame and need to be filter out.
Since the data comes in continuously, only the asynchronous usb transfer can handle this. synchronous usb read can not handle this because there is a time gap between two synchronous usb read. If this gap happen within a frame, It will cause pause of the readout. Since the camrea's buffer is very small(For QHY5II is 4KB and for QHY5III is more than 100kB) The data will fill full of the buffer and cause data lost. So it can hardly to get a good frame with synchronous usb read.
Since it is the continuous video streaming. You need to make a double buffer or FIFO to handle the USB data in. For double buffer, there is buffer A and buffer B. When data is put into A , you can read the buffer B. When data is putting into B, you can read A. For FIFO, you need to set a FIFO which size is twice than the image size. And you can put data into the FIFO and another side you can readout the FIFO. Each readout is just one frame.
Now return to the asynchronous usb transfer, the advantage is that you can start multiple USB request. For example, you can apply 100 USB asynchronous request at one time. These requests will wait the data coming. When data fill one request, it will begin to fill next request. So there is no gap between two USB request.
And you can use "wait" command to wait one request end. For continuous streaming mode, when you find one request is end, you need to restart this request again. Then you will have unlimited usb request.
Here is an example to show this working flow.
memsize=100;
//Generic 100 USB request
for(int i=0;i<memsize;i++) request=new UsbRequest();
//init these usb request
for(int i=0;i<memsize;i++) request.initialize(qconnection,qEP);
//start these request, maxium size is 16384bytes
for(int i=0;i<memsize;i++) request.queue(xbuffer, 16384);
while(onStreaming==1){
qconnection.requestWait(); //wait one request end
rx_byte=xbuffer.position(); // one request end. get to know how many data received in this request
if(rx_byte== 5 ){......} //according the data size , do the different thing
eles if (rx_byte==xxxx) {.....}
else {.....}
xbuffer.clear();
request.queue(xbuffer,16384); //restart this request
x++;
if (x>memsize-1) x=0; //cycle and cycle
}
The key point of above working flow is that, when you get one request end, you need to restart this request. This can guarantee there always 100 request in background to receive the data. If computer run this loop is faster than the data in rate, there is always empty request exist and the data can be send to computer continuously without data lost
Now next thing is how to find the image head. In continuous steaming it is very important to get to know where a new frame starting. Then you can copy the data after that to the image buffer. For double buffer, once you find a image head, you can switch the buffer to receive the image data. The working flow is :
detected a image head
switch buffer
copy data in this buffer
In most of QHYCCD, they are using four or five byte as the image head. So you can detect if there is such four or five byte in sequence.
But if check each byte of the image will cause heavy CPU loading. So we should not use this global checking method. And since after this image head. The camera hardware will send a packet end signal. So it will cause the usb request finished immediately after this four or five image head.
This means: The image head byte must be at the end of one USB request.
So that you need to check the end four or five byte of the data in one usb request data package. This will save a lot time.
For example, one USB request has 16384 byte(byte0.....byte16383). Just check the byte 16379,16380,16381,16382,16383. If this five byte is the same with the image head identity byte. It is just the image head.
Note: Sometimes you can find a short request data length, just it is four or five byte. You need to check if it is just the image head also.
Bad Frame Identity
Now next topic is how to identity one frame is a good frame or bad frame. The method is very simple. Just to count the total data length of each frame. For example, the image size is 1280*960 8bit. So the image size should be 1280*960bytes. If you find one frame data length(when not calculate the image head five or four bytes length) is just 1280*960. That should be a good frame. Any frame smaller or bigger than this size it should be a bad frame.
In most condition the bad frame has less data length than full image data length. The following two condition will cause this happen
1.CPU is busy or slow, cause the usb request paused to received the data. The camera buffer then get full and the data come later can not enter the camera buffer so some data lost.
2.The USB transfer meet the CRC error and cause some USB packet lost. (Normally the USB cable problem, USB socket contact problem, the power leak, strong EMI issue like the human static electricity, high power device switch on/off) will cause this.
In seldom condition, the bad frame is bigger than the full image data length. This is due to the image head packet is just lost due to above reason(cpu busy or CRC error). This chance is much less . But still possible happen. So please make sure you can well handle the bigger data length and avoid the buffer size not enough and cause the point exceed the buffer memory size.