summaryrefslogtreecommitdiff
path: root/src/libac3/xine_decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libac3/xine_decoder.c')
-rw-r--r--src/libac3/xine_decoder.c121
1 files changed, 100 insertions, 21 deletions
diff --git a/src/libac3/xine_decoder.c b/src/libac3/xine_decoder.c
index b11987299..5b9ab7ef6 100644
--- a/src/libac3/xine_decoder.c
+++ b/src/libac3/xine_decoder.c
@@ -17,7 +17,7 @@
* 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.2 2001/05/26 15:07:18 guenter Exp $
+ * $Id: xine_decoder.c,v 1.3 2001/05/27 23:48:12 guenter Exp $
*
* stuff needed to turn libac3 into a xine decoder plugin
*/
@@ -48,8 +48,12 @@ typedef struct ac3dec_decoder_s {
uint16_t syncword;
ao_functions_t *audio_out;
+ int audio_caps;
+ int bypass_mode;
+ int max_num_channels;
int output_sampling_rate;
int output_open;
+ int output_mode;
} ac3dec_decoder_t;
@@ -62,11 +66,36 @@ void ac3dec_init (audio_decoder_t *this_gen, ao_functions_t *audio_out) {
ac3dec_decoder_t *this = (ac3dec_decoder_t *) this_gen;
- this->audio_out = audio_out;
- ac3_init ();
+ this->audio_out = audio_out;
+ this->audio_caps = audio_out->get_capabilities(audio_out);
this->syncword = 0;
this->sync_todo = 6;
this->output_open = 0;
+
+ ac3_init ();
+
+ /*
+ * find out if this driver supports ac3 output
+ * or, if not, how many channels we've got
+ */
+
+ if (this->audio_caps & AO_CAP_MODE_AC3)
+ this->bypass_mode = 1;
+ else {
+ this->bypass_mode = 0;
+
+ /* find best mode */
+ if (this->audio_caps & AO_CAP_MODE_5CHANNEL)
+ this->max_num_channels = 5;
+ else if (this->audio_caps & AO_CAP_MODE_4CHANNEL)
+ this->max_num_channels = 4;
+ else if (this->audio_caps & AO_CAP_MODE_STEREO)
+ this->max_num_channels = 2;
+ else {
+ printf ("HELP! a mono-only audio driver?!\n");
+ this->max_num_channels = 1;
+ }
+ }
}
void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
@@ -77,6 +106,7 @@ void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
uint8_t *end = buf->content + buf->size;
ac3_frame_t *ac3_frame;
int sampling_rate;
+ int output_mode;
uint8_t byte;
@@ -125,30 +155,79 @@ void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
return ;
}
- /* now, decode this frame */
+ /*
+ * do we want to decode this frame in software?
+ */
- ac3_frame = ac3_decode_frame (this->frame_buffer);
+ if (!this->bypass_mode) {
+
+ /* oki, decode this frame in software*/
+
+ ac3_frame = ac3_decode_frame (this->frame_buffer, this->max_num_channels);
+
+ /* determine output mode */
+ switch (ac3_frame->num_channels) {
+ case 1:
+ output_mode = AO_CAP_MODE_MONO;
+ break;
+ case 2:
+ output_mode = AO_CAP_MODE_STEREO;
+ break;
+ case 4:
+ output_mode = AO_CAP_MODE_4CHANNEL;
+ break;
+ case 5:
+ output_mode = AO_CAP_MODE_5CHANNEL;
+ break;
+ }
- /* output audio */
+ /* output decoded samples */
- if (!this->output_open
- || (ac3_frame->sampling_rate != this->output_sampling_rate) ) {
+ if (!this->output_open
+ || (ac3_frame->sampling_rate != this->output_sampling_rate)
+ || (output_mode != this->output_mode)) {
- if (this->output_open)
- this->audio_out->close (this->audio_out);
+ 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,
+ output_mode) == 1);
+ this->output_sampling_rate = ac3_frame->sampling_rate;
+ this->output_mode = output_mode;
+ }
+
+ if (this->output_open) {
+ this->audio_out->write_audio_data (this->audio_out,
+ ac3_frame->audio_data,
+ 256*6,
+ this->pts);
+ this->pts = 0;
+ }
+ } else {
+
+ /*
+ * loop through ac3 data
+ */
+
+ if (!this->output_open) {
+ this->output_open = (this->audio_out->open (this->audio_out, 16,
+ ac3_sampling_rate(this->frame_buffer),
+ AO_CAP_MODE_AC3) == 1);
+ this->output_mode - AO_CAP_MODE_AC3;
+ }
+
+
+ if (this->output_open) {
+ this->audio_out->write_audio_data (this->audio_out,
+ this->frame_buffer,
+ this->frame_length,
+ this->pts);
+ this->pts = 0;
+ }
- 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 */