Commit 54b29b2b authored by Laurent Aimar's avatar Laurent Aimar

* transcode: should be able to compress raw audio, need to be cleaned up.

 u8,s8,s16 big and little endian should be supported but not all tested.
parent cb5d09cd
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* transcode.c * transcode.c
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * Copyright (C) 2001, 2002 VideoLAN
* $Id: transcode.c,v 1.6 2003/05/02 03:41:03 fenrir Exp $ * $Id: transcode.c,v 1.7 2003/05/02 14:51:57 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -487,34 +487,49 @@ static int transcode_audio_ffmpeg_new ( sout_stream_t *p_stream, sout_stream_i ...@@ -487,34 +487,49 @@ static int transcode_audio_ffmpeg_new ( sout_stream_t *p_stream, sout_stream_i
{ {
int i_ff_codec; int i_ff_codec;
/* find decoder */ if( id->f_src.i_fourcc == VLC_FOURCC('s','1','6','l') ||
id->f_src.i_fourcc == VLC_FOURCC('s','1','6','b') ||
i_ff_codec = get_ff_codec( id->f_src.i_fourcc ); id->f_src.i_fourcc == VLC_FOURCC('s','8',' ',' ') ||
if( i_ff_codec == 0 ) id->f_src.i_fourcc == VLC_FOURCC('u','8',' ',' ') )
{ {
msg_Err( p_stream, "cannot find decoder" ); id->ff_dec = NULL;
return VLC_EGENERIC;
}
id->ff_dec = avcodec_find_decoder( i_ff_codec ); id->ff_dec_c = avcodec_alloc_context();
if( !id->ff_dec ) id->ff_dec_c->sample_rate = id->f_src.i_sample_rate;
{ id->ff_dec_c->channels = id->f_src.i_channels;
msg_Err( p_stream, "cannot find decoder" ); id->ff_dec_c->block_align = id->f_src.i_block_align;
return VLC_EGENERIC; id->ff_dec_c->bit_rate = id->f_src.i_bitrate;
} }
else
{
/* find decoder */
i_ff_codec = get_ff_codec( id->f_src.i_fourcc );
if( i_ff_codec == 0 )
{
msg_Err( p_stream, "cannot find decoder" );
return VLC_EGENERIC;
}
id->ff_dec_c = avcodec_alloc_context(); id->ff_dec = avcodec_find_decoder( i_ff_codec );
id->ff_dec_c->sample_rate = id->f_src.i_sample_rate; if( !id->ff_dec )
id->ff_dec_c->channels = id->f_src.i_channels; {
id->ff_dec_c->block_align = id->f_src.i_block_align; msg_Err( p_stream, "cannot find decoder" );
id->ff_dec_c->bit_rate = id->f_src.i_bitrate; return VLC_EGENERIC;
}
id->ff_dec_c->extradata_size = id->f_src.i_extra_data; id->ff_dec_c = avcodec_alloc_context();
id->ff_dec_c->extradata = id->f_src.p_extra_data; id->ff_dec_c->sample_rate = id->f_src.i_sample_rate;
if( avcodec_open( id->ff_dec_c, id->ff_dec ) ) id->ff_dec_c->channels = id->f_src.i_channels;
{ id->ff_dec_c->block_align = id->f_src.i_block_align;
msg_Err( p_stream, "cannot open decoder" ); id->ff_dec_c->bit_rate = id->f_src.i_bitrate;
return VLC_EGENERIC;
id->ff_dec_c->extradata_size = id->f_src.i_extra_data;
id->ff_dec_c->extradata = id->f_src.p_extra_data;
if( avcodec_open( id->ff_dec_c, id->ff_dec ) )
{
msg_Err( p_stream, "cannot open decoder" );
return VLC_EGENERIC;
}
} }
/* find encoder */ /* find encoder */
...@@ -561,7 +576,10 @@ static int transcode_audio_ffmpeg_new ( sout_stream_t *p_stream, sout_stream_i ...@@ -561,7 +576,10 @@ static int transcode_audio_ffmpeg_new ( sout_stream_t *p_stream, sout_stream_i
static void transcode_audio_ffmpeg_close ( sout_stream_t *p_stream, sout_stream_id_t *id ) static void transcode_audio_ffmpeg_close ( sout_stream_t *p_stream, sout_stream_id_t *id )
{ {
avcodec_close( id->ff_dec_c ); if( id->ff_dec )
{
avcodec_close( id->ff_dec_c );
}
avcodec_close( id->ff_enc_c ); avcodec_close( id->ff_enc_c );
free( id->ff_dec_c ); free( id->ff_dec_c );
...@@ -581,44 +599,131 @@ static int transcode_audio_ffmpeg_process( sout_stream_t *p_stream, sout_stream_ ...@@ -581,44 +599,131 @@ static int transcode_audio_ffmpeg_process( sout_stream_t *p_stream, sout_stream_
(mtime_t)(id->i_buffer_pos / 2 / id->ff_enc_c->channels )/ (mtime_t)(id->i_buffer_pos / 2 / id->ff_enc_c->channels )/
(mtime_t)id->ff_enc_c->sample_rate; (mtime_t)id->ff_enc_c->sample_rate;
if( id->i_buffer_in_pos + in->i_size > id->i_buffer_in )
{
/* extend buffer_in */
id->i_buffer_in = id->i_buffer_in_pos + in->i_size + 1024;
id->p_buffer_in = realloc( id->p_buffer_in, id->i_buffer_in );
}
memcpy( &id->p_buffer_in[id->i_buffer_in_pos], memcpy( &id->p_buffer_in[id->i_buffer_in_pos],
in->p_buffer, in->p_buffer,
in->i_size ); in->i_size );
id->i_buffer_in_pos += in->i_size; id->i_buffer_in_pos += in->i_size;
/* decode as many data as possible */ /* decode as many data as possible */
for( ;; ) if( id->ff_dec )
{ {
int i_buffer_size; for( ;; )
int i_used; {
int i_buffer_size;
int i_used;
i_buffer_size = id->i_buffer - id->i_buffer_pos; i_buffer_size = id->i_buffer - id->i_buffer_pos;
i_used = avcodec_decode_audio( id->ff_dec_c, i_used = avcodec_decode_audio( id->ff_dec_c,
(int16_t*)&id->p_buffer[id->i_buffer_pos], &i_buffer_size, (int16_t*)&id->p_buffer[id->i_buffer_pos], &i_buffer_size,
id->p_buffer_in, id->i_buffer_in_pos ); id->p_buffer_in, id->i_buffer_in_pos );
/* msg_Warn( p_stream, "avcodec_decode_audio: %d used", i_used ); */ /* msg_Warn( p_stream, "avcodec_decode_audio: %d used", i_used ); */
id->i_buffer_pos += i_buffer_size; id->i_buffer_pos += i_buffer_size;
if( i_used < 0 ) if( i_used < 0 )
{
msg_Warn( p_stream, "error");
id->i_buffer_in_pos = 0;
break;
}
else if( i_used < id->i_buffer_in_pos )
{
memmove( id->p_buffer_in,
&id->p_buffer_in[i_used],
id->i_buffer_in - i_used );
id->i_buffer_in_pos -= i_used;
}
else
{
id->i_buffer_in_pos = 0;
break;
}
}
}
else
{
int16_t *sout = (int16_t*)&id->p_buffer[id->i_buffer_pos];
int i_used;
if( id->f_src.i_fourcc == VLC_FOURCC( 's', '8', ' ', ' ' ) )
{ {
msg_Warn( p_stream, "error"); int8_t *sin = (int8_t*)id->p_buffer_in;
id->i_buffer_in_pos = 0; int i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos ) / 2, id->i_buffer_in_pos );
break; i_used = i_samples;
while( i_samples > 0 )
{
*sout++ = ( *sin++ ) << 8;
i_samples--;
}
} }
else if( i_used < id->i_buffer_in_pos ) else if( id->f_src.i_fourcc == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
{
int8_t *sin = (int8_t*)id->p_buffer_in;
int i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos ) / 2, id->i_buffer_in_pos );
i_used = i_samples;
while( i_samples > 0 )
{
*sout++ = ( *sin++ - 128 ) << 8;
i_samples--;
}
}
else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'l' ) )
{
int i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos ) / 2, id->i_buffer_in_pos / 2);
i_used = i_samples * 2;
#ifdef WORDS_BIGENDIAN
uint8_t *sin = (uint8_t*)id->p_buffer_in;
while( i_samples > 0 )
{
uint8_t tmp[2];
tmp[1] = *sin++;
tmp[0] = *sin++;
*sout++ = *(int16_t*)tmp;
i_samples--;
}
#else
memcpy( sout, id->p_buffer_in, i_samples * 2 );
sout += i_samples;
#endif
}
else if( id->f_src.i_fourcc == VLC_FOURCC( 's', '1', '6', 'b' ) )
{
int i_samples = __MIN( ( id->i_buffer - id->i_buffer_pos ) / 2, id->i_buffer_in_pos / 2);
i_used = i_samples * 2;
#ifdef WORDS_BIGENDIAN
memcpy( sout, id->p_buffer_in, i_samples * 2 );
sout += i_samples;
#else
uint8_t *sin = (uint8_t*)id->p_buffer_in;
while( i_samples > 0 )
{
uint8_t tmp[2];
tmp[1] = *sin++;
tmp[0] = *sin++;
*sout++ = *(int16_t*)tmp;
i_samples--;
}
#endif
}
id->i_buffer_pos = (uint8_t*)sout - id->p_buffer;
if( i_used < id->i_buffer_in_pos )
{ {
memmove( id->p_buffer_in, memmove( id->p_buffer_in,
&id->p_buffer_in[i_used], &id->p_buffer_in[i_used],
id->i_buffer_in - i_used ); id->i_buffer_in - i_used );
id->i_buffer_in_pos -= i_used;
}
else
{
id->i_buffer_in_pos = 0;
break;
} }
id->i_buffer_in_pos -= i_used;
} }
/* encode as many data as possible */ /* encode as many data as possible */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment