summaryrefslogtreecommitdiff
path: root/xine/BluRay/xine_lpcm_decoder.c
diff options
context:
space:
mode:
authorphintuka <phintuka>2010-01-06 11:33:15 +0000
committerphintuka <phintuka>2010-01-06 11:33:15 +0000
commit4ac0ecd8ccb71a9f3b5c163b23a33ef97f9ef871 (patch)
treec8f27c902aae8d2abf4f971f0372059e8639c9f9 /xine/BluRay/xine_lpcm_decoder.c
parente7e8929388530020de26245bae61e7d8b415744e (diff)
downloadxineliboutput-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)
Diffstat (limited to 'xine/BluRay/xine_lpcm_decoder.c')
-rw-r--r--xine/BluRay/xine_lpcm_decoder.c51
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);
}