tv: remove global option variables

Pretty much nothing changes, but using -tv-scan with suboptions doesn't
work anymore (instead of "-tv-scan x" it's "-tv scan-x" now). Flat
options ("-tv-scan-x") stay compatible.
This commit is contained in:
wm4 2014-06-09 23:54:45 +02:00
parent 98c0930f9b
commit 383cf20785
8 changed files with 375 additions and 389 deletions

View File

@ -2395,192 +2395,184 @@ OPTIONS
Verify peer certificates when using TLS (e.g. with ``https://...``).
(Silently fails with older ffmpeg or libav versions.)
``--tv=<option1:option2:...>``
This option tunes various properties of the TV capture module. For
``--tv-...``
These options tune various properties of the TV capture module. For
watching TV with mpv, use ``tv://`` or ``tv://<channel_number>`` or
even ``tv://<channel_name>`` (see option ``channels`` for ``channel_name``
even ``tv://<channel_name>`` (see option ``tv-channels`` for ``channel_name``
below) as a movie URL. You can also use ``tv:///<input_id>`` to start
watching a movie from a composite or S-Video input (see option ``input`` for
details).
Available options are:
``--no-tv-audio``
no sound
``noaudio``
no sound
``--tv-automute=<0-255> (v4l and v4l2 only)``
If signal strength reported by device is less than this value, audio
and video will be muted. In most cases automute=100 will be enough.
Default is 0 (automute disabled).
``automute=<0-255> (v4l and v4l2 only)``
If signal strength reported by device is less than this value, audio
and video will be muted. In most cases automute=100 will be enough.
Default is 0 (automute disabled).
``--tv-driver=<value>``
See ``--tv=driver=help`` for a list of compiled-in TV input drivers.
available: dummy, v4l2 (default: autodetect)
``driver=<value>``
See ``--tv=driver=help`` for a list of compiled-in TV input drivers.
available: dummy, v4l2 (default: autodetect)
``--tv-device=<value>``
Specify TV device (default: ``/dev/video0``).
``device=<value>``
Specify TV device (default: ``/dev/video0``).
``--tv-input=<value>``
Specify input (default: 0 (TV), see console output for available
inputs).
``input=<value>``
Specify input (default: 0 (TV), see console output for available
inputs).
``--tv-freq=<value>``
Specify the frequency to set the tuner to (e.g. 511.250). Not
compatible with the channels parameter.
``freq=<value>``
Specify the frequency to set the tuner to (e.g. 511.250). Not
compatible with the channels parameter.
``--tv-outfmt=<value>``
Specify the output format of the tuner with a preset value supported
by the V4L driver (YV12, UYVY, YUY2, I420) or an arbitrary format given
as hex value.
``outfmt=<value>``
Specify the output format of the tuner with a preset value supported
by the V4L driver (YV12, UYVY, YUY2, I420) or an arbitrary format given
as hex value.
``--tv-width=<value>``
output window width
``width=<value>``
output window width
``--tv-height=<value>``
output window height
``height=<value>``
output window height
``--tv-fps=<value>``
framerate at which to capture video (frames per second)
``fps=<value>``
framerate at which to capture video (frames per second)
``--tv-buffersize=<value>``
maximum size of the capture buffer in megabytes (default: dynamical)
``buffersize=<value>``
maximum size of the capture buffer in megabytes (default: dynamical)
``--tv-norm=<value>``
See the console output for a list of all available norms, also see the
``normid`` option below.
``norm=<value>``
See the console output for a list of all available norms, also see the
``normid`` option below.
``--tv-normid=<value> (v4l2 only)``
Sets the TV norm to the given numeric ID. The TV norm depends on the
capture card. See the console output for a list of available TV norms.
``normid=<value> (v4l2 only)``
Sets the TV norm to the given numeric ID. The TV norm depends on the
capture card. See the console output for a list of available TV norms.
``--tv-channel=<value>``
Set tuner to <value> channel.
``channel=<value>``
Set tuner to <value> channel.
``--tv-chanlist=<value>``
available: argentina, australia, china-bcast, europe-east,
europe-west, france, ireland, italy, japan-bcast, japan-cable,
newzealand, russia, southafrica, us-bcast, us-cable, us-cable-hrc
``chanlist=<value>``
available: argentina, australia, china-bcast, europe-east,
europe-west, france, ireland, italy, japan-bcast, japan-cable,
newzealand, russia, southafrica, us-bcast, us-cable, us-cable-hrc
``--tv-channels=<chan>-<name>[=<norm>],<chan>-<name>[=<norm>],...``
Set names for channels.
``channels=<chan>-<name>[=<norm>],<chan>-<name>[=<norm>],...``
Set names for channels.
.. note::
.. note::
If <chan> is an integer greater than 1000, it will be treated as
frequency (in kHz) rather than channel name from frequency table.
Use _ for spaces in names (or play with quoting ;-) ). The channel
names will then be written using OSD, and the slave commands
``tv_step_channel``, ``tv_set_channel`` and ``tv_last_channel``
will be usable for a remote control (see LIRC). Not compatible with
the ``frequency`` parameter.
If <chan> is an integer greater than 1000, it will be treated as
frequency (in kHz) rather than channel name from frequency table.
Use _ for spaces in names (or play with quoting ;-) ). The channel
names will then be written using OSD, and the slave commands
``tv_step_channel``, ``tv_set_channel`` and ``tv_last_channel``
will be usable for a remote control (see LIRC). Not compatible with
the ``frequency`` parameter.
.. note::
.. note::
The channel number will then be the position in the 'channels'
list, beginning with 1.
The channel number will then be the position in the 'channels'
list, beginning with 1.
.. admonition:: Examples
.. admonition:: Examples
``tv://1``, ``tv://TV1``, ``tv_set_channel 1``,
``tv_set_channel TV1``
``tv://1``, ``tv://TV1``, ``tv_set_channel 1``,
``tv_set_channel TV1``
``--tv-[brightness|contrast|hue|saturation]=<-100-100>``
Set the image equalizer on the card.
``[brightness|contrast|hue|saturation]=<-100-100>``
Set the image equalizer on the card.
``--tv-audiorate=<value>``
Set input audio sample rate.
``audiorate=<value>``
Set input audio sample rate.
``--tv-forceaudio``
Capture audio even if there are no audio sources reported by v4l.
``forceaudio``
Capture audio even if there are no audio sources reported by v4l.
``--tv-alsa``
Capture from ALSA.
``alsa``
Capture from ALSA.
``--tv-amode=<0-3>``
Choose an audio mode:
``amode=<0-3>``
Choose an audio mode:
:0: mono
:1: stereo
:2: language 1
:3: language 2
:0: mono
:1: stereo
:2: language 1
:3: language 2
``--tv-forcechan=<1-2>``
By default, the count of recorded audio channels is determined
automatically by querying the audio mode from the TV card. This option
allows forcing stereo/mono recording regardless of the amode option
and the values returned by v4l. This can be used for troubleshooting
when the TV card is unable to report the current audio mode.
``forcechan=<1-2>``
By default, the count of recorded audio channels is determined
automatically by querying the audio mode from the TV card. This option
allows forcing stereo/mono recording regardless of the amode option
and the values returned by v4l. This can be used for troubleshooting
when the TV card is unable to report the current audio mode.
``--tv-adevice=<value>``
Set an audio device. <value> should be ``/dev/xxx`` for OSS and a
hardware ID for ALSA. You must replace any ':' by a '.' in the
hardware ID for ALSA.
``adevice=<value>``
Set an audio device. <value> should be ``/dev/xxx`` for OSS and a
hardware ID for ALSA. You must replace any ':' by a '.' in the
hardware ID for ALSA.
``--tv-audioid=<value>``
Choose an audio output of the capture card, if it has more than one.
``audioid=<value>``
Choose an audio output of the capture card, if it has more than one.
``--tv-[volume|bass|treble|balance]=<0-100>``
These options set parameters of the mixer on the video capture card.
They will have no effect, if your card does not have one. For v4l2 50
maps to the default value of the control, as reported by the driver.
``[volume|bass|treble|balance]=<0-100>``
These options set parameters of the mixer on the video capture card.
They will have no effect, if your card does not have one. For v4l2 50
maps to the default value of the control, as reported by the driver.
``--tv-gain=<0-100>``
Set gain control for video devices (usually webcams) to the desired
value and switch off automatic control. A value of 0 enables automatic
control. If this option is omitted, gain control will not be modified.
``gain=<0-100>``
Set gain control for video devices (usually webcams) to the desired
value and switch off automatic control. A value of 0 enables automatic
control. If this option is omitted, gain control will not be modified.
``--tv-immediatemode=<bool>``
A value of 0 means capture and buffer audio and video together. A
value of 1 (default) means to do video capture only and let the audio
go through a loopback cable from the TV card to the sound card.
``immediatemode=<bool>``
A value of 0 means capture and buffer audio and video together. A
value of 1 (default) means to do video capture only and let the audio
go through a loopback cable from the TV card to the sound card.
``--tv-mjpeg``
Use hardware MJPEG compression (if the card supports it). When using
this option, you do not need to specify the width and height of the
output window, because mpv will determine it automatically from
the decimation value (see below).
``mjpeg``
Use hardware MJPEG compression (if the card supports it). When using
this option, you do not need to specify the width and height of the
output window, because mpv will determine it automatically from
the decimation value (see below).
``--tv-decimation=<1|2|4>``
choose the size of the picture that will be compressed by hardware
MJPEG compression:
``decimation=<1|2|4>``
choose the size of the picture that will be compressed by hardware
MJPEG compression:
:1: full size
:1: full size
- 704x576 PAL
- 704x480 NTSC
- 704x576 PAL
- 704x480 NTSC
:2: medium size
:2: medium size
- 352x288 PAL
- 352x240 NTSC
- 352x288 PAL
- 352x240 NTSC
:4: small size
:4: small size
- 176x144 PAL
- 176x120 NTSC
- 176x144 PAL
- 176x120 NTSC
``--tv-quality=<0-100>``
Choose the quality of the JPEG compression (< 60 recommended for full
size).
``quality=<0-100>``
Choose the quality of the JPEG compression (< 60 recommended for full
size).
``--tv-scan-autostart``
Begin channel scanning immediately after startup (default: disabled).
``--tv-scan=<option1:option2:...>``
Tune the TV channel scanner. mpv will also print value for
``--tv=channels=`` option, including existing and just found channels.
``--tv-scan-period=<0.1-2.0>``
Specify delay in seconds before switching to next channel (default:
0.5). Lower values will cause faster scanning, but can detect inactive
TV channels as active.
Available suboptions are:
``autostart``
Begin channel scanning immediately after startup (default: disabled).
``period=<0.1-2.0>``
Specify delay in seconds before switching to next channel (default:
0.5). Lower values will cause faster scanning, but can detect inactive
TV channels as active.
``threshold=<1-100>``
Threshold value for the signal strength (in percent), as reported by
the device (default: 50). A signal strength higher than this value will
indicate that the currently scanning channel is active.
``--tv-scan-threshold=<1-100>``
Threshold value for the signal strength (in percent), as reported by
the device (default: 50). A signal strength higher than this value will
indicate that the currently scanning channel is active.
``--use-filedir-conf``
Look for a file-specific configuration file in the same directory as the

View File

@ -62,53 +62,7 @@ static void print_help(struct mp_log *log)
mp_info(log, "%s", mp_help_text);
}
#if HAVE_TV
static const m_option_t tvopts_conf[]={
{"immediatemode", &stream_tv_defaults.immediate, CONF_TYPE_INT, CONF_RANGE, 0, 1, NULL},
{"audio", &stream_tv_defaults.noaudio, CONF_TYPE_FLAG, 0, 1, 0, NULL},
{"audiorate", &stream_tv_defaults.audiorate, CONF_TYPE_INT, 0, 0, 0, NULL},
{"driver", &stream_tv_defaults.driver, CONF_TYPE_STRING, 0, 0, 0, NULL},
{"device", &stream_tv_defaults.device, CONF_TYPE_STRING, 0, 0, 0, NULL},
{"freq", &stream_tv_defaults.freq, CONF_TYPE_STRING, 0, 0, 0, NULL},
{"channel", &stream_tv_defaults.channel, CONF_TYPE_STRING, 0, 0, 0, NULL},
{"chanlist", &stream_tv_defaults.chanlist, CONF_TYPE_STRING, 0, 0, 0, NULL},
{"norm", &stream_tv_defaults.norm, CONF_TYPE_STRING, 0, 0, 0, NULL},
{"automute", &stream_tv_defaults.automute, CONF_TYPE_INT, CONF_RANGE, 0, 255, NULL},
#if HAVE_TV_V4L2
{"normid", &stream_tv_defaults.normid, CONF_TYPE_INT, 0, 0, 0, NULL},
#endif
{"width", &stream_tv_defaults.width, CONF_TYPE_INT, 0, 0, 4096, NULL},
{"height", &stream_tv_defaults.height, CONF_TYPE_INT, 0, 0, 4096, NULL},
{"input", &stream_tv_defaults.input, CONF_TYPE_INT, 0, 0, 20, NULL},
{"outfmt", &stream_tv_defaults.outfmt, CONF_TYPE_FOURCC, 0, 0, 0, NULL},
{"fps", &stream_tv_defaults.fps, CONF_TYPE_FLOAT, 0, 0, 100.0, NULL},
{"channels", &stream_tv_defaults.channels, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL},
{"brightness", &stream_tv_defaults.brightness, CONF_TYPE_INT, CONF_RANGE, -100, 100, NULL},
{"contrast", &stream_tv_defaults.contrast, CONF_TYPE_INT, CONF_RANGE, -100, 100, NULL},
{"hue", &stream_tv_defaults.hue, CONF_TYPE_INT, CONF_RANGE, -100, 100, NULL},
{"saturation", &stream_tv_defaults.saturation, CONF_TYPE_INT, CONF_RANGE, -100, 100, NULL},
{"gain", &stream_tv_defaults.gain, CONF_TYPE_INT, CONF_RANGE, -1, 100, NULL},
#if HAVE_TV_V4L2
{"amode", &stream_tv_defaults.amode, CONF_TYPE_INT, CONF_RANGE, 0, 3, NULL},
{"volume", &stream_tv_defaults.volume, CONF_TYPE_INT, CONF_RANGE, 0, 65535, NULL},
{"bass", &stream_tv_defaults.bass, CONF_TYPE_INT, CONF_RANGE, 0, 65535, NULL},
{"treble", &stream_tv_defaults.treble, CONF_TYPE_INT, CONF_RANGE, 0, 65535, NULL},
{"balance", &stream_tv_defaults.balance, CONF_TYPE_INT, CONF_RANGE, 0, 65535, NULL},
{"forcechan", &stream_tv_defaults.forcechan, CONF_TYPE_INT, CONF_RANGE, 1, 2, NULL},
{"forceaudio", &stream_tv_defaults.force_audio, CONF_TYPE_FLAG, 0, 0, 1, NULL},
{"buffersize", &stream_tv_defaults.buffer_size, CONF_TYPE_INT, CONF_RANGE, 16, 1024, NULL},
{"mjpeg", &stream_tv_defaults.mjpeg, CONF_TYPE_FLAG, 0, 0, 1, NULL},
{"decimation", &stream_tv_defaults.decimation, CONF_TYPE_INT, CONF_RANGE, 1, 4, NULL},
{"quality", &stream_tv_defaults.quality, CONF_TYPE_INT, CONF_RANGE, 0, 100, NULL},
#if HAVE_ALSA
{"alsa", &stream_tv_defaults.alsa, CONF_TYPE_FLAG, 0, 0, 1, NULL},
#endif /* HAVE_ALSA */
#endif /* HAVE_TV_V4L2 */
{"adevice", &stream_tv_defaults.adevice, CONF_TYPE_STRING, 0, 0, 0, NULL},
{"audioid", &stream_tv_defaults.audio_id, CONF_TYPE_INT, CONF_RANGE, 0, 9, NULL},
{NULL, NULL, 0, 0, 0, 0, NULL}
};
#endif /* HAVE_TV */
extern const struct m_sub_options tv_params_conf;
extern int pvr_param_aspect_ratio;
extern int pvr_param_sample_rate;
@ -168,15 +122,6 @@ static const m_option_t mfopts_conf[]={
{NULL, NULL, 0, 0, 0, 0, NULL}
};
#if HAVE_TV
static const m_option_t tvscan_conf[]={
{"autostart", &stream_tv_defaults.scan, CONF_TYPE_FLAG, 0, 0, 1, NULL},
{"threshold", &stream_tv_defaults.scan_threshold, CONF_TYPE_INT, CONF_RANGE, 1, 100, NULL},
{"period", &stream_tv_defaults.scan_period, CONF_TYPE_FLOAT, CONF_RANGE, 0.1, 2.0, NULL},
{NULL, NULL, 0, 0, 0, 0, NULL}
};
#endif
#define OPT_BASE_STRUCT struct MPOpts
extern const struct m_sub_options image_writer_conf;
@ -321,7 +266,7 @@ const m_option_t mp_opts[] = {
{"mf", (void *) mfopts_conf, CONF_TYPE_SUBCONFIG, 0,0,0, NULL},
#if HAVE_TV
{"tv", (void *) tvopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
OPT_SUBSTRUCT("tv", tv_params, tv_params_conf, 0),
#endif /* HAVE_TV */
#if HAVE_PVR
{"pvr", (void *) pvropts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
@ -604,9 +549,6 @@ const m_option_t mp_opts[] = {
OPT_INTRANGE("key-fifo-size", input.key_fifo_size, CONF_GLOBAL, 2, 65000),
OPT_FLAG("input-terminal", consolecontrols, CONF_GLOBAL),
OPT_FLAG("input-cursor", vo.enable_mouse_movements, CONF_GLOBAL),
#if HAVE_TV
{"tv-scan", (void *) tvscan_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
#endif /* HAVE_TV */
{"screenshot", (void *) screenshot_conf, CONF_TYPE_SUBCONFIG},

View File

@ -238,6 +238,8 @@ typedef struct MPOpts {
int network_tls_verify;
char *network_tls_ca_file;
struct tv_params *tv_params;
struct lavc_param {
int fast;
int show_all;

View File

@ -45,6 +45,7 @@
#include "osdep/io.h"
#include "common/msg.h"
#include "options/options.h"
#include "stream.h"
#include "pvr.h"
@ -110,6 +111,7 @@ typedef struct stationlist_s {
struct pvr_t {
struct mp_log *log;
tv_param_t *tv_params;
int dev_fd;
char *video_dev;
@ -408,12 +410,12 @@ parse_setup_stationlist (struct pvr_t *pvr)
return -1;
/* Create our station/channel list */
if (stream_tv_defaults.chanlist)
if (pvr->tv_params->chanlist)
{
/* select channel list */
for (i = 0; chanlists[i].name != NULL; i++)
{
if (!strcasecmp (chanlists[i].name, stream_tv_defaults.chanlist))
if (!strcasecmp (chanlists[i].name, pvr->tv_params->chanlist))
{
chantab = i;
break;
@ -422,7 +424,7 @@ parse_setup_stationlist (struct pvr_t *pvr)
if (!chanlists[i].name)
{
MP_ERR(pvr, "%s unable to find channel list %s, using default %s\n",
LOG_LEVEL_V4L2, stream_tv_defaults.chanlist, chanlists[chantab].name);
LOG_LEVEL_V4L2, pvr->tv_params->chanlist, chanlists[chantab].name);
}
else
{
@ -445,11 +447,11 @@ parse_setup_stationlist (struct pvr_t *pvr)
}
/* Handle user channel mappings */
if (stream_tv_defaults.channels)
if (pvr->tv_params->channels)
{
char channel[PVR_STATION_NAME_SIZE];
char station[PVR_STATION_NAME_SIZE];
char **channels = stream_tv_defaults.channels;
char **channels = pvr->tv_params->channels;
disable_all_stations (pvr);
@ -1094,59 +1096,59 @@ parse_v4l2_tv_options (struct pvr_t *pvr)
if (set_station_by_channelname_or_freq (pvr, pvr->param_channel,
-1, 0) >= 0)
{
if (stream_tv_defaults.freq)
if (pvr->tv_params->freq)
{
MP_INFO(pvr, "%s tv param freq %s is overwritten by channel setting freq %d\n", LOG_LEVEL_V4L2,
stream_tv_defaults.freq, pvr->freq);
pvr->tv_params->freq, pvr->freq);
}
}
}
if (pvr->freq < 0 && stream_tv_defaults.freq)
if (pvr->freq < 0 && pvr->tv_params->freq)
{
MP_INFO(pvr, "%s tv param freq %s is used directly\n",
LOG_LEVEL_V4L2, stream_tv_defaults.freq);
LOG_LEVEL_V4L2, pvr->tv_params->freq);
if (set_station_by_channelname_or_freq (pvr, NULL,
atoi (stream_tv_defaults.freq), 0)<0)
atoi (pvr->tv_params->freq), 0)<0)
{
MP_WARN(pvr, "%s tv param freq %s invalid to set station\n",
LOG_LEVEL_V4L2, stream_tv_defaults.freq);
LOG_LEVEL_V4L2, pvr->tv_params->freq);
}
}
if (stream_tv_defaults.device)
if (pvr->tv_params->device)
{
free (pvr->video_dev);
pvr->video_dev = strdup (stream_tv_defaults.device);
pvr->video_dev = strdup (pvr->tv_params->device);
}
if (stream_tv_defaults.noaudio)
pvr->mute = stream_tv_defaults.noaudio;
if (!pvr->tv_params->audio)
pvr->mute = !pvr->tv_params->audio;
if (stream_tv_defaults.input)
pvr->input = stream_tv_defaults.input;
if (pvr->tv_params->input)
pvr->input = pvr->tv_params->input;
if (stream_tv_defaults.normid)
pvr->normid = stream_tv_defaults.normid;
if (pvr->tv_params->normid)
pvr->normid = pvr->tv_params->normid;
if (stream_tv_defaults.brightness)
pvr->brightness = stream_tv_defaults.brightness;
if (pvr->tv_params->brightness)
pvr->brightness = pvr->tv_params->brightness;
if (stream_tv_defaults.contrast)
pvr->contrast = stream_tv_defaults.contrast;
if (pvr->tv_params->contrast)
pvr->contrast = pvr->tv_params->contrast;
if (stream_tv_defaults.hue)
pvr->hue = stream_tv_defaults.hue;
if (pvr->tv_params->hue)
pvr->hue = pvr->tv_params->hue;
if (stream_tv_defaults.saturation)
pvr->saturation = stream_tv_defaults.saturation;
if (pvr->tv_params->saturation)
pvr->saturation = pvr->tv_params->saturation;
if (stream_tv_defaults.width)
pvr->width = stream_tv_defaults.width;
if (pvr->tv_params->width)
pvr->width = pvr->tv_params->width;
if (stream_tv_defaults.height)
pvr->height = stream_tv_defaults.height;
if (pvr->tv_params->height)
pvr->height = pvr->tv_params->height;
}
static int
@ -1519,6 +1521,7 @@ pvr_stream_open (stream_t *stream)
struct pvr_t *pvr = NULL;
pvr = pvr_init ();
pvr->tv_params = stream->opts->tv_params;
pvr->log = stream->log;
/**
@ -1527,8 +1530,8 @@ pvr_stream_open (stream_t *stream)
*/
if (stream->url && strlen (stream->url) > 6 && stream->url[6] != '\0')
pvr->param_channel = strdup (stream->url + 6);
else if (stream_tv_defaults.channel && strlen (stream_tv_defaults.channel))
pvr->param_channel = strdup (stream_tv_defaults.channel);
else if (pvr->tv_params->channel && strlen (pvr->tv_params->channel))
pvr->param_channel = strdup (pvr->tv_params->channel);
parse_v4l2_tv_options (pvr);
parse_encoder_options (pvr);

View File

@ -32,49 +32,7 @@
#include <stdio.h>
tv_param_t stream_tv_defaults = {
NULL, //freq
NULL, //channel
"europe-east", //chanlist
"pal", //norm
0, //automute
-1, //normid
NULL, //device
NULL, //driver
-1, //width
-1, //height
0, //input, used in v4l and bttv
-1, //outfmt
-1.0, //fps
NULL, //channels
0, //noaudio;
1, //immediate;
44100, //audiorate;
0, //audio_id
-1, //amode
-1, //volume
-1, //bass
-1, //treble
-1, //balance
-1, //forcechan
0, //force_audio
-1, //buffer_size
0, //mjpeg
2, //decimation
90, //quality
0, //alsa
NULL, //adevice
0, //brightness
0, //contrast
0, //hue
0, //saturation
-1, //gain
0, //scan_autostart
50, //scan_threshold
0.5, //scan_period
};
#define OPT_BASE_STRUCT tv_param_t
#define OPT_BASE_STRUCT struct tv_stream_params
static const m_option_t stream_opts_fields[] = {
OPT_STRING("channel", channel, 0),
OPT_INT("input", input, 0),
@ -102,7 +60,9 @@ const stream_info_t stream_info_tv = {
.open = tv_stream_open,
.protocols = (const char*[]){ "tv", NULL },
.priv_size = sizeof(tv_param_t),
.priv_defaults = &stream_tv_defaults,
.priv_defaults = &(const struct tv_stream_params){
.input = -1,
},
.options = stream_opts_fields,
.url_options = (const char*[]){
"hostname=channel",

View File

@ -31,6 +31,7 @@
#include <string.h>
#include <ctype.h>
#include <sys/time.h>
#include <assert.h>
#include <libavutil/avstring.h>
#include "config.h"
@ -38,6 +39,10 @@
#include "common/msg.h"
#include "options/m_option.h"
#include "options/m_config.h"
#include "options/options.h"
#include "stream.h"
#include "demux/demux.h"
#include "demux/stheader.h"
@ -50,10 +55,6 @@
#include "frequencies.h"
tv_channels_t *tv_channel_list;
tv_channels_t *tv_channel_current, *tv_channel_last;
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;
@ -67,6 +68,83 @@ static const tvi_info_t* tvi_driver_list[]={
NULL
};
#define OPT_BASE_STRUCT tv_param_t
const struct m_sub_options tv_params_conf = {
.opts = (const m_option_t[]) {
OPT_FLAG("immediatemode", immediate, 0),
OPT_FLAG("audio", audio, 0),
OPT_INT("audiorate", audiorate, 0),
OPT_STRING("driver", driver, 0),
OPT_STRING("device", device, 0),
OPT_STRING("freq", freq, 0),
OPT_STRING("channel", channel, 0),
OPT_STRING("chanlist", chanlist, 0),
OPT_STRING("norm", norm, 0),
OPT_INTRANGE("automute", automute, 0, 0, 255),
#if HAVE_TV_V4L2
OPT_INT("normid", normid, 0),
#endif
OPT_INTRANGE("width", width, 0, 0, 4096),
OPT_INTRANGE("height", height, 0, 0, 4096),
OPT_INT("input", input, 0),
OPT_GENERAL(int, "outfmt", outfmt, 0, .type = &m_option_type_fourcc),
OPT_FLOAT("fps", fps, 0),
OPT_STRINGLIST("channels", channels, 0),
OPT_INTRANGE("brightness", brightness, 0, -100, 100),
OPT_INTRANGE("contrast", contrast, 0, -100, 100),
OPT_INTRANGE("hue", hue, 0, -100, 100),
OPT_INTRANGE("saturation", saturation, 0, -100, 100),
OPT_INTRANGE("gain", gain, 0, -1, 100),
#if HAVE_TV_V4L2
OPT_INTRANGE("amode", amode, 0, 0, 3),
OPT_INTRANGE("volume", volume, 0, 0, 65535),
OPT_INTRANGE("bass", bass, 0, 0, 65535),
OPT_INTRANGE("treble", treble, 0, 0, 65535),
OPT_INTRANGE("balance", balance, 0, 0, 65535),
OPT_INTRANGE("forcechan", forcechan, 0, 1, 2),
OPT_FLAG("forceaudio", force_audio, 0),
OPT_INTRANGE("buffersize", buffer_size, 0, 16, 1024),
OPT_FLAG("mjpeg", mjpeg, 0),
OPT_INTRANGE("decimation", decimation, 0, 1, 4),
OPT_INTRANGE("quality", quality, 0, 0, 100),
#if HAVE_ALSA
OPT_FLAG("alsa", alsa, 0),
#endif /* HAVE_ALSA */
#endif /* HAVE_TV_V4L2 */
OPT_STRING("adevice", adevice, 0),
OPT_INTRANGE("audioid", audio_id, 0, 0, 9),
OPT_FLAG("scan-autostart", scan, 0),
OPT_INTRANGE("scan-threshold", scan_threshold, 0, 1, 100),
OPT_FLOATRANGE("scan-period", scan_period, 0, 0.1, 2.0),
{0}
},
.size = sizeof(tv_param_t),
.defaults = &(const tv_param_t){
.chanlist = "europe-east",
.norm = "pal",
.normid = -1,
.width = -1,
.height = -1,
.outfmt = -1,
.fps = -1.0,
.audio = 1,
.immediate = 1,
.audiorate = 44100,
.amode = -1,
.volume = -1,
.bass = -1,
.treble = -1,
.balance = -1,
.forcechan = -1,
.buffer_size = -1,
.decimation = 2,
.quality = 90,
.gain = -1,
.scan_threshold = 50,
.scan_period = 0.5,
},
};
tvi_handle_t *tv_new_handle(int size, struct mp_log *log, const tvi_functions_t *functions)
{
tvi_handle_t *h = malloc(sizeof(*h));
@ -144,7 +222,7 @@ static void tv_scan(tvi_handle_t *tvh)
if (tv_get_signal(tvh)>tvh->tv_param->scan_threshold) {
cl = tvh->chanlist_s[scan->channel_num];
tv_channel_tmp=tv_channel_list;
tv_channel_tmp=tvh->tv_channel_list;
while (tv_channel_tmp) {
index++;
if (cl.freq==tv_channel_tmp->freq){
@ -165,11 +243,11 @@ static void tv_scan(tvi_handle_t *tvh)
snprintf(tv_channel_tmp->name,sizeof(tv_channel_tmp->name),"ch%d",index);
strncpy(tv_channel_tmp->number, cl.name, 5);
tv_channel_tmp->number[4]='\0';
if (!tv_channel_list)
tv_channel_list=tv_channel_tmp;
if (!tvh->tv_channel_list)
tvh->tv_channel_list=tv_channel_tmp;
else {
tv_channel_add->next=tv_channel_tmp;
tv_channel_list->prev=tv_channel_tmp;
tvh->tv_channel_list->prev=tv_channel_tmp;
}
}else
MP_INFO(tvh, "Found existing channel: %s-%s.\n",
@ -180,7 +258,7 @@ static void tv_scan(tvi_handle_t *tvh)
if (scan->channel_num>=chanlists[tvh->chanlist].count) {
tvh->tv_param->scan=0;
MP_INFO(tvh, "TV scan end. Found %d new channels.\n", scan->new_channels);
tv_channel_tmp=tv_channel_list;
tv_channel_tmp=tvh->tv_channel_list;
if(tv_channel_tmp){
MP_INFO(tvh, "channels=");
while(tv_channel_tmp){
@ -191,9 +269,9 @@ static void tv_scan(tvi_handle_t *tvh)
}
MP_INFO(tvh, "\n");
}
if (!tv_channel_current) tv_channel_current=tv_channel_list;
if (tv_channel_current)
tv_set_freq_float(tvh, tv_channel_current->freq);
if (!tvh->tv_channel_current) tvh->tv_channel_current=tvh->tv_channel_list;
if (tvh->tv_channel_current)
tv_set_freq_float(tvh, tvh->tv_channel_current->freq);
free(tvh->scan);
tvh->scan=NULL;
}else{
@ -232,7 +310,7 @@ static int demux_tv_fill_buffer(demuxer_t *demux)
/* ================== ADD AUDIO PACKET =================== */
if (want_audio && tvh->tv_param->noaudio == 0 &&
if (want_audio && tvh->tv_param->audio &&
tvh->functions->control(tvh->priv,
TVI_CONTROL_IS_AUDIO, 0) == TVI_CONTROL_TRUE)
{
@ -306,12 +384,12 @@ static void parse_channels(tvi_handle_t *tvh)
char** channels = tvh->tv_param->channels;
MP_INFO(tvh, "TV channel names detected.\n");
tv_channel_list = malloc(sizeof(tv_channels_t));
tv_channel_list->index=1;
tv_channel_list->next=NULL;
tv_channel_list->prev=NULL;
tv_channel_current = tv_channel_list;
tv_channel_current->norm = tvh->norm;
tvh->tv_channel_list = malloc(sizeof(tv_channels_t));
tvh->tv_channel_list->index=1;
tvh->tv_channel_list->next=NULL;
tvh->tv_channel_list->prev=NULL;
tvh->tv_channel_current = tvh->tv_channel_list;
tvh->tv_channel_current->norm = tvh->norm;
while (*channels) {
char* tmp = *(channels++);
@ -321,64 +399,64 @@ static void parse_channels(tvi_handle_t *tvh)
if (!sep) continue; // Wrong syntax, but mplayer should not crash
av_strlcpy(tv_channel_current->name, sep + 1,
sizeof(tv_channel_current->name));
av_strlcpy(tvh->tv_channel_current->name, sep + 1,
sizeof(tvh->tv_channel_current->name));
sep[0] = '\0';
strncpy(tv_channel_current->number, tmp, 5);
tv_channel_current->number[4]='\0';
strncpy(tvh->tv_channel_current->number, tmp, 5);
tvh->tv_channel_current->number[4]='\0';
while ((sep=strchr(tv_channel_current->name, '_')))
while ((sep=strchr(tvh->tv_channel_current->name, '_')))
sep[0] = ' ';
// if channel number is a number and larger than 1000 threat it as frequency
// tmp still contain pointer to null-terminated string with channel number here
if (atoi(tmp)>1000){
tv_channel_current->freq=atoi(tmp);
tvh->tv_channel_current->freq=atoi(tmp);
}else{
tv_channel_current->freq = 0;
tvh->tv_channel_current->freq = 0;
for (i = 0; i < chanlists[tvh->chanlist].count; i++) {
cl = tvh->chanlist_s[i];
if (!strcasecmp(cl.name, tv_channel_current->number)) {
tv_channel_current->freq=cl.freq;
if (!strcasecmp(cl.name, tvh->tv_channel_current->number)) {
tvh->tv_channel_current->freq=cl.freq;
break;
}
}
}
if (tv_channel_current->freq == 0)
if (tvh->tv_channel_current->freq == 0)
MP_ERR(tvh, "Couldn't find frequency for channel %s (%s)\n",
tv_channel_current->number, tv_channel_current->name);
tvh->tv_channel_current->number, tvh->tv_channel_current->name);
else {
sep = strchr(tv_channel_current->name, '-');
if ( !sep ) sep = strchr(tv_channel_current->name, '+');
sep = strchr(tvh->tv_channel_current->name, '-');
if ( !sep ) sep = strchr(tvh->tv_channel_current->name, '+');
if ( sep ) {
i = atoi (sep+1);
if ( sep[0] == '+' ) tv_channel_current->freq += i * 100;
if ( sep[0] == '-' ) tv_channel_current->freq -= i * 100;
if ( sep[0] == '+' ) tvh->tv_channel_current->freq += i * 100;
if ( sep[0] == '-' ) tvh->tv_channel_current->freq -= i * 100;
sep[0] = '\0';
}
sep = strchr(tv_channel_current->name, '=');
sep = strchr(tvh->tv_channel_current->name, '=');
if ( sep ) {
tv_channel_current->norm = norm_from_string(tvh, sep+1);
tvh->tv_channel_current->norm = norm_from_string(tvh, sep+1);
sep[0] = '\0';
}
}
/*MP_INFO(tvh, "-- Detected channel %s - %s (%5.3f)\n",
tv_channel_current->number, tv_channel_current->name,
(float)tv_channel_current->freq/1000);*/
tvh->tv_channel_current->number, tvh->tv_channel_current->name,
(float)tvh->tv_channel_current->freq/1000);*/
tv_channel_current->next = malloc(sizeof(tv_channels_t));
tv_channel_current->next->index = tv_channel_current->index + 1;
tv_channel_current->next->prev = tv_channel_current;
tv_channel_current->next->next = NULL;
tv_channel_current = tv_channel_current->next;
tv_channel_current->norm = tvh->norm;
tvh->tv_channel_current->next = malloc(sizeof(tv_channels_t));
tvh->tv_channel_current->next->index = tvh->tv_channel_current->index + 1;
tvh->tv_channel_current->next->prev = tvh->tv_channel_current;
tvh->tv_channel_current->next->next = NULL;
tvh->tv_channel_current = tvh->tv_channel_current->next;
tvh->tv_channel_current->norm = tvh->norm;
}
if (tv_channel_current->prev)
tv_channel_current->prev->next = NULL;
free(tv_channel_current);
if (tvh->tv_channel_current->prev)
tvh->tv_channel_current->prev->next = NULL;
free(tvh->tv_channel_current);
}
int tv_set_norm(tvi_handle_t *tvh, char* norm)
@ -544,9 +622,9 @@ static int open_tv(tvi_handle_t *tvh)
if (tvh->tv_param->channels) {
parse_channels(tvh);
} else
tv_channel_last_real = malloc(5);
tvh->tv_channel_last_real = malloc(5);
if (tv_channel_list) {
if (tvh->tv_channel_list) {
int channel = 0;
if (tvh->tv_param->channel)
{
@ -558,27 +636,27 @@ static int open_tv(tvi_handle_t *tvh)
/* if tvh->tv_param->channel does not begin with a digit
set the first channel that contains tvh->tv_param->channel in its name */
tv_channel_current = tv_channel_list;
while ( tv_channel_current ) {
if ( strstr(tv_channel_current->name, tvh->tv_param->channel) )
tvh->tv_channel_current = tvh->tv_channel_list;
while ( tvh->tv_channel_current ) {
if ( strstr(tvh->tv_channel_current->name, tvh->tv_param->channel) )
break;
tv_channel_current = tv_channel_current->next;
tvh->tv_channel_current = tvh->tv_channel_current->next;
}
if ( !tv_channel_current ) tv_channel_current = tv_channel_list;
if ( !tvh->tv_channel_current ) tvh->tv_channel_current = tvh->tv_channel_list;
}
}
else
channel = 1;
if ( channel ) {
tv_channel_current = tv_channel_list;
tvh->tv_channel_current = tvh->tv_channel_list;
for (int n = 1; n < channel; n++)
if (tv_channel_current->next)
tv_channel_current = tv_channel_current->next;
if (tvh->tv_channel_current->next)
tvh->tv_channel_current = tvh->tv_channel_current->next;
}
set_norm_and_freq(tvh, tv_channel_current);
tv_channel_last = tv_channel_current;
set_norm_and_freq(tvh, tvh->tv_channel_current);
tvh->tv_channel_last = tvh->tv_channel_current;
} else {
/* we need to set frequency */
if (tvh->tv_param->freq)
@ -604,7 +682,7 @@ static int open_tv(tvi_handle_t *tvh)
// i, cl.name, cl.freq);
if (!strcasecmp(cl.name, tvh->tv_param->channel))
{
strcpy(tv_channel_last_real, cl.name);
strcpy(tvh->tv_channel_last_real, cl.name);
tvh->channel = i;
MP_INFO(tvh, "Selected channel: %s (freq: %.3f)\n",
cl.name, cl.freq/1000.0);
@ -669,7 +747,8 @@ static tvi_handle_t *tv_begin(tv_param_t* tv_param, struct mp_log *log)
tvi_driver_list[i]->name,
tvi_driver_list[i]->author,
tvi_driver_list[i]->comment?tvi_driver_list[i]->comment:"");
tv_param->driver=strdup(tvi_driver_list[i]->short_name);
talloc_free(tv_param->driver);
tv_param->driver=talloc_strdup(NULL, tvi_driver_list[i]->short_name);
return h;
}
}
@ -704,8 +783,18 @@ static int demux_open_tv(demuxer_t *demuxer, enum demux_check check)
if (check > DEMUX_CHECK_REQUEST || demuxer->stream->type != STREAMTYPE_TV)
return -1;
demuxer->priv=NULL;
if(!(tvh=tv_begin(demuxer->stream->priv, demuxer->log))) return -1;
tv_param_t *params = m_sub_options_copy(demuxer, &tv_params_conf,
demuxer->opts->tv_params);
struct tv_stream_params *sparams = demuxer->stream->priv;
if (sparams->channel && sparams->channel[0]) {
talloc_free(params->channel);
params->channel = talloc_strdup(NULL, sparams->channel);
}
if (sparams->input >= 0)
params->input = sparams->input;
assert(demuxer->priv==NULL);
if(!(tvh=tv_begin(params, demuxer->log))) return -1;
if (!tvh->functions->init(tvh->priv)) return -1;
tvh->demuxer = demuxer;
@ -747,7 +836,7 @@ static int demux_open_tv(demuxer_t *demuxer, enum demux_check check)
if(tvh->tv_param->immediate == 1)
{
funcs->control(tvh->priv, TVI_CONTROL_IMMEDIATE, 0);
tvh->tv_param->noaudio = 1;
tvh->tv_param->audio = 0;
}
/* set width */
@ -759,7 +848,7 @@ static int demux_open_tv(demuxer_t *demuxer, enum demux_check check)
demuxer->seekable = 0;
/* here comes audio init */
if (tvh->tv_param->noaudio == 0 && funcs->control(tvh->priv, TVI_CONTROL_IS_AUDIO, 0) == TVI_CONTROL_TRUE)
if (tvh->tv_param->audio && funcs->control(tvh->priv, TVI_CONTROL_IS_AUDIO, 0) == TVI_CONTROL_TRUE)
{
int audio_format;
@ -955,7 +1044,7 @@ int tv_step_channel_real(tvi_handle_t *tvh, int direction)
{
if (tvh->channel-1 >= 0)
{
strcpy(tv_channel_last_real, tvh->chanlist_s[tvh->channel].name);
strcpy(tvh->tv_channel_last_real, tvh->chanlist_s[tvh->channel].name);
cl = tvh->chanlist_s[--tvh->channel];
MP_INFO(tvh, "Selected channel: %s (freq: %.3f)\n",
cl.name, cl.freq/1000.0);
@ -967,7 +1056,7 @@ int tv_step_channel_real(tvi_handle_t *tvh, int direction)
{
if (tvh->channel+1 < chanlists[tvh->chanlist].count)
{
strcpy(tv_channel_last_real, tvh->chanlist_s[tvh->channel].name);
strcpy(tvh->tv_channel_last_real, tvh->chanlist_s[tvh->channel].name);
cl = tvh->chanlist_s[++tvh->channel];
MP_INFO(tvh, "Selected channel: %s (freq: %.3f)\n",
cl.name, cl.freq/1000.0);
@ -979,23 +1068,23 @@ int tv_step_channel_real(tvi_handle_t *tvh, int direction)
int tv_step_channel(tvi_handle_t *tvh, int direction) {
tvh->tv_param->scan=0;
if (tv_channel_list) {
if (tvh->tv_channel_list) {
if (direction == TV_CHANNEL_HIGHER) {
tv_channel_last = tv_channel_current;
if (tv_channel_current->next)
tv_channel_current = tv_channel_current->next;
tvh->tv_channel_last = tvh->tv_channel_current;
if (tvh->tv_channel_current->next)
tvh->tv_channel_current = tvh->tv_channel_current->next;
else
tv_channel_current = tv_channel_list;
set_norm_and_freq(tvh, tv_channel_current);
tvh->tv_channel_current = tvh->tv_channel_list;
set_norm_and_freq(tvh, tvh->tv_channel_current);
}
if (direction == TV_CHANNEL_LOWER) {
tv_channel_last = tv_channel_current;
if (tv_channel_current->prev)
tv_channel_current = tv_channel_current->prev;
tvh->tv_channel_last = tvh->tv_channel_current;
if (tvh->tv_channel_current->prev)
tvh->tv_channel_current = tvh->tv_channel_current->prev;
else
while (tv_channel_current->next)
tv_channel_current = tv_channel_current->next;
set_norm_and_freq(tvh, tv_channel_current);
while (tvh->tv_channel_current->next)
tvh->tv_channel_current = tvh->tv_channel_current->next;
set_norm_and_freq(tvh, tvh->tv_channel_current);
}
} else tv_step_channel_real(tvh, direction);
return 1;
@ -1006,7 +1095,7 @@ int tv_set_channel_real(tvi_handle_t *tvh, char *channel) {
struct CHANLIST cl;
tvh->tv_param->scan=0;
strcpy(tv_channel_last_real, tvh->chanlist_s[tvh->channel].name);
strcpy(tvh->tv_channel_last_real, tvh->chanlist_s[tvh->channel].name);
for (i = 0; i < chanlists[tvh->chanlist].count; i++)
{
cl = tvh->chanlist_s[i];
@ -1028,14 +1117,14 @@ int tv_set_channel(tvi_handle_t *tvh, char *channel) {
int i, channel_int;
tvh->tv_param->scan=0;
if (tv_channel_list) {
tv_channel_last = tv_channel_current;
if (tvh->tv_channel_list) {
tvh->tv_channel_last = tvh->tv_channel_current;
channel_int = atoi(channel);
tv_channel_current = tv_channel_list;
tvh->tv_channel_current = tvh->tv_channel_list;
for (i = 1; i < channel_int; i++)
if (tv_channel_current->next)
tv_channel_current = tv_channel_current->next;
set_norm_and_freq(tvh, tv_channel_current);
if (tvh->tv_channel_current->next)
tvh->tv_channel_current = tvh->tv_channel_current->next;
set_norm_and_freq(tvh, tvh->tv_channel_current);
} else tv_set_channel_real(tvh, channel);
return 1;
}
@ -1043,14 +1132,14 @@ int tv_set_channel(tvi_handle_t *tvh, char *channel) {
int tv_last_channel(tvi_handle_t *tvh) {
tvh->tv_param->scan=0;
if (tv_channel_list) {
if (tvh->tv_channel_list) {
tv_channels_t *tmp;
tmp = tv_channel_last;
tv_channel_last = tv_channel_current;
tv_channel_current = tmp;
tmp = tvh->tv_channel_last;
tvh->tv_channel_last = tvh->tv_channel_current;
tvh->tv_channel_current = tmp;
set_norm_and_freq(tvh, tv_channel_current);
set_norm_and_freq(tvh, tvh->tv_channel_current);
} else {
int i;
struct CHANLIST cl;
@ -1058,9 +1147,9 @@ int tv_last_channel(tvi_handle_t *tvh) {
for (i = 0; i < chanlists[tvh->chanlist].count; i++)
{
cl = tvh->chanlist_s[i];
if (!strcasecmp(cl.name, tv_channel_last_real))
if (!strcasecmp(cl.name, tvh->tv_channel_last_real))
{
strcpy(tv_channel_last_real, tvh->chanlist_s[tvh->channel].name);
strcpy(tvh->tv_channel_last_real, tvh->chanlist_s[tvh->channel].name);
tvh->channel = i;
MP_INFO(tvh, "Selected channel: %s (freq: %.3f)\n",
cl.name, cl.freq/1000.0);

View File

@ -27,7 +27,7 @@
struct mp_log;
typedef struct tv_param_s {
typedef struct tv_params {
char *freq;
char *channel;
char *chanlist;
@ -42,7 +42,7 @@ typedef struct tv_param_s {
int outfmt;
float fps;
char **channels;
int noaudio;
int audio;
int immediate;
int audiorate;
int audio_id;
@ -68,14 +68,12 @@ typedef struct tv_param_s {
int scan;
int scan_threshold;
float scan_period;
/**
Terminate stream with video renderer instead of Null renderer
Will help if video freezes but audio does not.
May not work with -vo directx and -vf crop combination.
*/
} tv_param_t;
extern tv_param_t stream_tv_defaults;
struct tv_stream_params {
char *channel;
int input;
};
typedef struct tvi_info_s
{
@ -115,6 +113,10 @@ typedef struct tvi_handle_s {
int channel;
tv_param_t * tv_param;
void * scan;
struct tv_channels_s *tv_channel_list;
struct tv_channels_s *tv_channel_current, *tv_channel_last;
char *tv_channel_last_real;
} tvi_handle_t;
typedef struct tv_channels_s {
@ -127,10 +129,6 @@ typedef struct tv_channels_s {
struct tv_channels_s *prev;
} tv_channels_t;
extern tv_channels_t *tv_channel_list;
extern tv_channels_t *tv_channel_current, *tv_channel_last;
extern char *tv_channel_last_real;
typedef struct {
unsigned int scan_timer;
int channel_num;

View File

@ -401,7 +401,7 @@ static void init_audio(priv_t *priv)
{
if (priv->audio_initialized) return;
if (!priv->tv_param->noaudio) {
if (priv->tv_param->audio) {
#if HAVE_ALSA
if (priv->tv_param->alsa)
audio_in_init(&priv->audio_in, priv->log, AUDIO_IN_ALSA);
@ -995,7 +995,7 @@ static int uninit(priv_t *priv)
}
/* stop audio thread */
if (!priv->tv_param->noaudio && priv->audio_grabber_thread) {
if (priv->tv_param->audio && priv->audio_grabber_thread) {
pthread_join(priv->audio_grabber_thread, NULL);
pthread_mutex_destroy(&priv->skew_mutex);
pthread_mutex_destroy(&priv->audio_mutex);
@ -1015,7 +1015,7 @@ static int uninit(priv_t *priv)
}
free(priv->video_ringbuffer);
}
if (!priv->tv_param->noaudio) {
if (priv->tv_param->audio) {
free(priv->audio_ringbuffer);
free(priv->audio_skew_buffer);
free(priv->audio_skew_delta_buffer);
@ -1245,7 +1245,7 @@ static int start(priv_t *priv)
/* setup audio parameters */
init_audio(priv);
if (!priv->tv_param->noaudio && !priv->audio_initialized) return 0;
if (priv->tv_param->audio && !priv->audio_initialized) return 0;
/* we need this to size the audio buffer properly */
if (priv->immediate_mode) {
@ -1254,7 +1254,7 @@ static int start(priv_t *priv)
priv->video_buffer_size_max = get_capture_buffer_size(priv);
}
if (!priv->tv_param->noaudio) {
if (priv->tv_param->audio) {
setup_audio_buffer_sizes(priv);
priv->audio_skew_buffer = calloc(priv->aud_skew_cnt, sizeof(long long));
if (!priv->audio_skew_buffer) {
@ -1296,7 +1296,7 @@ static int start(priv_t *priv)
}
/* setup video parameters */
if (!priv->tv_param->noaudio) {
if (priv->tv_param->audio) {
if (priv->video_buffer_size_max < 3*getfps(priv)*priv->audio_secs_per_block) {
MP_ERR(priv, "Video buffer shorter than 3 times audio frame duration.\n"
"You will probably experience heavy framedrops.\n");
@ -1433,7 +1433,7 @@ static void *video_grabber(void *data)
}
priv->streamon = 1;
if (!priv->tv_param->noaudio) {
if (priv->tv_param->audio) {
pthread_create(&priv->audio_grabber_thread, NULL, audio_grabber, priv);
}
@ -1510,9 +1510,9 @@ static void *video_grabber(void *data)
/* store the timestamp of the very first frame as reference */
if (!priv->frames++) {
if (!priv->tv_param->noaudio) pthread_mutex_lock(&priv->skew_mutex);
if (priv->tv_param->audio) pthread_mutex_lock(&priv->skew_mutex);
priv->first_frame = (long long)1e6*buf.timestamp.tv_sec + buf.timestamp.tv_usec;
if (!priv->tv_param->noaudio) pthread_mutex_unlock(&priv->skew_mutex);
if (priv->tv_param->audio) pthread_mutex_unlock(&priv->skew_mutex);
}
priv->curr_frame = (long long)buf.timestamp.tv_sec*1e6+buf.timestamp.tv_usec;
// fprintf(stderr, "idx = %d, ts = %f\n", buf.index, (double)(priv->curr_frame) / 1e6);
@ -1522,9 +1522,9 @@ static void *video_grabber(void *data)
if (!priv->immediate_mode) {
// interpolate the skew in time
if (!priv->tv_param->noaudio) pthread_mutex_lock(&priv->skew_mutex);
if (priv->tv_param->audio) pthread_mutex_lock(&priv->skew_mutex);
xskew = priv->audio_skew + (interval - priv->audio_skew_measure_time)*priv->audio_skew_factor;
if (!priv->tv_param->noaudio) pthread_mutex_unlock(&priv->skew_mutex);
if (priv->tv_param->audio) pthread_mutex_unlock(&priv->skew_mutex);
// correct extreme skew changes to avoid (especially) moving backwards in time
if (xskew - prev_skew > delta*MAX_SKEW_DELTA) {
skew = prev_skew + delta*MAX_SKEW_DELTA;