From 95f8f18d133d3541c13f2ef2137ecbaf9495d2c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Sun, 17 May 2026 03:50:59 +0200 Subject: [PATCH] demux_mkv: add support for splitting EL track from in-band --- demux/demux_mkv.c | 27 ++++++++++++++++++++++++++- demux/stheader.h | 1 + 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c index f609411927..a6c9a34dd1 100644 --- a/demux/demux_mkv.c +++ b/demux/demux_mkv.c @@ -55,6 +55,7 @@ #include "video/csputils.h" #include "video/mp_image.h" #include "demux.h" +#include "dovi_split.h" #include "packet_pool.h" #include "stheader.h" #include "ebml.h" @@ -166,6 +167,7 @@ typedef struct mkv_track { size_t last_index_entry; AVDOVIDecoderConfigurationRecord *dovi_config; + struct mp_dovi_split *dovi_split; } mkv_track_t; typedef struct mkv_index { @@ -864,6 +866,7 @@ static void demux_mkv_free_trackentry(mkv_track_t *track) { talloc_free(track->parser_tmp); av_freep(&track->dovi_config); + TA_FREEP(&track->dovi_split); talloc_free(track); } @@ -1798,11 +1801,17 @@ static int demux_mkv_open_video(demuxer_t *demuxer, mkv_track_t *track) sh_v->dovi = true; sh_v->dv_level = track->dovi_config->dv_level; sh_v->dv_profile = track->dovi_config->dv_profile; + sh_v->dv_el_present = track->dovi_config->bl_present_flag && + track->dovi_config->el_present_flag; } done: demux_add_sh_stream(demuxer, sh); + // Profile 7 NALU-interleaved + if (sh_v->dv_el_present) + track->dovi_split = mp_dovi_split_create(demuxer, sh); + return 0; } @@ -2745,6 +2754,7 @@ static void mkv_seek_reset(demuxer_t *demuxer) av_parser_close(track->av_parser); track->av_parser = NULL; avcodec_free_context(&track->av_parser_codec); + mp_dovi_split_reset(track->dovi_split); } for (int n = 0; n < mkv_d->num_blocks; n++) @@ -2892,7 +2902,16 @@ static void mkv_parse_and_add_packet(demuxer_t *demuxer, mkv_track_t *track, } if (!track->parse || !track->av_parser || !track->av_parser_codec) { + struct demux_packet *el_dp = NULL; + struct sh_stream *el_sh = NULL; + if (track->dovi_split) { + el_sh = mp_dovi_split_el_stream(track->dovi_split); + if (el_sh && demux_stream_is_selected(el_sh)) + el_dp = mp_dovi_split_dispatch(track->dovi_split, dp); + } add_packet(demuxer, stream, dp); + if (el_dp) + add_packet(demuxer, el_sh, el_dp); return; } @@ -3030,7 +3049,13 @@ static int handle_block(demuxer_t *demuxer, struct block_info *block_info) struct sh_stream *stream = track->stream; bool use_this_block = tc >= mkv_d->skip_to_timecode; - if (!demux_stream_is_selected(stream)) + // Keep BL blocks flowing to feed the Dolby Vision splitter when its + // virtual EL is selected, even if the BL itself isn't selected. + struct sh_stream *split_el = track->dovi_split + ? mp_dovi_split_el_stream(track->dovi_split) + : NULL; + bool need_for_split = split_el && demux_stream_is_selected(split_el); + if (!demux_stream_is_selected(stream) && !need_for_split) return 0; current_pts = tc / 1e9 - track->codec_delay; diff --git a/demux/stheader.h b/demux/stheader.h index 5cfd3f5a24..01754746b2 100644 --- a/demux/stheader.h +++ b/demux/stheader.h @@ -175,6 +175,7 @@ struct mp_codec_params { bool dovi; uint8_t dv_profile; uint8_t dv_level; + bool dv_el_present; // BL and EL interleaved in this stream (Profile 7) // STREAM_VIDEO + STREAM_AUDIO int bits_per_coded_sample;