From 132f395aacb2c658e91b8845076115f98158edce Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 13 Apr 2014 18:51:43 +0200 Subject: Remove radio:// It was disabled by default, works only for analogue radio, and I bet nobody uses it. --- DOCS/man/en/mpv.rst | 1 - DOCS/man/en/options.rst | 55 --- old-configure | 58 --- old-makefile | 2 - options/options.c | 18 +- stream/stream.c | 4 - stream/stream_radio.c | 977 ------------------------------------------------ stream/stream_radio.h | 59 --- wscript | 20 +- wscript_build.py | 1 - 10 files changed, 3 insertions(+), 1192 deletions(-) delete mode 100644 stream/stream_radio.c delete mode 100644 stream/stream_radio.h diff --git a/DOCS/man/en/mpv.rst b/DOCS/man/en/mpv.rst index 58d676f8d4..491ea18cdb 100644 --- a/DOCS/man/en/mpv.rst +++ b/DOCS/man/en/mpv.rst @@ -21,7 +21,6 @@ SYNOPSIS | **mpv** dvdnav://[longest|menu|title][/device] [options] | **mpv** \vcd://[/device] | **mpv** \tv://[channel][/input_id] [options] -| **mpv** radio://[channel|frequency][/capture] [options] | **mpv** \pvr:// [options] | **mpv** \dvb://[card\_number@]channel [options] | **mpv** \mf://[filemask|\@listfile] [-mf options] [options] diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst index f217efbe80..9e139c0578 100644 --- a/DOCS/man/en/options.rst +++ b/DOCS/man/en/options.rst @@ -1827,61 +1827,6 @@ OPTIONS functionality is limited to switching between ``best`` and ``default`` if the ``cycle`` input command is used. -``--radio=`` - These options set various parameters of the radio capture module. For - listening to radio with mpv, use ``radio://`` (if channels - option is not given) or ``radio://`` (if channels option - is given) as a movie URL. You can see allowed frequency range by running - mpv with ``-v``. To start the grabbing subsystem, use - ``radio:///capture``. If the capture keyword is not - given, you can listen to radio using the line-in cable only. Using capture - to listen is not recommended due to synchronization problems, which makes - this process uncomfortable. - - Available options are: - - ``device=`` - Radio device to use (default: ``/dev/radio0`` for Linux and - ``/dev/tuner0`` for \*BSD). - - ``driver=`` - Radio driver to use (default: v4l2 if available, otherwise v4l). - Currently, v4l and v4l2 drivers are supported. - - ``volume=<0..100>`` - Sound volume for radio device (default 100). - - ``channels=-,-,...`` - Set channel list. Use _ for spaces in names (or play with quoting ;-) ). - The channel names will then be written using OSD, and the slave - commands ``radio_step_channel`` and ``radio_set_channel`` will be usable - for a remote control (see LIRC). If given, number in movie URL will be - treated as channel position in channel list. - - .. admonition:: Example - - ``radio://1``, ``radio://104.4``, ``radio_set_channel 1`` - - ``adevice=`` (radio capture only) - Name of device to capture sound from. Without such a name, capture will - be disabled, even if the ``capture`` keyword appears in the URL. - For ALSA devices, use it in the form ``hw=.``. If the - device name contains a '=', the module will use ALSA to capture, - otherwise OSS. - - ``arate=`` (radio capture only) - Rate in samples per second (default: 44100). - - .. note:: - - When using audio capture set also ``--rawaudio=rate=`` option - with the same value as arate. If you have problems with sound speed - (runs too quickly), try to play with different rate values (e.g. - 48000, 44100, 32000,...). - - ``achannels=`` (radio capture only) - Number of audio channels to capture. - ``--really-quiet`` Display even less output and status messages than with ``--quiet``. diff --git a/old-configure b/old-configure index 98ffaf8c00..ab75ba16c3 100755 --- a/old-configure +++ b/old-configure @@ -304,9 +304,6 @@ Optional features: --enable-joystick enable joystick support [disable] --disable-vm disable X video mode extensions [autodetect] --disable-xf86keysym disable support for multimedia keys [autodetect] - --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-tv disable TV interface (TV/DVB grabbers) [enable] --disable-tv-v4l2 disable Video4Linux2 TV interface [autodetect] --disable-libv4l2 disable libv4l2 [autodetect] @@ -459,9 +456,6 @@ _xf86keysym=auto _sndio=auto _alsa=auto _select=yes -_radio=no -_radio_capture=no -_radio_v4l2=auto _tv=yes _tv_v4l2=auto _libv4l2=auto @@ -657,12 +651,6 @@ for ac_option do --disable-tv-v4l2) _tv_v4l2=no ;; --enable-libv4l2) _libv4l2=yes ;; --disable-libv4l2) _libv4l2=no ;; - --enable-radio) _radio=yes ;; - --enable-radio-capture) _radio_capture=yes ;; - --disable-radio-capture) _radio_capture=no ;; - --disable-radio) _radio=no ;; - --enable-radio-v4l2) _radio_v4l2=yes ;; - --disable-radio-v4l2) _radio_v4l2=no ;; --enable-pvr) _pvr=yes ;; --disable-pvr) _pvr=no ;; --enable-smb) _smb=yes ;; @@ -2903,47 +2891,6 @@ else fi echores "$_libv4l2" -echocheck "Radio interface" -if test "$_radio" = yes ; then - def_radio='#define HAVE_RADIO 1' - inputmodules="radio $inputmodules" - if test "$_alsa" != yes -a "$_ossaudio" != yes ; then - _radio_capture=no - fi - if test "$_radio_capture" = yes ; then - _audio_input=yes - def_radio_capture="#define HAVE_RADIO_CAPTURE 1" - else - def_radio_capture="#define HAVE_RADIO_CAPTURE 0" - fi -else - noinputmodules="radio $noinputmodules" - def_radio='#define HAVE_RADIO 0' - def_radio_capture="#define HAVE_RADIO_CAPTURE 0" - _radio_capture=no -fi -echores "$_radio" -echocheck "Capture for Radio interface" -echores "$_radio_capture" - -echocheck "Video 4 Linux 2 Radio interface" -if test "$_radio_v4l2" = auto ; then - _radio_v4l2=no - if test "$_radio" = yes && (linux || freebsd) ; then - header_check linux/videodev2.h && _radio_v4l2=yes - fi -fi -if test "$_radio_v4l2" = yes ; then - def_radio_v4l2='#define HAVE_RADIO_V4L2 1' -else - def_radio_v4l2='#define HAVE_RADIO_V4L2 0' -fi -echores "$_radio_v4l2" - - -if test "$_radio_v4l2" = no && test "$_radio" = yes ; then - die "Radio driver requires V4L2!" -fi echocheck "Video 4 Linux 2 MPEG PVR interface" if test "$_pvr" = auto ; then @@ -3261,8 +3208,6 @@ PRIORITY = $_priority PULSE = $_pulse PORTAUDIO = $_portaudio PVR = $_pvr -RADIO=$_radio -RADIO_CAPTURE=$_radio_capture RSOUND = $_rsound SNDIO = $_sndio STREAM_CACHE = $_stream_cache @@ -3413,9 +3358,6 @@ $def_libbs2b $def_joystick $def_lirc $def_pvr -$def_radio -$def_radio_capture -$def_radio_v4l2 $def_tv $def_tv_v4l2 $def_libv4l2 diff --git a/old-makefile b/old-makefile index 411163fa9a..ed2eefe00f 100644 --- a/old-makefile +++ b/old-makefile @@ -64,8 +64,6 @@ SOURCES-$(WIN32) += osdep/path-win.c \ SOURCES-$(PRIORITY) += osdep/priority.c SOURCES-$(PVR) += stream/stream_pvr.c -SOURCES-$(RADIO) += stream/stream_radio.c -SOURCES-$(RADIO_CAPTURE) += stream/audio_in.c SOURCES-$(STREAM_CACHE) += stream/cache.c SOURCES-$(TV) += stream/stream_tv.c stream/tv.c \ diff --git a/options/options.c b/options/options.c index 77d9205082..42ca0846d9 100644 --- a/options/options.c +++ b/options/options.c @@ -32,8 +32,8 @@ #include "m_config.h" #include "m_option.h" #include "common/common.h" +#include "stream/stream.h" #include "stream/tv.h" -#include "stream/stream_radio.h" #include "video/csputils.h" #include "sub/osd.h" #include "audio/mixer.h" @@ -62,19 +62,6 @@ static void print_help(struct mp_log *log) mp_info(log, "%s", mp_help_text); } -#if HAVE_RADIO -static 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}, - {"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}, - {"arate", &stream_radio_defaults.arate, CONF_TYPE_INT, CONF_MIN, 0 ,0, NULL}, - {"achannels", &stream_radio_defaults.achannels, CONF_TYPE_INT, CONF_MIN, 0 ,0, NULL}, - {NULL, NULL, 0, 0, 0, 0, NULL} -}; -#endif /* HAVE_RADIO */ - #if HAVE_TV static const m_option_t tvopts_conf[]={ {"immediatemode", &stream_tv_defaults.immediate, CONF_TYPE_INT, CONF_RANGE, 0, 1, NULL}, @@ -338,9 +325,6 @@ const m_option_t mp_opts[] = { OPT_STRING("sub-demuxer", sub_demuxer_name, 0), {"mf", (void *) mfopts_conf, CONF_TYPE_SUBCONFIG, 0,0,0, NULL}, -#if HAVE_RADIO - {"radio", (void *) radioopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, -#endif /* HAVE_RADIO */ #if HAVE_TV {"tv", (void *) tvopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, #endif /* HAVE_TV */ diff --git a/stream/stream.c b/stream/stream.c index a7990595d2..99e871d5a0 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -64,7 +64,6 @@ extern const stream_info_t stream_info_vcd; extern const stream_info_t stream_info_cdda; extern const stream_info_t stream_info_dvb; extern const stream_info_t stream_info_tv; -extern const stream_info_t stream_info_radio; extern const stream_info_t stream_info_pvr; extern const stream_info_t stream_info_smb; extern const stream_info_t stream_info_null; @@ -97,9 +96,6 @@ static const stream_info_t *const stream_list[] = { #if HAVE_TV &stream_info_tv, #endif -#if HAVE_RADIO - &stream_info_radio, -#endif #if HAVE_PVR &stream_info_pvr, #endif diff --git a/stream/stream_radio.c b/stream/stream_radio.c deleted file mode 100644 index 4dc60ae112..0000000000 --- a/stream/stream_radio.c +++ /dev/null @@ -1,977 +0,0 @@ -/* - * radio support - * - * Abilities: - * * Listening v4l compatible radio cards using line-in or - * similar cable - * * Grabbing audio data using -ao pcm or -dumpaudio - * (must be compiled with --enable-radio-capture). - * - * Initially written by Vladimir Voroshilov . - * Based on tv.c and tvi_v4l2.c code. - * - * 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" - -#include -#include -#include -#include -#include -#include - -#if HAVE_RADIO_V4L2 -#include -#endif - -#include - -#include "stream.h" -#include "options/m_option.h" -#include "common/msg.h" -#include "stream_radio.h" - -#include "osdep/io.h" - -#if HAVE_RADIO_CAPTURE -#include "audio_in.h" - -#if HAVE_SYS_SOUNDCARD_H -#include -#else -#if HAVE_SOUNDCARD_H -#include -#else -#include -#endif -#endif - -#endif - -#define _(x) (x) - -typedef struct radio_channels_s { - int index; ///< channel index in channels list - float freq; ///< frequency in MHz - char name[20]; ///< channel name - struct radio_channels_s * next; - struct radio_channels_s * prev; -} radio_channels_t; - -/// default values for options -radio_param_t stream_radio_defaults={ - "/dev/radio0", //device; - "default", //driver - NULL, //channels - 100, //volume - NULL, //adevice - 44100, //arate - 2, //achannels - 0, //freq_channel - NULL, //capture -}; - -typedef struct radio_priv_s { - struct mp_log *log; - int radio_fd; ///< radio device descriptor - int frac; ///< fraction value (see comment to init_frac) - radio_channels_t* radio_channel_list; - radio_channels_t* radio_channel_current; - float rangelow; ///< lowest tunable frequency in MHz - float rangehigh; ///< highest tunable frequency in MHz - const struct radio_driver_s* driver; - int old_snd_volume; -#if HAVE_RADIO_CAPTURE - volatile int do_capture; ///< is capture enabled - audio_in_t audio_in; - unsigned char* audio_ringbuffer; - int audio_head; ///< start of meanfull data in ringbuffer - int audio_tail; ///< end of meanfull data in ringbuffer - int audio_buffer_size; ///< size of ringbuffer - int audio_cnt; ///< size of meanfull data inringbuffer - int audio_drop; ///< number of dropped bytes - int audio_initialized; -#endif - radio_param_t *radio_param; -} radio_priv_t; - -typedef struct radio_driver_s { - char* name; - char* info; - int (*init_frac)(radio_priv_t* priv); - void (*set_volume)(radio_priv_t* priv,int volume); - int (*get_volume)(radio_priv_t* priv,int* volume); - int (*set_frequency)(radio_priv_t* priv,float frequency); - int (*get_frequency)(radio_priv_t* priv,float* frequency); -} radio_driver_t; - -#define OPT_BASE_STRUCT radio_param_t -static const m_option_t stream_opts_fields[] = { - OPT_FLOAT("title", freq_channel, 0), - OPT_STRING("capture", capture, 0), - {0} -}; - -static void close_s(struct stream *stream); -#if HAVE_RADIO_CAPTURE -static int clear_buffer(radio_priv_t* priv); -#endif - - -/***************************************************************** - * \brief parse channels parameter and store result into list - * \param freq_channel if channels!=NULL this mean channel number, otherwise - frequency - * \param pfreq selected frequency (from selected channel or from URL) - * \result STREAM_OK if success, STREAM_ERROR otherwise - * - * channels option must be in the following format - * -,-,... - * - * '_' will be replaced with spaces. - * - * If channels option is not null, number in movie URL will be treated as - * channel position in channel list. - */ -static int parse_channels(radio_priv_t* priv,float freq_channel,float* pfreq){ - char** channels; - int i; - int channel = 0; - if (priv->radio_param->channels){ - /*parsing channels string*/ - channels=priv->radio_param->channels; - - MP_INFO(priv, "Radio channel names detected.\n"); - priv->radio_channel_list = malloc(sizeof(radio_channels_t)); - priv->radio_channel_list->index=1; - priv->radio_channel_list->next=NULL; - priv->radio_channel_list->prev=NULL; - priv->radio_channel_current = priv->radio_channel_list; - - while (*channels) { - char* tmp = *(channels++); - char* sep = strchr(tmp,'-'); - if (!sep) continue; // Wrong syntax, but mplayer should not crash - av_strlcpy(priv->radio_channel_current->name, sep + 1,sizeof(priv->radio_channel_current->name)-1); - - sep[0] = '\0'; - - priv->radio_channel_current->freq=atof(tmp); - - if ((priv->radio_channel_current->freq>priv->rangehigh)||(priv->radio_channel_current->freqrangelow)) - MP_ERR(priv, "Wrong frequency for channel %s\n", - priv->radio_channel_current->name); - - while ((sep=strchr(priv->radio_channel_current->name, '_'))) sep[0] = ' '; - - priv->radio_channel_current->next = malloc(sizeof(radio_channels_t)); - priv->radio_channel_current->next->index = priv->radio_channel_current->index + 1; - priv->radio_channel_current->next->prev = priv->radio_channel_current; - priv->radio_channel_current->next->next = NULL; - priv->radio_channel_current = priv->radio_channel_current->next; - } - if (priv->radio_channel_current->prev) - priv->radio_channel_current->prev->next = NULL; - free(priv->radio_channel_current); - - if (freq_channel) - channel = freq_channel; - else - channel = 1; - - priv->radio_channel_current = priv->radio_channel_list; - for (i = 1; i < channel; i++) - if (priv->radio_channel_current->next) - priv->radio_channel_current = priv->radio_channel_current->next; - if (priv->radio_channel_current->index!=channel){ - if (((float)((int)freq_channel))!=freq_channel) - MP_ERR(priv, "Wrong channel number: %.2f\n",freq_channel); - else - MP_ERR(priv, "Wrong channel number: %d\n",(int)freq_channel); - return STREAM_ERROR; - } - MP_INFO(priv, "Selected channel: %d - %s (freq: %.2f)\n", priv->radio_channel_current->index, - priv->radio_channel_current->name, priv->radio_channel_current->freq); - *pfreq=priv->radio_channel_current->freq; - }else{ - if (freq_channel){ - MP_INFO(priv, "Radio frequency parameter detected.\n"); - priv->radio_channel_list=malloc(sizeof(radio_channels_t)); - priv->radio_channel_list->next=NULL; - priv->radio_channel_list->prev=NULL; - priv->radio_channel_list->index=1; - snprintf(priv->radio_channel_list->name,sizeof(priv->radio_channel_current->name)-1,"Freq: %.2f",freq_channel); - - priv->radio_channel_current=priv->radio_channel_list; - *pfreq=freq_channel; - } - } - MP_DBG(priv, "Done parsing channels.\n"); - return STREAM_OK; -} - -#if HAVE_RADIO_V4L2 -/***************************************************************** - * \brief get fraction value for using in set_frequency and get_frequency - * \return STREAM_OK if success, STREAM_ERROR otherwise - * - * V4L2_TUNER_CAP_LOW: - * unit=62.5Hz - * frac= 1MHz/unit=1000000/62.5 =16000 - * - * otherwise: - * unit=62500Hz - * frac= 1MHz/unit=1000000/62500 =16 - */ -static int init_frac_v4l2(radio_priv_t* priv){ - struct v4l2_tuner tuner; - - memset(&tuner,0,sizeof(tuner)); - tuner.index=0; - if (ioctl(priv->radio_fd, VIDIOC_G_TUNER, &tuner)<0){ - MP_WARN(priv, "Warning: ioctl get tuner failed: %s. Setting frac to %d.\n",strerror(errno),priv->frac); - return STREAM_ERROR; - } - if(tuner.type!=V4L2_TUNER_RADIO){ - MP_ERR(priv, "%s is no radio device!\n",priv->radio_param->device); - return STREAM_ERROR; - } - if(tuner.capability & V4L2_TUNER_CAP_LOW){ - priv->frac=16000; - MP_DBG(priv, "tuner is low:yes frac=%d\n",priv->frac); - } - else{ - priv->frac=16; - MP_DBG(priv, "tuner is low:no frac=%d\n",priv->frac); - } - - priv->rangelow=((float)tuner.rangelow)/priv->frac; - priv->rangehigh=((float)tuner.rangehigh)/priv->frac; - MP_VERBOSE(priv, "Allowed frequency range is %.2f-%.2f MHz.\n",priv->rangelow,priv->rangehigh); - 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_v4l2(radio_priv_t* priv,float frequency){ - struct v4l2_frequency freq; - - memset(&freq,0,sizeof(freq)); - freq.tuner=0; - freq.type=V4L2_TUNER_RADIO; - freq.frequency=frequency*priv->frac; - if(ioctl(priv->radio_fd,VIDIOC_S_FREQUENCY,&freq)<0){ - MP_ERR(priv, "ioctl set frequency 0x%x (%.2f) failed: %s\n",freq.frequency, - 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_v4l2(radio_priv_t* priv,float* frequency){ - struct v4l2_frequency freq; - memset(&freq,0,sizeof(freq)); - if (ioctl(priv->radio_fd, VIDIOC_G_FREQUENCY, &freq) < 0) { - MP_ERR(priv, "ioctl get frequency failed: %s\n",strerror(errno)); - return STREAM_ERROR; - } - *frequency=((float)freq.frequency)/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 - */ -static void set_volume_v4l2(radio_priv_t* priv,int volume){ - struct v4l2_queryctrl qctrl; - struct v4l2_control control; - - /*arg must be between 0 and 100*/ - if (volume > 100) volume = 100; - if (volume < 0) volume = 0; - - memset(&control,0,sizeof(control)); - control.id=V4L2_CID_AUDIO_MUTE; - control.value = (volume==0?1:0); - if (ioctl(priv->radio_fd, VIDIOC_S_CTRL, &control)<0){ - MP_WARN(priv, "ioctl set mute failed: %s\n",strerror(errno)); - } - - memset(&qctrl,0,sizeof(qctrl)); - qctrl.id = V4L2_CID_AUDIO_VOLUME; - if (ioctl(priv->radio_fd, VIDIOC_QUERYCTRL, &qctrl) < 0) { - MP_WARN(priv, "ioctl query control failed: %s\n",strerror(errno)); - return; - } - - memset(&control,0,sizeof(control)); - control.id=V4L2_CID_AUDIO_VOLUME; - control.value=qctrl.minimum+volume*(qctrl.maximum-qctrl.minimum)/100; - if (ioctl(priv->radio_fd, VIDIOC_S_CTRL, &control) < 0) { - MP_WARN(priv, "ioctl set volume failed: %s\n",strerror(errno)); - } -} - -/***************************************************************** - * \brief get current volume from radio card - * \param volume where to store volume level (0..100) - * \return STREAM_OK if success, STREAM_ERROR otherwise - */ -static int get_volume_v4l2(radio_priv_t* priv,int* volume){ - struct v4l2_queryctrl qctrl; - struct v4l2_control control; - - memset(&qctrl,0,sizeof(qctrl)); - qctrl.id = V4L2_CID_AUDIO_VOLUME; - if (ioctl(priv->radio_fd, VIDIOC_QUERYCTRL, &qctrl) < 0) { - MP_ERR(priv, "ioctl query control failed: %s\n",strerror(errno)); - return STREAM_ERROR; - } - - memset(&control,0,sizeof(control)); - control.id=V4L2_CID_AUDIO_VOLUME; - if (ioctl(priv->radio_fd, VIDIOC_G_CTRL, &control) < 0) { - MP_ERR(priv, "ioctl get volume failed: %s\n",strerror(errno)); - return STREAM_ERROR; - } - - if (qctrl.maximum==qctrl.minimum) - *volume=qctrl.minimum; - else - *volume=100*(control.value-qctrl.minimum)/(qctrl.maximum-qctrl.minimum); - - /*arg must be between 0 and 100*/ - if (*volume > 100) *volume = 100; - if (*volume < 0) *volume = 0; - - return STREAM_OK; -} - -/* v4l2 driver info structure */ -static const radio_driver_t radio_driver_v4l2={ - "v4l2", - _("Using V4Lv2 radio interface.\n"), - init_frac_v4l2, - set_volume_v4l2, - get_volume_v4l2, - set_frequency_v4l2, - get_frequency_v4l2 -}; -#endif /* HAVE_RADIO_V4L2 */ - -static inline int init_frac(radio_priv_t* priv){ - return priv->driver->init_frac(priv); -} -static inline int set_frequency(radio_priv_t* priv,float frequency){ - if ((frequencyrangelow)||(frequency>priv->rangehigh)){ - MP_ERR(priv, "Wrong frequency: %.2f\n",frequency); - return STREAM_ERROR; - } - if(priv->driver->set_frequency(priv,frequency)!=STREAM_OK) - return STREAM_ERROR; - -#if HAVE_RADIO_CAPTURE - if(clear_buffer(priv)!=STREAM_OK){ - MP_ERR(priv, "Clearing buffer failed: %s\n",strerror(errno)); - return STREAM_ERROR; - } -#endif - return STREAM_OK; -} -static inline int get_frequency(radio_priv_t* priv,float* frequency){ - return priv->driver->get_frequency(priv,frequency); -} -static inline void set_volume(radio_priv_t* priv,int volume){ - priv->driver->set_volume(priv,volume); -} -static inline int get_volume(radio_priv_t* priv,int* volume){ - return priv->driver->get_volume(priv,volume); -} - - -#if !HAVE_RADIO_CAPTURE -/***************************************************************** - * \brief stub, if capture disabled at compile-time - * \return STREAM_OK - */ -static inline int init_audio(radio_priv_t *priv){ return STREAM_OK;} -#else -/***************************************************************** - * \brief making buffer empty - * \return STREAM_OK if success, STREAM_ERROR otherwise - * - * when changing channel we must clear buffer to avoid large switching delay - */ -static int clear_buffer(radio_priv_t* priv){ - if (!priv->do_capture) return STREAM_OK; - priv->audio_tail = 0; - priv->audio_head = 0; - priv->audio_cnt=0; - memset(priv->audio_ringbuffer,0,priv->audio_in.blocksize); - return STREAM_OK; -} -/***************************************************************** - * \brief read next part of data into buffer - * \return -1 if error occured or no data available yet, otherwise - bytes read - * NOTE: audio device works in non-blocking mode - */ -static int read_chunk(audio_in_t *ai, unsigned char *buffer) -{ - int ret; - - switch (ai->type) { -#if HAVE_ALSA - case AUDIO_IN_ALSA: - //device opened in non-blocking mode - ret = snd_pcm_readi(ai->alsa.handle, buffer, ai->alsa.chunk_size); - if (ret != ai->alsa.chunk_size) { - if (ret < 0) { - if (ret==-EAGAIN) return -1; - MP_ERR(ai, "\nError reading audio: %s\n", snd_strerror(ret)); - if (ret == -EPIPE) { - if (ai_alsa_xrun(ai) == 0) { - MP_ERR(ai, "Recovered from cross-run, some frames may be left out!\n"); - } else { - MP_ERR(ai, "Fatal error, cannot recover!\n"); - } - } - } else { - MP_ERR(ai, "\nNot enough audio samples!\n"); - } - return -1; - } - return ret; -#endif -#if HAVE_OSS_AUDIO - case AUDIO_IN_OSS: - { - int bt=0; - /* - we must return exactly blocksize bytes, so if we have got any bytes - at first call to read, we will loop untils get all blocksize bytes - otherwise we will return -1 - */ - while(btblocksize){ - //device opened in non-blocking mode - ret = read(ai->oss.audio_fd, buffer+bt, ai->blocksize-bt); - if (ret==ai->blocksize) return ret; - if (ret<0){ - if (errno==EAGAIN && bt==0) return -1; //no data avail yet - if (errno==EAGAIN) { usleep(1000); continue;} //nilling buffer to blocksize size - MP_ERR(ai, "\nError reading audio: %s\n", strerror(errno)); - return -1; - } - bt+=ret; - } - return bt; - } -#endif - default: - return -1; - } -} -/***************************************************************** - * \brief grab next frame from audio device - * \parameter buffer - store buffer - * \parameter len - store buffer size in bytes - * \return number of bytes written into buffer - * - * grabs len (or less) bytes from ringbuffer into buffer - * if ringbuffer is empty waits until len bytes of data will be available - * - * priv->audio_cnt - size (in bytes) of ringbuffer's filled part - * priv->audio_drop - size (in bytes) of dropped data (if no space in ringbuffer) - * priv->audio_head - index of first byte in filled part - * priv->audio_tail - index of last byte in filled part - * - * NOTE: audio_tail always aligned by priv->audio_in.blocksize - * audio_head may NOT. - */ -static int grab_audio_frame(radio_priv_t *priv, char *buffer, int len) -{ - int i; - MP_TRACE(priv, "%s: in buffer=%d dropped=%d\n","grab_audio_frame",priv->audio_cnt,priv->audio_drop); - /* Cache buffer must be filled by some audio packets when playing starts. - Otherwise MPlayer will quit with EOF error. - Probably, there is need more carefull checking rather than simple 'for' loop - (something like timer or similar). - - 1000ms delay will happen only at first buffer filling. At next call function - just fills buffer until either buffer full or no data from driver available. - */ - for (i=0;i<1000 && !priv->audio_cnt; i++){ - //read_chunk fills exact priv->blocksize bytes - if(read_chunk(&priv->audio_in, priv->audio_ringbuffer+priv->audio_tail) < 0){ - //sleppeing only when waiting first block to fill empty buffer - if (!priv->audio_cnt){ - usleep(1000); - continue; - }else - break; - } - priv->audio_cnt+=priv->audio_in.blocksize; - priv->audio_tail = (priv->audio_tail+priv->audio_in.blocksize) % priv->audio_buffer_size; - } - if(priv->audio_cntaudio_cnt; - memcpy(buffer, priv->audio_ringbuffer+priv->audio_head,len); - priv->audio_head = (priv->audio_head+len) % priv->audio_buffer_size; - priv->audio_cnt-=len; - return len; -} -/***************************************************************** - * \brief init audio device - * \return STREAM_OK if success, STREAM_ERROR otherwise - */ -static int init_audio(radio_priv_t *priv) -{ - int is_oss=1; - int seconds=2; - char* tmp; - if (priv->audio_initialized) return 1; - - /* do_capture==0 mplayer was not started with capture keyword, so disabling capture*/ - if(!priv->do_capture) - return STREAM_OK; - - if (!priv->radio_param->adevice){ - priv->do_capture=0; - return STREAM_OK; - } - - priv->do_capture=1; - MP_VERBOSE(priv, "Starting capture stuff.\n"); -#if HAVE_ALSA - while ((tmp = strrchr(priv->radio_param->adevice, '='))){ - tmp[0] = ':'; - //adevice option looks like ALSA device name. Switching to ALSA - is_oss=0; - } - while ((tmp = strrchr(priv->radio_param->adevice, '.'))) - tmp[0] = ','; -#endif - - if(audio_in_init(&priv->audio_in, priv->log, is_oss?AUDIO_IN_OSS:AUDIO_IN_ALSA)<0){ - MP_ERR(priv, "audio_in_init failed.\n"); - } - - audio_in_set_device(&priv->audio_in, priv->radio_param->adevice); - audio_in_set_channels(&priv->audio_in, priv->radio_param->achannels); - audio_in_set_samplerate(&priv->audio_in, priv->radio_param->arate); - - if (audio_in_setup(&priv->audio_in) < 0) { - MP_ERR(priv, "audio_in_setup call failed: %s\n", strerror(errno)); - return STREAM_ERROR; - } -#if HAVE_OSS_AUDIO - if(is_oss) - ioctl(priv->audio_in.oss.audio_fd, SNDCTL_DSP_NONBLOCK, 0); -#endif -#if HAVE_ALSA - if(!is_oss) - snd_pcm_nonblock(priv->audio_in.alsa.handle,1); -#endif - - priv->audio_buffer_size = seconds*priv->audio_in.samplerate*priv->audio_in.channels* - priv->audio_in.bytes_per_sample+priv->audio_in.blocksize; - if (priv->audio_buffer_size < 256*priv->audio_in.blocksize) - priv->audio_buffer_size = 256*priv->audio_in.blocksize; - MP_VERBOSE(priv, "Audio capture - buffer=%d bytes (block=%d bytes).\n", - priv->audio_buffer_size,priv->audio_in.blocksize); - /* start capture */ - priv->audio_ringbuffer = calloc(1, priv->audio_buffer_size); - if (!priv->audio_ringbuffer) { - MP_ERR(priv, "cannot allocate audio buffer (block=%d,buf=%d): %s\n",priv->audio_in.blocksize, priv->audio_buffer_size, strerror(errno)); - return STREAM_ERROR; - } - priv->audio_head = 0; - priv->audio_tail = 0; - priv->audio_cnt = 0; - priv->audio_drop = 0; - - audio_in_start_capture(&priv->audio_in); - - priv->audio_initialized = 1; - - return STREAM_OK; -} -#endif /* HAVE_RADIO_CAPTURE */ - -/*------------------------------------------------------------------------- - for call from mplayer.c ---------------------------------------------------------------------------*/ -/***************************************************************** - * \brief public wrapper for get_frequency - * \parameter frequency pointer to float, which will contain frequency in MHz - * \return 1 if success,0 - otherwise - */ -int radio_get_freq(struct stream *stream, float *frequency){ - radio_priv_t* priv=(radio_priv_t*)stream->priv; - - if (!frequency) - return 0; - if (get_frequency(priv,frequency)!=STREAM_OK){ - return 0; - } - return 1; -} -/***************************************************************** - * \brief public wrapper for set_frequency - * \parameter frequency frequency in MHz - * \return 1 if success,0 - otherwise - */ -int radio_set_freq(struct stream *stream, float frequency){ - radio_priv_t* priv=(radio_priv_t*)stream->priv; - - if (set_frequency(priv,frequency)!=STREAM_OK){ - return 0; - } - if (get_frequency(priv,&frequency)!=STREAM_OK){ - return 0; - } - MP_INFO(priv, "Current frequency: %.2f\n",frequency); - return 1; -} - -/***************************************************************** - * \brief tune current frequency by step_interval value - * \parameter step_interval increment value - * \return 1 if success,0 - otherwise - * - */ -int radio_step_freq(struct stream *stream, float step_interval){ - float frequency; - radio_priv_t* priv=(radio_priv_t*)stream->priv; - - if (get_frequency(priv,&frequency)!=STREAM_OK) - return 0; - - frequency+=step_interval; - if (frequency>priv->rangehigh) - frequency=priv->rangehigh; - if (frequencyrangelow) - frequency=priv->rangelow; - - return radio_set_freq(stream,frequency); -} -/***************************************************************** - * \brief step channel up or down - * \parameter direction RADIO_CHANNEL_LOWER - go to prev channel,RADIO_CHANNEL_HIGHER - to next - * \return 1 if success,0 - otherwise - * - * if channel parameter is NULL function prints error message and does nothing, otherwise - * changes channel to prev or next in list - */ -int radio_step_channel(struct stream *stream, int direction) { - radio_priv_t* priv=(radio_priv_t*)stream->priv; - - if (priv->radio_channel_list) { - switch (direction){ - case RADIO_CHANNEL_HIGHER: - if (priv->radio_channel_current->next) - priv->radio_channel_current = priv->radio_channel_current->next; - else - priv->radio_channel_current = priv->radio_channel_list; - if(!radio_set_freq(stream,priv->radio_channel_current->freq)) - return 0; - MP_VERBOSE(priv, "Selected channel: %d - %s (freq: %.2f)\n", - priv->radio_channel_current->index, priv->radio_channel_current->name, - priv->radio_channel_current->freq); - break; - case RADIO_CHANNEL_LOWER: - if (priv->radio_channel_current->prev) - priv->radio_channel_current = priv->radio_channel_current->prev; - else - while (priv->radio_channel_current->next) - priv->radio_channel_current = priv->radio_channel_current->next; - if(!radio_set_freq(stream,priv->radio_channel_current->freq)) - return 0; - MP_VERBOSE(priv, "Selected channel: %d - %s (freq: %.2f)\n", - priv->radio_channel_current->index, priv->radio_channel_current->name, - priv->radio_channel_current->freq); - break; - } - }else - MP_ERR(priv, "Can not change channel: no channel list given.\n"); - return 1; -} - -/***************************************************************** - * \brief change channel to one with given index - * \parameter channel string, containing channel number - * \return 1 if success,0 - otherwise - * - * if channel parameter is NULL function prints error message and does nothing, otherwise - * changes channel to given - */ -int radio_set_channel(struct stream *stream, char *channel) { - radio_priv_t* priv=(radio_priv_t*)stream->priv; - int i, channel_int; - radio_channels_t* tmp; - char* endptr; - - if (*channel=='\0') - MP_ERR(priv, "Wrong channel name: %s\n",channel); - - if (priv->radio_channel_list) { - channel_int = strtol(channel,&endptr,10); - tmp = priv->radio_channel_list; - if (*endptr!='\0'){ - //channel is not a number, so it contains channel name - for ( ; tmp; tmp=tmp->next) - if (!strncmp(channel,tmp->name,sizeof(tmp->name)-1)) - break; - if (!tmp){ - MP_ERR(priv, "Wrong channel name: %s\n",channel); - return 0; - } - }else{ - for (i = 1; i < channel_int; i++) - if (tmp->next) - tmp = tmp->next; - else - break; - if (tmp->index!=channel_int){ - MP_ERR(priv, "Wrong channel number: %d\n",channel_int); - return 0; - } - } - priv->radio_channel_current=tmp; - MP_VERBOSE(priv, "Selected channel: %d - %s (freq: %.2f)\n", priv->radio_channel_current->index, - priv->radio_channel_current->name, priv->radio_channel_current->freq); - if(!radio_set_freq(stream, priv->radio_channel_current->freq)) - return 0; - } else - MP_ERR(priv, "Can not change channel: no channel list given.\n"); - return 1; -} - -/***************************************************************** - * \brief get current channel's name - * \return pointer to string, containing current channel's name - * - * NOTE: return value may be NULL (e.g. when channel list not initialized) - */ -char* radio_get_channel_name(struct stream *stream){ - radio_priv_t* priv=(radio_priv_t*)stream->priv; - if (priv->radio_channel_current) { - return priv->radio_channel_current->name; - } - return NULL; -} - -/***************************************************************** - * \brief fills given buffer with audio data - * \return number of bytes, written into buffer - */ -static int fill_buffer_s(struct stream *s, char *buffer, int max_len){ - int len=max_len; - -#if HAVE_RADIO_CAPTURE - radio_priv_t* priv=(radio_priv_t*)s->priv; - - if (priv->do_capture){ - len=grab_audio_frame(priv, buffer,max_len); - } - else -#endif - memset(buffer,0,len); - return len; -} - - -/* - order if significant! - when no driver explicitly specified first available will be used - */ -static const radio_driver_t* radio_drivers[]={ -#if HAVE_RADIO_V4L2 - &radio_driver_v4l2, -#endif - 0 -}; - -/***************************************************************** - * Stream initialization - * \return STREAM_OK if success, STREAM_ERROR otherwise - */ -static int open_s(stream_t *stream,int mode) -{ - radio_priv_t* priv; - float frequency=0; - int i; - - if (strncmp("radio://",stream->url,8) != 0) - return STREAM_UNSUPPORTED; - - if(mode != STREAM_READ) - return STREAM_UNSUPPORTED; - - priv=calloc(1,sizeof(radio_priv_t)); - - if (!priv) - return STREAM_ERROR; - - - priv->log = stream->log; - priv->radio_param=stream->priv; - stream->priv=NULL; - -#if HAVE_RADIO_CAPTURE - if (priv->radio_param->capture && strncmp("capture",priv->radio_param->capture,7)==0) - priv->do_capture=1; - else - priv->do_capture=0; -#endif - - - - if (strncmp(priv->radio_param->driver,"default",7)==0) - priv->driver=radio_drivers[0]; - else - priv->driver=NULL; - - MP_VERBOSE(priv, "Available drivers: "); - for(i=0;radio_drivers[i];i++){ - MP_VERBOSE(priv, "%s, ",radio_drivers[i]->name); - if(strcmp(priv->radio_param->driver,radio_drivers[i]->name)==0) - priv->driver=radio_drivers[i]; - } - MP_VERBOSE(priv, "\n"); - - if(priv->driver) - MP_INFO(priv, "%s", priv->driver->info); - else{ - MP_INFO(priv, "Unknown driver name: %s\n",priv->radio_param->driver); - close_s(stream); - return STREAM_ERROR; - } - - stream->type = STREAMTYPE_RADIO; - /* using rawaudio demuxer */ - stream->demuxer = "lavf"; - stream->flags = STREAM_READ; - - priv->radio_fd=-1; - - stream->start_pos=0; - stream->end_pos=0; - stream->priv=priv; - stream->close=close_s; - stream->fill_buffer=fill_buffer_s; - - priv->radio_fd = open(priv->radio_param->device, O_RDONLY | O_CLOEXEC); - if (priv->radio_fd < 0) { - MP_ERR(priv, "Unable to open '%s': %s\n", - priv->radio_param->device, strerror(errno)); - close_s(stream); - return STREAM_ERROR; - } - MP_VERBOSE(priv, "Radio fd: %d, %s\n", priv->radio_fd,priv->radio_param->device); - fcntl(priv->radio_fd, F_SETFD, FD_CLOEXEC); - - get_volume(priv, &priv->old_snd_volume); - set_volume(priv,0); - - if (init_frac(priv)!=STREAM_OK){ - close_s(stream); - return STREAM_ERROR; - }; - - if (parse_channels(priv,priv->radio_param->freq_channel,&frequency)!=STREAM_OK){ - close_s(stream); - return STREAM_ERROR; - } - - if ((frequencyrangelow)||(frequency>priv->rangehigh)){ - MP_ERR(priv, "Wrong frequency: %.2f\n",frequency); - close_s(stream); - return STREAM_ERROR; - }else - MP_INFO(priv, "Using frequency: %.2f.\n",frequency); - - if(set_frequency(priv,frequency)!=STREAM_OK){ - close_s(stream); - return STREAM_ERROR; - } - - - if (init_audio(priv)!=STREAM_OK){ - close_s(stream); - return STREAM_ERROR; - } - - set_volume(priv,priv->radio_param->volume); - - return STREAM_OK; -} - -/***************************************************************** - * Close stream. Clear structures. - */ -static void close_s(struct stream *stream){ - radio_priv_t* priv=(radio_priv_t*)stream->priv; - radio_channels_t * tmp; - if (!priv) return; - -#if HAVE_RADIO_CAPTURE - free(priv->audio_ringbuffer); - priv->audio_ringbuffer = NULL; - - priv->do_capture=0; -#endif - - while (priv->radio_channel_list) { - tmp=priv->radio_channel_list; - priv->radio_channel_list=priv->radio_channel_list->next; - free(tmp); - } - priv->radio_channel_current=NULL; - priv->radio_channel_list=NULL; - - if (priv->radio_fd>0){ - set_volume(priv, priv->old_snd_volume); - close(priv->radio_fd); - } - - free(priv); - stream->priv=NULL; -} - -const stream_info_t stream_info_radio = { - .name = "radio", - .open = open_s, - .protocols = (const char*[]){ "radio", NULL }, - .priv_size = sizeof(radio_param_t), - .priv_defaults = &stream_radio_defaults, - .options = stream_opts_fields, - .url_options = (const char*[]){ - "hostname=freqchannel", - "filename=capture", - NULL - }, -}; diff --git a/stream/stream_radio.h b/stream/stream_radio.h deleted file mode 100644 index ac8d19aa1f..0000000000 --- a/stream/stream_radio.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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. - */ - -#ifndef MPLAYER_STREAM_RADIO_H -#define MPLAYER_STREAM_RADIO_H - -#include "config.h" -#include "stream.h" - -#define RADIO_CHANNEL_LOWER 1 -#define RADIO_CHANNEL_HIGHER 2 - -typedef struct radio_param_s{ - /** name of radio device file */ - char* device; - /** radio driver (v4l,v4l2) */ - char* driver; - /** channels list (see man page) */ - char** channels; - /** initial volume for radio device */ - int volume; - /** name of audio device file to grab data from */ - char* adevice; - /** audio framerate (please also set -rawaudio rate - parameter to the same value) */ - int arate; - /** number of audio channels */ - int achannels; - /** if channels parameter exist, here will be channel - number otherwise - frequency */ - float freq_channel; - char* capture; -} radio_param_t; - -extern radio_param_t stream_radio_defaults; - -int radio_set_freq(struct stream *stream, float freq); -int radio_get_freq(struct stream *stream, float* freq); -char* radio_get_channel_name(struct stream *stream); -int radio_set_channel(struct stream *stream, char *channel); -int radio_step_channel(struct stream *stream, int direction); -int radio_step_freq(struct stream *stream, float step_interval); - -#endif /* MPLAYER_STREAM_RADIO_H */ diff --git a/wscript b/wscript index 07a2b65b4c..fc761030ab 100644 --- a/wscript +++ b/wscript @@ -693,22 +693,6 @@ hwaccel_features = [ radio_and_tv_features = [ { - 'name': '--radio', - 'desc': 'Radio interface', - 'func': check_true, - 'default': 'disable' - }, { - 'name': '--radio-capture', - 'desc': 'Radio capture (through PCI/line-in)', - 'func': check_true, - 'deps': [ 'radio' ], - 'deps_any': [ 'alsa', 'oss-audio', 'sndio'], - }, { - 'name': '--radio-v4l2', - 'desc': 'Video4Linux2 radio interface', - 'func': check_cc(header_name='linux/videodev2.h'), - 'default': 'disable' - }, { 'name': '--tv', 'desc': 'TV interface', 'func': check_true, @@ -727,7 +711,7 @@ radio_and_tv_features = [ }, { 'name': '--audio-input', 'desc': 'audio input support', - 'deps_any': [ 'radio-capture', 'tv-v4l2' ], + 'deps_any': [ 'tv-v4l2' ], 'func': check_true } ] @@ -772,7 +756,7 @@ def options(opt): opt.parse_features('audio outputs', audio_output_features) opt.parse_features('video outputs', video_output_features) opt.parse_features('hwaccels', hwaccel_features) - opt.parse_features('radio/tv features', radio_and_tv_features) + opt.parse_features('tv features', radio_and_tv_features) opt.parse_features('scripting', scripting_features) group = opt.get_option_group("scripting") diff --git a/wscript_build.py b/wscript_build.py index 8790c96d4a..0b02f518f9 100644 --- a/wscript_build.py +++ b/wscript_build.py @@ -247,7 +247,6 @@ def build(ctx): ( "stream/stream_mf.c" ), ( "stream/stream_null.c" ), ( "stream/stream_pvr.c", "pvr" ), - ( "stream/stream_radio.c", "radio" ), ( "stream/stream_rar.c" ), ( "stream/stream_smb.c", "libsmbclient" ), ( "stream/stream_tv.c", "tv" ), -- cgit v1.2.3