Query on improving ADV driver 7180

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

I am currently using ADV7180 as a video decoder and using to view any one of the four video channel inputs.


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.






_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@xxxxxxxxxxxxxxxxx
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux