diff options
Diffstat (limited to 'src/libac3/xine_decoder.c')
-rw-r--r-- | src/libac3/xine_decoder.c | 124 |
1 files changed, 110 insertions, 14 deletions
diff --git a/src/libac3/xine_decoder.c b/src/libac3/xine_decoder.c index 5d1486f05..b11987299 100644 --- a/src/libac3/xine_decoder.c +++ b/src/libac3/xine_decoder.c @@ -17,13 +17,13 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_decoder.c,v 1.1 2001/04/29 16:40:33 guenter Exp $ + * $Id: xine_decoder.c,v 1.2 2001/05/26 15:07:18 guenter Exp $ * * stuff needed to turn libac3 into a xine decoder plugin */ /* - * FIXME: libac3 uses global variables (that are written) + * FIXME: libac3 uses global variables (that are written to) */ @@ -34,10 +34,23 @@ #include "buffer.h" #include "xine_internal.h" +#define FRAME_SIZE 4096 typedef struct ac3dec_decoder_s { audio_decoder_t audio_decoder; - ac3_config_t ac3c; /* FIXME - global variables, see above */ + + uint32_t pts; + + uint8_t frame_buffer[FRAME_SIZE]; + uint8_t *frame_ptr; + int sync_todo; + int frame_length, frame_todo; + uint16_t syncword; + + ao_functions_t *audio_out; + int output_sampling_rate; + int output_open; + } ac3dec_decoder_t; int ac3dec_can_handle (audio_decoder_t *this_gen, int buf_type) { @@ -49,21 +62,109 @@ void ac3dec_init (audio_decoder_t *this_gen, ao_functions_t *audio_out) { ac3dec_decoder_t *this = (ac3dec_decoder_t *) this_gen; - ac3_init (&this->ac3c, audio_out); + this->audio_out = audio_out; + ac3_init (); + this->syncword = 0; + this->sync_todo = 6; + this->output_open = 0; } void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { - /* ac3dec_decoder_t *this = (ac3dec_decoder_t *) this_gen;*/ - ac3_decode_data (buf->content, buf->content + buf->size, - buf->PTS); + ac3dec_decoder_t *this = (ac3dec_decoder_t *) this_gen; + + uint8_t *current = buf->content; + uint8_t *end = buf->content + buf->size; + ac3_frame_t *ac3_frame; + int sampling_rate; + + uint8_t byte; + + this->pts = buf->PTS; + + while (current != end) { + + while (1) { + byte = *current++; + + if (this->sync_todo>0) { + + /* search and collect syncinfo */ + + if (this->syncword != 0x0b77) { + this->syncword = (this->syncword << 8) | byte; + + if (this->syncword == 0x0b77) { + + this->frame_buffer[0] = 0x0b; + this->frame_buffer[1] = 0x77; + + this->sync_todo = 4; + this->frame_ptr = this->frame_buffer+2; + } + } else { + *this->frame_ptr++ = byte; + this->sync_todo--; + + if (this->sync_todo==0) { + this->frame_length = ac3_frame_length (this->frame_buffer); + this->frame_todo = this->frame_length - 6; + } + + } + } else { + + *this->frame_ptr++ = byte; + this->frame_todo--; + + if (this->frame_todo == 0) + break; + } + + if (current == end) + return ; + } + + /* now, decode this frame */ + + ac3_frame = ac3_decode_frame (this->frame_buffer); + + /* output audio */ + + if (!this->output_open + || (ac3_frame->sampling_rate != this->output_sampling_rate) ) { + + if (this->output_open) + this->audio_out->close (this->audio_out); + + this->output_open = (this->audio_out->open (this->audio_out, 16, + ac3_frame->sampling_rate, + AO_CAP_MODE_STEREO) == 1); + this->output_sampling_rate = ac3_frame->sampling_rate; + } + + if (this->output_open) { + this->audio_out->write_audio_data (this->audio_out, + ac3_frame->audio_data, + 256*6, + this->pts); + this->pts = 0; + } + + /* done with frame, prepare for next one */ + + this->syncword = 0; + this->sync_todo = 6; + + } } void ac3dec_close (audio_decoder_t *this_gen) { - /* ac3dec_decoder_t *this = (ac3dec_decoder_t *) this_gen; */ + ac3dec_decoder_t *this = (ac3dec_decoder_t *) this_gen; - ac3_reset (); + if (this->output_open) + this->audio_out->close (this->audio_out); } static char *ac3dec_get_id(void) { @@ -79,11 +180,6 @@ audio_decoder_t *init_audio_decoder_plugin (int iface_version, config_values_t * this = (ac3dec_decoder_t *) malloc (sizeof (ac3dec_decoder_t)); - this->ac3c.flags = 0; - this->ac3c.fill_buffer_callback = NULL; - this->ac3c.num_output_ch = 2; /* FIXME */ - this->ac3c.dual_mono_ch_sel = 0; - this->audio_decoder.interface_version = 1; this->audio_decoder.can_handle = ac3dec_can_handle; this->audio_decoder.init = ac3dec_init; |