[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