mirror of https://github.com/mpv-player/mpv
command: redo ancient TV/DVB/PVR commands
Convert all these commands to properties. (Except tv_last_channel, not sure what to do with this.) Also, internally, don't access stream details directly, but dispatch commands with stream ctrls. Many of the new properties are a bit strange, because they're write- only. Also remove some OSD output these commands produced, because I couldn't be bothered to port these. In general, this makes everything much cleaner, and will also make it easier to e.g. move the demuxer to its own thread. Don't bother updating input.conf, but changes.rst documents how old commands map to the new ones. Mostly untested, due to lack of hardware.
This commit is contained in:
parent
9420eb5a07
commit
e033f3c8bc
|
@ -274,6 +274,32 @@ input.conf and Slave Commands
|
|||
+--------------------------------+----------------------------------------+
|
||||
| ``af_switch``, ``af_add``, ... | ``af set|add|...`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_start_scan`` | ``set tv-scan yes`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_set_channel <val>`` | ``set tv-channel <val>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_step_channel`` | ``cycle tv-channel`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``dvb_set_channel <v1> <v2>`` | ``set dvb-channel <v1>-<v2>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``dvb_step_channel`` | ``cycle dvb-channel`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_set_freq <val>`` | ``set tv-freq <val>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_step_freq`` | ``cycle tv-freq`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_set_norm <norm>`` | ``set tv-norm <norm>`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``tv_step_norm`` | ``cycle tv-norm`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
|
||||
.. note::
|
||||
|
||||
Due to lack of hardware and users using the TV/DVB/PVR features, and
|
||||
due to the need to cleanup the related command code, it's possible
|
||||
that the new commands are buggy or behave worse. This can be improved
|
||||
if testers are available. Otherwise, some of the TV code will be
|
||||
removed at some point.
|
||||
|
||||
Slave mode
|
||||
~~~~~~~~~~
|
||||
|
|
|
@ -493,11 +493,8 @@ Input Commands that are Possibly Subject to Change
|
|||
be used in input.conf to reassign such bindings.)
|
||||
|
||||
|
||||
Undocumented commands: ``tv_start_scan``, ``tv_step_channel``, ``tv_step_norm``,
|
||||
``tv_step_chanlist``, ``tv_set_channel``, ``tv_last_channel``, ``tv_set_freq``,
|
||||
``tv_step_freq``, ``tv_set_norm``, ``dvb_set_channel`` (all of these
|
||||
should be replaced by properties), ``stop`` (questionable use), ``get_property``
|
||||
(?), ``vo_cmdline`` (experimental).
|
||||
Undocumented commands: ``tv_last_channel`` (TV/DVB only), ``stop`` (questionable
|
||||
use), ``get_property`` (?), ``vo_cmdline`` (experimental).
|
||||
|
||||
Input Command Prefixes
|
||||
----------------------
|
||||
|
|
|
@ -56,6 +56,13 @@ enum demux_ctrl {
|
|||
DEMUXER_CTRL_GET_START_TIME,
|
||||
DEMUXER_CTRL_RESYNC,
|
||||
DEMUXER_CTRL_IDENTIFY_PROGRAM,
|
||||
DEMUXER_CTRL_STREAM_CTRL, // stupid workaround for legacy TV code
|
||||
};
|
||||
|
||||
struct demux_ctrl_stream_ctrl {
|
||||
int ctrl;
|
||||
void *arg;
|
||||
int res;
|
||||
};
|
||||
|
||||
#define SEEK_ABSOLUTE (1 << 0)
|
||||
|
|
|
@ -156,12 +156,6 @@
|
|||
#l cycle quvi-format 1
|
||||
#L cycle quvi-format -1
|
||||
|
||||
# TV
|
||||
#h tv_step_channel 1
|
||||
#k tv_step_channel -1
|
||||
#n tv_step_norm
|
||||
#u tv_step_chanlist
|
||||
|
||||
# Apple Remote section
|
||||
#AR_PLAY cycle pause
|
||||
#AR_PLAY_HOLD quit
|
||||
|
|
|
@ -93,17 +93,7 @@ const struct mp_cmd_def mp_cmds[] = {
|
|||
{ MP_CMD_SUB_REMOVE, "sub_remove", { OARG_INT(-1) } },
|
||||
{ MP_CMD_SUB_RELOAD, "sub_reload", { OARG_INT(-1) } },
|
||||
|
||||
{ MP_CMD_TV_START_SCAN, "tv_start_scan", },
|
||||
{ MP_CMD_TV_STEP_CHANNEL, "tv_step_channel", { ARG_INT } },
|
||||
{ MP_CMD_TV_STEP_NORM, "tv_step_norm", },
|
||||
{ MP_CMD_TV_STEP_CHANNEL_LIST, "tv_step_chanlist", },
|
||||
{ MP_CMD_TV_SET_CHANNEL, "tv_set_channel", { ARG_STRING } },
|
||||
{ MP_CMD_TV_LAST_CHANNEL, "tv_last_channel", },
|
||||
{ MP_CMD_TV_SET_FREQ, "tv_set_freq", { ARG_FLOAT } },
|
||||
{ MP_CMD_TV_STEP_FREQ, "tv_step_freq", { ARG_FLOAT } },
|
||||
{ MP_CMD_TV_SET_NORM, "tv_set_norm", { ARG_STRING } },
|
||||
|
||||
{ MP_CMD_DVB_SET_CHANNEL, "dvb_set_channel", { ARG_INT, ARG_INT } },
|
||||
|
||||
{ MP_CMD_SCREENSHOT, "screenshot", {
|
||||
OARG_CHOICE(2, ({"video", 0},
|
||||
|
|
|
@ -46,9 +46,6 @@ enum mp_command_type {
|
|||
MP_CMD_PLAYLIST_NEXT,
|
||||
MP_CMD_PLAYLIST_PREV,
|
||||
MP_CMD_OSD,
|
||||
MP_CMD_TV_STEP_CHANNEL,
|
||||
MP_CMD_TV_STEP_NORM,
|
||||
MP_CMD_TV_STEP_CHANNEL_LIST,
|
||||
MP_CMD_SCREENSHOT,
|
||||
MP_CMD_SCREENSHOT_TO_FILE,
|
||||
MP_CMD_LOADFILE,
|
||||
|
@ -58,10 +55,7 @@ enum mp_command_type {
|
|||
MP_CMD_PLAYLIST_MOVE,
|
||||
MP_CMD_SUB_STEP,
|
||||
MP_CMD_SUB_SEEK,
|
||||
MP_CMD_TV_SET_CHANNEL,
|
||||
MP_CMD_TV_LAST_CHANNEL,
|
||||
MP_CMD_TV_SET_FREQ,
|
||||
MP_CMD_TV_SET_NORM,
|
||||
MP_CMD_FRAME_STEP,
|
||||
MP_CMD_FRAME_BACK_STEP,
|
||||
MP_CMD_RUN,
|
||||
|
@ -77,8 +71,6 @@ enum mp_command_type {
|
|||
MP_CMD_CYCLE,
|
||||
MP_CMD_MULTIPLY,
|
||||
MP_CMD_CYCLE_VALUES,
|
||||
MP_CMD_TV_STEP_FREQ,
|
||||
MP_CMD_TV_START_SCAN,
|
||||
MP_CMD_STOP,
|
||||
|
||||
MP_CMD_ENABLE_INPUT_SECTION,
|
||||
|
@ -86,9 +78,6 @@ enum mp_command_type {
|
|||
|
||||
MP_CMD_DISCNAV,
|
||||
|
||||
/// DVB commands
|
||||
MP_CMD_DVB_SET_CHANNEL,
|
||||
|
||||
/// Audio Filter commands
|
||||
MP_CMD_AF,
|
||||
|
||||
|
|
266
player/command.c
266
player/command.c
|
@ -59,11 +59,6 @@
|
|||
#include "video/decode/dec_video.h"
|
||||
#include "audio/decode/dec_audio.h"
|
||||
#include "options/path.h"
|
||||
#include "stream/tv.h"
|
||||
#include "stream/pvr.h"
|
||||
#if HAVE_DVBIN
|
||||
#include "stream/dvbin.h"
|
||||
#endif
|
||||
#include "screenshot.h"
|
||||
#if HAVE_SYS_MMAN_H
|
||||
#include <sys/mman.h>
|
||||
|
@ -2102,33 +2097,120 @@ static int mp_property_sub_pos(m_option_t *prop, int action, void *arg,
|
|||
return property_osd_helper(prop, action, arg, mpctx);
|
||||
}
|
||||
|
||||
#if HAVE_TV
|
||||
|
||||
static tvi_handle_t *get_tvh(struct MPContext *mpctx)
|
||||
static int demux_stream_control(struct MPContext *mpctx, int ctrl, void *arg)
|
||||
{
|
||||
if (!(mpctx->master_demuxer && mpctx->master_demuxer->type == DEMUXER_TYPE_TV))
|
||||
return NULL;
|
||||
return mpctx->master_demuxer->priv;
|
||||
int r = STREAM_UNSUPPORTED;
|
||||
if (mpctx->stream)
|
||||
r = stream_control(mpctx->stream, ctrl, arg);
|
||||
if (r == STREAM_UNSUPPORTED && mpctx->demuxer) {
|
||||
struct demux_ctrl_stream_ctrl c = {ctrl, arg, STREAM_UNSUPPORTED};
|
||||
demux_control(mpctx->demuxer, DEMUXER_CTRL_STREAM_CTRL, &c);
|
||||
r = c.res;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static int prop_stream_ctrl(struct MPContext *mpctx, int ctrl, void *arg)
|
||||
{
|
||||
int r = demux_stream_control(mpctx, ctrl, arg);
|
||||
switch (r) {
|
||||
case STREAM_OK: return M_PROPERTY_OK;
|
||||
case STREAM_UNSUPPORTED: return M_PROPERTY_UNAVAILABLE;
|
||||
default: return M_PROPERTY_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
static int mp_property_tv_norm(m_option_t *prop, int action, void *arg,
|
||||
MPContext *mpctx)
|
||||
{
|
||||
switch (action) {
|
||||
case M_PROPERTY_SET:
|
||||
return prop_stream_ctrl(mpctx, STREAM_CTRL_TV_SET_NORM, *(char **)arg);
|
||||
case M_PROPERTY_SWITCH:
|
||||
return prop_stream_ctrl(mpctx, STREAM_CTRL_TV_STEP_NORM, NULL);
|
||||
}
|
||||
return M_PROPERTY_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static int mp_property_tv_scan(m_option_t *prop, int action, void *arg,
|
||||
MPContext *mpctx)
|
||||
{
|
||||
switch (action) {
|
||||
case M_PROPERTY_SET:
|
||||
return prop_stream_ctrl(mpctx, STREAM_CTRL_TV_SET_SCAN, arg);
|
||||
}
|
||||
return M_PROPERTY_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/// TV color settings (RW)
|
||||
static int mp_property_tv_color(m_option_t *prop, int action, void *arg,
|
||||
MPContext *mpctx)
|
||||
{
|
||||
tvi_handle_t *tvh = get_tvh(mpctx);
|
||||
if (!tvh)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
|
||||
int req[2] = {prop->offset};
|
||||
switch (action) {
|
||||
case M_PROPERTY_SET:
|
||||
return tv_set_color_options(tvh, prop->offset, *(int *) arg);
|
||||
case M_PROPERTY_GET:
|
||||
return tv_get_color_options(tvh, prop->offset, arg);
|
||||
req[1] = *(int *)arg;
|
||||
return prop_stream_ctrl(mpctx, STREAM_CTRL_SET_TV_COLORS, req);
|
||||
case M_PROPERTY_GET: {
|
||||
int r = prop_stream_ctrl(mpctx, STREAM_CTRL_GET_TV_COLORS, req);
|
||||
if (r == M_PROPERTY_OK)
|
||||
*(int *)arg = req[1];
|
||||
return r;
|
||||
}
|
||||
}
|
||||
return M_PROPERTY_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
#endif
|
||||
static int mp_property_tv_freq(m_option_t *prop, int action, void *arg,
|
||||
MPContext *mpctx)
|
||||
{
|
||||
switch (action) {
|
||||
case M_PROPERTY_SET:
|
||||
return prop_stream_ctrl(mpctx, STREAM_CTRL_SET_TV_FREQ, arg);
|
||||
case M_PROPERTY_GET:
|
||||
return prop_stream_ctrl(mpctx, STREAM_CTRL_GET_TV_FREQ, arg);
|
||||
}
|
||||
return M_PROPERTY_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static int mp_property_tv_channel(m_option_t *prop, int action, void *arg,
|
||||
MPContext *mpctx)
|
||||
{
|
||||
switch (action) {
|
||||
case M_PROPERTY_SET:
|
||||
return prop_stream_ctrl(mpctx, STREAM_CTRL_TV_SET_CHAN, *(char **)arg);
|
||||
case M_PROPERTY_SWITCH: {
|
||||
struct m_property_switch_arg *sa = arg;
|
||||
int dir = sa->inc >= 0 ? 1 : -1;
|
||||
return prop_stream_ctrl(mpctx, STREAM_CTRL_TV_STEP_CHAN, &dir);
|
||||
}
|
||||
}
|
||||
return M_PROPERTY_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static int mp_property_dvb_channel(m_option_t *prop, int action, void *arg,
|
||||
MPContext *mpctx)
|
||||
{
|
||||
int r;
|
||||
switch (action) {
|
||||
case M_PROPERTY_SET:
|
||||
mpctx->last_dvb_step = 1;
|
||||
r = prop_stream_ctrl(mpctx, STREAM_CTRL_DVB_SET_CHANNEL, arg);
|
||||
if (r == M_PROPERTY_OK)
|
||||
mpctx->stop_play = PT_RELOAD_DEMUXER;
|
||||
return r;
|
||||
case M_PROPERTY_SWITCH: {
|
||||
struct m_property_switch_arg *sa = arg;
|
||||
int dir = sa->inc >= 0 ? 1 : -1;
|
||||
mpctx->last_dvb_step = dir;
|
||||
r = prop_stream_ctrl(mpctx, STREAM_CTRL_DVB_STEP_CHANNEL, &dir);
|
||||
if (r == M_PROPERTY_OK)
|
||||
mpctx->stop_play = PT_RELOAD_DEMUXER;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
return M_PROPERTY_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static int mp_property_playlist_pos(m_option_t *prop, int action, void *arg,
|
||||
MPContext *mpctx)
|
||||
|
@ -2490,7 +2572,6 @@ static const m_option_t mp_properties[] = {
|
|||
M_OPTION_PROPERTY_CUSTOM("vf", mp_property_vf),
|
||||
M_OPTION_PROPERTY_CUSTOM("af", mp_property_af),
|
||||
|
||||
#if HAVE_TV
|
||||
{ "tv-brightness", mp_property_tv_color, CONF_TYPE_INT,
|
||||
M_OPT_RANGE, -100, 100, .offset = TV_COLOR_BRIGHTNESS },
|
||||
{ "tv-contrast", mp_property_tv_color, CONF_TYPE_INT,
|
||||
|
@ -2499,7 +2580,12 @@ static const m_option_t mp_properties[] = {
|
|||
M_OPT_RANGE, -100, 100, .offset = TV_COLOR_SATURATION },
|
||||
{ "tv-hue", mp_property_tv_color, CONF_TYPE_INT,
|
||||
M_OPT_RANGE, -100, 100, .offset = TV_COLOR_HUE },
|
||||
#endif
|
||||
{ "tv-freq", mp_property_tv_freq, CONF_TYPE_FLOAT, },
|
||||
{ "tv-norm", mp_property_tv_norm, CONF_TYPE_STRING, },
|
||||
{ "tv-scan", mp_property_tv_scan, CONF_TYPE_FLAG,
|
||||
M_OPT_RANGE, 0, 1 },
|
||||
{ "tv-channel", mp_property_tv_channel, CONF_TYPE_STRING, },
|
||||
{ "dvb-channel", mp_property_dvb_channel, &m_option_type_intpair, },
|
||||
|
||||
M_PROPERTY_ALIAS("video", "vid"),
|
||||
M_PROPERTY_ALIAS("audio", "aid"),
|
||||
|
@ -3432,142 +3518,10 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
|
|||
(bar_osd ? OSD_SEEK_INFO_BAR : 0);
|
||||
break;
|
||||
|
||||
#if HAVE_TV
|
||||
case MP_CMD_TV_START_SCAN:
|
||||
if (get_tvh(mpctx))
|
||||
tv_start_scan(get_tvh(mpctx), 1);
|
||||
case MP_CMD_TV_LAST_CHANNEL: {
|
||||
demux_stream_control(mpctx, STREAM_CTRL_TV_LAST_CHAN, NULL);
|
||||
break;
|
||||
case MP_CMD_TV_SET_FREQ:
|
||||
if (get_tvh(mpctx))
|
||||
tv_set_freq(get_tvh(mpctx), cmd->args[0].v.f * 16.0);
|
||||
#if HAVE_PVR
|
||||
else if (mpctx->stream && mpctx->stream->type == STREAMTYPE_PVR) {
|
||||
pvr_set_freq(mpctx->stream, ROUND(cmd->args[0].v.f));
|
||||
set_osd_msg(mpctx, osdl, osd_duration, "%s: %s",
|
||||
pvr_get_current_channelname(mpctx->stream),
|
||||
pvr_get_current_stationname(mpctx->stream));
|
||||
}
|
||||
#endif /* HAVE_PVR */
|
||||
break;
|
||||
|
||||
case MP_CMD_TV_STEP_FREQ:
|
||||
if (get_tvh(mpctx))
|
||||
tv_step_freq(get_tvh(mpctx), cmd->args[0].v.f * 16.0);
|
||||
#if HAVE_PVR
|
||||
else if (mpctx->stream && mpctx->stream->type == STREAMTYPE_PVR) {
|
||||
pvr_force_freq_step(mpctx->stream, ROUND(cmd->args[0].v.f));
|
||||
set_osd_msg(mpctx, osdl, osd_duration, "%s: f %d",
|
||||
pvr_get_current_channelname(mpctx->stream),
|
||||
pvr_get_current_frequency(mpctx->stream));
|
||||
}
|
||||
#endif /* HAVE_PVR */
|
||||
break;
|
||||
|
||||
case MP_CMD_TV_SET_NORM:
|
||||
if (get_tvh(mpctx))
|
||||
tv_set_norm(get_tvh(mpctx), cmd->args[0].v.s);
|
||||
break;
|
||||
|
||||
case MP_CMD_TV_STEP_CHANNEL:
|
||||
if (get_tvh(mpctx)) {
|
||||
int v = cmd->args[0].v.i;
|
||||
if (v > 0) {
|
||||
tv_step_channel(get_tvh(mpctx), TV_CHANNEL_HIGHER);
|
||||
} else {
|
||||
tv_step_channel(get_tvh(mpctx), TV_CHANNEL_LOWER);
|
||||
}
|
||||
if (tv_channel_list) {
|
||||
set_osd_msg(mpctx, osdl, osd_duration,
|
||||
"Channel: %s", tv_channel_current->name);
|
||||
}
|
||||
}
|
||||
#if HAVE_PVR
|
||||
else if (mpctx->stream &&
|
||||
mpctx->stream->type == STREAMTYPE_PVR) {
|
||||
pvr_set_channel_step(mpctx->stream, cmd->args[0].v.i);
|
||||
set_osd_msg(mpctx, osdl, osd_duration, "%s: %s",
|
||||
pvr_get_current_channelname(mpctx->stream),
|
||||
pvr_get_current_stationname(mpctx->stream));
|
||||
}
|
||||
#endif /* HAVE_PVR */
|
||||
#if HAVE_DVBIN
|
||||
if (mpctx->stream && mpctx->stream->type == STREAMTYPE_DVB) {
|
||||
int dir;
|
||||
int v = cmd->args[0].v.i;
|
||||
|
||||
mpctx->last_dvb_step = v;
|
||||
if (v > 0)
|
||||
dir = DVB_CHANNEL_HIGHER;
|
||||
else
|
||||
dir = DVB_CHANNEL_LOWER;
|
||||
|
||||
|
||||
if (dvb_step_channel(mpctx->stream, dir)) {
|
||||
mpctx->stop_play = PT_RELOAD_DEMUXER;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_DVBIN */
|
||||
break;
|
||||
|
||||
case MP_CMD_TV_SET_CHANNEL:
|
||||
if (get_tvh(mpctx)) {
|
||||
tv_set_channel(get_tvh(mpctx), cmd->args[0].v.s);
|
||||
if (tv_channel_list) {
|
||||
set_osd_msg(mpctx, osdl, osd_duration,
|
||||
"Channel: %s", tv_channel_current->name);
|
||||
}
|
||||
}
|
||||
#if HAVE_PVR
|
||||
else if (mpctx->stream && mpctx->stream->type == STREAMTYPE_PVR) {
|
||||
pvr_set_channel(mpctx->stream, cmd->args[0].v.s);
|
||||
set_osd_msg(mpctx, osdl, osd_duration, "%s: %s",
|
||||
pvr_get_current_channelname(mpctx->stream),
|
||||
pvr_get_current_stationname(mpctx->stream));
|
||||
}
|
||||
#endif /* HAVE_PVR */
|
||||
break;
|
||||
|
||||
#if HAVE_DVBIN
|
||||
case MP_CMD_DVB_SET_CHANNEL:
|
||||
if (mpctx->stream && mpctx->stream->type == STREAMTYPE_DVB) {
|
||||
mpctx->last_dvb_step = 1;
|
||||
|
||||
if (dvb_set_channel(mpctx->stream, cmd->args[1].v.i,
|
||||
cmd->args[0].v.i)) {
|
||||
mpctx->stop_play = PT_RELOAD_DEMUXER;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif /* HAVE_DVBIN */
|
||||
|
||||
case MP_CMD_TV_LAST_CHANNEL:
|
||||
if (get_tvh(mpctx)) {
|
||||
tv_last_channel(get_tvh(mpctx));
|
||||
if (tv_channel_list) {
|
||||
set_osd_msg(mpctx, osdl, osd_duration,
|
||||
"Channel: %s", tv_channel_current->name);
|
||||
}
|
||||
}
|
||||
#if HAVE_PVR
|
||||
else if (mpctx->stream && mpctx->stream->type == STREAMTYPE_PVR) {
|
||||
pvr_set_lastchannel(mpctx->stream);
|
||||
set_osd_msg(mpctx, osdl, osd_duration, "%s: %s",
|
||||
pvr_get_current_channelname(mpctx->stream),
|
||||
pvr_get_current_stationname(mpctx->stream));
|
||||
}
|
||||
#endif /* HAVE_PVR */
|
||||
break;
|
||||
|
||||
case MP_CMD_TV_STEP_NORM:
|
||||
if (get_tvh(mpctx))
|
||||
tv_step_norm(get_tvh(mpctx));
|
||||
break;
|
||||
|
||||
case MP_CMD_TV_STEP_CHANNEL_LIST:
|
||||
if (get_tvh(mpctx))
|
||||
tv_step_chanlist(get_tvh(mpctx));
|
||||
break;
|
||||
#endif /* HAVE_TV */
|
||||
}
|
||||
|
||||
case MP_CMD_SUB_ADD: {
|
||||
struct track *sub = mp_add_subtitles(mpctx, cmd->args[0].v.s);
|
||||
|
|
|
@ -1257,20 +1257,13 @@ goto_reopen_demuxer: ;
|
|||
//==================== START PLAYING =======================
|
||||
|
||||
if (!mpctx->d_video && !mpctx->d_audio) {
|
||||
struct stream *s = mpctx->stream;
|
||||
MP_FATAL(mpctx, "No video or audio streams selected.\n");
|
||||
#if HAVE_DVBIN
|
||||
if (mpctx->stream->type == STREAMTYPE_DVB) {
|
||||
int dir;
|
||||
int v = mpctx->last_dvb_step;
|
||||
if (v > 0)
|
||||
dir = DVB_CHANNEL_HIGHER;
|
||||
else
|
||||
dir = DVB_CHANNEL_LOWER;
|
||||
|
||||
if (dvb_step_channel(mpctx->stream, dir))
|
||||
if (s->uncached_type == STREAMTYPE_DVB) {
|
||||
int dir = mpctx->last_dvb_step;
|
||||
if (stream_control(s, STREAM_CTRL_DVB_STEP_CHANNEL, &dir) > 0)
|
||||
mpctx->stop_play = PT_RELOAD_DEMUXER;
|
||||
}
|
||||
#endif
|
||||
goto terminate_playback;
|
||||
}
|
||||
|
||||
|
|
|
@ -303,7 +303,6 @@ struct MPContext *mp_create(void)
|
|||
|
||||
struct MPContext *mpctx = talloc(NULL, MPContext);
|
||||
*mpctx = (struct MPContext){
|
||||
.last_dvb_step = 1,
|
||||
.last_chapter = -2,
|
||||
.term_osd_contents = talloc_strdup(mpctx, ""),
|
||||
.osd_progbar = { .type = -1 },
|
||||
|
|
|
@ -92,7 +92,19 @@ enum stream_ctrl {
|
|||
STREAM_CTRL_GET_BASE_FILENAME,
|
||||
STREAM_CTRL_GET_NAV_EVENT, // struct mp_nav_event**
|
||||
STREAM_CTRL_NAV_CMD, // struct mp_nav_cmd*
|
||||
STREAM_CTRL_GET_DISC_NAME
|
||||
STREAM_CTRL_GET_DISC_NAME,
|
||||
STREAM_CTRL_TV_SET_SCAN,
|
||||
STREAM_CTRL_SET_TV_FREQ,
|
||||
STREAM_CTRL_GET_TV_FREQ,
|
||||
STREAM_CTRL_SET_TV_COLORS,
|
||||
STREAM_CTRL_GET_TV_COLORS,
|
||||
STREAM_CTRL_TV_SET_NORM,
|
||||
STREAM_CTRL_TV_STEP_NORM,
|
||||
STREAM_CTRL_TV_SET_CHAN,
|
||||
STREAM_CTRL_TV_STEP_CHAN,
|
||||
STREAM_CTRL_TV_LAST_CHAN,
|
||||
STREAM_CTRL_DVB_SET_CHANNEL,
|
||||
STREAM_CTRL_DVB_STEP_CHANNEL,
|
||||
};
|
||||
|
||||
struct stream_lang_req {
|
||||
|
@ -106,6 +118,12 @@ struct stream_dvd_info_req {
|
|||
int num_subs;
|
||||
};
|
||||
|
||||
// for STREAM_CTRL_SET_TV_COLORS
|
||||
#define TV_COLOR_BRIGHTNESS 1
|
||||
#define TV_COLOR_HUE 2
|
||||
#define TV_COLOR_SATURATION 3
|
||||
#define TV_COLOR_CONTRAST 4
|
||||
|
||||
struct stream;
|
||||
typedef struct stream_info_st {
|
||||
const char *name;
|
||||
|
|
|
@ -550,13 +550,26 @@ int dvb_step_channel(stream_t *stream, int dir)
|
|||
return 0;
|
||||
}
|
||||
|
||||
new_current = (list->NUM_CHANNELS + list->current + (dir == DVB_CHANNEL_HIGHER ? 1 : -1)) % list->NUM_CHANNELS;
|
||||
new_current = (list->NUM_CHANNELS + list->current + (dir >= 0 ? 1 : -1)) % list->NUM_CHANNELS;
|
||||
|
||||
return dvb_set_channel(stream, priv->card, new_current);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int dvbin_stream_control(struct stream *s, int cmd, void *arg)
|
||||
{
|
||||
int r;
|
||||
switch (cmd) {
|
||||
case STREAM_CTRL_DVB_SET_CHANNEL: {
|
||||
int *iarg = arg;
|
||||
r = dvb_set_channel(s, iarg[1], iarg[0]);
|
||||
return r ? STREAM_OK : STREAM_ERROR;
|
||||
}
|
||||
case STREAM_CTRL_DVB_STEP_CHANNEL:
|
||||
r = dvb_step_channel(s, *(int *)arg);
|
||||
return r ? STREAM_OK : STREAM_ERROR;
|
||||
}
|
||||
return STREAM_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static void dvbin_close(stream_t *stream)
|
||||
{
|
||||
|
@ -692,6 +705,7 @@ static int dvb_open(stream_t *stream)
|
|||
stream->type = STREAMTYPE_DVB;
|
||||
stream->fill_buffer = dvb_streaming_read;
|
||||
stream->close = dvbin_close;
|
||||
stream->control = dvbin_stream_control;
|
||||
|
||||
stream->demuxer = "lavf";
|
||||
stream->lavf_type = "mpegts";
|
||||
|
|
|
@ -142,6 +142,8 @@ struct pvr_t {
|
|||
int stream_type;
|
||||
};
|
||||
|
||||
static int pvr_stream_control(struct stream *s, int cmd, void *arg);
|
||||
|
||||
static struct pvr_t *
|
||||
pvr_init (void)
|
||||
{
|
||||
|
@ -1608,6 +1610,7 @@ pvr_stream_open (stream_t *stream)
|
|||
stream->type = STREAMTYPE_PVR;
|
||||
stream->fill_buffer = pvr_stream_read;
|
||||
stream->close = pvr_stream_close;
|
||||
stream->control = pvr_stream_control;
|
||||
|
||||
return STREAM_OK;
|
||||
}
|
||||
|
@ -1698,6 +1701,28 @@ pvr_force_freq_step (stream_t *stream, int step)
|
|||
return force_freq_step (pvr, step);
|
||||
}
|
||||
|
||||
static int pvr_stream_control(struct stream *s, int cmd, void *arg)
|
||||
{
|
||||
switch (cmd) {
|
||||
case STREAM_CTRL_SET_TV_FREQ:
|
||||
pvr_set_freq(s, (int)(*(float *)arg + 0.5f));
|
||||
return STREAM_OK;
|
||||
case STREAM_CTRL_GET_TV_FREQ:
|
||||
*(float *)arg = pvr_get_current_frequency(s);
|
||||
return STREAM_OK;
|
||||
case STREAM_CTRL_TV_SET_CHAN:
|
||||
pvr_set_channel(s, (char *)arg);
|
||||
return STREAM_OK;
|
||||
case STREAM_CTRL_TV_STEP_CHAN:
|
||||
pvr_set_channel_step(s, *(int *)arg);
|
||||
return STREAM_OK;
|
||||
case STREAM_CTRL_TV_LAST_CHAN:
|
||||
pvr_set_lastchannel(s);
|
||||
return STREAM_OK;
|
||||
}
|
||||
return STREAM_UNSUPPORTED;
|
||||
}
|
||||
|
||||
const stream_info_t stream_info_pvr = {
|
||||
.name = "pvr",
|
||||
.open = pvr_stream_open,
|
||||
|
|
54
stream/tv.c
54
stream/tv.c
|
@ -1087,9 +1087,58 @@ int tv_step_norm(tvi_handle_t *tvh)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int tv_step_chanlist(tvi_handle_t *tvh)
|
||||
static int tv_stream_control(tvi_handle_t *tvh, int cmd, void *arg)
|
||||
{
|
||||
return 1;
|
||||
switch (cmd) {
|
||||
case STREAM_CTRL_TV_SET_SCAN:
|
||||
tv_start_scan(tvh, *(int *)arg);
|
||||
return STREAM_OK;
|
||||
case STREAM_CTRL_SET_TV_FREQ:
|
||||
tv_set_freq(tvh, *(float *)arg * 16.0f);
|
||||
return STREAM_OK;
|
||||
case STREAM_CTRL_GET_TV_FREQ: {
|
||||
unsigned long tmp = 0;
|
||||
tv_get_freq(tvh, &tmp);
|
||||
*(float *)arg = tmp / 16.0f;
|
||||
return STREAM_OK;
|
||||
}
|
||||
case STREAM_CTRL_SET_TV_COLORS:
|
||||
tv_set_color_options(tvh, ((int *)arg)[0], ((int *)arg)[1]);
|
||||
return STREAM_OK;
|
||||
case STREAM_CTRL_GET_TV_COLORS:
|
||||
tv_get_color_options(tvh, ((int *)arg)[0], &((int *)arg)[1]);
|
||||
return STREAM_OK;
|
||||
case STREAM_CTRL_TV_SET_NORM:
|
||||
tv_set_norm(tvh, (char *)arg);
|
||||
return STREAM_OK;
|
||||
case STREAM_CTRL_TV_STEP_NORM:
|
||||
tv_step_norm(tvh);
|
||||
return STREAM_OK;
|
||||
case STREAM_CTRL_TV_SET_CHAN:
|
||||
tv_set_channel(tvh, (char *)arg);
|
||||
return STREAM_OK;
|
||||
case STREAM_CTRL_TV_STEP_CHAN:
|
||||
if (*(int *)arg >= 0) {
|
||||
tv_step_channel(tvh, TV_CHANNEL_HIGHER);
|
||||
} else {
|
||||
tv_step_channel(tvh, TV_CHANNEL_LOWER);
|
||||
}
|
||||
return STREAM_OK;
|
||||
case STREAM_CTRL_TV_LAST_CHAN:
|
||||
tv_last_channel(tvh);
|
||||
return STREAM_OK;
|
||||
}
|
||||
return STREAM_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static int demux_tv_control(demuxer_t *demuxer, int cmd, void *arg)
|
||||
{
|
||||
tvi_handle_t *tvh=(tvi_handle_t*)(demuxer->priv);
|
||||
if (cmd != DEMUXER_CTRL_STREAM_CTRL)
|
||||
return DEMUXER_CTRL_NOTIMPL;
|
||||
struct demux_ctrl_stream_ctrl *ctrl = arg;
|
||||
ctrl->res = tv_stream_control(tvh, ctrl->ctrl, ctrl->arg);
|
||||
return DEMUXER_CTRL_OK;
|
||||
}
|
||||
|
||||
demuxer_desc_t demuxer_desc_tv = {
|
||||
|
@ -1097,6 +1146,7 @@ demuxer_desc_t demuxer_desc_tv = {
|
|||
.desc = "TV card demuxer",
|
||||
.type = DEMUXER_TYPE_TV,
|
||||
.fill_buffer = demux_tv_fill_buffer,
|
||||
.control = demux_tv_control,
|
||||
.open = demux_open_tv,
|
||||
.close = demux_close_tv,
|
||||
};
|
||||
|
|
|
@ -201,10 +201,6 @@ typedef struct {
|
|||
|
||||
int tv_set_color_options(tvi_handle_t *tvh, int opt, int val);
|
||||
int tv_get_color_options(tvi_handle_t *tvh, int opt, int* val);
|
||||
#define TV_COLOR_BRIGHTNESS 1
|
||||
#define TV_COLOR_HUE 2
|
||||
#define TV_COLOR_SATURATION 3
|
||||
#define TV_COLOR_CONTRAST 4
|
||||
|
||||
int tv_step_channel_real(tvi_handle_t *tvh, int direction);
|
||||
int tv_step_channel(tvi_handle_t *tvh, int direction);
|
||||
|
|
Loading…
Reference in New Issue