Remove BSD legacy TV/radio support (BT848 stuff)

FreeBSD actually supports V4L2, and V4L2 supports this chip. Also,
this chip is from 1997. Farewell.
This commit is contained in:
wm4 2013-02-06 21:55:35 +01:00
parent c5340512dd
commit 37c5c114af
8 changed files with 5 additions and 1184 deletions

View File

@ -1598,12 +1598,6 @@
volume=<0..100>
sound volume for radio device (default 100)
freq_min=<value> (\*BSD BT848 only)
minimum allowed frequency (default: 87.50)
freq_max=<value> (\*BSD BT848 only)
maximum allowed frequency (default: 108.00)
channels=<frequency>-<name>,<frequency>-<name>,...
Set channel list. Use _ for spaces in names (or play with quoting ;-).
The channel names will then be written using OSD and the slave
@ -2059,13 +2053,10 @@
driver=<value>
See ``--tv=driver=help`` for a list of compiled-in TV input drivers.
available: dummy, v4l, v4l2, bsdbt848 (default: autodetect)
available: dummy, v4l2 (default: autodetect)
device=<value>
Specify TV device (default: ``/dev/video0``). NOTE: For the bsdbt848
driver you can provide both bktr and tuner device names separating
them with a comma, tuner after bktr (e.g. ``--tv
device=/dev/bktr1,/dev/tuner1``).
Specify TV device (default: ``/dev/video0``).
input=<value>
Specify input (default: 0 (TV), see console output for available
@ -2093,8 +2084,7 @@
maximum size of the capture buffer in megabytes (default: dynamical)
norm=<value>
For bsdbt848 and v4l, PAL, SECAM, NTSC are available. For v4l2, see
the console output for a list of all available norms, also see the
See the console output for a list of all available norms, also see the
normid option below.
normid=<value> (v4l2 only)

View File

@ -72,7 +72,6 @@ SOURCES-$(STREAM_CACHE) += stream/cache2.c
SOURCES-$(TV) += stream/stream_tv.c stream/tv.c \
stream/frequencies.c stream/tvi_dummy.c
SOURCES-$(TV_BSDBT848) += stream/tvi_bsdbt848.c
SOURCES-$(TV_V4L2) += stream/tvi_v4l2.c stream/audio_in.c
SOURCES-$(VCD) += stream/stream_vcd.c

115
configure vendored
View File

@ -305,10 +305,8 @@ Optional features:
--enable-radio enable radio interface [disable]
--enable-radio-capture enable radio capture (through PCI/line-in) [disable]
--disable-radio-v4l2 disable Video4Linux2 radio interface [autodetect]
--disable-radio-bsdbt848 disable BSD BT848 radio interface [autodetect]
--disable-tv disable TV interface (TV/DVB grabbers) [enable]
--disable-tv-v4l2 disable Video4Linux2 TV interface [autodetect]
--disable-tv-bsdbt848 disable BSD BT848 interface [autodetect]
--disable-pvr disable Video4Linux2 MPEG PVR [autodetect]
--disable-networking disable networking [enable]
--enable-winsock2_h enable winsock2_h [autodetect]
@ -454,10 +452,8 @@ _select=yes
_radio=no
_radio_capture=no
_radio_v4l2=auto
_radio_bsdbt848=auto
_tv=yes
_tv_v4l2=auto
_tv_bsdbt848=auto
_pvr=auto
networking=yes
_winsock2_h=auto
@ -646,8 +642,6 @@ for ac_option do
--disable-alsa) _alsa=no ;;
--enable-tv) _tv=yes ;;
--disable-tv) _tv=no ;;
--enable-tv-bsdbt848) _tv_bsdbt848=yes ;;
--disable-tv-bsdbt848) _tv_bsdbt848=no ;;
--enable-tv-v4l2) _tv_v4l2=yes ;;
--disable-tv-v4l2) _tv_v4l2=no ;;
--enable-radio) _radio=yes ;;
@ -656,8 +650,6 @@ for ac_option do
--disable-radio) _radio=no ;;
--enable-radio-v4l2) _radio_v4l2=yes ;;
--disable-radio-v4l2) _radio_v4l2=no ;;
--enable-radio-bsdbt848) _radio_bsdbt848=yes ;;
--disable-radio-bsdbt848) _radio_bsdbt848=no ;;
--enable-pvr) _pvr=yes ;;
--disable-pvr) _pvr=no ;;
--enable-networking) networking=yes ;;
@ -2727,81 +2719,6 @@ fi
echores "$_tv"
if freebsd || netbsd || openbsd || dragonfly ; then
echocheck "*BSD BT848 bt8xx header"
_ioctl_bt848_h=no
for file in "machine/ioctl_bt848.h" \
"dev/bktr/ioctl_bt848.h" \
"dev/video/bktr/ioctl_bt848.h" \
"dev/ic/bt8xx.h" ; do
cat > $TMPC <<EOF
#include <sys/types.h>
#include <sys/ioctl.h>
#include <$file>
int main(void) { ioctl(0, TVTUNER_GETFREQ, 0); return 0; }
EOF
if cc_check ; then
_ioctl_bt848_h=yes
_ioctl_bt848_h_name="$file"
break;
fi
done
if test "$_ioctl_bt848_h" = yes ; then
def_ioctl_bt848_h_name="#define IOCTL_BT848_H_NAME <$_ioctl_bt848_h_name>"
res_comment="using $_ioctl_bt848_h_name"
else
def_ioctl_bt848_h_name="#undef IOCTL_BT848_H_NAME"
fi
echores "$_ioctl_bt848_h"
echocheck "*BSD ioctl_meteor.h"
_ioctl_meteor_h=no
for ioctl_meteor_h_path in "machine/ioctl_meteor.h" "dev/bktr/ioctl_meteor.h" "dev/video/bktr/ioctl_meteor.h" ; do
statement_check_broken "sys/types.h" "$ioctl_meteor_h_path" 'ioctl(0, METEORSINPUT, 0)' &&
_ioctl_meteor_h=yes && break
done
if test "$_ioctl_meteor_h" = yes ; then
def_ioctl_meteor_h_name="#define IOCTL_METEOR_H_NAME <$ioctl_meteor_h_path>"
res_comment="using $ioctl_meteor_h_path"
else
def_ioctl_meteor_h_name="#undef IOCTL_METEOR_H_NAME"
fi
echores "$_ioctl_meteor_h"
echocheck "*BSD BrookTree 848 TV interface"
if test "$_tv_bsdbt848" = auto ; then
_tv_bsdbt848=no
if test "$_tv" = yes ; then
cat > $TMPC <<EOF
#include <sys/types.h>
$def_ioctl_meteor_h_name
$def_ioctl_bt848_h_name
#ifdef IOCTL_METEOR_H_NAME
#include IOCTL_METEOR_H_NAME
#endif
#ifdef IOCTL_BT848_H_NAME
#include IOCTL_BT848_H_NAME
#endif
int main(void) {
ioctl(0, METEORSINPUT, 0);
ioctl(0, TVTUNER_GETFREQ, 0);
return 0;
}
EOF
cc_check && _tv_bsdbt848=yes
fi
fi
if test "$_tv_bsdbt848" = yes ; then
def_tv_bsdbt848='#define CONFIG_TV_BSDBT848 1'
inputmodules="tv-bsdbt848 $inputmodules"
else
def_tv_bsdbt848='#undef CONFIG_TV_BSDBT848'
noinputmodules="tv-bsdbt848 $noinputmodules"
fi
echores "$_tv_bsdbt848"
fi #if freebsd || netbsd || openbsd || dragonfly
echocheck "Video 4 Linux 2 TV interface"
if test "$_tv_v4l2" = auto ; then
_tv_v4l2=no
@ -2860,31 +2777,8 @@ fi
echores "$_radio_v4l2"
if freebsd || netbsd || openbsd || dragonfly &&
test "$_radio" = yes && test "$_radio_bsdbt848" = auto ; then
echocheck "*BSD BrookTree 848 Radio interface"
_radio_bsdbt848=no
cat > $TMPC <<EOF
#include <sys/types.h>
$def_ioctl_bt848_h_name
#ifdef IOCTL_BT848_H_NAME
#include IOCTL_BT848_H_NAME
#endif
int main(void) { ioctl(0, RADIO_GETFREQ, 0); return 0; }
EOF
cc_check && _radio_bsdbt848=yes
echores "$_radio_bsdbt848"
fi #if freebsd || netbsd || openbsd || dragonfly && _radio && _radio_bsdbt848
if test "$_radio_bsdbt848" = yes ; then
def_radio_bsdbt848='#define CONFIG_RADIO_BSDBT848 1'
else
def_radio_bsdbt848='#undef CONFIG_RADIO_BSDBT848'
fi
if test "$_radio_v4l2" = no &&
test "$_radio_bsdbt848" = no && test "$_radio" = yes ; then
die "Radio driver requires BSD BT848 or V4L2!"
if test "$_radio_v4l2" = no && test "$_radio" = yes ; then
die "Radio driver requires V4L2!"
fi
echocheck "Video 4 Linux 2 MPEG PVR interface"
@ -3135,7 +3029,6 @@ RADIO_CAPTURE=$_radio_capture
RSOUND = $_rsound
STREAM_CACHE = $_stream_cache
TV = $_tv
TV_BSDBT848 = $_tv_bsdbt848
TV_V4L2 = $_tv_v4l2
VCD = $_vcd
VDPAU = $_vdpau
@ -3290,18 +3183,14 @@ $def_libbs2b
/* input */
$def_apple_ir
$def_apple_remote
$def_ioctl_bt848_h_name
$def_ioctl_meteor_h_name
$def_joystick
$def_lirc
$def_lircc
$def_pvr
$def_radio
$def_radio_bsdbt848
$def_radio_capture
$def_radio_v4l2
$def_tv
$def_tv_bsdbt848
$def_tv_v4l2

View File

@ -59,10 +59,6 @@ extern const char pp_help[];
const m_option_t radioopts_conf[]={
{"device", &stream_radio_defaults.device, CONF_TYPE_STRING, 0, 0 ,0, NULL},
{"driver", &stream_radio_defaults.driver, CONF_TYPE_STRING, 0, 0 ,0, NULL},
#ifdef RADIO_BSDBT848_HDR
{"freq_min", &stream_radio_defaults.freq_min, CONF_TYPE_FLOAT, 0, 0 ,0, NULL},
{"freq_max", &stream_radio_defaults.freq_max, CONF_TYPE_FLOAT, 0, 0 ,0, NULL},
#endif
{"channels", &stream_radio_defaults.channels, CONF_TYPE_STRING_LIST, 0, 0 ,0, NULL},
{"volume", &stream_radio_defaults.volume, CONF_TYPE_INT, CONF_RANGE, 0 ,100, NULL},
{"adevice", &stream_radio_defaults.adevice, CONF_TYPE_STRING, 0, 0 ,0, NULL},

View File

@ -35,23 +35,8 @@
#include <errno.h>
#include <unistd.h>
#ifdef CONFIG_RADIO_BSDBT848
#include <sys/param.h>
#ifdef IOCTL_BT848_H_NAME
#include IOCTL_BT848_H_NAME
#endif
#else /* CONFIG_RADIO_BSDBT848 */
#include <linux/types.h>
#ifdef CONFIG_RADIO_V4L2
#include <linux/videodev2.h>
#endif
#endif // !IOCTL_BT848_H_NAME
#include "stream.h"
#include "demux/demux.h"
#include "core/m_struct.h"
@ -85,13 +70,7 @@ typedef struct radio_channels_s {
/// default values for options
radio_param_t stream_radio_defaults={
#ifdef CONFIG_RADIO_BSDBT848
"/dev/tuner0", //device
87.50, //freq_min
108.00, //freq_max
#else
"/dev/radio0", //device;
#endif
"default", //driver
NULL, //channels
100, //volume
@ -404,118 +383,6 @@ static const radio_driver_t radio_driver_v4l2={
get_frequency_v4l2
};
#endif /* CONFIG_RADIO_V4L2 */
#ifdef CONFIG_RADIO_BSDBT848
/*****************************************************************
* \brief get fraction value for using in set_frequency and get_frequency
* \return STREAM_OK if success, STREAM_ERROR otherwise
*
* For *BSD BT848 frac=100
*
* Here is a coment from FreeBSD 5.2-RELEASE source code:
*
* * Tuner Notes:
* * Programming the tuner properly is quite complicated.
* * Here are some notes, based on a FM1246 data sheet for a PAL-I tuner.
* * The tuner (front end) covers 45.75 MHz - 855.25 MHz and an FM band of
* * 87.5 MHz to 108.0 MHz.
*
* Thus, frequency range is limited to 87.5-108.0, but you can change
* it, using freq_min and freq_max options
*/
static int init_frac_bsdbt848(radio_priv_t* priv){
priv->frac=100;
priv->rangelow=priv->radio_param->freq_min;
priv->rangehigh=priv->radio_param->freq_max;
return STREAM_OK;
}
/*****************************************************************
* \brief tune card to given frequency
* \param frequency frequency in MHz
* \return STREAM_OK if success, STREAM_ERROR otherwise
*/
static int set_frequency_bsdbt848(radio_priv_t* priv,float frequency){
unsigned int freq;
freq=frequency*priv->frac;
if(ioctl(priv->radio_fd,RADIO_SETFREQ,&freq)<0){
mp_tmsg(MSGT_RADIO,MSGL_ERR,"[radio] ioctl set frequency 0x%x (%.2f) failed: %s\n",freq, frequency, strerror(errno));
return STREAM_ERROR;
}
return STREAM_OK;
}
/*****************************************************************
* \brief get current tuned frequency from card
* \param frequency where to store frequency in MHz
* \return STREAM_OK if success, STREAM_ERROR otherwise
*/
static int get_frequency_bsdbt848(radio_priv_t* priv,float* frequency){
unsigned int freq;
if (ioctl(priv->radio_fd, RADIO_GETFREQ, &freq) < 0) {
mp_tmsg(MSGT_RADIO,MSGL_ERR,"[radio] ioctl get frequency failed: %s\n",strerror(errno));
return STREAM_ERROR;
}
*frequency=((float)freq)/priv->frac;
return STREAM_OK;
}
/*****************************************************************
* \brief set volume on radio card
* \param volume volume level (0..100)
* \return STREAM_OK if success, STREAM_ERROR otherwise
*
* *BSD BT848 does not have volume changing abilities, so
* we will just mute sound if volume=0 and unmute it otherwise.
*/
static void set_volume_bsdbt848(radio_priv_t* priv,int volume){
int audio_flags;
/*arg must be between 0 and 100*/
if (volume > 100) volume = 100;
if (volume < 0) volume = 0;
audio_flags = (volume==0?AUDIO_MUTE:AUDIO_UNMUTE);
if (ioctl(priv->radio_fd, BT848_SAUDIO, &audio_flags)<0){
mp_tmsg(MSGT_RADIO,MSGL_WARN,"[radio] ioctl set mute failed: %s\n",strerror(errno));
}
}
/*****************************************************************
* \brief get current volume from radio card
* \param volume where to store volume level (0..100)
* \return previous STREAM_OK if success, STREAM_ERROR otherwise
*
* *BSD BT848 does not have volume changing abilities, so
* we will return 0 if sound is muted and 100 otherwise.
*/
static int get_volume_bsdbt848(radio_priv_t* priv,int* volume){
int audio_flags;
if (ioctl(priv->radio_fd, BT848_GAUDIO, &audio_flags)<0){
mp_tmsg(MSGT_RADIO,MSGL_ERR,"[radio] ioctl get volume failed: %s\n",strerror(errno));
return STREAM_ERROR;
}
if (audio_flags & AUDIO_MUTE)
*volume=0;
else
*volume=100;
return STREAM_OK;
}
/* bsdbt848 driver info structure */
static const radio_driver_t radio_driver_bsdbt848={
"bsdbt848",
_("[radio] Using *BSD BT848 radio interface.\n"),
init_frac_bsdbt848,
set_volume_bsdbt848,
get_volume_bsdbt848,
set_frequency_bsdbt848,
get_frequency_bsdbt848
};
#endif /* CONFIG_RADIO_BSDBT848 */
static inline int init_frac(radio_priv_t* priv){
return priv->driver->init_frac(priv);
@ -943,9 +810,6 @@ static int fill_buffer_s(struct stream *s, char *buffer, int max_len){
when no driver explicitly specified first available will be used
*/
static const radio_driver_t* radio_drivers[]={
#ifdef CONFIG_RADIO_BSDBT848
&radio_driver_bsdbt848,
#endif
#ifdef CONFIG_RADIO_V4L2
&radio_driver_v4l2,
#endif

View File

@ -28,12 +28,6 @@
typedef struct radio_param_s{
/** name of radio device file */
char* device;
#ifdef CONFIG_RADIO_BSDBT848
/** minimal allowed frequency */
float freq_min;
/** maximal allowed frequency */
float freq_max;
#endif
/** radio driver (v4l,v4l2) */
char* driver;
/** channels list (see man page) */

View File

@ -57,15 +57,11 @@ char *tv_channel_last_real;
/* enumerating drivers (like in stream.c) */
extern const tvi_info_t tvi_info_dummy;
extern const tvi_info_t tvi_info_v4l2;
extern const tvi_info_t tvi_info_bsdbt848;
/** List of drivers in autodetection order */
static const tvi_info_t* tvi_driver_list[]={
#ifdef CONFIG_TV_V4L2
&tvi_info_v4l2,
#endif
#ifdef CONFIG_TV_BSDBT848
&tvi_info_bsdbt848,
#endif
&tvi_info_dummy,
NULL

View File

@ -1,907 +0,0 @@
/*
* *BSD (hopefully, requires working driver!) BrookTree capture support.
*
* Still in (active) development!
*
* v1.1 Mar 13 2002 Fully functional, need to move ring buffer to
* the kernel driver.
* v1.0 Feb 19 2002 First Release, need to add support for changing
* audio parameters.
*
* Copyright (C) 2002 Charles R. Henrich (henrich@msu.edu)
*
* This file is part of MPlayer.
*
* MPlayer is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* MPlayer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#define RINGSIZE 8
#define FRAGSIZE 4096 /* (2^12 see SETFRAGSIZE below) */
#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 29.97
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/filio.h>
#include <sys/time.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <sys/param.h>
#ifdef CONFIG_SUN_AUDIO
#include <sys/audioio.h>
#endif
#ifdef IOCTL_METEOR_H_NAME
#include IOCTL_METEOR_H_NAME
#endif
#ifdef IOCTL_BT848_H_NAME
#include IOCTL_BT848_H_NAME
#endif
#ifdef HAVE_SYS_SOUNDCARD_H
#include <sys/soundcard.h>
#else
#ifdef HAVE_SOUNDCARD_H
#include <soundcard.h>
#else
#include <machine/soundcard.h>
#endif
#endif
#include "audio/format.h"
#include "video/img_fourcc.h"
#include "tv.h"
#include "core/mp_msg.h"
static tvi_handle_t *tvi_init_bsdbt848(tv_param_t* tv_param);
/* information about this file */
const tvi_info_t tvi_info_bsdbt848 = {
tvi_init_bsdbt848,
"Brooktree848 Support",
"bsdbt848",
"Charles Henrich",
"in development"
};
typedef struct {
int dirty;
double timestamp;
char *buf;
} RBFRAME;
/* private data's */
typedef struct priv {
/* Audio */
char *dspdev;
int dspready;
int dspfd;
int dspsamplesize;
int dspstereo;
int dspspeed;
int dspfmt;
int dspframesize;
int dsprate;
long long dspbytesread;
/* Video */
char *btdev;
int videoready;
int btfd;
int source;
float maxfps;
float fps;
int iformat;
int maxheight;
int maxwidth;
struct meteor_geomet geom;
struct meteor_capframe capframe;
/* Frame Buffer */
int framebufsize;
float timestamp;
int curpaintframe;
int curbufframe;
unsigned char *livebuf;
RBFRAME framebuf[RINGSIZE];
/* Inputs */
int input;
/* Tuner */
char *tunerdev;
int tunerfd;
int tunerready;
u_long tunerfreq;
struct bktr_chnlset cset;
/* Other */
int immediatemode;
double starttime;
tv_param_t *tv_param;
} priv_t;
#include "tvi_def.h"
static priv_t *G_private=NULL;
static int getinput(int innumber);
static void processframe(int signal)
{
struct timeval curtime;
if(G_private->immediatemode == TRUE) return;
gettimeofday(&curtime, NULL);
if(G_private->framebuf[G_private->curpaintframe].dirty == TRUE)
{
memcpy(G_private->framebuf[G_private->curpaintframe].buf,
G_private->livebuf, G_private->framebufsize);
G_private->framebuf[G_private->curpaintframe].dirty = FALSE;
G_private->framebuf[G_private->curpaintframe].timestamp =
curtime.tv_sec + curtime.tv_usec*.000001;
G_private->curpaintframe++;
if(G_private->curpaintframe >= RINGSIZE) G_private->curpaintframe = 0;
}
return;
}
/* handler creator - entry point ! */
static tvi_handle_t *tvi_init_bsdbt848(tv_param_t* tv_param)
{
char* sep ;
tvi_handle_t* tvh;
priv_t* priv;
tvh = tv_new_handle(sizeof(priv_t), &functions);
if(!tvh)
return NULL;
priv=(priv_t*)tvh->priv;
/*
if user needs to specify both /dev/bktr<n> and /dev/tuner<n>
it can do this with "-tv device=/dev/bktr1,/dev/tuner1"
*/
/* set video device name */
if (!tv_param->device){
priv->btdev = strdup("/dev/bktr0");
priv->tunerdev = strdup("/dev/tuner0");
}else{
sep = strchr(tv_param->device,',');
priv->btdev = strdup(tv_param->device);
if(sep){
// tuner device is also passed
priv->tunerdev = strdup(sep+1);
priv->btdev[sep - tv_param->device] = 0;
}else{
priv->tunerdev = strdup("/dev/tuner0");
}
}
/* set audio device name */
if (!tv_param->adevice)
#ifdef CONFIG_SUN_AUDIO
priv->dspdev = strdup("/dev/sound");
#else
priv->dspdev = strdup("/dev/dsp");
#endif
else
priv->dspdev = strdup(tv_param->adevice);
priv->tv_param=tv_param;
return tvh;
}
static int control(priv_t *priv, int cmd, void *arg)
{
switch(cmd)
{
/* Tuner Controls */
case TVI_CONTROL_IS_TUNER:
if(priv->tunerready == FALSE) return TVI_CONTROL_FALSE;
return TVI_CONTROL_TRUE;
case TVI_CONTROL_TUN_GET_FREQ:
{
if(ioctl(priv->tunerfd, TVTUNER_GETFREQ, &priv->tunerfreq) < 0)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Call to %s ioctl failed. Error: %s\n", "TVTUNER_GETFREQ", strerror(errno));
return TVI_CONTROL_FALSE;
}
*(int *)arg = priv->tunerfreq;
return TVI_CONTROL_TRUE;
}
case TVI_CONTROL_TUN_SET_FREQ:
{
priv->tunerfreq = *(int *)arg;
if(ioctl(priv->tunerfd, TVTUNER_SETFREQ, &priv->tunerfreq) < 0)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Call to %s ioctl failed. Error: %s\n", "TVTUNER_SETFREQ", strerror(errno));
return 0;
}
return TVI_CONTROL_TRUE;
}
case TVI_CONTROL_TUN_GET_SIGNAL:
{
int status;
if(ioctl(priv->tunerfd, TVTUNER_GETSTATUS, &status) < 0)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Call to %s ioctl failed. Error: %s\n", "GETSTATUS", strerror(errno));
return 0;
}
*(int*)arg=(status & 0x02)? 100 : 0;
return TVI_CONTROL_TRUE;
}
case TVI_CONTROL_TUN_GET_TUNER:
case TVI_CONTROL_TUN_SET_TUNER:
/* Inputs */
case TVI_CONTROL_SPC_GET_INPUT:
{
if(ioctl(priv->btfd, METEORGINPUT, &priv->input) < 0)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Call to %s ioctl failed. Error: %s\n", "METEORGINPUT", strerror(errno));
return TVI_CONTROL_FALSE;
}
*(int *)arg = priv->input;
return TVI_CONTROL_TRUE;
}
case TVI_CONTROL_SPC_SET_INPUT:
{
priv->input = getinput(*(int *)arg);
if(ioctl(priv->btfd, METEORSINPUT, &priv->input) < 0)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Call to %s ioctl failed. Error: %s\n", "METEORSINPUT", strerror(errno));
return 0;
}
return TVI_CONTROL_TRUE;
}
/* Audio Controls */
case TVI_CONTROL_IS_AUDIO:
if(priv->dspready == FALSE) return TVI_CONTROL_FALSE;
return TVI_CONTROL_TRUE;
case TVI_CONTROL_AUD_GET_FORMAT:
{
*(int *)arg = AF_FORMAT_S16_LE;
return TVI_CONTROL_TRUE;
}
case TVI_CONTROL_AUD_GET_CHANNELS:
{
*(int *)arg = 2;
return TVI_CONTROL_TRUE;
}
case TVI_CONTROL_AUD_SET_SAMPLERATE:
{
int dspspeed = *(int *)arg;
if(ioctl(priv->dspfd, SNDCTL_DSP_SPEED, &dspspeed) == -1)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Invalid audio rate. Error: %s\n", strerror(errno));
return TVI_CONTROL_FALSE;
}
priv->dspspeed = dspspeed;
priv->dspframesize = priv->dspspeed*priv->dspsamplesize/8/
priv->fps * (priv->dspstereo+1);
priv->dsprate = priv->dspspeed * priv->dspsamplesize/8*
(priv->dspstereo+1);
return TVI_CONTROL_TRUE;
}
case TVI_CONTROL_AUD_GET_SAMPLERATE:
{
*(int *)arg = priv->dspspeed;
return TVI_CONTROL_TRUE;
}
case TVI_CONTROL_AUD_GET_SAMPLESIZE:
{
*(int *)arg = priv->dspsamplesize/8;
return TVI_CONTROL_TRUE;
}
/* Video Controls */
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 *)arg;
u_short tmp_fps;
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);
priv->dsprate = priv->dspspeed * priv->dspsamplesize/8 *
(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)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Call to %s ioctl failed. Error: %s\n", "METEORSFMT", strerror(errno));
return TVI_CONTROL_FALSE;
}
if(ioctl(priv->btfd, METEORSETGEO, &priv->geom) < 0)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Call to %s ioctl failed. Error: %s\n", "METEORSETGEO", strerror(errno));
return 0;
}
tmp_fps = priv->fps;
if(ioctl(priv->btfd, METEORSFPS, &tmp_fps) < 0)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Call to %s ioctl failed. Error: %s\n", "METEORSFPS", strerror(errno));
return 0;
}
#ifdef BT848_SAUDIO
if(priv->tunerready == TRUE &&
ioctl(priv->tunerfd, BT848_SAUDIO, &priv->tv_param->audio_id) < 0)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Call to %s ioctl failed. Error: %s\n", "BT848_SAUDIO", strerror(errno));
}
#endif
return TVI_CONTROL_TRUE;
}
case TVI_CONTROL_VID_GET_FORMAT:
*(int *)arg = MP_FOURCC_UYVY;
return TVI_CONTROL_TRUE;
case TVI_CONTROL_VID_SET_FORMAT:
{
int req_fmt = *(int *)arg;
if(req_fmt != MP_FOURCC_UYVY) return TVI_CONTROL_FALSE;
return TVI_CONTROL_TRUE;
}
case TVI_CONTROL_VID_SET_WIDTH:
priv->geom.columns = *(int *)arg;
if(priv->geom.columns > priv->maxwidth)
{
priv->geom.columns = priv->maxwidth;
}
if(ioctl(priv->btfd, METEORSETGEO, &priv->geom) < 0)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Error setting picture width. Error: %s\n", strerror(errno));
return 0;
}
return TVI_CONTROL_TRUE;
case TVI_CONTROL_VID_GET_WIDTH:
*(int *)arg = priv->geom.columns;
return TVI_CONTROL_TRUE;
case TVI_CONTROL_VID_SET_HEIGHT:
priv->geom.rows = *(int *)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)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Error setting picture width. Error: %s\n", strerror(errno));
return 0;
}
return TVI_CONTROL_TRUE;
case TVI_CONTROL_VID_GET_HEIGHT:
*(int *)arg = priv->geom.rows;
return TVI_CONTROL_TRUE;
case TVI_CONTROL_VID_GET_FPS:
*(float *)arg = priv->fps;
return TVI_CONTROL_TRUE;
/*
case TVI_CONTROL_VID_SET_FPS:
priv->fps = *(int *)arg;
if(priv->fps > priv->maxfps) priv->fps = priv->maxfps;
if(ioctl(priv->btfd, METEORSFPS, &priv->fps) < 0)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Call to %s ioctl failed. Error: %s\n", "METEORSFPS", strerror(errno));
return 0;
}
return TVI_CONTROL_TRUE;
*/
case TVI_CONTROL_VID_CHK_WIDTH:
case TVI_CONTROL_VID_CHK_HEIGHT:
return TVI_CONTROL_TRUE;
case TVI_CONTROL_IMMEDIATE:
priv->immediatemode = TRUE;
return TVI_CONTROL_TRUE;
}
return TVI_CONTROL_UNKNOWN;
}
static int init(priv_t *priv)
{
int marg;
int count;
u_short tmp_fps;
G_private = priv; /* Oooh, sick */
/* Video Configuration */
priv->videoready = TRUE;
priv->immediatemode = FALSE;
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->starttime=0;
priv->curpaintframe=0;
priv->curbufframe=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)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Unable to open bktr device. Error: %s\n", strerror(errno));
priv->videoready = FALSE;
}
if(priv->videoready == TRUE &&
ioctl(priv->btfd, METEORSFMT, &priv->iformat) < 0)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Call to %s ioctl failed. Error: %s\n", "SETEORSFMT", strerror(errno));
}
if(priv->videoready == TRUE &&
ioctl(priv->btfd, METEORSINPUT, &priv->source) < 0)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Call to %s ioctl failed. Error: %s\n", "METEORSINPUT", strerror(errno));
}
tmp_fps = priv->fps;
if(priv->videoready == TRUE &&
ioctl(priv->btfd, METEORSFPS, &tmp_fps) < 0)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Call to %s ioctl failed. Error: %s\n", "METEORSFPS", strerror(errno));
}
if(priv->videoready == TRUE &&
ioctl(priv->btfd, METEORSETGEO, &priv->geom) < 0)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Call to %s ioctl failed. Error: %s\n", "METEORSGEQ", strerror(errno));
}
if(priv->videoready == TRUE)
{
priv->framebufsize = (priv->geom.columns * priv->geom.rows * 2);
priv->livebuf = (u_char *)mmap((caddr_t)0, priv->framebufsize, PROT_READ,
MAP_SHARED, priv->btfd, (off_t)0);
if(priv->livebuf == (u_char *) MAP_FAILED)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: mmap failed. Error: %s\n", strerror(errno));
priv->videoready = FALSE;
}
for(count=0;count<RINGSIZE;count++)
{
priv->framebuf[count].buf = malloc(priv->framebufsize);
if(priv->framebuf[count].buf == NULL)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Frame buffer allocation failed. Error: %s\n", strerror(errno));
priv->videoready = FALSE;
break;
}
priv->framebuf[count].dirty = TRUE;
priv->framebuf[count].timestamp = 0;
}
}
/* Tuner Configuration */
priv->tunerready = TRUE;
priv->tunerfd = open(priv->tunerdev, O_RDONLY);
if(priv->tunerfd < 0)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Unable to open tuner device. Error: %s\n", strerror(errno));
priv->tunerready = FALSE;
}
/* Audio Configuration */
priv->dspready = TRUE;
priv->dspsamplesize = 16;
priv->dspstereo = 1;
priv->dspspeed = 44100;
priv->dspfmt = AFMT_S16_LE;
priv->dspbytesread = 0;
priv->dsprate = priv->dspspeed * priv->dspsamplesize/8*(priv->dspstereo+1);
priv->dspframesize = priv->dspspeed*priv->dspsamplesize/8/priv->fps *
(priv->dspstereo+1);
if((priv->dspfd = open (priv->dspdev, O_RDONLY, 0)) < 0)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Unable to open dsp device. Error: %s\n", strerror(errno));
priv->dspready = FALSE;
}
marg = (256 << 16) | 12;
if (ioctl(priv->dspfd, SNDCTL_DSP_SETFRAGMENT, &marg ) < 0 )
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Call to %s ioctl failed. Error: %s\n", "SNDCTL_DSP_SETFRAGMENT", strerror(errno));
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)))
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Configuration of dsp failed. Error: %s\n", strerror(errno));
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 tmp;
struct timeval curtime;
int marg;
fprintf(stderr,"START\n");
if(priv->videoready == FALSE) return 0;
signal(SIGUSR1, processframe);
signal(SIGALRM, processframe);
marg = SIGUSR1;
if(ioctl(priv->btfd, METEORSSIGNAL, &marg) < 0)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Call to %s ioctl failed. Error: %s\n", "METEORSSIGNAL", strerror(errno));
return 0;
}
read(priv->dspfd, &tmp, 2);
gettimeofday(&curtime, NULL);
priv->starttime = curtime.tv_sec + (curtime.tv_usec *.000001);
marg = METEOR_CAP_CONTINOUS;
if(ioctl(priv->btfd, METEORCAPTUR, &marg) < 0)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Call to %s ioctl failed. Error: %s\n", "METEORCAPTUR", strerror(errno));
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 )
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Call to %s ioctl failed. Error: %s\n", "METEORSSIGNAL", strerror(errno));
return 0;
}
marg = METEOR_CAP_STOP_CONT;
if(ioctl(priv->btfd, METEORCAPTUR, &marg) < 0 )
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Unable to stop capture. Error: %s\n", strerror(errno));
return 0;
}
close(priv->btfd);
close(priv->dspfd);
priv->dspfd = -1;
priv->btfd = -1;
priv->dspready = priv->videoready = FALSE;
return 1;
}
static double grabimmediate_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->livebuf, len);
/* PTS = 0, show the frame NOW, this routine is only used in playback mode
without audio capture .. */
return 0;
}
static double grab_video_frame(priv_t *priv, char *buffer, int len)
{
double timestamp=0;
sigset_t sa_mask;
if(priv->videoready == FALSE) return 0;
if(priv->immediatemode == TRUE)
{
return grabimmediate_video_frame(priv, buffer, len);
}
while(priv->framebuf[priv->curbufframe].dirty == TRUE)
{
alarm(1);
sigemptyset(&sa_mask);
sigsuspend(&sa_mask);
alarm(0);
}
memcpy(buffer, priv->framebuf[priv->curbufframe].buf, len);
timestamp = priv->framebuf[priv->curbufframe].timestamp;
priv->framebuf[priv->curbufframe].dirty = TRUE;
priv->curbufframe++;
if(priv->curbufframe >= RINGSIZE) priv->curbufframe = 0;
return timestamp-priv->starttime;
}
static int get_video_framesize(priv_t *priv)
{
return priv->geom.columns * priv->geom.rows * 16 / 8;
}
static double grab_audio_frame(priv_t *priv, char *buffer, int len)
{
struct timeval curtime;
double curpts;
double timeskew;
int bytesread;
int ret;
if(priv->dspready == FALSE) return 0;
gettimeofday(&curtime, NULL);
/* 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)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Error reading audio data. Error: %s\n", strerror(errno));
return 0;
}
bytesread+=ret;
}
priv->dspbytesread += bytesread;
curpts = curtime.tv_sec + curtime.tv_usec * .000001;
timeskew = priv->dspbytesread * 1.0 / priv->dsprate - (curpts-priv->starttime);
if(timeskew > .125/priv->fps)
{
priv->starttime -= timeskew;
}
else
{
if(timeskew < -.125/priv->fps)
{
priv->starttime -= timeskew;
}
}
return priv->dspbytesread * 1.0 / priv->dsprate;
}
static int get_audio_framesize(priv_t *priv)
{
int bytesavail;
#ifdef CONFIG_SUN_AUDIO
struct audio_info auinf;
#endif
if(priv->dspready == FALSE) return 0;
#ifdef CONFIG_SUN_AUDIO
if(ioctl(priv->dspfd, AUDIO_GETINFO, &auinf) < 0)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Call to %s ioctl failed. Error: %s\n", "AUDIO_GETINFO", strerror(errno));
return TVI_CONTROL_FALSE;
}
else
bytesavail = auinf.record.seek; /* *priv->dspsamplesize; */
#else
if(ioctl(priv->dspfd, FIONREAD, &bytesavail) < 0)
{
mp_tmsg(MSGT_TV, MSGL_ERR, "tvi_bsdbt848: Call to %s ioctl failed. Error: %s\n", "FIONREAD", strerror(errno));
return TVI_CONTROL_FALSE;
}
#endif
/* When mencoder wants audio data, it wants data..
it won't go do anything else until it gets it :( */
if(bytesavail == 0) return FRAGSIZE;
return bytesavail;
}
static int getinput(int innumber)
{
switch(innumber)
{
case 0: return METEOR_INPUT_DEV0; /* RCA */
case 1: return METEOR_INPUT_DEV1; /* Tuner */
case 2: return METEOR_INPUT_DEV2; /* In 1 */
case 3: return METEOR_INPUT_DEV3; /* In 2 */
case 4: return METEOR_INPUT_DEV_RGB; /* RGB */
case 5: return METEOR_INPUT_DEV_SVIDEO; /* SVid */
}
return 0;
}