summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-04-13 18:51:43 +0200
committerwm4 <wm4@nowhere>2014-04-13 18:51:43 +0200
commit132f395aacb2c658e91b8845076115f98158edce (patch)
tree412302d36033ff11554ffd888e947927975493d8
parent78128bddda4bcea1f256fc13cc33fa2652ed277c (diff)
downloadmpv-132f395aacb2c658e91b8845076115f98158edce.tar.bz2
mpv-132f395aacb2c658e91b8845076115f98158edce.tar.xz
Remove radio://
It was disabled by default, works only for analogue radio, and I bet nobody uses it.
-rw-r--r--DOCS/man/en/mpv.rst1
-rw-r--r--DOCS/man/en/options.rst55
-rwxr-xr-xold-configure58
-rw-r--r--old-makefile2
-rw-r--r--options/options.c18
-rw-r--r--stream/stream.c4
-rw-r--r--stream/stream_radio.c977
-rw-r--r--stream/stream_radio.h59
-rw-r--r--wscript20
-rw-r--r--wscript_build.py1
10 files changed, 3 insertions, 1192 deletions
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=<option1:option2:...>``
- These options set various parameters of the radio capture module. For
- listening to radio with mpv, use ``radio://<frequency>`` (if channels
- option is not given) or ``radio://<channel_number>`` (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://<frequency or channel>/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=<value>``
- Radio device to use (default: ``/dev/radio0`` for Linux and
- ``/dev/tuner0`` for \*BSD).
-
- ``driver=<value>``
- 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=<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
- 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=<value>`` (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=<card>.<device>``. If the
- device name contains a '=', the module will use ALSA to capture,
- otherwise OSS.
-
- ``arate=<value>`` (radio capture only)
- Rate in samples per second (default: 44100).
-
- .. note::
-
- When using audio capture set also ``--rawaudio=rate=<value>`` 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=<value>`` (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 <voroshil@univer.omsk.su>.
- * 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 <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-#include <unistd.h>
-
-#if HAVE_RADIO_V4L2
-#include <linux/videodev2.h>
-#endif
-
-#include <libavutil/avstring.h>
-
-#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 <sys/soundcard.h>
-#else
-#if HAVE_SOUNDCARD_H
-#include <soundcard.h>
-#else
-#include <linux/soundcard.h>
-#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
- * <frequency>-<name>,<frequency>-<name>,...
- *
- * '_' 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->freq<priv->rangelow))
- 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 ((frequency<priv->rangelow)||(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(bt<ai->blocksize){
- //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_cnt<len)
- len=priv->audio_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