diff options
author | Darren Salt <linux@youmustbejoking.demon.co.uk> | 2009-04-25 20:32:03 +0100 |
---|---|---|
committer | Darren Salt <linux@youmustbejoking.demon.co.uk> | 2009-04-25 20:32:03 +0100 |
commit | 8c3fd22df0ca058d6acd94772d79cd1550627b4d (patch) | |
tree | 518880dedce9453e79ff03b88012a2d62bdbf3da /src/libmad | |
parent | d2d49b41bb8e8bf3d00b79e9e22ea68bb803c67c (diff) | |
parent | ef1392356f35acf52d1d6eb254f60c9ccbbf7b18 (diff) | |
download | xine-lib-8c3fd22df0ca058d6acd94772d79cd1550627b4d.tar.gz xine-lib-8c3fd22df0ca058d6acd94772d79cd1550627b4d.tar.bz2 |
Merge -gapless branch.
Diffstat (limited to 'src/libmad')
-rw-r--r-- | src/libmad/xine_mad_decoder.c | 55 |
1 files changed, 49 insertions, 6 deletions
diff --git a/src/libmad/xine_mad_decoder.c b/src/libmad/xine_mad_decoder.c index 3097c2d70..cb8c52831 100644 --- a/src/libmad/xine_mad_decoder.c +++ b/src/libmad/xine_mad_decoder.c @@ -84,6 +84,9 @@ typedef struct mad_decoder_s { uint8_t buffer[INPUT_BUF_SIZE]; int bytes_in_buffer; int preview_mode; + int start_padding; + int end_padding; + int needs_more_data; } mad_decoder_t; @@ -98,6 +101,9 @@ static void mad_reset (audio_decoder_t *this_gen) { this->pts = 0; this->bytes_in_buffer = 0; this->preview_mode = 0; + this->start_padding = 0; + this->end_padding = 0; + this->needs_more_data = 0; mad_synth_init (&this->synth); mad_stream_init (&this->stream); @@ -187,6 +193,17 @@ static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { if (this->bytes_in_buffer < MAD_MIN_SIZE) return; + if (!this->needs_more_data) { + this->pts = buf->pts; + if (buf->decoder_flags & BUF_FLAG_AUDIO_PADDING) { + this->start_padding = buf->decoder_info[1]; + this->end_padding = buf->decoder_info[2]; + } else { + this->start_padding = 0; + this->end_padding = 0; + } + } + while (1) { if (mad_frame_decode (&this->frame, &this->stream) != 0) { @@ -204,6 +221,8 @@ static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { switch (this->stream.error) { case MAD_ERROR_BUFLEN: + /* libmad wants more data */ + this->needs_more_data = 1; return; default: @@ -284,7 +303,24 @@ static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { nsamples = pcm->length; left_ch = pcm->samples[0]; right_ch = pcm->samples[1]; - + + /* padding */ + if (this->start_padding || this->end_padding) { + /* check padding validity */ + if (nsamples < (this->start_padding + this->end_padding)) { + lprintf("invalid padding data"); + this->start_padding = 0; + this->end_padding = 0; + } + lprintf("nsamples=%d, start_padding=%d, end_padding=%d\n", + nsamples, this->start_padding, this->end_padding); + nsamples -= this->start_padding + this->end_padding; + left_ch += this->start_padding; + right_ch += this->start_padding; + } + audio_buffer->num_frames = nsamples; + audio_buffer->vpts = this->pts; + while (nsamples--) { /* output sample(s) in 16-bit signed little-endian PCM */ @@ -315,14 +351,21 @@ static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { this->xstream->audio_out->put_buffer (this->xstream->audio_out, audio_buffer, this->xstream); + this->pts = buf->pts; buf->pts = 0; - + if (buf->decoder_flags & BUF_FLAG_AUDIO_PADDING) { + this->start_padding = buf->decoder_info[1]; + this->end_padding = buf->decoder_info[2]; + buf->decoder_info[1] = 0; + buf->decoder_info[2] = 0; + } else { + this->start_padding = 0; + this->end_padding = 0; + } } - - lprintf ("decode worked\n"); + lprintf ("decode worked\n"); } - } - + } } } |