diff options
author | Christopher Martin <christopher.martin@utoronto.ca> | 2011-05-15 09:09:29 -0400 |
---|---|---|
committer | Christopher Martin <christopher.martin@utoronto.ca> | 2011-05-15 09:09:29 -0400 |
commit | 48a9464eb6f0ec4fe1cadef792e041e67ccb4156 (patch) | |
tree | 70bc34b47a85b91bc81b8d53e6194cfd1e2dbe03 /src/libxineadec | |
parent | 138e3a387bb7f5770cd358700d158576a0461cf7 (diff) | |
download | xine-lib-48a9464eb6f0ec4fe1cadef792e041e67ccb4156.tar.gz xine-lib-48a9464eb6f0ec4fe1cadef792e041e67ccb4156.tar.bz2 |
Better support for 24-bit lpcm
First of all, it improves the qt demuxer, ensuring that 24-bit audio is
marked appropriately, and detecting little vs. big endian audio. It also
adjusts the buffer size when audio is 24-bit, ensuring that samples aren't
chopped in half (8192 does not divide evenly into 3 byte samples).
Secondly, in the lpcm decoder, the patch distinguishes between standard
24-bit lpcm (big and little endian) and special DVD-format 24-bit lpcm (see
http://wiki.multimedia.cx/index.php?title=PCM) and now handles both, instead
of only handling the DVD format.
The result is that xine now correctly plays all the 24-bit lpcm samples I
throw at it, whereas before only a few worked.
Diffstat (limited to 'src/libxineadec')
-rw-r--r-- | src/libxineadec/xine_lpcm_decoder.c | 66 |
1 files changed, 45 insertions, 21 deletions
diff --git a/src/libxineadec/xine_lpcm_decoder.c b/src/libxineadec/xine_lpcm_decoder.c index 6f4e71003..17db68550 100644 --- a/src/libxineadec/xine_lpcm_decoder.c +++ b/src/libxineadec/xine_lpcm_decoder.c @@ -94,6 +94,7 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { int stream_be; audio_buffer_t *audio_buffer; int format_changed = 0; + int special_dvd_audio = 0; /* Drop preview data */ if (buf->decoder_flags & BUF_FLAG_PREVIEW) @@ -116,7 +117,7 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { switch ((buf->decoder_info[2] >> (24+6)) & 0x03) { case 1: bits_per_sample = 16; break; case 2: bits_per_sample = 20; break; - case 3: bits_per_sample = 24; break; + case 3: bits_per_sample = 24; special_dvd_audio = 1; break; default: bits_per_sample = 0; break; } switch ((buf->decoder_info[2] >> 16) & 0x0f) { @@ -152,7 +153,7 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { switch ((buf->decoder_info[2]>>6) & 3) { case 0: bits_per_sample = 16; break; case 1: bits_per_sample = 20; break; - case 2: bits_per_sample = 24; break; + case 2: bits_per_sample = 24; special_dvd_audio = 1; break; } } @@ -270,35 +271,58 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { int n = buf_size; if ( stream_be ) { - while (n >= 12) { + if (special_dvd_audio) + while (n >= 12) { + if ( stream_be == this->cpu_be ) { + *d++ = s[0]; + *d++ = s[1]; + *d++ = s[2]; + *d++ = s[3]; + *d++ = s[4]; + *d++ = s[5]; + *d++ = s[6]; + *d++ = s[7]; + } else { + *d++ = s[1]; + *d++ = s[0]; + *d++ = s[3]; + *d++ = s[2]; + *d++ = s[5]; + *d++ = s[4]; + *d++ = s[7]; + *d++ = s[6]; + } + s += 12; + n -= 12; + } + else + while (n >= 3) { + if ( stream_be == this->cpu_be ) { + *d++ = s[0]; + *d++ = s[1]; + } else { + *d++ = s[1]; + *d++ = s[0]; + } + s += 3; + n -= 3; + } + } else { + while (n >= 3) { if ( stream_be == this->cpu_be ) { - *d++ = s[0]; *d++ = s[1]; *d++ = s[2]; - *d++ = s[3]; - *d++ = s[4]; - *d++ = s[5]; - *d++ = s[6]; - *d++ = s[7]; } else { - *d++ = s[1]; - *d++ = s[0]; - *d++ = s[3]; *d++ = s[2]; - *d++ = s[5]; - *d++ = s[4]; - *d++ = s[7]; - *d++ = s[6]; + *d++ = s[1]; } - s += 12; - n -= 12; + s += 3; + n -= 3; } - } else { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "lpcm_decoder: I don't know what should decode lpcm 24bit little endian byte stream"); } if ( (d - (uint8_t*)audio_buffer->mem)/2*3 < buf_size ) - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "lpcm_decoder: lost %i bytes\n", (int)(buf_size - (d - (uint8_t*)audio_buffer->mem))/2*3); + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "lpcm_decoder: lost %i bytes of %i in the buffer\n", (int)(buf_size - (d - (uint8_t*)audio_buffer->mem)/2*3), buf_size); } else { memcpy (audio_buffer->mem, sample_buffer, buf_size); |