diff options
Diffstat (limited to 'src/libac3/xine_decoder.c')
-rw-r--r-- | src/libac3/xine_decoder.c | 83 |
1 files changed, 53 insertions, 30 deletions
diff --git a/src/libac3/xine_decoder.c b/src/libac3/xine_decoder.c index 72909c58e..0bd12e5e2 100644 --- a/src/libac3/xine_decoder.c +++ b/src/libac3/xine_decoder.c @@ -17,15 +17,11 @@ * 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.15 2001/07/17 15:22:20 jkeil Exp $ + * $Id: xine_decoder.c,v 1.16 2001/07/20 22:37:56 guenter Exp $ * * stuff needed to turn libac3 into a xine decoder plugin */ -/* - * FIXME: libac3 uses global variables (that are written to) - */ - #include <stdlib.h> #include <unistd.h> @@ -42,9 +38,7 @@ #define FRAME_SIZE 4096 -stream_samples_t samples; - -/* int ac3file; */ +int ac3file; typedef struct ac3dec_decoder_s { audio_decoder_t audio_decoder; @@ -63,11 +57,14 @@ typedef struct ac3dec_decoder_s { int ac3_bit_rate; int ac3_sample_rate; float ac3_level; + int have_lfe; int ac3_flags_map[8]; int ao_flags_map[8]; - int16_t samples [6 * 256]; + int16_t int_samples [6 * 256]; + sample_t delay[6*256]; + sample_t samples[6][256]; ao_functions_t *audio_out; int audio_caps; @@ -125,7 +122,14 @@ void ac3dec_init (audio_decoder_t *this_gen, ao_functions_t *audio_out) { this->ao_flags_map[AC3_3F2R] = AO_CAP_MODE_STEREO; /* find best mode */ - if (this->audio_caps & AO_CAP_MODE_5CHANNEL) { + if (this->audio_caps & AO_CAP_MODE_5_1CHANNEL) { + + this->ac3_flags_map[AC3_2F2R] = AC3_2F2R; + this->ac3_flags_map[AC3_3F2R] = AC3_3F2R | AC3_LFE; + this->ao_flags_map[AC3_2F2R] = AO_CAP_MODE_4CHANNEL; + this->ao_flags_map[AC3_3F2R] = AO_CAP_MODE_5CHANNEL; + + } else if (this->audio_caps & AO_CAP_MODE_5CHANNEL) { this->ac3_flags_map[AC3_2F2R] = AC3_2F2R; this->ac3_flags_map[AC3_3F2R] = AC3_3F2R; @@ -167,7 +171,7 @@ void ac3dec_init (audio_decoder_t *this_gen, ao_functions_t *audio_out) { for (i = 0; i<8; i++) this->ac3_flags_map[i] |= AC3_ADJUST_LEVEL; */ - /* ac3file = open ("test.ac3", O_CREAT); */ + ac3file = open ("test.ac3", O_CREAT | O_WRONLY | O_TRUNC, 0644); } @@ -214,12 +218,16 @@ static void ac3dec_decode_frame (ac3dec_decoder_t *this, uint32_t pts) { if (ac3_frame (&this->ac3_state, this->frame_buffer, &ac3_output_flags, - &level, 384)) { + &level, 384, this->delay)) { printf ("libac3: ac3_frame error\n"); return; } - output_mode = this->ao_flags_map[ac3_output_flags]; + this->have_lfe = ac3_output_flags & AC3_LFE; + if (this->have_lfe) + output_mode = AO_CAP_MODE_5_1CHANNEL; + else + output_mode = this->ao_flags_map[ac3_output_flags]; /* * (re-)open output device @@ -250,31 +258,39 @@ static void ac3dec_decode_frame (ac3dec_decoder_t *this, uint32_t pts) { */ for (i = 0; i < 6; i++) { - if (ac3_block (&this->ac3_state)) { + if (ac3_block (&this->ac3_state, this->samples)) { printf ("libac3: ac3_block error\n"); - return; + return; } switch (output_mode) { case AO_CAP_MODE_MONO: - float_to_int (*samples, this->samples, 1); + float_to_int (this->samples[0], this->int_samples, 1); break; case AO_CAP_MODE_STEREO: - float_to_int (samples[0], this->samples, 2); - float_to_int (samples[1], this->samples+1, 2); + float_to_int (this->samples[0], this->int_samples, 2); + float_to_int (this->samples[1], this->int_samples+1, 2); break; case AO_CAP_MODE_4CHANNEL: - float_to_int (samples[0], this->samples, 4); - float_to_int (samples[1], this->samples+1, 4); - float_to_int (samples[2], this->samples+2, 4); - float_to_int (samples[3], this->samples+3, 4); + float_to_int (this->samples[0], this->int_samples, 4); + float_to_int (this->samples[1], this->int_samples+1, 4); + float_to_int (this->samples[2], this->int_samples+2, 4); + float_to_int (this->samples[3], this->int_samples+3, 4); break; case AO_CAP_MODE_5CHANNEL: - float_to_int (samples[0], this->samples, 5); - float_to_int (samples[1], this->samples+1, 5); - float_to_int (samples[2], this->samples+2, 5); - float_to_int (samples[3], this->samples+3, 5); - float_to_int (samples[4], this->samples+4, 5); + float_to_int (this->samples[0], this->int_samples, 5); + float_to_int (this->samples[1], this->int_samples+1, 5); + float_to_int (this->samples[2], this->int_samples+2, 5); + float_to_int (this->samples[3], this->int_samples+3, 5); + float_to_int (this->samples[4], this->int_samples+4, 5); + break; + case AO_CAP_MODE_5_1CHANNEL: + float_to_int (this->samples[0], this->int_samples, 6); + float_to_int (this->samples[1], this->int_samples+1, 6); + float_to_int (this->samples[2], this->int_samples+2, 6); + float_to_int (this->samples[3], this->int_samples+3, 6); + float_to_int (this->samples[4], this->int_samples+4, 6); + float_to_int (this->samples[5], this->int_samples+5, 6); break; default: printf ("libac3: help - unsupported mode %08x\n", output_mode); @@ -283,7 +299,7 @@ static void ac3dec_decode_frame (ac3dec_decoder_t *this, uint32_t pts) { /* output decoded samples */ this->audio_out->write_audio_data (this->audio_out, - this->samples, + this->int_samples, 256, pts); pts = 0; @@ -341,6 +357,7 @@ void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { if ( (this->sync_todo == 0) && (this->frame_todo == 0) ) { ac3dec_decode_frame (this, this->pts); + write (ac3file, this->frame_buffer, this->frame_length); this->pts = 0; this->sync_todo = 7; this->syncword = 0; @@ -374,7 +391,13 @@ void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { &this->ac3_flags, &this->ac3_sample_rate, &this->ac3_bit_rate); - this->frame_todo = this->frame_length - 7; + if (this->frame_length) { + this->frame_todo = this->frame_length - 7; + } else { + this->sync_todo = 7; + this->syncword = 0; + printf ("libac3: skip frame of zero length\n"); + } } @@ -406,7 +429,7 @@ void ac3dec_close (audio_decoder_t *this_gen) { this->output_open = 0; - /* close (ac3file); */ + close (ac3file); } static char *ac3dec_get_id(void) { |