From 3f3ffd0de4943a1ce8e5dd1fbf457bcba989fc2b Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 2 Jul 2013 12:18:04 +0200 Subject: 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.) --- core/mp_core.h | 1 + core/mplayer.c | 5 +++++ demux/demux.c | 13 +++++++++++++ demux/demux.h | 3 +++ stream/cache.c | 23 ++++++++++++++++++++++- stream/stream.h | 1 + 6 files changed, 45 insertions(+), 1 deletion(-) 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 @@ -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 -- cgit v1.2.3