[vlc-commits] [Git][videolan/vlc][master] 4 commits: demux: mkv: do not call getChannelMask() with an empty mask

Steve Lhomme (@robUx4) gitlab at videolan.org
Thu Aug 27 11:25:07 UTC 2026



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
ba76c8f1 by Steve Lhomme at 2026-08-27T11:13:59+00:00
demux: mkv: do not call getChannelMask() with an empty mask

It will return a match of 0 which is not valid.

- - - - -
cfb23590 by Steve Lhomme at 2026-08-27T11:13:59+00:00
demux: mkv: adjust indentation

No functional changes.

- - - - -
8bca8c90 by Steve Lhomme at 2026-08-27T11:13:59+00:00
demux: mkv: apply the default mask if not set

Similar to 277c4076cc5625efd50faaf0de0e8c36dc606276.

- - - - -
6061ca97 by Steve Lhomme at 2026-08-27T11:13:59+00:00
demux: mkv: verify the computed match is valid

Similar to what is done in wav.c we reset the channel mask if it's not.

- - - - -


1 changed file:

- modules/demux/mkv/matroska_segment_parse.cpp


Changes:

=====================================
modules/demux/mkv/matroska_segment_parse.cpp
=====================================
@@ -1978,46 +1978,76 @@ bool matroska_segment_c::TrackInit( mkv_track_t * p_tk )
                     if( p_tk->fmt.audio.i_channels > 2 &&
                         ( p_tk->fmt.i_codec != VLC_CODEC_UNKNOWN ) )
                     {
+                        unsigned i_channel_mask = 0;
                         uint32_t wfextcm = GetDWLE( p_tk->p_extra_data + offsetof(WAVEFORMATEXTENSIBLE, dwChannelMask) );
-                        int match;
-                        unsigned i_channel_mask = getChannelMask( &wfextcm,
-                                                                  p_tk->fmt.audio.i_channels,
-                                                                  &match );
-
-                        if( match < p_fmt->audio.i_channels )
+                        if (wfextcm)
                         {
-                            int i_missing = p_fmt->audio.i_channels - match;
-                            msg_Warn( vars.p_demuxer, "Trying to fill up unspecified position for %d channels", p_fmt->audio.i_channels - match );
-
-                            static const uint32_t pi_pair[] = { AOUT_CHAN_REARLEFT|AOUT_CHAN_REARRIGHT,
-                                                                AOUT_CHAN_MIDDLELEFT|AOUT_CHAN_MIDDLERIGHT,
-                                                                AOUT_CHAN_LEFT|AOUT_CHAN_RIGHT };
+                            int match;
+                            i_channel_mask = getChannelMask( &wfextcm,
+                                                             p_tk->fmt.audio.i_channels,
+                                                             &match );
 
-                            /* Try to complete with pair */
-                            for( unsigned i = 0; i < ARRAY_SIZE(pi_pair); i++ )
+                            if( match < p_fmt->audio.i_channels )
                             {
-                                if( i_missing >= 2 && !(i_channel_mask & pi_pair[i] ) )
+                                int i_missing = p_fmt->audio.i_channels - match;
+                                msg_Warn( vars.p_demuxer, "Trying to fill up unspecified position for %d channels", p_fmt->audio.i_channels - match );
+
+                                static const uint32_t pi_pair[] = { AOUT_CHAN_REARLEFT|AOUT_CHAN_REARRIGHT,
+                                                                    AOUT_CHAN_MIDDLELEFT|AOUT_CHAN_MIDDLERIGHT,
+                                                                    AOUT_CHAN_LEFT|AOUT_CHAN_RIGHT };
+
+                                /* Try to complete with pair */
+                                for( unsigned i = 0; i < ARRAY_SIZE(pi_pair); i++ )
                                 {
-                                    i_missing -= 2;
-                                    i_channel_mask |= pi_pair[i];
+                                    if( i_missing >= 2 && !(i_channel_mask & pi_pair[i] ) )
+                                    {
+                                        i_missing -= 2;
+                                        i_channel_mask |= pi_pair[i];
+                                    }
                                 }
-                            }
-                            /* Well fill up with what we can */
-                            for( unsigned i = 0; i < ARRAY_SIZE(pi_channels_aout) && i_missing > 0; i++ )
-                            {
-                                if( !( i_channel_mask & pi_channels_aout[i] ) )
+                                /* Well fill up with what we can */
+                                for( unsigned i = 0; i < ARRAY_SIZE(pi_channels_aout) && i_missing > 0; i++ )
                                 {
-                                    i_channel_mask |= pi_channels_aout[i];
-                                    i_missing--;
-
-                                    if( i_missing <= 0 )
-                                        break;
+                                    if( !( i_channel_mask & pi_channels_aout[i] ) )
+                                    {
+                                        i_channel_mask |= pi_channels_aout[i];
+                                        i_missing--;
+
+                                        if( i_missing <= 0 )
+                                            break;
+                                    }
                                 }
+
+                                match = p_fmt->audio.i_channels - i_missing;
+                            }
+                            if( match < p_fmt->audio.i_channels )
+                            {
+                                msg_Err( vars.p_demuxer, "Invalid/unsupported channel mask" );
+                                i_channel_mask = 0;
                             }
+                        }
 
-                            match = p_fmt->audio.i_channels - i_missing;
+                        if( i_channel_mask == 0 && p_fmt->audio.i_channels <= AOUT_CHAN_MAX )
+                        {
+                            /* A dwChannelMask of 0 tells the audio device to render the first
+                             * channel to the first port on the device, the second channel to the
+                             * second port on the device, and so on. pi_default_channels is
+                             * different than pi_channels_aout. Indeed FLC/FRC must be treated a
+                             * SL/SR in that case. See "Default Channel Ordering" and "Details
+                             * about dwChannelMask" from msdn */
+
+                            static const uint32_t pi_default_channels[] = {
+                                AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER,
+                                AOUT_CHAN_LFE, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT,
+                                AOUT_CHAN_MIDDLELEFT, AOUT_CHAN_MIDDLERIGHT, AOUT_CHAN_REARCENTER };
+
+                            for( unsigned i = 0; i < p_fmt->audio.i_channels &&
+                                 i < ARRAY_SIZE(pi_default_channels);
+                                 i++ )
+                                i_channel_mask |= pi_default_channels[i];
                         }
 
+
                         p_tk->fmt.i_codec = vlc_fourcc_GetCodecAudio( p_tk->fmt.i_codec,
                                                                       p_tk->fmt.audio.i_bitspersample );
                         if( i_channel_mask )



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/17dabd7ed47712c1beebd3b99c75d0b993e51ce6...6061ca97d97f3f14303c6ae99490f49525da0c7d

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/17dabd7ed47712c1beebd3b99c75d0b993e51ce6...6061ca97d97f3f14303c6ae99490f49525da0c7d
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help




More information about the vlc-commits mailing list