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