[MPlayer-dev-eng] [PATCH] BrookTree 848 support for tv capture
Charles Henrich
henrich at sigbus.com
Tue Feb 19 03:35:55 CET 2002
Includes support for FreeBSD (possibly all *BSD's) bktr0 TV device. Initial
release only supports video input, no tuner support.
-------------- next part --------------
? libmpdemux/tvi_bt848.c
Index: libmpdemux/Makefile
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/Makefile,v
retrieving revision 1.20
diff -u -r1.20 Makefile
--- libmpdemux/Makefile 14 Feb 2002 13:04:35 -0000 1.20
+++ libmpdemux/Makefile 19 Feb 2002 02:46:04 -0000
@@ -3,7 +3,7 @@
include ../config.mak
-SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c aviwrite.c demux_asf.c demux_avi.c demux_mov.c demux_mpg.c demux_viv.c demuxer.c dvdauth.c open.c parse_es.c stream.c tv.c tvi_dummy.c tvi_v4l.c frequencies.c demux_fli.c demux_real.c demux_y4m.c yuv4mpeg.c yuv4mpeg_ratio.c demux_nuv.c demux_film.c demux_roq.c mf.c demux_mf.c demux_audio.c
+SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c aviwrite.c demux_asf.c demux_avi.c demux_mov.c demux_mpg.c demux_viv.c demuxer.c dvdauth.c open.c parse_es.c stream.c tv.c tvi_dummy.c tvi_bt848.c tvi_v4l.c frequencies.c demux_fli.c demux_real.c demux_y4m.c yuv4mpeg.c yuv4mpeg_ratio.c demux_nuv.c demux_film.c demux_roq.c mf.c demux_mf.c demux_audio.c
ifeq ($(STREAMING),yes)
SRCS += asf_streaming.c url.c http.c network.c rtp.c
endif
Index: libmpdemux/tv.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/tv.c,v
retrieving revision 1.24
diff -u -r1.24 tv.c
--- libmpdemux/tv.c 26 Jan 2002 15:43:31 -0000 1.24
+++ libmpdemux/tv.c 19 Feb 2002 02:46:04 -0000
@@ -5,13 +5,16 @@
API idea based on libvo2
- UNDER HEAVY DEVELOPEMENT, NO FEATURE REQUESTS PLEASE! :)
+ Feb 19, 2002: Significant rewrites by Charles R. Henrich (henrich at msu.edu)
+ to add support for audio, and bktr *BSD support.
+
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include <sys/time.h>
#include "config.h"
@@ -34,12 +37,13 @@
#include "frequencies.h"
/* some default values */
+int tv_param_noaudio = 0;
char *tv_param_freq = NULL;
char *tv_param_channel = NULL;
char *tv_param_norm = "pal";
char *tv_param_chanlist = "europe-east";
char *tv_param_device = NULL;
-char *tv_param_driver = "dummy";
+char *tv_param_driver = "bt848";
int tv_param_width = -1;
int tv_param_height = -1;
int tv_param_input = 0; /* used in v4l and bttv */
@@ -53,44 +57,58 @@
1 = successfully read a packet
*/
/* fill demux->video and demux->audio */
+
int demux_tv_fill_buffer(demuxer_t *demux, tvi_handle_t *tvh)
{
- int seq = tvh->seq++;
demux_packet_t* dp;
- int len;
+
sh_video_t *sh_video = demux->video->sh;
+ u_int len;
+ u_int cframe;
+ int aframeswaiting;
- mp_dbg(MSGT_DEMUX, MSGL_DBG2, "demux_tv_fill_buffer(sequence:%d) called!\n", seq);
+ len = cframe = -1;
-// demux->filepos = -1;
+ /* ================== ADD AUDIO PACKET =================== */
-// seq++;
-// tvh->seq++;
+ if (tv_param_noaudio == 0 &&
+ tvh->functions->control(tvh->priv,
+ TVI_CONTROL_IS_AUDIO, 0) == TVI_CONTROL_TRUE)
+ {
+ len = tvh->functions->get_audio_framesize(tvh->priv);
+
+ do {
+ dp=new_demux_packet(len);
+ aframeswaiting=tvh->functions->grab_audio_frame(tvh->priv,
+ dp->buffer,len);
+ dp->pts=tvh->seq/sh_video->fps;
+ dp->pos=tvh->seq*len;
+ ds_add_packet(demux->audio,dp);
+
+ tvh->seq++;
+
+ } while (aframeswaiting > 0);
+ }
/* ================== ADD VIDEO PACKET =================== */
- len = tvh->functions->get_video_framesize(tvh->priv);
- dp=new_demux_packet(len);
- tvh->functions->grab_video_frame(tvh->priv, dp->buffer, len);
- dp->pts=seq/sh_video->fps; //(float)pts/90000.0f;
- //dp->pos=pos;
- //dp->flags=flags;
- // append packet to DS stream:
- ds_add_packet(demux->video,dp);
+ if (tvh->functions->control(tvh->priv,
+ TVI_CONTROL_IS_VIDEO, 0) == TVI_CONTROL_TRUE)
+ {
+ len = tvh->functions->get_video_framesize(tvh->priv);
- /* ================== ADD AUDIO PACKET =================== */
- if (tvh->functions->control(tvh->priv, TVI_CONTROL_IS_AUDIO, 0) != TVI_CONTROL_TRUE)
- return 1; /* no audio, only video */
+ dp=new_demux_packet(len);
- len = tvh->functions->get_audio_framesize(tvh->priv);
+ cframe=tvh->functions->grab_video_frame(tvh->priv, dp->buffer,
+ len);
- dp=new_demux_packet(len);
- tvh->functions->grab_audio_frame(tvh->priv, dp->buffer, len);
- //dp->pts=pts; //(float)pts/90000.0f;
- //dp->pos=pos;
- //dp->flags=flags;
- // append packet to DS stream:
- ds_add_packet(demux->audio,dp);
+ if(tv_param_noaudio == 1) tvh->seq = cframe;
+
+ dp->pos=tvh->seq*len;
+ dp->pts=tvh->seq/sh_video->fps;
+
+ ds_add_packet(demux->video,dp);
+ }
return 1;
}
@@ -167,6 +185,7 @@
tvh->norm = TV_NORM_SECAM;
mp_msg(MSGT_TV, MSGL_INFO, "Selected norm: %s\n", tv_param_norm);
+ funcs->control(tvh->priv, TVI_CONTROL_TUN_SET_NORM, &tvh->norm);
if (funcs->control(tvh->priv, TVI_CONTROL_IS_TUNER, 0) != TVI_CONTROL_TRUE)
{
@@ -251,13 +270,18 @@
// sh_video->format = 0x0;
/* set FPS and FRAMETIME */
+
if(!sh_video->fps)
{
- if (funcs->control(tvh->priv, TVI_CONTROL_VID_GET_FPS, &sh_video->fps) != TVI_CONTROL_TRUE)
- sh_video->fps = 25.0f; /* on PAL */
- }
+ int tmp;
+ if (funcs->control(tvh->priv, TVI_CONTROL_VID_GET_FPS, &tmp) != TVI_CONTROL_TRUE)
+ sh_video->fps = 25.0f; /* on PAL */
+ else sh_video->fps = tmp;
+ }
+
if (tv_param_fps != -1.0f)
- sh_video->fps = tv_param_fps;
+ sh_video->fps = tv_param_fps;
+
sh_video->frametime = 1.0f/sh_video->fps;
printf("fps: %f, frametime: %f\n", sh_video->fps, sh_video->frametime);
@@ -277,20 +301,16 @@
// demuxer->seekable = 0;
/* here comes audio init */
- if (funcs->control(tvh->priv, TVI_CONTROL_IS_AUDIO, 0) == TVI_CONTROL_TRUE)
+
+ if (tv_param_noaudio == 0 && funcs->control(tvh->priv, TVI_CONTROL_IS_AUDIO, 0) == TVI_CONTROL_TRUE)
{
int audio_format;
+ int sh_audio_format;
- sh_audio = new_sh_audio(demuxer, 0);
-
- sh_audio->wf = malloc(sizeof(WAVEFORMATEX));
- memset(sh_audio->wf, 0, sizeof(WAVEFORMATEX));
-
/* yeah, audio is present */
if (funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_FORMAT, &audio_format) != TVI_CONTROL_TRUE)
goto no_audio;
- sh_audio->sample_format = audio_format;
- sh_audio->wf->wBitsPerSample = 16;
+
switch(audio_format)
{
case AFMT_U8:
@@ -301,7 +321,7 @@
case AFMT_S16_BE:
case AFMT_S32_LE:
case AFMT_S32_BE:
- sh_audio->format = 0x1; /* PCM */
+ sh_audio_format = 0x1; /* PCM */
break;
case AFMT_IMA_ADPCM:
case AFMT_MU_LAW:
@@ -313,13 +333,42 @@
goto no_audio;
}
- funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_CHANNELS, &sh_audio->wf->nChannels);
- funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_SAMPLERATE, &sh_audio->wf->nSamplesPerSec);
- funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_SAMPLESIZE, &sh_audio->wf->nAvgBytesPerSec);
+ sh_audio = new_sh_audio(demuxer, 0);
+ sh_audio->wf = (WAVEFORMATEX *)malloc(sizeof(WAVEFORMATEX));
+ sh_audio->format = sh_audio_format;
+ sh_audio->sample_format = audio_format;
+
+ sh_audio->o_bps = sh_audio->samplerate * sh_audio->samplesize/8 *
+ sh_audio->channels;
+
+/* sh_audio->i_bps = 0 */ /* Unknown what this is for XXX:CRH */
+
+ funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_SAMPLERATE,
+ &sh_audio->samplerate);
+ funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_SAMPLESIZE,
+ &sh_audio->samplesize);
+ funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_CHANNELS,
+ &sh_audio->channels);
+
+ sh_audio->wf->nBlockAlign = sh_audio->wf->nAvgBytesPerSec;
demuxer->audio->sh = sh_audio;
sh_audio->ds = demuxer->audio;
demuxer->audio->id = 0;
+
+ // uncompressed PCM format
+ sh_audio->wf->wFormatTag = sh_audio->format;
+ sh_audio->wf->nChannels = sh_audio->channels;
+ sh_audio->wf->wBitsPerSample = sh_audio->samplesize;
+ sh_audio->wf->nSamplesPerSec = sh_audio->samplerate;
+ sh_audio->wf->nAvgBytesPerSec = sh_audio->wf->nChannels *
+ sh_audio->samplesize/8 *
+ sh_audio->samplerate;
+
+ mp_msg(MSGT_DECVIDEO, MSGL_V, " TV audio: %d channels, %d bits, %d Hz\n",
+ sh_audio->wf->nChannels, sh_audio->wf->wBitsPerSample,
+ sh_audio->wf->nSamplesPerSec);
+
}
no_audio:
@@ -334,6 +383,10 @@
#ifdef HAVE_TV_V4L
if (!strcmp(tv_param_driver, "v4l"))
return (tvi_handle_t *)tvi_init_v4l(tv_param_device);
+#endif
+#ifdef HAVE_TV_BT848
+ if (!strcmp(tv_param_driver, "bt848"))
+ return (tvi_handle_t *)tvi_init_bt848(tv_param_device);
#endif
mp_msg(MSGT_TV, MSGL_ERR, "No such driver: %s\n", tv_param_driver);
Index: libmpdemux/tvi_v4l.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/tvi_v4l.c,v
retrieving revision 1.18
diff -u -r1.18 tvi_v4l.c
--- libmpdemux/tvi_v4l.c 27 Dec 2001 23:52:48 -0000 1.18
+++ libmpdemux/tvi_v4l.c 19 Feb 2002 02:46:04 -0000
@@ -63,6 +63,7 @@
struct video_mmap *buf;
int nbuf;
int queue;
+ int currentframe;
/* audio */
int audio_id;
@@ -808,6 +809,8 @@
int frame = priv->queue % priv->nbuf;
int nextframe = (priv->queue+1) % priv->nbuf;
+ priv->currentframe++;
+
mp_dbg(MSGT_TV, MSGL_DBG2, "grab_video_frame(priv=%p, buffer=%p, len=%d)\n",
priv, buffer, len);
@@ -835,7 +838,7 @@
/* copy the actual frame */
memcpy(buffer, priv->mmap+priv->mbuf.offsets[frame], len);
- return(len);
+ return(priv->currentframe);
}
static int get_video_framesize(priv_t *priv)
Index: libmpdemux/video.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/video.c,v
retrieving revision 1.10
diff -u -r1.10 video.c
--- libmpdemux/video.c 14 Feb 2002 22:15:53 -0000 1.10
+++ libmpdemux/video.c 19 Feb 2002 02:46:05 -0000
@@ -278,6 +278,10 @@
sh_video->fps=1.0f/d;
}
} else
+ if(demuxer->file_format==DEMUXER_TYPE_TV && !force_fps){
+ // TV has variable video frame rate, fixed audio...
+ frame_time=d_video->pts-pts1;
+ } else
if(demuxer->file_format==DEMUXER_TYPE_MOV && !force_fps){
// .MOV files has no fixed FPS - just frame durations!
frame_time=d_video->pts-pts1;
-------------- next part --------------
/*
(C)2002 Charles R. Henrich (henrich at msu.edu)
*BSD (hopefully, requires working driver!) BrookTree capture support.
Still in (active) development!
v1.0 Feb 19 2002 First Release, need to add support for changing
audio parameters.
*/
#include "config.h"
#if defined(USE_TV) && defined(HAVE_TV_BT848)
#define TRUE (1==1)
#define FALSE (1==0)
#define PAL_WIDTH 768
#define PAL_HEIGHT 576
#define PAL_FPS 25
#define NTSC_WIDTH 640
#define NTSC_HEIGHT 480
#define NTSC_FPS 30
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <signal.h>
#include <string.h>
#include <machine/ioctl_meteor.h>
#include <machine/ioctl_bt848.h>
#include <machine/soundcard.h>
#include "../libvo/img_format.h"
#include "tv.h"
/* information about this file */
static tvi_info_t info = {
"Brooktree848 Support",
"bt848",
"Charles Henrich",
"in development"
};
/* private data's */
typedef struct {
/* Audio */
char *dspdev;
int dspready;
int dspfd;
int dspsamplesize;
int dspstereo;
int dspspeed;
int dspfmt;
int dspframesize;
/* Video */
char *btdev;
int videoready;
int btfd;
int source;
int maxfps;
int fps;
int iformat;
int maxheight;
int maxwidth;
struct meteor_geomet geom;
struct meteor_capframe capframe;
int buffersize;
unsigned char *buffer;
int currentframe;
} priv_t;
#include "tvi_def.h"
static priv_t *G_private=NULL;
static void catchsignal(int signal)
{
G_private->currentframe++;
return;
}
/* handler creator - entry point ! */
tvi_handle_t *tvi_init_bt848(char *device)
{
return(new_handle());
}
static int control(priv_t *priv, int cmd, void *arg)
{
switch(cmd)
{
case TVI_CONTROL_IS_AUDIO:
if(priv->dspready == FALSE) return TVI_CONTROL_FALSE;
return(TVI_CONTROL_TRUE);
case TVI_CONTROL_AUD_GET_FORMAT:
{
(int)*(void **)arg = AFMT_S16_LE;
return(TVI_CONTROL_TRUE);
}
case TVI_CONTROL_AUD_GET_CHANNELS:
{
(int)*(void **)arg = 2;
return(TVI_CONTROL_TRUE);
}
case TVI_CONTROL_AUD_GET_SAMPLERATE:
{
(int)*(void **)arg = 44100;
return(TVI_CONTROL_TRUE);
}
case TVI_CONTROL_AUD_GET_SAMPLESIZE:
{
(int)*(void **)arg = priv->dspsamplesize;
return(TVI_CONTROL_TRUE);
}
case TVI_CONTROL_IS_VIDEO:
if(priv->videoready == FALSE) return TVI_CONTROL_FALSE;
return(TVI_CONTROL_TRUE);
case TVI_CONTROL_TUN_SET_NORM:
{
int req_mode = (int)*(void **)arg;
priv->iformat = METEOR_FMT_AUTOMODE;
if(req_mode == TV_NORM_PAL)
{
priv->iformat = METEOR_FMT_PAL;
priv->maxheight = PAL_HEIGHT;
priv->maxwidth = PAL_WIDTH;
priv->maxfps = PAL_FPS;
priv->fps = PAL_FPS;
if(priv->fps > priv->maxfps) priv->fps = priv->maxfps;
if(priv->geom.rows > priv->maxheight)
{
priv->geom.rows = priv->maxheight;
}
if(priv->geom.columns > priv->maxwidth)
{
priv->geom.columns = priv->maxwidth;
}
}
if(req_mode == TV_NORM_NTSC)
{
priv->iformat = METEOR_FMT_NTSC;
priv->maxheight = NTSC_HEIGHT;
priv->maxwidth = NTSC_WIDTH;
priv->maxfps = NTSC_FPS;
priv->fps = NTSC_FPS;
priv->dspframesize = priv->dspspeed*priv->dspsamplesize/8/
priv->fps * (priv->dspstereo+1);
if(priv->fps > priv->maxfps) priv->fps = priv->maxfps;
if(priv->geom.rows > priv->maxheight)
{
priv->geom.rows = priv->maxheight;
}
if(priv->geom.columns > priv->maxwidth)
{
priv->geom.columns = priv->maxwidth;
}
}
if(req_mode == TV_NORM_SECAM) priv->iformat = METEOR_FMT_SECAM;
if(ioctl(priv->btfd, METEORSFMT, &priv->iformat) < 0)
{
perror("format:ioctl");
return(TVI_CONTROL_FALSE);
}
if(ioctl(priv->btfd, METEORSETGEO, &priv->geom) < 0)
{
perror("geo:ioctl");
return(0);
}
if(ioctl(priv->btfd, METEORSFPS, &priv->fps) < 0)
{
perror("fps:ioctl");
return(0);
}
return(TVI_CONTROL_TRUE);
}
case TVI_CONTROL_VID_GET_FORMAT:
(int)*(void **)arg = IMGFMT_UYVY;
return(TVI_CONTROL_TRUE);
case TVI_CONTROL_VID_SET_FORMAT:
{
int req_fmt = (int)*(void **)arg;
if(req_fmt != IMGFMT_UYVY) return(TVI_CONTROL_FALSE);
return(TVI_CONTROL_TRUE);
}
case TVI_CONTROL_VID_SET_WIDTH:
priv->geom.columns = (int)*(void **)arg;
if(priv->geom.columns > priv->maxwidth)
{
priv->geom.columns = priv->maxwidth;
}
if(ioctl(priv->btfd, METEORSETGEO, &priv->geom) < 0)
{
perror("width:ioctl");
return(0);
}
return(TVI_CONTROL_TRUE);
case TVI_CONTROL_VID_GET_WIDTH:
(int)*(void **)arg = priv->geom.columns;
return(TVI_CONTROL_TRUE);
case TVI_CONTROL_VID_SET_HEIGHT:
priv->geom.rows = (int)*(void **)arg;
if(priv->geom.rows > priv->maxheight)
{
priv->geom.rows = priv->maxheight;
}
if(priv->geom.rows <= priv->maxheight / 2)
{
priv->geom.oformat |= METEOR_GEO_EVEN_ONLY;
}
if(ioctl(priv->btfd, METEORSETGEO, &priv->geom) < 0)
{
perror("height:ioctl");
return(0);
}
return(TVI_CONTROL_TRUE);
case TVI_CONTROL_VID_GET_HEIGHT:
(int)*(void **)arg = priv->geom.rows;
return(TVI_CONTROL_TRUE);
case TVI_CONTROL_VID_GET_FPS:
(int)*(void **)arg = (int)priv->fps;
return(TVI_CONTROL_TRUE);
/*
case TVI_CONTROL_VID_SET_FPS:
priv->fps = (int)*(void **)arg;
if(priv->fps > priv->maxfps) priv->fps = priv->maxfps;
if(ioctl(priv->btfd, METEORSFPS, &priv->fps) < 0)
{
perror("fps:ioctl");
return(0);
}
return(TVI_CONTROL_TRUE);
*/
case TVI_CONTROL_VID_CHK_WIDTH:
case TVI_CONTROL_VID_CHK_HEIGHT:
return(TVI_CONTROL_TRUE);
}
return(TVI_CONTROL_UNKNOWN);
}
static int init(priv_t *priv)
{
int marg;
G_private = priv; /* Oooh, sick */
priv->videoready = TRUE;
priv->dspready = TRUE;
/* Video Configuration */
priv->btdev = strdup("/dev/bktr0");
priv->iformat = METEOR_FMT_PAL;
priv->maxheight = PAL_HEIGHT;
priv->maxwidth = PAL_WIDTH;
priv->maxfps = PAL_FPS;
priv->source = METEOR_INPUT_DEV0;
priv->fps = priv->maxfps;
priv->currentframe=0;
priv->geom.columns = priv->maxwidth;
priv->geom.rows = priv->maxheight;
priv->geom.frames = 1;
priv->geom.oformat = METEOR_GEO_YUV_PACKED;
priv->btfd = open(priv->btdev, O_RDONLY);
if(priv->btfd < 0)
{
perror("bktr open");
priv->videoready = FALSE;
}
if(priv->videoready == TRUE &&
ioctl(priv->btfd, METEORSFMT, &priv->iformat) < 0)
{
perror("FMT:ioctl");
}
if(priv->videoready == TRUE &&
ioctl(priv->btfd, METEORSINPUT, &priv->source) < 0)
{
perror("SINPUT:ioctl");
}
if(priv->videoready == TRUE &&
ioctl(priv->btfd, METEORSFPS, &priv->fps) < 0)
{
perror("SFPS:ioctl");
}
if(priv->videoready == TRUE &&
ioctl(priv->btfd, METEORSETGEO, &priv->geom) < 0)
{
perror("SGEO:ioctl");
}
if(priv->videoready == TRUE)
{
priv->buffersize = (priv->geom.columns * priv->geom.rows * 2);
priv->buffer = (u_char *)mmap((caddr_t)0, priv->buffersize, PROT_READ,
MAP_SHARED, priv->btfd, (off_t)0);
if(priv->buffer == (u_char *) MAP_FAILED)
{
perror("mmap");
priv->videoready = FALSE;
}
}
/* Audio Configuration */
priv->dspdev = strdup("/dev/dsp");
priv->dspsamplesize = 16;
priv->dspstereo = 1;
priv->dspspeed = 44100;
priv->dspfmt = AFMT_S16_LE;
priv->dspframesize = priv->dspspeed*priv->dspsamplesize/8/priv->fps *
(priv->dspstereo+1);
if((priv->dspfd = open ("/dev/dsp", O_RDONLY, 0)) < 0)
{
perror("/dev/dsp open");
priv->dspready = FALSE;
}
marg = (256 << 16) | 13;
if (ioctl(priv->dspfd, SNDCTL_DSP_SETFRAGMENT, &marg ) < 0 )
{
perror("setfrag");
priv->dspready = FALSE;
}
if((priv->dspready == TRUE) &&
(ioctl(priv->dspfd, SNDCTL_DSP_SAMPLESIZE, &priv->dspsamplesize) == -1) ||
(ioctl(priv->dspfd, SNDCTL_DSP_STEREO, &priv->dspstereo) == -1) ||
(ioctl(priv->dspfd, SNDCTL_DSP_SPEED, &priv->dspspeed) == -1) ||
(ioctl(priv->dspfd, SNDCTL_DSP_SETFMT, &priv->dspfmt) == -1))
{
perror ("configuration of /dev/dsp failed");
close(priv->dspfd);
priv->dspready = FALSE;
}
return(1);
}
/* that's the real start, we'got the format parameters (checked with control) */
static int start(priv_t *priv)
{
int marg;
if(priv->videoready == FALSE) return(0);
signal(SIGUSR1, catchsignal);
signal(SIGALRM, catchsignal);
marg = SIGUSR1;
if(ioctl(priv->btfd, METEORSSIGNAL, &marg) < 0)
{
perror("METEORSSIGNAL failed");
return(0);
}
marg = METEOR_CAP_CONTINOUS;
if(ioctl(priv->btfd, METEORCAPTUR, &marg) < 0)
{
perror("METEORCAPTUR failed");
return(0);
}
return(1);
}
static int uninit(priv_t *priv)
{
int marg;
if(priv->videoready == FALSE) return(0);
marg = METEOR_SIG_MODE_MASK;
if(ioctl( priv->btfd, METEORSSIGNAL, &marg) < 0 )
{
perror("METEORSSIGNAL");
return(0);
}
marg = METEOR_CAP_STOP_CONT;
if(ioctl(priv->btfd, METEORCAPTUR, &marg) < 0 )
{
perror("METEORCAPTUR STOP");
return(0);
}
close(priv->btfd);
close(priv->dspfd);
priv->dspfd = -1;
priv->btfd = -1;
priv->dspready = priv->videoready = FALSE;
return(1);
}
static int grab_video_frame(priv_t *priv, char *buffer, int len)
{
sigset_t sa_mask;
if(priv->videoready == FALSE) return(0);
alarm(1);
sigfillset(&sa_mask);
sigdelset(&sa_mask,SIGINT);
sigdelset(&sa_mask,SIGUSR1);
sigdelset(&sa_mask,SIGALRM);
sigsuspend(&sa_mask);
alarm(0);
memcpy(buffer, priv->buffer, len);
return(priv->currentframe);
}
static int get_video_framesize(priv_t *priv)
{
return(priv->geom.columns*priv->geom.rows*16/8);
}
static int grab_audio_frame(priv_t *priv, char *buffer, int len)
{
struct audio_buf_info abi;
int bytesread;
int ret;
if(priv->dspready == FALSE) return 0;
/* Get exactly one frame of audio, which forces video sync to audio.. */
bytesread=read(priv->dspfd, buffer, len);
while(bytesread < len)
{
ret=read(priv->dspfd, &buffer[bytesread], len-bytesread);
if(ret == -1)
{
perror("Audio read failed!");
return 0;
}
bytesread+=ret;
}
if(ioctl(priv->dspfd, SNDCTL_DSP_GETISPACE, &abi) < 0)
{
perror("abi:ioctl");
return(TVI_CONTROL_FALSE);
}
return(abi.bytes/len);
}
static int get_audio_framesize(priv_t *priv)
{
if(priv->dspready == FALSE) return 0;
return(priv->dspframesize);
}
#endif /* USE_TV */
More information about the MPlayer-dev-eng
mailing list