[Mplayer-cvslog] CVS: main/libmpdemux tv.c,1.50,1.51 tv.h,1.21,1.22 tvi_v4l.c,1.57,1.58

Jindrich Makovicka CVS henry at mplayerhq.hu
Wed Mar 19 17:27:02 CET 2003


Update of /cvsroot/mplayer/main/libmpdemux
In directory mail:/var/tmp.root/cvs-serv31844/libmpdemux

Modified Files:
	tv.c tv.h tvi_v4l.c 
Log Message:
hardware mjpeg encoding using v4l by Iván Szántó <szivan at freemail.hu>

Index: tv.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/tv.c,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -r1.50 -r1.51
--- tv.c	3 Mar 2003 10:59:07 -0000	1.50
+++ tv.c	19 Mar 2003 16:26:58 -0000	1.51
@@ -63,6 +63,9 @@
 int tv_param_forcechan = -1;
 int tv_param_force_audio = 0;
 int tv_param_buffer_size = -1;
+int tv_param_mjpeg = 0;
+int tv_param_decimation = 2;
+int tv_param_quality = 90;
 #ifdef HAVE_ALSA9
 int tv_param_alsa = 0;
 #endif
@@ -178,6 +181,27 @@
 	mp_msg(MSGT_TV, MSGL_ERR, "Error: cannot set norm!\n");
 	return 0;
     }
+
+
+#ifdef HAVE_TV_V4L
+    if ( tv_param_mjpeg )
+    {
+      /* set width to expected value */
+      if (tv_param_width == -1)
+        {
+          tv_param_width = 704/tv_param_decimation;
+        }
+      if (tv_param_height == -1)
+        {
+	  if ( tvh->norm != TV_NORM_NTSC )
+            tv_param_height = 576/tv_param_decimation; 
+	  else
+            tv_param_height = 480/tv_param_decimation; 
+        }
+      mp_msg(MSGT_TV, MSGL_INFO, 
+	       "  MJP: width %d height %d\n", tv_param_width, tv_param_height);
+    }
+#endif
 
     /* limits on w&h are norm-dependent -- JM */
     /* set width */

Index: tv.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/tv.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- tv.h	28 Dec 2002 22:57:39 -0000	1.21
+++ tv.h	19 Mar 2003 16:26:58 -0000	1.22
@@ -34,6 +34,9 @@
 extern int tv_param_forcechan;
 extern int tv_param_force_audio;
 extern int tv_param_buffer_size;
+extern int tv_param_mjpeg;
+extern int tv_param_decimation;
+extern int tv_param_quality;
 #ifdef HAVE_ALSA9
 extern int tv_param_alsa;
 #endif

Index: tvi_v4l.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/tvi_v4l.c,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -r1.57 -r1.58
--- tvi_v4l.c	16 Mar 2003 16:38:16 -0000	1.57
+++ tvi_v4l.c	19 Mar 2003 16:26:58 -0000	1.58
@@ -9,6 +9,9 @@
   Multithreading, a/v sync and native ALSA support by
     Jindrich Makovicka <makovick at kmlinux.fjfi.cvut.cz>
 
+  Mjpeg hardware encoding support by 
+    Iván Szántó <szivan at freemail.hu>
+
   CODE IS UNDER DEVELOPMENT, NO FEATURE REQUESTS PLEASE!
 */
 
@@ -37,6 +40,7 @@
 #include "../libao2/afmt.h"
 #include "../libvo/img_format.h"
 #include "../libvo/fastmemcpy.h"
+#include "../libvo/videodev_mjpeg.h"
 
 #include "tv.h"
 
@@ -132,6 +136,7 @@
     long long                   audio_skew_total;
     long			audio_recv_blocks_total;
     long			audio_sent_blocks_total;
+    long                        mjpeg_bufsize;
     
 } priv_t;
 
@@ -443,8 +448,97 @@
 	priv->capability.maxwidth, priv->capability.maxheight);
     priv->width = priv->capability.minwidth;
     priv->height = priv->capability.minheight;
-    mp_msg(MSGT_TV, MSGL_INFO, " Inputs: %d\n", priv->capability.channels);
 
+    /* somewhere here could disable tv_param_mjpeg, if it is not a capability */
+
+    /* initialize if necessary */
+    if ( tv_param_mjpeg )
+      {
+        struct mjpeg_params bparm;
+        struct mjpeg_requestbuffers breq;          /* buffer requests */
+
+        if (ioctl(priv->video_fd, MJPIOC_G_PARAMS, &bparm) < 0)
+        {
+           mp_msg(MSGT_TV, MSGL_ERR, 
+              "  MJP: Error getting video parameters: %s\n", sys_errlist[errno]);
+           goto err;
+        }
+
+        mp_msg(MSGT_TV, MSGL_INFO, 
+	       "  MJP: previous params: x: %d, y: %d, w: %d, h: %d, decim: %d, fields: %d,\n",
+	           bparm.img_x, bparm.img_y, bparm.img_width, bparm.img_height,          
+		   bparm.decimation, bparm.field_per_buff);
+
+        mp_msg(MSGT_TV, MSGL_INFO, 
+	       "  MJP: HorDcm: %d, VerDcm: %d, TmpDcm: %d\n",
+	           bparm.HorDcm, bparm.VerDcm, bparm.TmpDcm);
+
+        bparm.input = tv_param_input; /* tv */
+        if (!strcasecmp(tv_param_norm, "pal"))
+	  bparm.norm =  0; /* PAL */
+        else if (!strcasecmp(tv_param_norm, "ntsc"))
+	  bparm.norm =  1; /* NTSC */
+        else if (!strcasecmp(tv_param_norm, "secam"))
+	  bparm.norm =  2; /* SECAM */
+        bparm.quality = tv_param_quality;
+        bparm.decimation = tv_param_decimation;
+
+        mp_msg(MSGT_TV, MSGL_INFO, "  MJP: setting params to decimation: %d, quality: %d\n", 
+	                                 bparm.decimation, bparm.quality);
+
+        if (ioctl(priv->video_fd, MJPIOC_S_PARAMS, &bparm) < 0)
+         {
+            mp_msg(MSGT_TV, MSGL_ERR,
+               "  MJP: Error setting video parameters: %s\n", sys_errlist[errno]);
+            goto err;
+         }
+
+        if (ioctl(priv->video_fd, MJPIOC_G_PARAMS, &bparm) < 0)
+        {
+           mp_msg(MSGT_TV, MSGL_ERR, 
+              "  MJP: Error getting video parameters: %s\n", sys_errlist[errno]);
+           goto err;
+        }
+
+        mp_msg(MSGT_TV, MSGL_INFO, 
+	       "  MJP: current params: x: %d, y: %d, w: %d, h: %d, decim: %d, fields: %d,\n",
+	           bparm.img_x, bparm.img_y, bparm.img_width, bparm.img_height,          
+		   bparm.decimation, bparm.field_per_buff);
+
+        mp_msg(MSGT_TV, MSGL_INFO, 
+	       "  MJP: HorDcm: %d, VerDcm: %d, TmpDcm: %d\n",
+	           bparm.HorDcm, bparm.VerDcm, bparm.TmpDcm);
+
+
+        breq.count = 64;
+	priv -> nbuf = breq.count;
+        priv->mbuf.frames = priv -> nbuf;
+        priv->mjpeg_bufsize = 256*1024;
+        if (tv_param_buffer_size >= 0) {
+          priv->mjpeg_bufsize = tv_param_buffer_size*1024;
+	  }
+        breq.size  = priv -> mjpeg_bufsize;
+        if (ioctl(priv->video_fd, MJPIOC_REQBUFS,&(breq)) < 0)
+        {
+           mp_msg (MSGT_TV, MSGL_ERR,
+              "  MJP: Error requesting video buffers: %s\n", sys_errlist[errno]);
+           goto err;
+        }
+        mp_msg(MSGT_TV, MSGL_INFO,
+           "  MJP: Got %ld buffers of size %ld KB\n", 
+                    breq.count, breq.size/1024);
+
+        priv -> mmap = mmap(0, breq.count * breq.size, 
+           PROT_READ|PROT_WRITE, MAP_SHARED, priv->video_fd, 0);
+        if (priv -> mmap == MAP_FAILED)
+        {
+           mp_msg(MSGT_TV, MSGL_INFO,
+              "  MJP: Error mapping video buffers: %s\n", sys_errlist[errno]);
+           goto err;
+        }
+      }
+
+    mp_msg(MSGT_TV, MSGL_INFO, " Inputs: %d\n", priv->capability.channels);
     priv->channels = (struct video_channel *)malloc(sizeof(struct video_channel)*priv->capability.channels);
     if (!priv->channels)
 	goto malloc_failed;
@@ -474,6 +568,8 @@
 	goto err;
     }
     
+    if ( !tv_param_mjpeg )
+    {
     /* map grab buffer */
     if (ioctl(priv->video_fd, VIDIOCGMBUF, &priv->mbuf) == -1)
     {
@@ -500,6 +596,7 @@
     if (!priv->buf)
 	goto malloc_failed;
     memset(priv->buf, 0, priv->nbuf * sizeof(struct video_mmap));
+    }
     
     /* init v4l audio even when we don't capture */
     init_v4l_audio(priv);
@@ -555,6 +652,7 @@
 
 static int uninit(priv_t *priv)
 {
+    unsigned long num;
     priv->shutdown = 1;
 
     mp_msg(MSGT_TV, MSGL_V, "Waiting for threads to finish... ");
@@ -573,6 +671,14 @@
 	ioctl(priv->video_fd, VIDIOCSAUDIO, &priv->audio[priv->audio_id]);
     }
     
+    if ( tv_param_mjpeg )
+      {
+	num = -1;
+        if (ioctl(priv->video_fd, MJPIOC_QBUF_CAPT, &num) < 0)
+          {
+            mp_msg(MSGT_TV, MSGL_ERR, "\n  MJP: ioctl MJPIOC_QBUF_CAPT failed: %s\n", strerror(errno));
+          }
+      }
     close(priv->video_fd);
 
     audio_in_uninit(&priv->audio_in);
@@ -660,6 +766,8 @@
 	return(0);
     }
 
+    if ( !tv_param_mjpeg )
+    {
     priv->nbuf = priv->mbuf.frames;
     for (i=0; i < priv->nbuf; i++)
     {
@@ -669,6 +777,7 @@
 	priv->buf[i].height = priv->height;
 	mp_msg(MSGT_TV, MSGL_DBG2, "buffer: %d => %p\n", i, &priv->buf[i]);
     } 
+    } 
 
 #if 0
     {
@@ -853,8 +962,19 @@
 	    int output_fmt = -1;
 
 	    output_fmt = priv->format;
+            if ( tv_param_mjpeg )
+	    {
+              mp_msg(MSGT_TV, MSGL_INFO, "  MJP: setting sh_video->format to mjpg\n");
+	      output_fmt = 0x47504a4d;
+	      output_fmt = 0x67706a6d;
+	      (int)*(void **)arg = output_fmt;
+	      mp_msg(MSGT_TV, MSGL_V, "Output format: %s\n", "mjpg");
+	    }
+	    else
+	    {
 	    (int)*(void **)arg = output_fmt;
 	    mp_msg(MSGT_TV, MSGL_V, "Output format: %s\n", vo_format_name(output_fmt));
+	    }
 	    return(TVI_CONTROL_TRUE);
 	}
 	case TVI_CONTROL_VID_SET_FORMAT:
@@ -1263,14 +1383,30 @@
     int i;
     int framecount;
     int tolerance;
+    unsigned long num;
 
     /* start the capture process */
 
+    if ( tv_param_mjpeg )
+      {
+        mp_msg(MSGT_TV, MSGL_INFO, "  MJP: gonna capture ! \n");
+        for (i=0; i < priv->nbuf; i++) {
+	num = i;
+        if (ioctl(priv->video_fd, MJPIOC_QBUF_CAPT, &num) < 0)
+          {
+            mp_msg(MSGT_TV, MSGL_ERR, 
+	           "\n  MJP: ioctl MJPIOC_QBUF_CAPT b failed: %s\n", strerror(errno));
+          }
+	  }
+      }
+    else
+      {
     for (i=0; i < priv->nbuf; i++) {
 	if (ioctl(priv->video_fd, VIDIOCMCAPTURE, &priv->buf[i]) == -1)
 	{
 	    mp_msg(MSGT_TV, MSGL_ERR, "\nioctl mcapture failed: %s\n", strerror(errno));
 	}
+      }
     }
 
     gettimeofday(&curtime, NULL);
@@ -1301,8 +1437,17 @@
 		
 	    frame = i;
 
+	    if ( tv_param_mjpeg )
+	    {
+	    while (ioctl(priv->video_fd, MJPIOC_SYNC, &priv->buf[frame].frame) < 0 &&
+		   (errno == EAGAIN || errno == EINTR));
+
+	    }
+	    else
+	    {
 	    while (ioctl(priv->video_fd, VIDIOCSYNC, &priv->buf[frame].frame) < 0 &&
 		   (errno == EAGAIN || errno == EINTR));
+	    }
 	    mp_dbg(MSGT_TV, MSGL_DBG3, "\npicture sync failed\n");
 
 	    gettimeofday(&curtime, NULL);
@@ -1405,20 +1550,38 @@
 		    priv->video_timebuffer[priv->video_tail] = interval - skew;
 		}
 		
+                if ( tv_param_mjpeg )
+		copy_frame(priv, priv->video_ringbuffer[priv->video_tail], 
+		           priv->mmap+(priv->mjpeg_bufsize)*i);
+		else
 		copy_frame(priv, priv->video_ringbuffer[priv->video_tail], priv->mmap+priv->mbuf.offsets[frame]);
 		priv->video_tail = (priv->video_tail+1)%priv->video_buffer_size_current;
 		priv->video_cnt++;
 	    }
 
+            if ( tv_param_mjpeg )
+            {
+	      num = frame;
+              if (ioctl(priv->video_fd, MJPIOC_QBUF_CAPT, &num) < 0)
+                {
+                  mp_msg(MSGT_TV, MSGL_ERR, "\n  MJP: ioctl MJPIOC_QBUF_CAPT end failed: %s\n", 
+		                                    strerror(errno));
+		  continue;
+                }
+	    }
+	    else
+	    {
 	    if (ioctl(priv->video_fd, VIDIOCMCAPTURE, &priv->buf[frame]) == -1)
 	    {
 		mp_msg(MSGT_TV, MSGL_ERR, "\nioctl mcapture failed: %s\n", strerror(errno));
 		continue;
 	    }
+	    }
 
 	}
 
     }
+    mp_msg(MSGT_TV, MSGL_INFO, "  MJP: returning! \n");
     return NULL;
 }
 



More information about the MPlayer-cvslog mailing list