diff options
author | phintuka <phintuka> | 2010-01-06 11:33:15 +0000 |
---|---|---|
committer | phintuka <phintuka> | 2010-01-06 11:33:15 +0000 |
commit | 4ac0ecd8ccb71a9f3b5c163b23a33ef97f9ef871 (patch) | |
tree | c8f27c902aae8d2abf4f971f0372059e8639c9f9 | |
parent | e7e8929388530020de26245bae61e7d8b415744e (diff) | |
download | xineliboutput-4ac0ecd8ccb71a9f3b5c163b23a33ef97f9ef871.tar.gz xineliboutput-4ac0ecd8ccb71a9f3b5c163b23a33ef97f9ef871.tar.bz2 |
Join multiple chunks before passing to audio out
(data is lost if PCM frames are splitted in the middle)
-rw-r--r-- | xine/BluRay/xine_lpcm_decoder.c | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/xine/BluRay/xine_lpcm_decoder.c b/xine/BluRay/xine_lpcm_decoder.c index 1bf52141..c3552688 100644 --- a/xine/BluRay/xine_lpcm_decoder.c +++ b/xine/BluRay/xine_lpcm_decoder.c @@ -74,15 +74,26 @@ typedef struct lpcm_decoder_s { int output_open; int cpu_be; /* TRUE, if we're a Big endian CPU */ + + int64_t pts; + + uint8_t *buf; + size_t buffered_bytes; + size_t buf_size; + } lpcm_decoder_t; static void lpcm_reset (audio_decoder_t *this_gen) { - /* lpcm_decoder_t *this = (lpcm_decoder_t *) this_gen; */ + lpcm_decoder_t *this = (lpcm_decoder_t *) this_gen; + free (this->buf); + this->buf = NULL; } static void lpcm_discontinuity (audio_decoder_t *this_gen) { + + lpcm_reset(this_gen); } static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { @@ -129,6 +140,15 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { xine_log (this->stream->xine, XINE_LOG_MSG, "lpcm_decoder: unsupported BluRay PCM format: 0x%08x\n", buf->decoder_info[2]); + if (this->buffered_bytes) + xine_log (this->stream->xine, XINE_LOG_MSG, "lpcm_decoder: %zd bytes lost !\n", this->buffered_bytes); + + if (!this->buf) { + this->buffered_bytes = 0; + this->buf_size = 8128; + this->buf = malloc(this->buf_size); + } + } else { /* MPEG2/DVD PCM header is one byte */ @@ -198,6 +218,30 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { if (!this->output_open || (buf->decoder_flags & BUF_FLAG_HEADER) ) return; + if (buf->pts && !this->pts) + this->pts = buf->pts; + + /* data accumulation */ + if (this->buf) { + int frame_end = buf->decoder_flags & BUF_FLAG_FRAME_END; + if (this->buffered_bytes || !frame_end) { + if (this->buf_size < this->buffered_bytes + buf->size) { + this->buf_size *= 2; + this->buf = realloc(this->buf, this->buf_size); + } + + memcpy(this->buf + this->buffered_bytes, buf->content, buf->size); + this->buffered_bytes += buf->size; + + if (!frame_end) + return; + + sample_buffer = (int16_t*)this->buf; + buf_size = this->buffered_bytes; + this->buffered_bytes = 0; + } + } + audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); /* Swap LPCM samples into native byte order, if necessary */ @@ -267,11 +311,12 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { memcpy (audio_buffer->mem, sample_buffer, buf_size); } - audio_buffer->vpts = buf->pts; + audio_buffer->vpts = this->pts; audio_buffer->num_frames = (((buf_size*8)/this->number_of_channels)/this->bits_per_sample); this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); + this->pts = 0; } static void lpcm_dispose (audio_decoder_t *this_gen) { @@ -281,6 +326,8 @@ static void lpcm_dispose (audio_decoder_t *this_gen) { this->stream->audio_out->close (this->stream->audio_out, this->stream); this->output_open = 0; + free (this->buf); + free (this_gen); } |