diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/audio_dec/xine_lpcm_decoder.c | 66 | ||||
-rw-r--r-- | src/demuxers/demux_aac.c | 4 | ||||
-rw-r--r-- | src/demuxers/demux_qt.c | 27 | ||||
-rw-r--r-- | src/video_out/video_out_directfb.c | 2 | ||||
-rw-r--r-- | src/xine-engine/buffer_types.c | 1 |
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, |