summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-07-30 02:21:35 +0200
committerwm4 <wm4@nowhere>2014-07-30 02:21:51 +0200
commit6856d81c6826e9698fe0154903f509d5a82917bb (patch)
tree65c0f0dc2a0452764dd464c3c88c8b46278ec606
parent26d973ce827555619405bf62db24bf4ae12a4a90 (diff)
downloadmpv-6856d81c6826e9698fe0154903f509d5a82917bb.tar.bz2
mpv-6856d81c6826e9698fe0154903f509d5a82917bb.tar.xz
stream: hack-fix rtmp-level seeking
This didn't work, because the timebase was wrong. According to the ffmpeg doxygen, if the stream index is -1 (which is what we used), the timebase is AV_TIME_BASE. But this didn't work, and it really expected the stream's timebase. Quite "surprising", since this feature (avio_seek_time) is used by rtmp only. Fixing this properly is too hard, so hack-fix our way around it. STREAM_CTRL_SEEK_TO_TIME is also used by DVD/BD, so a new STREAM_CTRL_AVSEEK is added. We simply pass-through the request verbatim.
-rw-r--r--demux/demux_lavf.c11
-rw-r--r--stream/cache.c1
-rw-r--r--stream/stream.h8
-rw-r--r--stream/stream_lavf.c13
4 files changed, 22 insertions, 11 deletions
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index 9a44e9ac35..41263ceabf 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -183,11 +183,14 @@ static int64_t mp_read_seek(void *opaque, int stream_idx, int64_t ts, int flags)
{
struct demuxer *demuxer = opaque;
struct stream *stream = demuxer->stream;
- struct lavf_priv *priv = demuxer->priv;
- AVStream *st = priv->avfc->streams[stream_idx];
- double pts = (double)ts * st->time_base.num / st->time_base.den;
- int ret = stream_control(stream, STREAM_CTRL_SEEK_TO_TIME, &pts);
+ struct stream_avseek cmd = {
+ .stream_index = stream_idx,
+ .timestamp = ts,
+ .flags = flags,
+ };
+
+ int ret = stream_control(stream, STREAM_CTRL_AVSEEK, &cmd);
return ret < 1 ? AVERROR(ENOSYS) : 0;
}
diff --git a/stream/cache.c b/stream/cache.c
index b1b3c9301f..6bd729c6fa 100644
--- a/stream/cache.c
+++ b/stream/cache.c
@@ -412,6 +412,7 @@ static bool control_needs_flush(int stream_ctrl)
{
switch (stream_ctrl) {
case STREAM_CTRL_SEEK_TO_TIME:
+ case STREAM_CTRL_AVSEEK:
case STREAM_CTRL_SET_ANGLE:
case STREAM_CTRL_SET_CURRENT_TITLE:
return true;
diff --git a/stream/stream.h b/stream/stream.h
index 344e8b55ef..2cd3d9f5fa 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -101,6 +101,7 @@ enum stream_ctrl {
STREAM_CTRL_TV_LAST_CHAN,
STREAM_CTRL_DVB_SET_CHANNEL,
STREAM_CTRL_DVB_STEP_CHANNEL,
+ STREAM_CTRL_AVSEEK,
};
struct stream_lang_req {
@@ -120,6 +121,13 @@ struct stream_dvd_info_req {
#define TV_COLOR_SATURATION 3
#define TV_COLOR_CONTRAST 4
+// for STREAM_CTRL_AVSEEK
+struct stream_avseek {
+ int stream_index;
+ int64_t timestamp;
+ int flags;
+};
+
struct stream;
typedef struct stream_info_st {
const char *name;
diff --git a/stream/stream_lavf.c b/stream/stream_lavf.c
index c736ade45f..8d8ceb3f94 100644
--- a/stream/stream_lavf.c
+++ b/stream/stream_lavf.c
@@ -101,8 +101,7 @@ static int control(stream_t *s, int cmd, void *arg)
AVIOContext *avio = s->priv;
if (!avio && cmd != STREAM_CTRL_RECONNECT)
return -1;
- int64_t size, ts;
- double pts;
+ int64_t size;
switch(cmd) {
case STREAM_CTRL_GET_SIZE:
size = avio_size(avio);
@@ -111,13 +110,13 @@ static int control(stream_t *s, int cmd, void *arg)
return 1;
}
break;
- case STREAM_CTRL_SEEK_TO_TIME:
- pts = *(double *)arg;
- ts = pts * AV_TIME_BASE;
- ts = avio_seek_time(avio, -1, ts, 0);
- if (ts >= 0)
+ case STREAM_CTRL_AVSEEK: {
+ struct stream_avseek *c = arg;
+ int64_t r = avio_seek_time(avio, c->stream_index, c->timestamp, c->flags);
+ if (r >= 0)
return 1;
break;
+ }
case STREAM_CTRL_GET_METADATA: {
*(struct mp_tags **)arg = read_icy(s);
if (!*(struct mp_tags **)arg)