summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio_dec/xine_lpcm_decoder.c66
-rw-r--r--src/demuxers/demux_aac.c4
-rw-r--r--src/demuxers/demux_qt.c27
-rw-r--r--src/video_out/video_out_directfb.c2
-rw-r--r--src/xine-engine/buffer_types.c1
5 files changed, 74 insertions, 26 deletions
diff --git a/src/audio_dec/xine_lpcm_decoder.c b/src/audio_dec/xine_lpcm_decoder.c
index b7e3344fe..7b9b4a81b 100644
--- a/src/audio_dec/xine_lpcm_decoder.c
+++ b/src/audio_dec/xine_lpcm_decoder.c
@@ -98,6 +98,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)
@@ -120,7 +121,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) {
@@ -156,7 +157,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;
}
}
@@ -274,35 +275,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);
diff --git a/src/demuxers/demux_aac.c b/src/demuxers/demux_aac.c
index 905d4c507..bc2e72f73 100644
--- a/src/demuxers/demux_aac.c
+++ b/src/demuxers/demux_aac.c
@@ -117,6 +117,10 @@ static int open_aac_file(demux_aac_t *this) {
syncword = (syncword << 8) | peak[i];
}
+ /* did we really find the ADTS header? */
+ if (i == MAX_PREVIEW_SIZE)
+ return 0; /* No, we didn't */
+
/* Look for second ADTS header to confirm it's really aac */
if (data_start + 5 < MAX_PREVIEW_SIZE) {
int frame_size = ((peak[data_start+3] & 0x03) << 11) |
diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c
index c342cc381..075eebd9f 100644
--- a/src/demuxers/demux_qt.c
+++ b/src/demuxers/demux_qt.c
@@ -90,6 +90,7 @@ typedef unsigned int qt_atom;
#define WAVE_ATOM QT_ATOM('w', 'a', 'v', 'e')
#define FRMA_ATOM QT_ATOM('f', 'r', 'm', 'a')
#define AVCC_ATOM QT_ATOM('a', 'v', 'c', 'C')
+#define ENDA_ATOM QT_ATOM('e', 'n', 'd', 'a')
#define IMA4_FOURCC ME_FOURCC('i', 'm', 'a', '4')
#define MAC3_FOURCC ME_FOURCC('M', 'A', 'C', '3')
@@ -103,6 +104,8 @@ typedef unsigned int qt_atom;
#define TWOS_FOURCC ME_FOURCC('t', 'w', 'o', 's')
#define SOWT_FOURCC ME_FOURCC('s', 'o', 'w', 't')
#define RAW_FOURCC ME_FOURCC('r', 'a', 'w', ' ')
+#define IN24_FOURCC ME_FOURCC('i', 'n', '2', '4')
+#define NI42_FOURCC ME_FOURCC('4', '2', 'n', 'i')
#define AVC1_FOURCC ME_FOURCC('a', 'v', 'c', '1')
#define UDTA_ATOM QT_ATOM('u', 'd', 't', 'a')
@@ -1197,6 +1200,13 @@ static qt_error parse_trak_atom (qt_trak *trak,
trak->stsd_atoms[k].audio.channels = trak_atom[atom_pos + 0x15];
trak->stsd_atoms[k].audio.bits = trak_atom[atom_pos + 0x17];
+ /* 24-bit audio doesn't always declare itself properly, and can be big- or little-endian */
+ if (trak->stsd_atoms[k].audio.codec_fourcc == IN24_FOURCC) {
+ trak->stsd_atoms[k].audio.bits = 24;
+ if (_X_BE_32(&trak_atom[atom_pos + 0x48]) == ENDA_ATOM && trak_atom[atom_pos + 0x4D])
+ trak->stsd_atoms[k].audio.codec_fourcc = NI42_FOURCC;
+ }
+
/* assume uncompressed audio parameters */
trak->stsd_atoms[k].audio.bytes_per_sample =
trak->stsd_atoms[k].audio.bits / 8;
@@ -1259,11 +1269,13 @@ static qt_error parse_trak_atom (qt_trak *trak,
* appears to be a handler for uncompressed data; if there are an
* extra 0x10 bytes, there are some more useful decoding params;
* further, do not do load these parameters if the audio is just
- * PCM ('raw ', 'twos', or 'sowt') */
+ * PCM ('raw ', 'twos', 'sowt' or 'in24') */
if ((current_stsd_atom_size > 0x24) &&
(trak->stsd_atoms[k].audio.codec_fourcc != TWOS_FOURCC) &&
(trak->stsd_atoms[k].audio.codec_fourcc != SOWT_FOURCC) &&
- (trak->stsd_atoms[k].audio.codec_fourcc != RAW_FOURCC)) {
+ (trak->stsd_atoms[k].audio.codec_fourcc != RAW_FOURCC) &&
+ (trak->stsd_atoms[k].audio.codec_fourcc != IN24_FOURCC) &&
+ (trak->stsd_atoms[k].audio.codec_fourcc != NI42_FOURCC)) {
if (_X_BE_32(&trak_atom[atom_pos + 0x20]))
trak->stsd_atoms[k].audio.samples_per_packet =
@@ -2349,6 +2361,7 @@ static int demux_qt_send_chunk(demux_plugin_t *this_gen) {
buf_element_t *buf = NULL;
unsigned int i, j;
unsigned int remaining_sample_bytes;
+ unsigned int frame_aligned_buf_size;
int frame_duration;
int first_buf;
qt_trak *video_trak = NULL;
@@ -2597,8 +2610,14 @@ static int demux_qt_send_chunk(demux_plugin_t *this_gen) {
buf->pts = audio_trak->frames[i].pts;
}
- if (remaining_sample_bytes > buf->max_size)
- buf->size = buf->max_size;
+ /* 24-bit audio doesn't fit evenly into the default 8192-byte buffers */
+ if (audio_trak->properties->audio.bits == 24)
+ frame_aligned_buf_size = 8184;
+ else
+ frame_aligned_buf_size = buf->max_size;
+
+ if (remaining_sample_bytes > frame_aligned_buf_size)
+ buf->size = frame_aligned_buf_size;
else
buf->size = remaining_sample_bytes;
remaining_sample_bytes -= buf->size;
diff --git a/src/video_out/video_out_directfb.c b/src/video_out/video_out_directfb.c
index d004939c2..2b6c31552 100644
--- a/src/video_out/video_out_directfb.c
+++ b/src/video_out/video_out_directfb.c
@@ -707,7 +707,7 @@ static void directfb_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen
|| (frame->vo_frame.crop_left != this->sc.crop_left)
|| (frame->vo_frame.crop_right != this->sc.crop_right)
|| (frame->vo_frame.crop_top != this->sc.crop_top)
- || (frame->vo_frame.crop_bottom != this->sc.crop_bottom) ) {
+ || (frame->vo_frame.crop_bottom != this->sc.crop_bottom) )
{
lprintf ("forcing redraw.\n");
this->sc.force_redraw = 1;
diff --git a/src/xine-engine/buffer_types.c b/src/xine-engine/buffer_types.c
index 2f362fa21..dc8550ca1 100644
--- a/src/xine-engine/buffer_types.c
+++ b/src/xine-engine/buffer_types.c
@@ -838,6 +838,7 @@ static const audio_db_t audio_db[] = {
0x01,
ME_FOURCC('r','a','w',' '),
ME_FOURCC('s','o','w','t'),
+ ME_FOURCC('4','2','n','i'),
0
},
BUF_AUDIO_LPCM_LE,