[FFmpeg-devel] [PATCH] libavformat/hls: Support metadata updates from subdemuxers
wm4
nfxjfg at googlemail.com
Fri Feb 2 08:18:13 EET 2018
On Thu, 1 Feb 2018 18:44:34 -0800
rshaffer at tunein.com wrote:
> From: Richard Shaffer <rshaffer at tunein.com>
>
> If a subdemuxer has the updated metadata event flag set, the metadata is copied
> to the corresponding stream. The flag is cleared on the subdemuxer and the
> appropriate event flag is set on the stream.
> ---
> This is semi-related to a patch I recently sent to enable parsing ID3 tags from
> .aac files between ADTS headers. However, it may be generically useful for
> other segment formats that support metadata updates.
>
> -Richard
>
> libavformat/hls.c | 38 ++++++++++++++++++++++++++++++++++++++
> 1 file changed, 38 insertions(+)
>
> diff --git a/libavformat/hls.c b/libavformat/hls.c
> index 9bd54c84cc..e48845de34 100644
> --- a/libavformat/hls.c
> +++ b/libavformat/hls.c
> @@ -1062,6 +1062,7 @@ static void handle_id3(AVIOContext *pb, struct playlist *pls)
> /* demuxer not yet opened, defer picture attachment */
> pls->id3_deferred_extra = extra_meta;
>
> + ff_id3v2_parse_priv_dict(&metadata, &extra_meta);
> av_dict_copy(&pls->ctx->metadata, metadata, 0);
> pls->id3_initial = metadata;
>
> @@ -1589,6 +1590,34 @@ static void add_metadata_from_renditions(AVFormatContext *s, struct playlist *pl
> }
> }
>
> +/* update metadata on main streams, if necessary */
> +static void update_metadata_from_subdemuxer(struct playlist *pls, int ignore_flags) {
Normally we put the { on a separate line for functions.
> + int i;
> +
> + if (pls->n_main_streams) {
> + AVStream *st = pls->main_streams[0];
> + if (ignore_flags) {
> + av_dict_copy(&st->metadata, pls->ctx->metadata, 0);
> + } else if (pls->ctx->event_flags & AVFMT_EVENT_FLAG_METADATA_UPDATED) {
> + av_dict_copy(&st->metadata, pls->ctx->metadata, 0);
> + pls->ctx->event_flags &= ~AVFMT_EVENT_FLAG_METADATA_UPDATED;
> + st->event_flags |= AVSTREAM_EVENT_FLAG_METADATA_UPDATED;
> + }
I don't get understand this: why only stream 0? Isn't this done below
already?
> + }
> +
> + for (i = 0; i < pls->ctx->nb_streams; i++) {
> + AVStream *ist = pls->ctx->streams[i];
> + AVStream *st = pls->main_streams[i];
> + if (ignore_flags) {
> + av_dict_copy(&st->metadata, ist->metadata, 0);
> + } else if (ist->event_flags & AVSTREAM_EVENT_FLAG_METADATA_UPDATED) {
> + av_dict_copy(&st->metadata, ist->metadata, 0);
> + ist->event_flags &= ~AVSTREAM_EVENT_FLAG_METADATA_UPDATED;
> + st->event_flags |= AVSTREAM_EVENT_FLAG_METADATA_UPDATED;
> + }
> + }
> +}
Like mentioned in the other patch, av_dict_copy not clearing the target
dict might be unintended.
> +
> /* if timestamp was in valid range: returns 1 and sets seq_no
> * if not: returns 0 and sets seq_no to closest segment */
> static int find_timestamp_in_playlist(HLSContext *c, struct playlist *pls,
> @@ -1960,6 +1989,7 @@ static int hls_read_header(AVFormatContext *s)
> if (pls->id3_deferred_extra && pls->ctx->nb_streams == 1) {
> ff_id3v2_parse_apic(pls->ctx, &pls->id3_deferred_extra);
> avformat_queue_attached_pictures(pls->ctx);
> + ff_id3v2_parse_priv(pls->ctx, &pls->id3_deferred_extra);
> ff_id3v2_free_extra_meta(&pls->id3_deferred_extra);
> pls->id3_deferred_extra = NULL;
> }
> @@ -1986,6 +2016,12 @@ static int hls_read_header(AVFormatContext *s)
> if (ret < 0)
> goto fail;
>
> + /*
> + * Copy any metadata from playlist to main streams, but do not set
> + * event flags.
> + */
> + update_metadata_from_subdemuxer(pls, 1);
> +
Possibly would be nicer to drop the ignore_flags parameter, and just
unset the event flag at the end of read_header (maybe even in generic
code).
> add_metadata_from_renditions(s, pls, AVMEDIA_TYPE_AUDIO);
> add_metadata_from_renditions(s, pls, AVMEDIA_TYPE_VIDEO);
> add_metadata_from_renditions(s, pls, AVMEDIA_TYPE_SUBTITLE);
> @@ -2170,6 +2206,8 @@ static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)
> return ret;
> }
>
> + update_metadata_from_subdemuxer(pls, 0);
> +
> /* check if noheader flag has been cleared by the subdemuxer */
> if (pls->has_noheader_flag && !(pls->ctx->ctx_flags & AVFMTCTX_NOHEADER)) {
> pls->has_noheader_flag = 0;
More information about the ffmpeg-devel
mailing list