Query on improving ADV driver 7180
sanchayan maity
victorascroft at gmail.com
Tue May 6 07:10:17 EDT 2014
Hello,
I am currently using ADV7180 as a video decoder and using to view any one
of the four video channel inputs.
The driver is here:
http://lxr.free-electrons.com/source/drivers/media/video/adv7180.c?v=3.0
The details for the decoder are here:
http://www.analog.com/en/audiovideo-products/video-decoders/adv7180/products/product.html
I am trying to display two or four channels simultaneously in different
windows. The problem is that even with two windows the frame rate is not
acceptable. I am using the below code with OpenCV for rendering to multiple
windows. ioctl call is use to switch between the multiple channels.
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <linux/videodev2.h>
#include "i2c-dev.h"
#include <fcntl.h>
#include <iostream>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <string.h>
#include <pthread.h>
#include <queue>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#define MAX4586_I2C_ADDR 0x37
#define RENDER_DELAY 80
#define SWITCH_DELAY 60
using namespace std;
using namespace cv;
queue<Mat> window1Queue;
queue<Mat> window2Queue;
pthread_t render1Thread;
pthread_t render2Thread;
void *renderToWindow1(void *arg)
{
while (true)
{
if(!window1Queue.empty())
{
imshow("Window 1", window1Queue.front());
window1Queue.pop();
}
usleep(RENDER_DELAY);
}
}
void *renderToWindow2(void *arg)
{
while (true)
{
if(!window2Queue.empty())
{
imshow("Window 2", window2Queue.front());
window2Queue.pop();
}
usleep(RENDER_DELAY);
}
}
/** @function main */
int main(int argc, const char** argv)
{
int fd, retVal;
int counter = 1, maxChannel = 0;
VideoCapture capture;
Mat frame;
fd = open("/dev/video0", O_RDWR);
if (fd < 0)
{
perror("Failed to open\n");
return -1;
}
try
{
// Surround the OpenCV call by a try/catch block so we can give a
useful error message!
capture.open(0);
/*------------------------------------------------------------*/
capture.set(CV_CAP_PROP_FRAME_WIDTH, 320);
capture.set(CV_CAP_PROP_FRAME_HEIGHT, 240);
/*------------------------------------------------------------*/
}
catch (cv::Exception &e)
{
}
if (!capture.isOpened())
{
cerr << "ERROR: Could not access the camera!" << endl;
exit(1);
}
pthread_create(&render1Thread, NULL, renderToWindow1, NULL);
pthread_create(&render2Thread, NULL, renderToWindow2, NULL);
while(true)
{
switch(counter)
{
case 1:
maxChannel = 0;
if (ioctl(fd, VIDIOC_S_INPUT, &maxChannel) < 0)
{
perror("1. Failed ioctl\n");
}
counter = 3;
capture >> frame;
if(!frame.empty())
{
window1Queue.push(frame);
}
break;
case 2:
break;
case 3:
maxChannel = 2;
if (ioctl(fd, VIDIOC_S_INPUT, &maxChannel) < 0)
{
perror("2. Failed ioctl\n");
}
counter = 1;
capture >> frame;
if(!frame.empty())
{
window2Queue.push(frame);
}
break;
case 4:
break;
default:
counter = 1;
break;
}
waitKey(SWITCH_DELAY);
}
return 0;
}
I am suspecting that the ioctl call, is one thing which take some time
here, due to the copy required from user space to kernel space. Can the
timing be improved with a mmap implementation in the driver, removing the
implicit copy from user space to kernel space, giving me a decent frame
rate for multi window rendering?
The waitKey(SWITCH_DELAY) provides a delay without which the frames glitch
badly and usleep(RENDER_DELAY) provides the necessary delay for rendering
to the window.
Thanks & Regards,
Sanchayan Maity.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20140506/3f348a8a/attachment-0001.html
More information about the Kernelnewbies
mailing list