summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-07-02 12:18:04 +0200
committerwm4 <wm4@nowhere>2013-07-02 12:19:16 +0200
commit3f3ffd0de4943a1ce8e5dd1fbf457bcba989fc2b (patch)
treef46693b5285f97bc3a24cfed58194caf669b8766
parente00621ac4605e96c9452f4d65216d0019f7e55cb (diff)
downloadmpv-3f3ffd0de4943a1ce8e5dd1fbf457bcba989fc2b.tar.bz2
mpv-3f3ffd0de4943a1ce8e5dd1fbf457bcba989fc2b.tar.xz
core: update metadata during playback, allow streams to export metadata
STREAM_CTRL_GET_METADATA will be used to poll for streamcast metadata. Also add DEMUXER_CTRL_UPDATE_INFO, which could in theory be used by demux_lavf.c. (Unfortunately, libavformat is too crappy to read metadata mid-stream for mp3 or ogg, so we don't implement it.)
-rw-r--r--core/mp_core.h1
-rw-r--r--core/mplayer.c5
-rw-r--r--demux/demux.c13
-rw-r--r--demux/demux.h3
-rw-r--r--stream/cache.c23
-rw-r--r--stream/stream.h1
6 files changed, 45 insertions, 1 deletions
diff --git a/core/mp_core.h b/core/mp_core.h
index 08f84dd817..600c56c4d6 100644
--- a/core/mp_core.h
+++ b/core/mp_core.h
@@ -226,6 +226,7 @@ typedef struct MPContext {
double audio_delay;
double last_heartbeat;
+ double last_metadata_update;
double mouse_timer;
unsigned int mouse_event_ts;
diff --git a/core/mplayer.c b/core/mplayer.c
index b564048560..28d120f636 100644
--- a/core/mplayer.c
+++ b/core/mplayer.c
@@ -3643,6 +3643,11 @@ static void run_playloop(struct MPContext *mpctx)
mp_input_get_cmd(mpctx->input, sleeptime * 1000, true);
}
+ if (mp_time_sec() > mpctx->last_metadata_update + 2) {
+ demux_info_update(mpctx->demuxer);
+ mpctx->last_metadata_update = mp_time_sec();
+ }
+
//================= Keyboard events, SEEKing ====================
handle_pause_on_low_cache(mpctx);
diff --git a/demux/demux.c b/demux/demux.c
index b66f5e3e61..a5d3211b0a 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -976,6 +976,7 @@ static struct demuxer *open_given_type(struct MPOpts *opts,
}
add_stream_chapters(demuxer);
demuxer_sort_chapters(demuxer);
+ demux_info_update(demuxer);
return demuxer;
} else {
// demux_mov can return playlist instead of mov
@@ -1227,6 +1228,18 @@ char *demux_info_get(demuxer_t *demuxer, const char *opt)
return NULL;
}
+void demux_info_update(struct demuxer *demuxer)
+{
+ demux_control(demuxer, DEMUXER_CTRL_UPDATE_INFO, NULL);
+ // Take care of stream metadata as well
+ char **meta;
+ if (stream_control(demuxer->stream, STREAM_CTRL_GET_METADATA, &meta) > 0) {
+ for (int n = 0; meta[n + 0]; n += 2)
+ demux_info_add(demuxer, meta[n + 0], meta[n + 1]);
+ talloc_free(meta);
+ }
+}
+
int demux_control(demuxer_t *demuxer, int cmd, void *arg)
{
diff --git a/demux/demux.h b/demux/demux.h
index f49a236b80..20e6ba7a66 100644
--- a/demux/demux.h
+++ b/demux/demux.h
@@ -93,6 +93,7 @@ enum timestamp_type {
#define DEMUXER_CTRL_OK 1
#define DEMUXER_CTRL_GUESS 2
+#define DEMUXER_CTRL_UPDATE_INFO 8
#define DEMUXER_CTRL_SWITCHED_TRACKS 9
#define DEMUXER_CTRL_GET_TIME_LENGTH 10
#define DEMUXER_CTRL_GET_START_TIME 11
@@ -385,6 +386,8 @@ int demux_info_add_bstr(struct demuxer *demuxer, struct bstr opt,
struct bstr param);
char *demux_info_get(struct demuxer *demuxer, const char *opt);
int demux_info_print(struct demuxer *demuxer);
+void demux_info_update(struct demuxer *demuxer);
+
int demux_control(struct demuxer *demuxer, int cmd, void *arg);
void demuxer_switch_track(struct demuxer *demuxer, enum stream_type type,
diff --git a/stream/cache.c b/stream/cache.c
index f30130ae35..4015aae82c 100644
--- a/stream/cache.c
+++ b/stream/cache.c
@@ -31,7 +31,7 @@
// Time in seconds the cache updates "cached" controls. Note that idle mode
// will block the cache from doing this, and this timeout is honored only if
// the cache is active.
-#define CACHE_UPDATE_CONTROLS_TIME 0.1
+#define CACHE_UPDATE_CONTROLS_TIME 2.0
#include <stdio.h>
@@ -102,6 +102,7 @@ struct priv {
unsigned int stream_num_chapters;
int stream_cache_idle;
int stream_cache_fill;
+ char **stream_metadata;
};
// Store additional per-byte metadata. Since per-byte would be way too
@@ -306,6 +307,7 @@ static void update_cached_controls(struct priv *s)
{
unsigned int ui;
double d;
+ char **m;
s->stream_time_length = 0;
if (stream_control(s->stream, STREAM_CTRL_GET_TIME_LENGTH, &d) == STREAM_OK)
s->stream_time_length = d;
@@ -318,6 +320,10 @@ static void update_cached_controls(struct priv *s)
s->stream_num_chapters = 0;
if (stream_control(s->stream, STREAM_CTRL_GET_NUM_CHAPTERS, &ui) == STREAM_OK)
s->stream_num_chapters = ui;
+ if (stream_control(s->stream, STREAM_CTRL_GET_METADATA, &m) == STREAM_OK) {
+ talloc_free(s->stream_metadata);
+ s->stream_metadata = talloc_steal(s, m);
+ }
stream_update_size(s->stream);
s->stream_size = s->stream->end_pos;
}
@@ -368,6 +374,21 @@ static int cache_get_cached_control(stream_t *cache, int cmd, void *arg)
}
return STREAM_UNSUPPORTED;
}
+ case STREAM_CTRL_GET_METADATA: {
+ if (s->stream_metadata && s->stream_metadata[0]) {
+ char **m = talloc_new(NULL);
+ int num_m = 0;
+ for (int n = 0; s->stream_metadata[n]; n++) {
+ char *t = talloc_strdup(m, s->stream_metadata[n]);
+ MP_TARRAY_APPEND(NULL, m, num_m, t);
+ }
+ MP_TARRAY_APPEND(NULL, m, num_m, NULL);
+ MP_TARRAY_APPEND(NULL, m, num_m, NULL);
+ *(char ***)arg = m;
+ return STREAM_OK;
+ }
+ return STREAM_UNSUPPORTED;
+ }
}
return STREAM_ERROR;
}
diff --git a/stream/stream.h b/stream/stream.h
index 1bcd97bed1..d5400470d3 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -103,6 +103,7 @@
#define STREAM_CTRL_GET_CHAPTER_TIME 21
#define STREAM_CTRL_GET_DVD_INFO 22
#define STREAM_CTRL_SET_CONTENTS 23
+#define STREAM_CTRL_GET_METADATA 24
struct stream_lang_req {
int type; // STREAM_AUDIO, STREAM_SUB