summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-06-09 23:38:28 +0200
committerwm4 <wm4@nowhere>2014-06-11 00:34:41 +0200
commite033f3c8bcf66de44b0cc25e543a85f19fc9f964 (patch)
tree08cfecb3736fd7b6cc0803a4f28cc8c42651b53f
parent9420eb5a073da434c31f5123dff93c22e5ba32fa (diff)
downloadmpv-e033f3c8bcf66de44b0cc25e543a85f19fc9f964.tar.bz2
mpv-e033f3c8bcf66de44b0cc25e543a85f19fc9f964.tar.xz
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.
-rw-r--r--DOCS/man/en/changes.rst26
-rw-r--r--DOCS/man/en/input.rst7
-rw-r--r--demux/demux.h7
-rw-r--r--etc/input.conf6
-rw-r--r--input/cmd_list.c10
-rw-r--r--input/cmd_list.h11
-rw-r--r--player/command.c260
-rw-r--r--player/loadfile.c15
-rw-r--r--player/main.c1
-rw-r--r--stream/stream.h20
-rw-r--r--stream/stream_dvb.c20
-rw-r--r--stream/stream_pvr.c25
-rw-r--r--stream/tv.c54
-rw-r--r--stream/tv.h4
14 files changed, 259 insertions, 207 deletions
diff --git a/DOCS/man/en/changes.rst b/DOCS/man/en/changes.rst
index a60cced3e6..1387d03372 100644
--- a/DOCS/man/en/changes.rst
+++ b/DOCS/man/en/changes.rst
@@ -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
~~~~~~~~~~
diff --git a/DOCS/man/en/input.rst b/DOCS/man/en/input.rst
index a482437818..d2ad209701 100644
--- a/DOCS/man/en/input.rst
+++ b/DOCS/man/en/input.rst
@@ -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
----------------------
diff --git a/demux/demux.h b/demux/demux.h
index 81568b96b9..2bcfc241c1 100644
--- a/demux/demux.h
+++ b/demux/demux.h
@@ -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)
diff --git a/etc/input.conf b/etc/input.conf
index 321ba71423..fbadd7f0a1 100644
--- a/etc/input.conf
+++ b/etc/input.conf
@@ -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
diff --git a/input/cmd_list.c b/input/cmd_list.c
index 24ef6e7a0e..1096e83d63 100644
--- a/input/cmd_list.c
+++ b/input/cmd_list.c
@@ -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},
diff --git a/input/cmd_list.h b/input/cmd_list.h
index f061814f23..ada1932f8d 100644
--- a/input/cmd_list.h
+++ b/input/cmd_list.h
@@ -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,
diff --git a/player/command.c b/player/command.c
index e2788b76be..315013b0e8 100644
--- a/player/command.c
+++ b/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 int demux_stream_control(struct MPContext *mpctx, int ctrl, void *arg)
+{
+ 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 tvi_handle_t *get_tvh(struct MPContext *mpctx)
+static int prop_stream_ctrl(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 = 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:
+ 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;
+}
+static int mp_property_tv_freq(m_option_t *prop, int action, void *arg,
+ MPContext *mpctx)
+{
switch (action) {
case M_PROPERTY_SET:
- return tv_set_color_options(tvh, prop->offset, *(int *) arg);
+ return prop_stream_ctrl(mpctx, STREAM_CTRL_SET_TV_FREQ, arg);
case M_PROPERTY_GET:
- return tv_get_color_options(tvh, prop->offset, arg);
+ return prop_stream_ctrl(mpctx, STREAM_CTRL_GET_TV_FREQ, arg);
}
return M_PROPERTY_NOT_IMPLEMENTED;
}
-#endif
+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);
- 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));
+ case MP_CMD_TV_LAST_CHANNEL: {
+ demux_stream_control(mpctx, STREAM_CTRL_TV_LAST_CHAN, NULL);
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);
diff --git a/player/loadfile.c b/player/loadfile.c
index cc65aedd6d..26f6c3a0c5 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -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;
}
diff --git a/player/main.c b/player/main.c
index d7b34e0ef8..19c24c036b 100644
--- a/player/main.c
+++ b/player/main.c
@@ -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 },
diff --git a/stream/stream.h b/stream/stream.h
index ec0059e451..ba3f6a4fe0 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -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;
diff --git a/stream/stream_dvb.c b/stream/stream_dvb.c
index cdf282d3ac..c1697ddebd 100644
--- a/stream/stream_dvb.c
+++ b/stream/stream_dvb.c
@@ -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";
diff --git a/stream/stream_pvr.c b/stream/stream_pvr.c
index e45c9005a1..c19e9f05cb 100644
--- a/stream/stream_pvr.c
+++ b/stream/stream_pvr.c
@@ -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,
diff --git a/stream/tv.c b/stream/tv.c
index c7017f4471..c42a81fde1 100644
--- a/stream/tv.c
+++ b/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,
};
diff --git a/stream/tv.h b/stream/tv.h
index 4323762139..c5e8aba91f 100644
--- a/stream/tv.h
+++ b/stream/tv.h
@@ -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);