[MPlayer-dev-eng] tv input problems and partial solutions

Paul Ortyl ortylp at 3miasto.net
Sun Jun 23 18:25:22 CEST 2002


Hi,

	I have spent some time on trying to make tv input recording (via v4l)
work properly.  Here are some "achievements":

*  -voc lavc works when -tv outfmt=yuy2
*  -aoc pcm  works
*  -aoc mp3lame (VBR) works, and there is no "double speed"

Problems:

*  A-V sync   with -aoc pcm seems to be constant about 700ms
*  A-V sync   with -aoc mp3lame  is NOT constant!!!
*  A-V sync   with fps=24 (set manually in libmpdemux/tv.c) and with -aoc mp3lame
		A-V seems to be constant (??!)

BIG QUESTION:

What does mencoder need from input stream to get proper A-V sync???
Maybe some timestamps???

One of the main problems is that I cannot be sure that video frame sampling
is time-uniform and really equal the given fps.  I can see many (a few per
5sec) dropped frames (but nothing is ever reported by mencoder).  The
recorded stream has missing frames and it is "broken" in the same fashion as
with xawtv in grabdisplay mode.  What makes me mad in the situation is that
there is still more than 40% of CPU free!


Some examples:

TVI_CONTROL_VID_GET_FPS was not supported by tvi_v4l and why framerate there
is an integer when all elsewhere it is a double?

priv->audio_samplerate[priv->audio_id] should not be passed directly to the
IOCTL because its value gets mysteriously changed from 44100 to 44101 
and later liblame does not accept the value of 44101.
===================================================================
diff -ur main.orig/libmpdemux/tvi_v4l.c main/libmpdemux/tvi_v4l.c
--- main.orig/libmpdemux/tvi_v4l.c      Wed Jun  5 03:49:03 2002
+++ main/libmpdemux/tvi_v4l.c   Sun Jun 23 18:11:21 2002
@@ -637,7 +637,10 @@
            priv->picture.contrast = (int)*(void **)arg;
            control(priv, TVI_CONTROL_VID_SET_PICTURE, 0);
            return(TVI_CONTROL_TRUE);
-
+        case TVI_CONTROL_VID_GET_FPS:
+            (int)*(void **)arg=priv->fps;
+            return(TVI_CONTROL_TRUE);
+              
        /* ========== TUNER controls =========== */
        case TVI_CONTROL_TUN_GET_FREQ:
        {
@@ -743,10 +746,9 @@
        }
        case TVI_CONTROL_AUD_SET_SAMPLERATE:
        {
-           priv->audio_samplerate[priv->audio_id] = (int)*(void **)arg;
+           int tmp = priv->audio_samplerate[priv->audio_id] = (int)*(void
**)arg;
            
-           if (ioctl(priv->audio_fd, SNDCTL_DSP_SPEED,
-               &priv->audio_samplerate[priv->audio_id]) == -1)
+           if (ioctl(priv->audio_fd, SNDCTL_DSP_SPEED, &tmp) == -1)
                return(TVI_CONTROL_FALSE);
            priv->audio_samplesize[priv->audio_id] =
=====================================================================


This patch adresses the problem of "doublespeed" encoding and max 12fps
framerate...  If the tv-audio is mono then there is no interleaved data and 
there is only len/2 samples in buffer.  This solution is not clear, but I do
not know how to encode mono audio stream with liblame.  It gives an AVI with
two channel audio regardless of (mux_a->wf->nChannels == 1) and mode=3 --
any ideas???
=====================================================================
diff -ur main.orig/mencoder.c main/mencoder.c
--- main.orig/mencoder.c        Thu Jun 13 23:35:10 2002
+++ main/mencoder.c     Sun Jun 23 14:15:54 2002
@@ -849,10 +849,16 @@
                  unsigned char tmp[2304];
                  int len=dec_audio(sh_audio,tmp,2304);
                  if(len<=0) break; // eof
+                 if(mux_a->wf->nChannels == 1){
+                 len=lame_encode_buffer(lame,
+                     tmp, tmp, len/2,
+							mux_a->buffer+mux_a->buffer_len,mux_a->buffer_size-mux_a->buffer_len);
+                 } else {
                  len=lame_encode_buffer_interleaved(lame,
                      tmp,len/4,
							mux_a->buffer+mux_a->buffer_len,mux_a->buffer_size-mux_a->buffer_len);
-                 if(len<0) break; // error
+                 }
+                  if(len<0) break; // error
                  mux_a->buffer_len+=len;
                }
                if(mux_a->buffer_len<4) break;
@@ -864,9 +870,15 @@
                  unsigned char tmp[2304];
                  int len=dec_audio(sh_audio,tmp,2304);
                  if(len<=0) break; // eof
+                 if(mux_a->wf->nChannels == 1){
+                 len=lame_encode_buffer(lame,
+                     tmp, tmp, len/2,
+							mux_a->buffer+mux_a->buffer_len,mux_a->buffer_size-mux_a->buffer_len);
+                 } else {
                  len=lame_encode_buffer_interleaved(lame,
                      tmp,len/4,
							mux_a->buffer+mux_a->buffer_len,mux_a->buffer_size-mux_a->buffer_len);
+                 }
                  if(len<0) break; // error
==========================================================================

BTW...  Why the above value of 2304 is so special???

While encoding in the status line there is printed FPS value -- it is
rounded downwards so that its stable value of 24.8 (instead of 25???) is
reported as 24.  (With this encoding framerate there is still plenty of CPU
free)

And what should be implemented in tvi_v4l so that A-V sync would be correct
in mencoder regardless of "dropped"/missing video frames?  Is it possible at all?

Regards,

	Paul

-- 
Paul Ortyl <mailto:ortylp at 3miasto.net>
  Technical University of Gdansk, Telecommunications Faculty
--



More information about the MPlayer-dev-eng mailing list