[CinCV TNG] Few observations on difference between v4l2 input module in mplayer and CinelerraCV

Andrew Randrianasulu randrianasulu at gmail.com
Fri Jul 21 18:31:09 CEST 2017


Hello.

Sorry for not coming with patch...

But I tried to compare Cinelerra's v4l2 input (now working on emulated v4l2 
device) and mplayer's one (working), found few differences, but not sure how to 
translate them from one codebase to another.

First, in file mplayer/stream/tvi_v4l2.c I can see this new addition obviously 
absent in CinelerraCV case:

// flag introduced in kernel 3.10
#ifndef V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
#define V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC 0x2000
#endif

it probably not showstopper, because gown the line I can see

#ifdef HAVE_CLOCK_GETTIME
        priv->clk_id = (priv->map[i].buf.flags & 
V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC)
                           ? CLOCK_MONOTONIC : CLOCK_REALTIME;
#else
        if (priv->map[i].buf.flags & V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC)
            mp_msg(MSGT_TV, MSGL_WARN, "MPlayer compiled without clock_gettime() 
that is needed to handle monotone video timestamps from the kernel. Expect 
desync.\n");
#endif

another workaround is more interesting.
at line 1679 (mplayer svn rev r37946) you can see

        memset(&buf,0,sizeof(buf));
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        ret = ioctl(priv->video_fd, VIDIOC_DQBUF, &buf);

        if (ret < 0) {
            /*
              if there's no signal, the buffer might me dequeued
              so we query all the buffers to see which one we should
              put back to queue

              observed with saa7134 0.2.8
              don't know if is it a bug or (mis)feature
             */
            mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl dequeue buffer failed: %s, idx 
= %d\n",
                   info.short_name, strerror(errno), buf.index);
            for (i = 0; i < priv->mapcount; i++) {
                memset(&buf,0,sizeof(buf));
                buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                buf.memory = V4L2_MEMORY_MMAP;
                buf.index = i;
                ret = ioctl(priv->video_fd, VIDIOC_QUERYBUF, &buf);
                if (ret < 0) {
                    mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer 
failed: %s, idx = %d\n",
                           info.short_name, strerror(errno), buf.index);
                    return 0;
                }
                if ((buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_MAPPED | 
V4L2_BUF_FLAG_DONE)) == V4L2_BUF_FLAG_MAPPED) {
                    if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) 
< 0) {
                        mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer 
failed: %s\n",
                               info.short_name, strerror(errno));
                        return 0;
                    }
                }
            }
            continue;
        }
----------

well, CinelerraCV printed a lot of 

VDeviceV4L2Thread::run VIDIOC_DQBUF: Обрыв канала

so I looked at cinelerra/cinelerra/vdevicev4l2.C

and this probably should indicate capture phase failed...

line 611:

// The driver returns the first buffer not queued, so only one buffer
// can be unqueued at a time.
		Thread::enable_cancel();
		ioctl_lock->lock("VDeviceV4L2Thread::run");
		int result = ioctl(input_fd, VIDIOC_DQBUF, &buffer);
		ioctl_lock->unlock();
// Delay so the mutexes don't get stuck
		usleep(1000000 * 1001 / 60000);
		Thread::disable_cancel();


		if(result < 0)
		{
			perror("VDeviceV4L2Thread::run VIDIOC_DQBUF");
			Thread::enable_cancel();
			usleep(100000);
			Thread::disable_cancel();
		}
		else
		{
			buffer_lock->lock("VDeviceV4L2Thread::run");

I also looked up v4l2 documentation, but was somewhat confused, because 
this 'broken pipe' (translated) msg should be only present for operation/mode 
Cinelerra not even know about?


https://linuxtv.org/downloads/v4l-dvb-apis/uapi/v4l/vidioc-qbuf.html
-----------------
EPIPE
VIDIOC_DQBUF returns this on an empty capture queue for mem2mem codecs if a 
buffer with the V4L2_BUF_FLAG_LAST was already dequeued and no new buffers are 
expected to become available.
-----------------

Also, may be this is documented somewhere - but I was slightly surprized to see 
v4l2 pixel format not dirrectly settable, but derived from project's 
colorformat setting....


More information about the Cinelerra mailing list