[vlc-commits] demux: voc: handle creative adpcm and a/ulaw
Francois Cartegnie
git at videolan.org
Wed Apr 15 12:51:04 CEST 2015
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Wed Apr 15 12:47:18 2015 +0200| [e4f45b408696da1e1c3af5d7b1db3c8921c29281] | committer: Francois Cartegnie
demux: voc: handle creative adpcm and a/ulaw
refs samples/A-codecs/CreativeADPCM8bit/
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=e4f45b408696da1e1c3af5d7b1db3c8921c29281
---
NEWS | 1 +
modules/demux/voc.c | 90 ++++++++++++++++++++++++++++++++++++---------------
2 files changed, 65 insertions(+), 26 deletions(-)
diff --git a/NEWS b/NEWS
index 05abf36..3b116ba 100644
--- a/NEWS
+++ b/NEWS
@@ -50,6 +50,7 @@ Demuxers:
* Support for lame's replaygain extension in mpeg files
* Fixes for DTS detection in WAV and MKV files
* Basic support for MPEG4-SL in TS and T-DMB
+ * Support for Creative ADPCM/alaw/ulaw/S16L in VOC files
Stream filter:
* Added ARIB STD-B25 TS streams decoder
diff --git a/modules/demux/voc.c b/modules/demux/voc.c
index 9fe503c..9b0f894 100644
--- a/modules/demux/voc.c
+++ b/modules/demux/voc.c
@@ -187,20 +187,59 @@ static int ReadBlockHeader( demux_t *p_demux )
if( stream_Read( p_demux->s, buf, 2 ) < 2 )
goto corrupt;
- if( buf[1] )
+ switch( buf[1] ) /* codec id */
{
- msg_Err( p_demux, "unsupported compression" );
+ case 0x0:
+ new_fmt.i_codec = VLC_CODEC_U8;
+ new_fmt.audio.i_bytes_per_frame = 1;
+ new_fmt.audio.i_bitspersample = 8;
+ break;
+ case 0x1:
+ new_fmt.i_codec = VLC_CODEC_ADPCM_SBPRO_4;
+ new_fmt.audio.i_bytes_per_frame = 1;
+ new_fmt.audio.i_bitspersample = 4;
+ break;
+ case 0x2:
+ new_fmt.i_codec = VLC_CODEC_ADPCM_SBPRO_3;
+ new_fmt.audio.i_bytes_per_frame = 3;
+ new_fmt.audio.i_bitspersample = 3;
+ break;
+ case 0x3:
+ new_fmt.i_codec = VLC_CODEC_ADPCM_SBPRO_2;
+ new_fmt.audio.i_bytes_per_frame = 1;
+ new_fmt.audio.i_bitspersample = 2;
+ break;
+ case 0x4:
+ new_fmt.i_codec = VLC_CODEC_S16L;
+ new_fmt.audio.i_bytes_per_frame = 2;
+ new_fmt.audio.i_bitspersample = 16;
+ break;
+ case 0x6:
+ new_fmt.i_codec = VLC_CODEC_ALAW;
+ new_fmt.audio.i_bytes_per_frame = 1;
+ new_fmt.audio.i_bitspersample = 8;
+ break;
+ case 0x7:
+ new_fmt.i_codec = VLC_CODEC_MULAW;
+ new_fmt.audio.i_bytes_per_frame = 1;
+ new_fmt.audio.i_bitspersample = 8;
+ break;
+ default:
+ msg_Err( p_demux, "unsupported compression 0x%"PRIx8, buf[1] );
return VLC_EGENERIC;
}
- new_fmt.i_codec = VLC_CODEC_U8;
- new_fmt.audio.i_rate = fix_voc_sr( 1000000L / (256L - buf[0]) );
- new_fmt.audio.i_bytes_per_frame = 1;
- new_fmt.audio.i_frame_length = 1;
new_fmt.audio.i_channels = 1;
- new_fmt.audio.i_blockalign = 1;
- new_fmt.audio.i_bitspersample = 8;
- new_fmt.i_bitrate = new_fmt.audio.i_rate * 8;
+ new_fmt.audio.i_bytes_per_frame *= new_fmt.audio.i_channels;
+ new_fmt.audio.i_blockalign = new_fmt.audio.i_bytes_per_frame;
+
+ new_fmt.audio.i_frame_length = new_fmt.audio.i_bytes_per_frame * 8
+ / new_fmt.audio.i_bitspersample;
+
+ new_fmt.audio.i_rate = fix_voc_sr( 1000000L / (256L - buf[0]) );
+ new_fmt.i_bitrate = new_fmt.audio.i_rate * new_fmt.audio.i_bitspersample
+ * new_fmt.audio.i_channels;
+
break;
case 2: /* data block with same format as the previous one */
@@ -422,12 +461,12 @@ corrupt:
*****************************************************************************
* Returns -1 in case of error, 0 in case of EOF, 1 otherwise
*****************************************************************************/
-#define SAMPLES_BUFFER 1000
+#define MAX_READ_FRAME 1000
static int Demux( demux_t *p_demux )
{
demux_sys_t *p_sys = p_demux->p_sys;
block_t *p_block;
- int64_t i;
+ int64_t i_read_frames;
if( p_sys->i_silence_countdown == 0 )
{
@@ -439,13 +478,14 @@ static int Demux( demux_t *p_demux )
return 1;
}
- i = ( p_sys->i_block_end - i_offset )
- / p_sys->fmt.audio.i_bytes_per_frame;
- if( i > SAMPLES_BUFFER )
- i = SAMPLES_BUFFER;
+ i_read_frames = ( p_sys->i_block_end - i_offset )
+ / p_sys->fmt.audio.i_bytes_per_frame;
+
+ if( i_read_frames > MAX_READ_FRAME )
+ i_read_frames = MAX_READ_FRAME;
p_block = stream_Block( p_demux->s,
- p_sys->fmt.audio.i_bytes_per_frame * i );
+ p_sys->fmt.audio.i_bytes_per_frame * i_read_frames );
if( p_block == NULL )
{
msg_Warn( p_demux, "cannot read data" );
@@ -454,26 +494,24 @@ static int Demux( demux_t *p_demux )
}
else
{ /* emulates silence from the stream */
- i = p_sys->i_silence_countdown;
- if( i > SAMPLES_BUFFER )
- i = SAMPLES_BUFFER;
+ i_read_frames = p_sys->i_silence_countdown;
+ if( i_read_frames > MAX_READ_FRAME )
+ i_read_frames = MAX_READ_FRAME;
- p_block = block_Alloc( i );
+ p_block = block_Alloc( i_read_frames );
if( p_block == NULL )
return VLC_ENOMEM;
- memset( p_block->p_buffer, 0, i );
- p_sys->i_silence_countdown -= i;
+ memset( p_block->p_buffer, 0, i_read_frames );
+ p_sys->i_silence_countdown -= i_read_frames;
}
p_block->i_dts = p_block->i_pts = VLC_TS_0 + date_Get( &p_sys->pts );
-
+ p_block->i_nb_samples = i_read_frames * p_sys->fmt.audio.i_frame_length;
+ date_Increment( &p_sys->pts, p_block->i_nb_samples );
es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts );
-
es_out_Send( p_demux->out, p_sys->p_es, p_block );
- date_Increment( &p_sys->pts, p_sys->fmt.audio.i_frame_length * i );
-
return 1;
}
More information about the vlc-commits
mailing list