I made three video port work as raw capture port in DM648, and I used an FPGA to feed video data to the three video ports at the same timing sequence. So the three video ports will operate at the exact same time in parallel only except for the different captured data. And my DSP code is written based on PSP video port driver and is as follows:
void tskVP0RawCap(void)
{
// Start capture operation
if (IOM_COMPLETED == status){
status |= FVID_control(capChInfoRaw0.chanHandle,
VPORT_CMD_START,
NULL);
}
else{
LOG_printf(&trace, "Failed at VP0 capture startup\n");
}
// Forever loop
while(1){
// Capture buffer will return a filled buffer
status = FVID_dequeue(capChInfoRaw0.chanHandle, &(capChInfoRaw0.frame));
if (IOM_COMPLETED != status) {
LOG_printf(&trace, "Failed at VP0 capture task\n");
}
SEM_post(&SemVP0CapComplete);
}
}
void tskVP1RawCap(void)
{
// Start capture operation
if (IOM_COMPLETED == status){
status |= FVID_control(capChInfoRaw1.chanHandle,
VPORT_CMD_START,
NULL);
}
else{
LOG_printf(&trace, "Failed at VP1 capture startup\n");
}
// Forever loop
while(1){
// Capture buffer will return a filled buffer
status = FVID_dequeue(capChInfoRaw1.chanHandle, &(capChInfoRaw1.frame));
if (IOM_COMPLETED != status) {
LOG_printf(&trace, "Failed at VP1 capture task\n");
}
SEM_post(&SemVP1CapComplete);
}
}
void tskVP2RawCap(void)
{
// Start capture operation
if (IOM_COMPLETED == status){
status |= FVID_control(capChInfoRaw2.chanHandle,
VPORT_CMD_START,
NULL);
}
else{
LOG_printf(&trace, "Failed at VP2 capture startup\n");
}
// Forever loop
while(1){
// Capture buffer will return a filled buffer
status = FVID_dequeue(capChInfoRaw2.chanHandle, &(capChInfoRaw2.frame));
if (IOM_COMPLETED != status) {
LOG_printf(&trace, "Failed at VP2 capture task\n");
}
SEM_post(&SemVP2CapComplete);
}
}
The three tasks are registered in DSP/BIOS, and will operate with a lower priority than the processing task, which will be pended for the three semaphores: SemVP0CapComplete, SemVP1CapComplete and SemVP2CapComplete. The processing task code is as follows (only the first several lines) :
void tskVideoProcessing(void)
{
// Forever loop
while(1)
{
// wait for capture completion
SEM_pend(&SemVP0CapComplete, SYS_FOREVER);
SEM_pend(&SemVP1CapComplete, SYS_FOREVER);
SEM_pend(&SemVP2CapComplete, SYS_FOREVER);
// processing starts here
………
}
}
Now the program executes correctly, but the frame rate is lower than the input video data. The expected frame rate is 60Hz but now I could measure only 37Hz approximately based on a timer. And I analyzed the execution graph and used profiling to trace the CPU cycles, I found that the three task consume a lot of CPU time on function FVID_dequeue(). Since the three capture port operate on the same timing, so if one of the three ports can ‘dequeue’ one frame back, the rest two ports should ‘dequeue’ the just captured frame back immediately. However as the code listed above, the DSP seems to capture three frames buffers on a serial sequences, which will lose some video frames.
What will the code look like if I want the three video ports to capture video data in parallel at an exact same timing?