summaryrefslogtreecommitdiffstats
path: root/demux/demux_lavf.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-08-12 21:39:32 +0200
committerwm4 <wm4@nowhere>2016-08-12 21:39:32 +0200
commitb9ba9a898a9354b52c2154e25a0b5afcb359c5b1 (patch)
tree17c2ff9e075b26165de788e469fe40b44b2bfaba /demux/demux_lavf.c
parente2a54bb1ca319652b8c742877a313e378b24e407 (diff)
downloadmpv-b9ba9a898a9354b52c2154e25a0b5afcb359c5b1.tar.bz2
mpv-b9ba9a898a9354b52c2154e25a0b5afcb359c5b1.tar.xz
demux: add per-track metadata
...and ignore it. The main purpose is for retrieving per-track replaygain tags. Other than that per-track tags are not used or accessed by the playback core yet. The demuxer infrastructure is still not really good with that whole synchronization thing (at least in part due to being inherited from mplayer's single-threaded architecture). A convoluted mechanism is needed to transport the tags from demuxer thread to user thread. Two factors contribute to the complexity: tags can change during playback, and tracks (i.e. struct sh_stream) are not duplicated per thread. In particular, we update the way replaygain tags are retrieved. We first try to use per-track tags (common in Matroska) and global tags (effectively formats like mp3). This part fixes #3405.
Diffstat (limited to 'demux/demux_lavf.c')
-rw-r--r--demux/demux_lavf.c37
1 files changed, 15 insertions, 22 deletions
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index a38fb60435..e28ebd0c23 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -168,7 +168,6 @@ typedef struct lavf_priv {
int num_streams;
int cur_program;
char *mime_type;
- bool merge_track_metadata;
double seek_delay;
} lavf_priv_t;
@@ -502,7 +501,7 @@ static void select_tracks(struct demuxer *demuxer, int start)
}
}
-static void export_replaygain(demuxer_t *demuxer, struct mp_codec_params *c,
+static void export_replaygain(demuxer_t *demuxer, struct sh_stream *sh,
AVStream *st)
{
for (int i = 0; i < st->nb_side_data; i++) {
@@ -528,7 +527,10 @@ static void export_replaygain(demuxer_t *demuxer, struct mp_codec_params *c,
rgain->album_peak = (av_rgain->album_peak != 0.0) ?
av_rgain->album_peak / 100000.0f : 1.0;
- c->replaygain_data = rgain;
+ // This must be run only before the stream was added, otherwise there
+ // will be race conditions with accesses from the user thread.
+ assert(!sh->ds);
+ sh->codec->replaygain_data = rgain;
}
}
@@ -575,7 +577,7 @@ static void handle_new_stream(demuxer_t *demuxer, int i)
delay = lavc_delay / (double)codec->sample_rate;
priv->seek_delay = MPMAX(priv->seek_delay, delay);
- export_replaygain(demuxer, sh->codec, st);
+ export_replaygain(demuxer, sh, st);
break;
}
@@ -681,6 +683,7 @@ static void handle_new_stream(demuxer_t *demuxer, int i)
if (!sh->title && sh->hls_bitrate > 0)
sh->title = talloc_asprintf(sh, "bitrate %d", sh->hls_bitrate);
sh->missing_timestamps = !!(priv->avif_flags & AVFMT_NOTIMESTAMPS);
+ mp_tags_copy_from_av_dictionary(sh->tags, st->metadata);
demux_add_sh_stream(demuxer, sh);
}
@@ -703,14 +706,14 @@ static void update_metadata(demuxer_t *demuxer, AVPacket *pkt)
priv->avfc->event_flags = 0;
demux_changed(demuxer, DEMUX_EVENT_METADATA);
}
- if (priv->merge_track_metadata) {
- for (int n = 0; n < priv->num_streams; n++) {
- AVStream *st = priv->streams[n] ? priv->avfc->streams[n] : NULL;
- if (st && st->event_flags & AVSTREAM_EVENT_FLAG_METADATA_UPDATED) {
- mp_tags_copy_from_av_dictionary(demuxer->metadata, st->metadata);
- st->event_flags = 0;
- demux_changed(demuxer, DEMUX_EVENT_METADATA);
- }
+
+ for (int n = 0; n < priv->num_streams; n++) {
+ AVStream *st = priv->streams[n] ? priv->avfc->streams[n] : NULL;
+ if (st && st->event_flags & AVSTREAM_EVENT_FLAG_METADATA_UPDATED) {
+ st->event_flags = 0;
+ struct mp_tags *tags = talloc_zero(NULL, struct mp_tags);
+ mp_tags_copy_from_av_dictionary(tags, st->metadata);
+ demux_set_stream_tags(demuxer, priv->streams[n], tags);
}
}
}
@@ -846,16 +849,6 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
add_new_streams(demuxer);
- // Often useful with OGG audio-only files, which have metadata in the audio
- // track metadata instead of the main metadata.
- if (demux_get_num_stream(demuxer) == 1) {
- priv->merge_track_metadata = true;
- for (int n = 0; n < priv->num_streams; n++) {
- if (priv->streams[n])
- mp_tags_copy_from_av_dictionary(demuxer->metadata, avfc->streams[n]->metadata);
- }
- }
-
mp_tags_copy_from_av_dictionary(demuxer->metadata, avfc->metadata);
update_metadata(demuxer, NULL);