<div dir="ltr"><div><div><div><div><div>Hello,<br><br></div>I am currently using ADV7180 as a video decoder and using to view any one of the four video channel inputs. <br><br></div><div>The driver is here:<br><a href="http://lxr.free-electrons.com/source/drivers/media/video/adv7180.c?v=3.0">http://lxr.free-electrons.com/source/drivers/media/video/adv7180.c?v=3.0</a><br>
<br></div><div>The details for the decoder are here:<br><a href="http://www.analog.com/en/audiovideo-products/video-decoders/adv7180/products/product.html">http://www.analog.com/en/audiovideo-products/video-decoders/adv7180/products/product.html</a><br>
</div><div><br></div>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. <br>
<br>#include &quot;opencv2/objdetect/objdetect.hpp&quot;<br>#include &quot;opencv2/highgui/highgui.hpp&quot;<br>#include &quot;opencv2/imgproc/imgproc.hpp&quot;<br>#include &lt;linux/videodev2.h&gt;<br>#include &quot;i2c-dev.h&quot;<br>
#include &lt;fcntl.h&gt;<br>#include &lt;iostream&gt;<br>#include &lt;stdio.h&gt;<br>#include &lt;errno.h&gt;<br>#include &lt;unistd.h&gt;                 <br>#include &lt;sys/ioctl.h&gt;<br>#include &lt;string.h&gt;<br>#include &lt;pthread.h&gt;<br>
#include &lt;queue&gt;<br>#include &lt;X11/Xlib.h&gt;<br>#include &lt;X11/Xutil.h&gt;<br><br>#define MAX4586_I2C_ADDR    0x37 <br>#define RENDER_DELAY        80<br>#define SWITCH_DELAY        60<br><br>using namespace std;<br>
using namespace cv;<br><br>queue&lt;Mat&gt; window1Queue;<br>queue&lt;Mat&gt; window2Queue;<br>pthread_t render1Thread;<br>pthread_t render2Thread;<br><br>void *renderToWindow1(void *arg)<br>{<br>    while (true)<br>    {<br>
        if(!window1Queue.empty())<br>        {        <br>            imshow(&quot;Window 1&quot;, window1Queue.front());    <br>            window1Queue.pop();                <br>        }        <br>        usleep(RENDER_DELAY);        <br>
    }<br>}<br><br>void *renderToWindow2(void *arg)<br>{<br>    while (true)<br>    {<br>        if(!window2Queue.empty())<br>        {            <br>            imshow(&quot;Window 2&quot;, window2Queue.front());<br>            window2Queue.pop();                        <br>
        }        <br>        usleep(RENDER_DELAY);            <br>    }    <br>}<br><br><br>/** @function main */<br>int main(int argc, const char** argv)<br>{    <br>    int fd, retVal;<br>    int    counter = 1, maxChannel = 0;<br>
    VideoCapture capture;<br>    Mat frame;      <br>    <br>    fd = open(&quot;/dev/video0&quot;, O_RDWR);<br>    if (fd &lt; 0) <br>    {<br>        perror(&quot;Failed to open\n&quot;);<br>        return -1;<br>    }    <br>
            <br>    try <br>    {   <br>        // Surround the OpenCV call by a try/catch block so we can give a useful error message!<br>        capture.open(0);<br>        /*------------------------------------------------------------*/<br>
        capture.set(CV_CAP_PROP_FRAME_WIDTH, 320);<br>        capture.set(CV_CAP_PROP_FRAME_HEIGHT, 240);<br>        /*------------------------------------------------------------*/<br>    } <br>    catch (cv::Exception &amp;e) <br>
    {<br>    <br>    }<br>    <br>    if (!capture.isOpened()) <br>    {<br>        cerr &lt;&lt; &quot;ERROR: Could not access the camera!&quot; &lt;&lt; endl;<br>        exit(1);<br>    }    <br>        <br>    pthread_create(&amp;render1Thread, NULL, renderToWindow1, NULL);<br>
    <br>    pthread_create(&amp;render2Thread, NULL, renderToWindow2, NULL);    <br>    <br>    while(true)<br>     {        <br>        switch(counter)<br>        {                <br>            case 1:                        <br>
                maxChannel = 0;<br>                if (ioctl(fd, VIDIOC_S_INPUT, &amp;maxChannel) &lt; 0) <br>                {<br>                     perror(&quot;1. Failed ioctl\n&quot;);                     <br>                }<br>
                <br>                counter = 3;                        <br>                capture &gt;&gt; frame;                <br>                if(!frame.empty())<br>                {                    <br>                    window1Queue.push(frame);                    <br>
                }<br>            break;<br>            <br>            case 2:                 <br>            break;<br>            <br>            case 3:                      <br>                maxChannel = 2;<br>                if (ioctl(fd, VIDIOC_S_INPUT, &amp;maxChannel) &lt; 0) <br>
                {<br>                     perror(&quot;2. Failed ioctl\n&quot;);                     <br>                }        <br>                counter = 1;                    <br>                capture &gt;&gt; frame;                <br>
                if(!frame.empty())<br>                {                         <br>                    window2Queue.push(frame);                    <br>                }<br>            break;<br>            <br>            case 4:                 <br>
            break;<br>            <br>            default: <br>                counter = 1;<br>            break;                      <br>        }<br>        <br>        waitKey(SWITCH_DELAY);                <br>    }    <br>
   <br>    return 0;<br> }<br><br></div>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?  <br>
<br>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. <br><br></div>Thanks &amp; Regards,<br></div>Sanchayan Maity.<br>
<div><div><br><br><br><br><div><div><br><br></div></div></div></div></div>