Commit 0b1ccd3e authored by Laurent Aimar's avatar Laurent Aimar

* au: ported to demux2 API.

parent 70127d0a
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* au.c : au file input module for vlc * au.c : au file input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001-2003 VideoLAN * Copyright (C) 2001-2003 VideoLAN
* $Id: au.c,v 1.12 2004/01/25 20:05:28 hartman Exp $ * $Id: au.c,v 1.13 2004/01/29 15:11:17 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -29,31 +29,27 @@ ...@@ -29,31 +29,27 @@
#include <vlc/vlc.h> #include <vlc/vlc.h>
#include <vlc/input.h> #include <vlc/input.h>
#include <codecs.h> /* TODO:
* - all adpcm things (I _NEED_ samples)
* - ...
*/
/***************************************************************************** /*****************************************************************************
* Module descriptor * Module descriptor
*****************************************************************************/ *****************************************************************************/
static int Open ( vlc_object_t * ); static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * ); static void Close( vlc_object_t * );
vlc_module_begin(); vlc_module_begin();
set_description( _("AU demuxer") ); set_description( _("AU demuxer") );
set_capability( "demux", 142 ); set_capability( "demux2", 10 );
set_callbacks( Open, Close ); set_callbacks( Open, Close );
add_shortcut( "au" );
vlc_module_end(); vlc_module_end();
/*
* TODO:
* - all adpcm things (I _NEED_ samples)
*/
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
static int DemuxPCM ( input_thread_t * );
/* TODO static int DemuxADPCM ( input_thread_t * ); */
enum AuType_e enum AuType_e
{ {
AU_UNKNOWN = 0, AU_UNKNOWN = 0,
...@@ -78,100 +74,85 @@ enum AuCat_e ...@@ -78,100 +74,85 @@ enum AuCat_e
AU_CAT_ADPCM = 2 AU_CAT_ADPCM = 2
}; };
typedef struct
#ifdef HAVE_ATTRIBUTE_PACKED
__attribute__((__packed__))
#endif
{
uint32_t i_header_size;
uint32_t i_data_size;
uint32_t i_encoding;
uint32_t i_sample_rate;
uint32_t i_channels;
} au_t;
struct demux_sys_t struct demux_sys_t
{ {
au_t au; es_format_t fmt;
es_out_id_t *es;
mtime_t i_time; mtime_t i_time;
es_format_t fmt;
es_out_id_t *p_es;
int i_frame_size; int i_frame_size;
mtime_t i_frame_length; mtime_t i_frame_length;
int i_header_size;
}; };
static int DemuxPCM( demux_t * );
static int Control ( demux_t *, int i_query, va_list args );
/***************************************************************************** /*****************************************************************************
* Open: check file and initializes structures * Open: check file and initializes structures
*****************************************************************************/ *****************************************************************************/
static int Open( vlc_object_t * p_this ) static int Open( vlc_object_t *p_this )
{ {
input_thread_t *p_input = (input_thread_t *)p_this; demux_t *p_demux = (demux_t*)p_this;
demux_sys_t *p_sys; demux_sys_t *p_sys;
uint8_t *p_peek;
int i_cat; uint8_t hdr[20];
uint8_t *p_peek;
int i_cat;
int i_samples, i_modulo;
/* a little test to see if it's a au file */ if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 )
if( input_Peek( p_input, &p_peek, 4 ) < 4 )
{ {
msg_Warn( p_input, "AU module discarded (cannot peek)" ); msg_Warn( p_demux, "cannot peek" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
if( strncmp( p_peek, ".snd", 4 ) ) if( strncmp( p_peek, ".snd", 4 ) )
{ {
msg_Warn( p_input, "AU module discarded (not a valid file)" ); msg_Warn( p_demux, "AU module discarded" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
p_input->p_demux_data = p_sys = malloc( sizeof( demux_sys_t ) );
p_sys->i_time = 0;
/* skip signature */ /* skip signature */
stream_Read( p_input->s, NULL, 4 ); /* cannot fail */ stream_Read( p_demux->s, NULL, 4 ); /* cannot fail */
/* read header */ /* read header */
if( stream_Read( p_input->s, &p_sys->au, sizeof(au_t) )<(int)sizeof(au_t) ) if( stream_Read( p_demux->s, hdr, 20 ) < 20 )
{ {
msg_Err( p_input, "cannot load header" ); msg_Err( p_demux, "cannot read" );
goto error; return VLC_EGENERIC;
} }
p_sys->au.i_header_size = GetDWBE( &p_sys->au.i_header_size );
p_sys->au.i_data_size = GetDWBE( &p_sys->au.i_data_size );
p_sys->au.i_encoding = GetDWBE( &p_sys->au.i_encoding );
p_sys->au.i_sample_rate = GetDWBE( &p_sys->au.i_sample_rate );
p_sys->au.i_channels = GetDWBE( &p_sys->au.i_channels );
msg_Dbg( p_input,
"au file: header_size=%d data_size=%d encoding=0x%x sample_rate=%d channels=%d",
p_sys->au.i_header_size,
p_sys->au.i_data_size,
p_sys->au.i_encoding,
p_sys->au.i_sample_rate,
p_sys->au.i_channels );
if( p_sys->au.i_header_size < 24 ) if( GetDWBE( &hdr[0] ) < 24 )
{ {
msg_Warn( p_input, "AU module discarded (not a valid file)" ); msg_Err( p_demux, "invalid file" );
goto error; return VLC_EGENERIC;
} }
p_sys = p_demux->p_sys = malloc( sizeof( demux_sys_t ) );
p_sys->i_time = 0;
p_sys->i_header_size = GetDWBE( &hdr[0] );
/* skip extra header data */ /* skip extra header data */
if( p_sys->au.i_header_size > 4 + sizeof( au_t ) ) if( p_sys->i_header_size > 24 )
{ {
stream_Read( p_input->s, stream_Read( p_demux->s, NULL, p_sys->i_header_size - 24 );
NULL, p_sys->au.i_header_size - 4 - sizeof( au_t ) );
} }
/* Create WAVEFORMATEX structure */ /* init fmt */
es_format_Init( &p_sys->fmt, AUDIO_ES, 0 ); es_format_Init( &p_sys->fmt, AUDIO_ES, 0 );
p_sys->fmt.audio.i_channels = p_sys->au.i_channels; p_sys->fmt.audio.i_rate = GetDWBE( &hdr[12] );
p_sys->fmt.audio.i_rate = p_sys->au.i_sample_rate; p_sys->fmt.audio.i_channels = GetDWBE( &hdr[16] );
switch( p_sys->au.i_encoding )
#if 0
p_sys->au.i_header_size = GetDWBE( &p_sys->au.i_header_size );
p_sys->au.i_data_size = GetDWBE( &p_sys->au.i_data_size );
p_sys->au.i_encoding = GetDWBE( &p_sys->au.i_encoding );
p_sys->au.i_sample_rate = GetDWBE( &p_sys->au.i_sample_rate );
p_sys->au.i_channels = GetDWBE( &p_sys->au.i_channels );
#endif
switch( GetDWBE( &hdr[8] ) )
{ {
case AU_ALAW_8: /* 8-bit ISDN A-law */ case AU_ALAW_8: /* 8-bit ISDN A-law */
p_sys->fmt.i_codec = VLC_FOURCC( 'a','l','a','w' ); p_sys->fmt.i_codec = VLC_FOURCC( 'a','l','a','w' );
...@@ -258,10 +239,13 @@ static int Open( vlc_object_t * p_this ) ...@@ -258,10 +239,13 @@ static int Open( vlc_object_t * p_this )
break; break;
default: default:
msg_Warn( p_input, "unknow encoding=0x%x", p_sys->au.i_encoding ); msg_Warn( p_demux, "unknow encoding=0x%x", GetDWBE( &hdr[8] ) );
p_sys->fmt.audio.i_bitspersample = 0;
p_sys->fmt.audio.i_blockalign = 0;
i_cat = AU_CAT_UNKNOWN; i_cat = AU_CAT_UNKNOWN;
goto error; break;
} }
p_sys->fmt.i_bitrate = p_sys->fmt.audio.i_rate * p_sys->fmt.i_bitrate = p_sys->fmt.audio.i_rate *
p_sys->fmt.audio.i_channels * p_sys->fmt.audio.i_channels *
p_sys->fmt.audio.i_bitspersample; p_sys->fmt.audio.i_bitspersample;
...@@ -271,50 +255,34 @@ static int Open( vlc_object_t * p_this ) ...@@ -271,50 +255,34 @@ static int Open( vlc_object_t * p_this )
p_sys->i_frame_size = 0; p_sys->i_frame_size = 0;
p_sys->i_frame_length = 0; p_sys->i_frame_length = 0;
msg_Err( p_input, "unsupported codec/type (Please report it)" ); msg_Err( p_demux, "unsupported codec/type (Please report it)" );
goto error; free( p_sys );
return VLC_EGENERIC;
} }
else
{
int i_samples, i_modulo;
/* read samples for 50ms of */ /* add the es */
i_samples = __MAX( p_sys->fmt.audio.i_rate / 20, 1 ); p_sys->es = es_out_Add( p_demux->out, &p_sys->fmt );
p_sys->i_frame_size = i_samples * p_sys->fmt.audio.i_channels * ( (p_sys->fmt.audio.i_bitspersample + 7) / 8 ); /* calculate 50ms frame size/time */
i_samples = __MAX( p_sys->fmt.audio.i_rate / 20, 1 );
if( p_sys->fmt.audio.i_blockalign > 0 ) p_sys->i_frame_size = i_samples * p_sys->fmt.audio.i_channels *
( (p_sys->fmt.audio.i_bitspersample + 7) / 8 );
if( p_sys->fmt.audio.i_blockalign > 0 )
{
if( ( i_modulo = p_sys->i_frame_size % p_sys->fmt.audio.i_blockalign ) != 0 )
{ {
if( ( i_modulo = p_sys->i_frame_size % p_sys->fmt.audio.i_blockalign ) != 0 ) p_sys->i_frame_size += p_sys->fmt.audio.i_blockalign - i_modulo;
{
p_sys->i_frame_size += p_sys->fmt.audio.i_blockalign - i_modulo;
}
} }
p_sys->i_frame_length = (mtime_t)1000000 *
(mtime_t)i_samples /
(mtime_t)p_sys->fmt.audio.i_rate;
p_input->pf_demux = DemuxPCM;
p_input->pf_demux_control = demux_vaControlDefault;
} }
p_sys->i_frame_length = (mtime_t)1000000 *
(mtime_t)i_samples /
(mtime_t)p_sys->fmt.audio.i_rate;
vlc_mutex_lock( &p_input->stream.stream_lock ); /* finish to set up p_demux */
if( input_InitStream( p_input, 0 ) == -1) p_demux->pf_demux = DemuxPCM;
{ p_demux->pf_control = Control;
vlc_mutex_unlock( &p_input->stream.stream_lock );
msg_Err( p_input, "cannot init stream" );
goto error;
}
p_input->stream.i_mux_rate = p_sys->fmt.i_bitrate / 50 / 8;
vlc_mutex_unlock( &p_input->stream.stream_lock );
p_sys->p_es = es_out_Add( p_input->p_es_out, &p_sys->fmt );
return VLC_SUCCESS; return VLC_SUCCESS;
error:
free( p_sys );
return VLC_EGENERIC;
} }
/***************************************************************************** /*****************************************************************************
...@@ -322,44 +290,28 @@ error: ...@@ -322,44 +290,28 @@ error:
***************************************************************************** *****************************************************************************
* Returns -1 in case of error, 0 in case of EOF, 1 otherwise * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
*****************************************************************************/ *****************************************************************************/
static int DemuxPCM( input_thread_t *p_input ) static int DemuxPCM( demux_t *p_demux )
{ {
demux_sys_t *p_sys = p_input->p_demux_data; demux_sys_t *p_sys = p_demux->p_sys;
block_t *p_block; block_t *p_block;
if( p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT )
{
int64_t i_pos = stream_Tell( p_input->s );
if( p_sys->fmt.audio.i_blockalign != 0 )
{
i_pos += p_sys->fmt.audio.i_blockalign - i_pos % p_sys->fmt.audio.i_blockalign;
if( stream_Seek( p_input->s, i_pos ) )
{
msg_Err( p_input, "seek failed (cannot resync)" );
}
}
}
input_ClockManageRef( p_input, /* set PCR */
p_input->stream.p_selected_program, es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_time );
p_sys->i_time * 9 / 100 );
if( ( p_block = stream_Block( p_input->s, p_sys->i_frame_size ) ) == NULL ) if( ( p_block = stream_Block( p_demux->s, p_sys->i_frame_size ) ) == NULL )
{ {
msg_Warn( p_input, "cannot read data" ); msg_Warn( p_demux, "cannot read data" );
return 0; return 0;
} }
p_block->i_dts = p_block->i_dts =
p_block->i_pts = input_ClockGetTS( p_input, p_block->i_pts = p_sys->i_time;
p_input->stream.p_selected_program,
p_sys->i_time * 9 / 100 );
es_out_Send( p_input->p_es_out, p_sys->p_es, p_block ); es_out_Send( p_demux->out, p_sys->es, p_block );
p_sys->i_time += p_sys->i_frame_length; p_sys->i_time += p_sys->i_frame_length;
return( 1 ); return 1;
} }
/***************************************************************************** /*****************************************************************************
...@@ -367,9 +319,87 @@ static int DemuxPCM( input_thread_t *p_input ) ...@@ -367,9 +319,87 @@ static int DemuxPCM( input_thread_t *p_input )
*****************************************************************************/ *****************************************************************************/
static void Close( vlc_object_t * p_this ) static void Close( vlc_object_t * p_this )
{ {
input_thread_t *p_input = (input_thread_t *)p_this; demux_t *p_demux = (demux_t*)p_this;
demux_sys_t *p_sys = p_input->p_demux_data; demux_sys_t *p_sys = p_demux->p_sys;
free( p_sys ); free( p_sys );
} }
/*****************************************************************************
* Control:
*****************************************************************************/
static int Control( demux_t *p_demux, int i_query, va_list args )
{
demux_sys_t *p_sys = p_demux->p_sys;
double f, *pf;
int64_t *pi64;
switch( i_query )
{
case DEMUX_GET_POSITION:
{
int64_t i_tell = stream_Tell( p_demux->s );
int64_t i_end = stream_Size( p_demux->s );
pf = (double*) va_arg( args, double* );
if( p_sys->i_header_size < i_end )
{
*pf = (double)( i_tell - p_sys->i_header_size ) /
(double)(i_end - p_sys->i_header_size);
return VLC_SUCCESS;
}
return VLC_EGENERIC;
}
case DEMUX_SET_POSITION:
{
int64_t i_end = stream_Size( p_demux->s );
f = (double) va_arg( args, double );
if( p_sys->i_header_size < i_end )
{
int64_t i_frame = (f * ( i_end - p_sys->i_header_size )) /
p_sys->fmt.audio.i_blockalign;
if( stream_Seek( p_demux->s, p_sys->i_header_size +
i_frame * p_sys->fmt.audio.i_blockalign ) )
{
return VLC_EGENERIC;
}
p_sys->i_time = 1 + ( i_frame * p_sys->fmt.audio.i_blockalign / p_sys->i_frame_size ) * p_sys->i_frame_length;
return VLC_SUCCESS;
}
return VLC_EGENERIC;
}
case DEMUX_GET_TIME:
pi64 = (int64_t*)va_arg( args, int64_t * );
*pi64 = p_sys->i_time;
return VLC_SUCCESS;
case DEMUX_GET_LENGTH:
{
int64_t i_size = stream_Size( p_demux->s ) - p_sys->i_header_size;
if( i_size > 0 )
{
pi64 = (int64_t*)va_arg( args, int64_t * );
*pi64 = i_size / p_sys->i_frame_size * p_sys->i_frame_length;
return VLC_SUCCESS;
}
return VLC_EGENERIC;
}
case DEMUX_SET_TIME:
case DEMUX_GET_FPS:
default:
return VLC_EGENERIC;
}
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* demux2 adaptation layer. * demux2 adaptation layer.
***************************************************************************** *****************************************************************************
* Copyright (C) 2004 VideoLAN * Copyright (C) 2004 VideoLAN
* $Id: demux2.c,v 1.7 2004/01/25 20:05:28 hartman Exp $ * $Id: demux2.c,v 1.8 2004/01/29 15:11:17 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -51,6 +51,7 @@ vlc_module_begin(); ...@@ -51,6 +51,7 @@ vlc_module_begin();
add_shortcut( "ps2" ); add_shortcut( "ps2" );
add_shortcut( "dvdnav" ); add_shortcut( "dvdnav" );
add_shortcut( "ffmpeg" ); add_shortcut( "ffmpeg" );
add_shortcut( "au" );
vlc_module_end(); vlc_module_end();
/***************************************************************************** /*****************************************************************************
......
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