From 302020cce36c78c372225b49cbf78662c529dafa Mon Sep 17 00:00:00 2001 From: Jean-Paul Saman Date: Sat, 10 Aug 2002 13:40:46 +0000 Subject: [PATCH] Adapted mad codec plugin to new aout3. Not tested yet.` Plugin is not being build by new built structure, this needs to be fixed first. --- modules/codec/mad/decoder.c | 30 ++-- modules/codec/mad/decoder.h | 13 +- modules/codec/mad/libmad.c | 295 ++++++++++++++++++++++++------------ modules/codec/mad/libmad.h | 3 +- 4 files changed, 226 insertions(+), 115 deletions(-) diff --git a/modules/codec/mad/decoder.c b/modules/codec/mad/decoder.c index 1e343b38f6..3d48c69040 100644 --- a/modules/codec/mad/decoder.c +++ b/modules/codec/mad/decoder.c @@ -142,11 +142,17 @@ static int InitThread( mad_adec_thread_t * p_mad_adec ) decoder_fifo_t * p_fifo = p_mad_adec->p_fifo; char *psz_downscale = NULL; + /* Initialize the thread properties */ + p_mad_adec->p_aout = NULL; + p_mad_adec->p_aout_input = NULL; + p_mad_adec->output_format.i_format = AOUT_FMT_FIXED32; + p_mad_adec->output_format.i_channels = 2; /* FIXME ! */ + /* * Properties of audio for libmad */ - - /* Look what scaling method was requested by the user */ + + /* Look what scaling method was requested by the user */ psz_downscale = config_GetPsz( p_fifo, "downscale" ); if ( strncmp(psz_downscale,"fast",4)==0 ) @@ -165,7 +171,7 @@ static int InitThread( mad_adec_thread_t * p_mad_adec ) msg_Dbg( p_fifo, "downscale default fast selected" ); } - if (psz_downscale) free(psz_downscale); + if (psz_downscale) free(psz_downscale); /* Initialize the libmad decoder structures */ p_mad_adec->libmad_decoder = (struct mad_decoder*) malloc(sizeof(struct mad_decoder)); @@ -177,21 +183,15 @@ static int InitThread( mad_adec_thread_t * p_mad_adec ) p_mad_adec->i_current_pts = p_mad_adec->i_next_pts = 0; mad_decoder_init( p_mad_adec->libmad_decoder, - p_mad_adec, /* vlc's thread structure and p_fifo playbuffer */ - libmad_input, /* input_func */ + p_mad_adec, /* vlc's thread structure and p_fifo playbuffer */ + libmad_input, /* input_func */ 0, /* header_func */ 0, /* filter */ - libmad_output, /* output_func */ - 0, /* error */ - 0); /* message */ + libmad_output3, /* output_func */ + 0, /* error */ + 0); /* message */ mad_decoder_options(p_mad_adec->libmad_decoder, MAD_OPTION_IGNORECRC); -// mad_timer_reset(&p_mad_adec->libmad_timer); - - /* - * Initialize the output properties - */ - p_mad_adec->p_aout_fifo = NULL; /* * Initialize the input properties @@ -221,7 +221,7 @@ static void EndThread (mad_adec_thread_t * p_mad_adec) /* If the audio output fifo was created, we destroy it */ if (p_mad_adec->p_aout_fifo != NULL) { - aout_DestroyFifo (p_mad_adec->p_aout_fifo); + aout_InputDelete( p_mad_adec->p_aout, p_mad_adec->p_aout_input ); /* Make sure the output thread leaves the NextFrame() function */ vlc_mutex_lock (&(p_mad_adec->p_aout_fifo->data_lock)); diff --git a/modules/codec/mad/decoder.h b/modules/codec/mad/decoder.h index 3112cc59fe..84944d9e14 100644 --- a/modules/codec/mad/decoder.h +++ b/modules/codec/mad/decoder.h @@ -50,8 +50,17 @@ typedef struct mad_adec_thread_s /* * Output properties */ - aout_fifo_t * p_aout_fifo; /* stores the decompressed audio frames */ - enum mad_scaling audio_scaling; +//old way aout_fifo_t * p_aout_fifo; /* stores the decompressed audio frames */ + + /* + * Output properties + */ + aout_instance_t * p_aout; /* opaque */ + aout_input_t * p_aout_input; /* opaque */ + audio_sample_format_t output_format; + + mtime_t last_date; + enum mad_scaling audio_scaling; } mad_adec_thread_t; diff --git a/modules/codec/mad/libmad.c b/modules/codec/mad/libmad.c index fe397edb7c..f569a45e1d 100644 --- a/modules/codec/mad/libmad.c +++ b/modules/codec/mad/libmad.c @@ -271,116 +271,217 @@ static inline mad_fixed_t s24_to_s16_pcm(mad_fixed_t sample) /***************************************************************************** * libmad_ouput: this function is called just after the frame is decoded *****************************************************************************/ -enum mad_flow libmad_output(void *data, struct mad_header const *p_libmad_header, struct mad_pcm *p_libmad_pcm) +//enum mad_flow libmad_output(void *data, struct mad_header const *p_libmad_header, struct mad_pcm *p_libmad_pcm) +//{ +// mad_adec_thread_t *p_mad_adec= (mad_adec_thread_t *) data; +// byte_t *buffer=NULL; +// mad_fixed_t const *left_ch = p_libmad_pcm->samples[0], *right_ch = p_libmad_pcm->samples[1]; +// register int nsamples = p_libmad_pcm->length; +// mad_fixed_t sample; +// static struct audio_dither dither; +// +// /* Creating the audio output fifo. +// * Assume the samplerate and nr of channels from the first decoded frame is right for the entire audio track. +// */ +// if (p_mad_adec->p_aout_fifo==NULL) +// { +// p_mad_adec->p_aout_fifo = aout_CreateFifo( +// p_mad_adec->p_fifo, +// AOUT_FIFO_PCM, /* fifo type */ +// 2, /*p_libmad_pcm->channels,*/ /* nr. of channels */ +// p_libmad_pcm->samplerate, /* frame rate in Hz ?*/ +// p_libmad_pcm->length*2, /* length of output buffer *2 channels*/ +// NULL ); /* buffer */ +// +// if ( p_mad_adec->p_aout_fifo == NULL ) +// { +// return MAD_FLOW_BREAK; +// } +// +// msg_Dbg( p_mad_adec->p_fifo, "aout fifo created"); +// } +// +// if (p_mad_adec->p_aout_fifo->i_rate != p_libmad_pcm->samplerate) +// { +// msg_Warn( p_mad_adec->p_fifo, "samplerate is changing from [%d] Hz " +// "to [%d] Hz, sample size [%d], error_code [%0x]", +// p_mad_adec->p_aout_fifo->i_rate, p_libmad_pcm->samplerate, +// p_libmad_pcm->length, +// p_mad_adec->libmad_decoder->sync->stream.error ); +// p_mad_adec->p_aout_fifo->i_rate = p_libmad_pcm->samplerate; +// } +// +// if( p_mad_adec->i_current_pts ) +// { +// p_mad_adec->p_aout_fifo->date[p_mad_adec->p_aout_fifo->i_end_frame] +// = p_mad_adec->i_current_pts; +// } +// else +// { +// p_mad_adec->p_aout_fifo->date[p_mad_adec->p_aout_fifo->i_end_frame] +// = LAST_MDATE; +// } +//// mad_timer_add(&p_mad_adec->libmad_timer,p_libmad_header->duration); +// +// buffer = ((byte_t *)p_mad_adec->p_aout_fifo->buffer) + (p_mad_adec->p_aout_fifo->i_end_frame * (p_libmad_pcm->length*4)); +// +// while (nsamples--) +// { +// switch (p_mad_adec->audio_scaling) +// { +// case MPG321_SCALING: +// sample = mpg321_s24_to_s16_pcm(16, *left_ch++, &dither); +// break; +// case FAST_SCALING: /* intended fall through */ +// default: +// sample = s24_to_s16_pcm(*left_ch++); +// break; +// } +// +// /* left audio channel */ +//#ifndef WORDS_BIGENDIAN +// *buffer++ = (byte_t) (sample >> 0); +// *buffer++ = (byte_t) (sample >> 8); +//#else +// *buffer++ = (byte_t) (sample >> 8); +// *buffer++ = (byte_t) (sample >> 0); +//#endif +// if (p_libmad_pcm->channels == 2) +// { +// /* right audio channel */ +// switch (p_mad_adec->audio_scaling) +// { +// case MPG321_SCALING: +// sample = mpg321_s24_to_s16_pcm(16, *right_ch++, &dither); +// break; +// case FAST_SCALING: /* intended fall through */ +// default: +// sample = s24_to_s16_pcm(*right_ch++); +// break; +// } +// } +// /* else reuse left_ch */ +//#ifndef WORDS_BIGENDIAN +// *buffer++ = (byte_t) (sample >> 0); +// *buffer++ = (byte_t) (sample >> 8); +//#else +// *buffer++ = (byte_t) (sample >> 8); +// *buffer++ = (byte_t) (sample >> 0); +//#endif +// } +// +// /* DEBUG */ +// /* +// if (p_libmad_pcm->channels == 1) { +// msg_Dbg( p_mad_adec->p_fifo, "libmad_output channels [%d]", p_libmad_pcm->channels); +// } +// */ +// +// vlc_mutex_lock (&p_mad_adec->p_aout_fifo->data_lock); +// p_mad_adec->p_aout_fifo->i_end_frame = (p_mad_adec->p_aout_fifo->i_end_frame + 1) & AOUT_FIFO_SIZE; +// vlc_cond_signal (&p_mad_adec->p_aout_fifo->data_wait); +// vlc_mutex_unlock (&p_mad_adec->p_aout_fifo->data_lock); +// +// return MAD_FLOW_CONTINUE; +//} + +/***************************************************************************** + * libmad_ouput3: this function is called just after the frame is decoded + *****************************************************************************/ +enum mad_flow libmad_output3(void *data, struct mad_header const *p_libmad_header, struct mad_pcm *p_libmad_pcm) { mad_adec_thread_t *p_mad_adec= (mad_adec_thread_t *) data; - byte_t *buffer=NULL; + aout_buffer_t * p_buffer; mad_fixed_t const *left_ch = p_libmad_pcm->samples[0], *right_ch = p_libmad_pcm->samples[1]; register int nsamples = p_libmad_pcm->length; mad_fixed_t sample; - static struct audio_dither dither; /* Creating the audio output fifo. - * Assume the samplerate and nr of channels from the first decoded frame is right for the entire audio track. + * Assume the samplerate and nr of channels from the first decoded frame + * is right for the entire audio track. */ - if (p_mad_adec->p_aout_fifo==NULL) + if( (p_mad_adec->p_aout_input != NULL) && + ( (p_mad_adec->output_format.i_rate != p_libmad_pcm->samplerate) + { + /* Parameters changed - this should not happen. */ + aout_InputDelete( p_mad_adec->p_aout, p_mad_adec->p_aout_input ); + p_mad_adec->p_aout_input = NULL; + } + + /* Creating the audio input if not created yet. */ + if( p_mad_adec->p_aout_input == NULL ) { - p_mad_adec->p_aout_fifo = aout_CreateFifo( - p_mad_adec->p_fifo, - AOUT_FIFO_PCM, /* fifo type */ - 2, /*p_libmad_pcm->channels,*/ /* nr. of channels */ - p_libmad_pcm->samplerate, /* frame rate in Hz ?*/ - p_libmad_pcm->length*2, /* length of output buffer *2 channels*/ - NULL ); /* buffer */ - - if ( p_mad_adec->p_aout_fifo == NULL ) - { - return MAD_FLOW_BREAK; - } - - msg_Dbg( p_mad_adec->p_fifo, "aout fifo created"); + p_mad_adec->output_format.i_rate = p_libmad_pcm->samplerate; + /* p_mad_adec->output_format.i_channels = p_libmad_pcm->channels; */ + p_mad_adec->p_aout_input = aout_InputNew( p_mad_adec->p_fifo, + &p_mad_adec->p_aout, + &p_mad_adec->output_format ); + + if ( p_mad_adec->p_aout_input == NULL ) + { + p_mad_adec->p_fifo->b_error = 1; + return MAD_FLOW_BREAK; + } + msg_Dbg( p_mad_adec->p_fifo, "aout3 buffer created"); } - if (p_mad_adec->p_aout_fifo->i_rate != p_libmad_pcm->samplerate) + if (p_mad_adec->output_format->i_rate != p_libmad_pcm->samplerate) { - msg_Warn( p_mad_adec->p_fifo, "samplerate is changing from [%d] Hz " + msg_Warn( p_mad_adec->p_fifo, "samplerate is changing from [%d] Hz " "to [%d] Hz, sample size [%d], error_code [%0x]", p_mad_adec->p_aout_fifo->i_rate, p_libmad_pcm->samplerate, p_libmad_pcm->length, p_mad_adec->libmad_decoder->sync->stream.error ); - p_mad_adec->p_aout_fifo->i_rate = p_libmad_pcm->samplerate; + p_mad_adec->output_format.i_rate = p_libmad_pcm->samplerate; } - if( p_mad_adec->i_current_pts ) + /* Set the Presentation Time Stamp */ + p_buffer = aout_BufferNew( p_mad_adec->p_aout, p_mad_adec->p_aout_input, + (p_libmad_pcm->length*4) ); + if ( p_buffer == NULL ) { - p_mad_adec->p_aout_fifo->date[p_mad_adec->p_aout_fifo->i_end_frame] - = p_mad_adec->i_current_pts; + return MAD_FLOW_BREAK; + } + /* Add accurate PTS to buffer. */ + if ( p_mad_adec->i_current_pts ) + { + p_buffer->start_date = p_mad_adec->i_current_pts; } else { - p_mad_adec->p_aout_fifo->date[p_mad_adec->p_aout_fifo->i_end_frame] - = LAST_MDATE; + p_buffer->start_date = LAST_MDATE; } -// mad_timer_add(&p_mad_adec->libmad_timer,p_libmad_header->duration); - - buffer = ((byte_t *)p_mad_adec->p_aout_fifo->buffer) + (p_mad_adec->p_aout_fifo->i_end_frame * (p_libmad_pcm->length*4)); + p_mad_adec->last_date += (mtime_t)(p_libmad_pcm->length*4) + / p_mad_adec->output_format.i_rate; + p_buffer->end_date = p_mad_adec->last_date; + /* Interleave and keep buffers in mad_fixed_t format */ while (nsamples--) { - switch (p_mad_adec->audio_scaling) - { - case MPG321_SCALING: - sample = mpg321_s24_to_s16_pcm(16, *left_ch++, &dither); - break; - case FAST_SCALING: /* intended fall through */ - default: - sample = s24_to_s16_pcm(*left_ch++); - break; - } - /* left audio channel */ + sample = *left_ch++; #ifndef WORDS_BIGENDIAN - *buffer++ = (byte_t) (sample >> 0); - *buffer++ = (byte_t) (sample >> 8); + p_buffer->p_buffer++ = (mad_fixed_t) (sample >> 0); + p_buffer->p_buffer++ = (mad_fixed_t) (sample >> 8); #else - *buffer++ = (byte_t) (sample >> 8); - *buffer++ = (byte_t) (sample >> 0); + p_buffer->p_buffer++ = (mad_fixed_t) (sample >> 8); + p_buffer->p_buffer++ = (mad_fixed_t) (sample >> 0); #endif - if (p_libmad_pcm->channels == 2) + /* right audio channel */ + if (p_libmad_pcm->channels == 2) { - /* right audio channel */ - switch (p_mad_adec->audio_scaling) - { - case MPG321_SCALING: - sample = mpg321_s24_to_s16_pcm(16, *right_ch++, &dither); - break; - case FAST_SCALING: /* intended fall through */ - default: - sample = s24_to_s16_pcm(*right_ch++); - break; - } - } - /* else reuse left_ch */ + sample = *right_ch++; + } /* else reuse left audio channel */ #ifndef WORDS_BIGENDIAN - *buffer++ = (byte_t) (sample >> 0); - *buffer++ = (byte_t) (sample >> 8); + p_buffer->p_buffer++ = (mad_fixed_t) (sample >> 0); + p_buffer->p_buffer++ = (mad_fixed_t) (sample >> 8); #else - *buffer++ = (byte_t) (sample >> 8); - *buffer++ = (byte_t) (sample >> 0); -#endif - } - - /* DEBUG */ - /* - if (p_libmad_pcm->channels == 1) { - msg_Dbg( p_mad_adec->p_fifo, "libmad_output channels [%d]", p_libmad_pcm->channels); + p_buffer->p_buffer++ = (mad_fixed_t) (sample >> 8); + p_buffer->p_buffer++ = (mad_fixed_t) (sample >> 0); +#endif } - */ - vlc_mutex_lock (&p_mad_adec->p_aout_fifo->data_lock); - p_mad_adec->p_aout_fifo->i_end_frame = (p_mad_adec->p_aout_fifo->i_end_frame + 1) & AOUT_FIFO_SIZE; - vlc_cond_signal (&p_mad_adec->p_aout_fifo->data_wait); - vlc_mutex_unlock (&p_mad_adec->p_aout_fifo->data_lock); + aout_BufferPlay( p_mad_adec->p_aout, p_mad_adec->p_aout_input, p_buffer ); return MAD_FLOW_CONTINUE; } @@ -395,88 +496,88 @@ enum mad_flow libmad_error(void *data, struct mad_stream *p_libmad_stream, struc switch (p_libmad_stream->error) { case MAD_ERROR_BUFLEN: /* input buffer too small (or EOF) */ -//X intf_ErrMsg("libmad error: input buffer too small (or EOF)"); +//X msg_Err("libmad error: input buffer too small (or EOF)"); result = MAD_FLOW_CONTINUE; break; case MAD_ERROR_BUFPTR: /* invalid (null) buffer pointer */ -//X intf_ErrMsg("libmad error: invalid (null) buffer pointer"); +//X msg_Err("libmad error: invalid (null) buffer pointer"); result = MAD_FLOW_STOP; break; case MAD_ERROR_NOMEM: /* not enough memory */ -//X intf_ErrMsg("libmad error: invalid (null) buffer pointer"); +//X msg_Err("libmad error: invalid (null) buffer pointer"); result = MAD_FLOW_STOP; break; case MAD_ERROR_LOSTSYNC: /* lost synchronization */ -//X intf_ErrMsg("libmad error: lost synchronization"); +//X msg_Err("libmad error: lost synchronization"); mad_stream_sync(p_libmad_stream); result = MAD_FLOW_CONTINUE; break; case MAD_ERROR_BADLAYER: /* reserved header layer value */ -//X intf_ErrMsg("libmad error: reserved header layer value"); +//X msg_Err("libmad error: reserved header layer value"); result = MAD_FLOW_CONTINUE; break; case MAD_ERROR_BADBITRATE: /* forbidden bitrate value */ -//X intf_ErrMsg("libmad error: forbidden bitrate value"); +//X msg_Err("libmad error: forbidden bitrate value"); result = MAD_FLOW_CONTINUE; break; case MAD_ERROR_BADSAMPLERATE: /* reserved sample frequency value */ -//X intf_ErrMsg("libmad error: reserved sample frequency value"); +//X msg_Err("libmad error: reserved sample frequency value"); result = MAD_FLOW_CONTINUE; break; case MAD_ERROR_BADEMPHASIS: /* reserved emphasis value */ -//X intf_ErrMsg("libmad error: reserverd emphasis value"); +//X msg_Err("libmad error: reserverd emphasis value"); result = MAD_FLOW_CONTINUE; break; case MAD_ERROR_BADCRC: /* CRC check failed */ -//X intf_ErrMsg("libmad error: CRC check failed"); +//X msg_Err("libmad error: CRC check failed"); result = MAD_FLOW_CONTINUE; break; case MAD_ERROR_BADBITALLOC: /* forbidden bit allocation value */ -//X intf_ErrMsg("libmad error: forbidden bit allocation value"); +//X msg_Err("libmad error: forbidden bit allocation value"); result = MAD_FLOW_IGNORE; break; case MAD_ERROR_BADSCALEFACTOR:/* bad scalefactor index */ -//X intf_ErrMsg("libmad error: bad scalefactor index"); +//X msg_Err("libmad error: bad scalefactor index"); result = MAD_FLOW_CONTINUE; break; case MAD_ERROR_BADFRAMELEN: /* bad frame length */ -//X intf_ErrMsg("libmad error: bad frame length"); +//X msg_Err("libmad error: bad frame length"); result = MAD_FLOW_CONTINUE; break; case MAD_ERROR_BADBIGVALUES: /* bad big_values count */ -//X intf_ErrMsg("libmad error: bad big values count"); +//X msg_Err("libmad error: bad big values count"); result = MAD_FLOW_IGNORE; break; case MAD_ERROR_BADBLOCKTYPE: /* reserved block_type */ -//X intf_ErrMsg("libmad error: reserverd block_type"); +//X msg_Err("libmad error: reserverd block_type"); result = MAD_FLOW_IGNORE; break; case MAD_ERROR_BADSCFSI: /* bad scalefactor selection info */ -//X intf_ErrMsg("libmad error: bad scalefactor selection info"); +//X msg_Err("libmad error: bad scalefactor selection info"); result = MAD_FLOW_CONTINUE; break; case MAD_ERROR_BADDATAPTR: /* bad main_data_begin pointer */ -//X intf_ErrMsg("libmad error: bad main_data_begin pointer"); +//X msg_Err("libmad error: bad main_data_begin pointer"); result = MAD_FLOW_STOP; break; case MAD_ERROR_BADPART3LEN: /* bad audio data length */ -//X intf_ErrMsg("libmad error: bad audio data length"); +//X msg_Err("libmad error: bad audio data length"); result = MAD_FLOW_IGNORE; break; case MAD_ERROR_BADHUFFTABLE: /* bad Huffman table select */ -//X intf_ErrMsg("libmad error: bad Huffman table select"); +//X msg_Err("libmad error: bad Huffman table select"); result = MAD_FLOW_IGNORE; break; case MAD_ERROR_BADHUFFDATA: /* Huffman data overrun */ -//X intf_ErrMsg("libmad error: Huffman data overrun"); +//X msg_Err("libmad error: Huffman data overrun"); result = MAD_FLOW_IGNORE; break; case MAD_ERROR_BADSTEREO: /* incompatible block_type for JS */ -//X intf_ErrMsg("libmad error: incompatible block_type for JS"); +//X msg_Err("libmad error: incompatible block_type for JS"); result = MAD_FLOW_IGNORE; break; default: -//X intf_ErrMsg("libmad error: unknown error occured stopping decoder"); +//X msg_Err("libmad error: unknown error occured stopping decoder"); result = MAD_FLOW_STOP; break; } @@ -559,7 +660,7 @@ static void PrintFrameInfo(struct mad_header *Header) break; } -//X intf_ErrMsg("statistics: %lu kb/s audio mpeg layer %s stream %s crc, " +//X msg_Err("statistics: %lu kb/s audio mpeg layer %s stream %s crc, " //X "%s with %s emphasis at %d Hz sample rate\n", //X Header->bitrate,Layer, //X Header->flags&MAD_FLAG_PROTECTION?"with":"without", diff --git a/modules/codec/mad/libmad.h b/modules/codec/mad/libmad.h index 20dbca9366..c33a54ec14 100644 --- a/modules/codec/mad/libmad.h +++ b/modules/codec/mad/libmad.h @@ -40,7 +40,8 @@ enum mad_flow libmad_header(void *data, struct mad_header const *p_libmad_header // enum mad_flow libmad_filter(void *data, struct mad_stream const *p_libmad_stream, struct mad_frame *p_libmad_frame); /* enum mad_flow (*output_func)(void *, struct mad_header const *, struct mad_pcm *); */ -enum mad_flow libmad_output(void *data, struct mad_header const *p_libmad_header, struct mad_pcm *p_libmad_pcm); +//enum mad_flow libmad_output(void *data, struct mad_header const *p_libmad_header, struct mad_pcm *p_libmad_pcm); +enum mad_flow libmad_output3(void *data, struct mad_header const *p_libmad_header, struct mad_pcm *p_libmad_pcm); /* enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *); */ enum mad_flow libmad_error(void *data, struct mad_stream *p_libmad_stream, struct mad_frame *p_libmad_frame); -- 2.39.5