[vlc-commits] [Git][videolan/vlc][master] 5 commits: codec: adpcm: fix ADPCM_IMA_QT samplesperblock
François Cartegnie (@fcartegnie)
gitlab at videolan.org
Fri Jul 24 11:02:01 UTC 2026
François Cartegnie pushed to branch master at VideoLAN / VLC
Commits:
f400deaf by François Cartegnie at 2026-07-24T12:38:12+02:00
codec: adpcm: fix ADPCM_IMA_QT samplesperblock
refs #29971
Reported-by: HE WEI (ギカク) <skyexpoc at gmail.com>
- - - - -
44a3ca9e by François Cartegnie at 2026-07-24T12:38:12+02:00
codec: adpcm: fix DK3 samplesperblock
- - - - -
16a4358b by François Cartegnie at 2026-07-24T12:38:12+02:00
codec: adpcm: fix EA ADPCM decoded samples boundary
limited by block aligned allocs
- - - - -
bdcb6522 by François Cartegnie at 2026-07-24T12:38:12+02:00
codec: adpcm: fix IMA WAV samplesperblock
- - - - -
9a8f0a76 by François Cartegnie at 2026-07-24T12:38:12+02:00
codec: adpcm: add some more codec description
- - - - -
1 changed file:
- modules/codec/adpcm.c
Changes:
=====================================
modules/codec/adpcm.c
=====================================
@@ -211,16 +211,26 @@ static int OpenDecoder( vlc_object_t *p_this )
switch( p_sys->codec )
{
case ADPCM_IMA_QT:
- p_sys->i_samplesperblock = 64;
+ if( p_sys->i_block >= 34 * i_channels )
+ p_sys->i_samplesperblock = (p_sys->i_block / (34 * i_channels) ) * 64;
break;
case ADPCM_IMA_WAV:
- if( p_sys->i_block >= 4 * i_channels )
+ /* 4 bytes block/channel preamble */
+ /* samples: 4 bytes aligned nibble per channel. 2 samples per byte */
+ if( i_channels == 2 && p_sys->i_block >= ((4+4) * 2) )
+ {
+ size_t padding = p_sys->i_block % 8;
+ p_sys->i_samplesperblock = 2 * ( p_sys->i_block - 4 * i_channels - padding )
+ / i_channels;
+ }
+ else if( i_channels == 1 && p_sys->i_block > 4 )
{
- p_sys->i_samplesperblock = 2 * ( p_sys->i_block - 4 * i_channels )
+ p_sys->i_samplesperblock = 2 * ( p_sys->i_block - 4 )
/ i_channels;
}
break;
case ADPCM_MS:
+ /* 7 bytes block/channel preamble outputs 2 samples */
if( p_sys->i_block >= 7 * i_channels )
{
p_sys->i_samplesperblock =
@@ -228,6 +238,7 @@ static int OpenDecoder( vlc_object_t *p_this )
}
break;
case ADPCM_DK4:
+ /* 4 bytes block/channel preamble outputs 1 sample */
if( p_sys->i_block >= 4 * i_channels )
{
p_sys->i_samplesperblock =
@@ -235,12 +246,19 @@ static int OpenDecoder( vlc_object_t *p_this )
}
break;
case ADPCM_DK3:
+ /* 16 bytes block (2 channels) preamble outputs 1 sample */
+ /* 3 ADPCM nibbles decodes to 4 16-bit PCM samples. Only stereo */
i_channels = 2;
- if( p_sys->i_block >= 16 )
- p_sys->i_samplesperblock = ( 4 * ( p_sys->i_block - 16 ) + 2 )/ 3;
+ if( p_sys->i_block > 16 )
+ {
+ size_t i_payload = p_sys->i_block - 16;
+ p_sys->i_samplesperblock = 4 * ( i_payload / 3 );
+ if( i_payload % 3 == 2 )
+ p_sys->i_samplesperblock += 2;
+ }
break;
case ADPCM_EA:
- if( p_sys->i_block >= i_channels )
+ if( p_sys->i_block > i_channels )
{
p_sys->i_samplesperblock =
2 * (p_sys->i_block - i_channels) / i_channels;
@@ -571,7 +589,7 @@ static void DecodeAdpcmImaWav( decoder_t *p_dec, int16_t *p_sample,
if( b_stereo )
{
for( i_nibbles = 2 * (p_sys->i_block - 8);
- i_nibbles > 0;
+ i_nibbles > 15;
i_nibbles -= 16 )
{
int i;
@@ -617,35 +635,38 @@ static void DecodeAdpcmImaWav( decoder_t *p_dec, int16_t *p_sample,
static void DecodeAdpcmImaQT( decoder_t *p_dec, int16_t *p_sample,
uint8_t *p_buffer )
{
+ decoder_sys_t *p_sys = p_dec->p_sys;
adpcm_ima_wav_channel_t channel[2];
int i_nibbles;
int i_ch;
- int i_step;
+ int i_chans = p_dec->fmt_out.audio.i_channels;
- i_step = p_dec->fmt_out.audio.i_channels;
-
- for( i_ch = 0; i_ch < p_dec->fmt_out.audio.i_channels; i_ch++ )
+ for( unsigned i=0; i<p_sys->i_block/(34 * i_chans); i++)
{
- /* load preamble */
- channel[i_ch].i_predictor = (int16_t)((( ( p_buffer[0] << 1 )|( p_buffer[1] >> 7 ) ))<<7);
- channel[i_ch].i_step_index = p_buffer[1]&0x7f;
+ for( i_ch = 0; i_ch < p_dec->fmt_out.audio.i_channels; i_ch++ )
+ {
+ int16_t *p_out = &p_sample[i_ch];
- CLAMP( channel[i_ch].i_step_index, 0, 88 );
- p_buffer += 2;
+ /* load preamble */
+ channel[i_ch].i_predictor = (int16_t)((( ( p_buffer[0] << 1 )|( p_buffer[1] >> 7 ) ))<<7);
+ channel[i_ch].i_step_index = p_buffer[1]&0x7f;
- for( i_nibbles = 0; i_nibbles < 64; i_nibbles +=2 )
- {
- *p_sample = AdpcmImaWavExpandNibble( &channel[i_ch], (*p_buffer)&0x0f);
- p_sample += i_step;
+ CLAMP( channel[i_ch].i_step_index, 0, 88 );
+ p_buffer += 2;
+
+ for( i_nibbles = 0; i_nibbles < 64; i_nibbles +=2 )
+ {
+ *p_out = AdpcmImaWavExpandNibble( &channel[i_ch], (*p_buffer)&0x0f);
+ p_out += i_chans;
- *p_sample = AdpcmImaWavExpandNibble( &channel[i_ch], (*p_buffer >> 4)&0x0f);
- p_sample += i_step;
+ *p_out = AdpcmImaWavExpandNibble( &channel[i_ch], (*p_buffer >> 4)&0x0f);
+ p_out += i_chans;
- p_buffer++;
+ p_buffer++;
+ }
}
- /* Next channel */
- p_sample += 1 - 64 * i_step;
+ p_sample += 64 * i_chans;
}
}
@@ -714,9 +735,12 @@ static void DecodeAdpcmDk3( decoder_t *p_dec, int16_t *p_sample,
GetByte( sum.i_step_index );
GetByte( diff.i_step_index );
+ CLAMP( sum.i_step_index, 0, 88 );
+ CLAMP( diff.i_step_index, 0, 88 );
+
i_diff_value = diff.i_predictor;
/* we process 6 nibbles at once */
- while( p_buffer + 1 <= p_end )
+ while( p_buffer + 1 < p_end )
{
/* first 3 nibbles */
AdpcmImaWavExpandNibble( &sum,
@@ -794,7 +818,7 @@ static void DecodeAdpcmEA( decoder_t *p_dec, int16_t *p_sample,
d[c] = (input & 0xf) + 8;
}
- for (p_buffer += chans; p_buffer < p_end; p_buffer += chans)
+ for (p_buffer += chans; p_buffer + chans <= p_end; p_buffer += chans)
{
union { uint32_t u; int32_t i; } spl;
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/b8105da78375c2c7e7d221e4ace091488a6dcd44...9a8f0a76ad639247188821ba3fc7395abde1850a
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/b8105da78375c2c7e7d221e4ace091488a6dcd44...9a8f0a76ad639247188821ba3fc7395abde1850a
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