diff options
Diffstat (limited to 'src/demuxers/demux_aac.c')
-rw-r--r-- | src/demuxers/demux_aac.c | 73 |
1 files changed, 50 insertions, 23 deletions
diff --git a/src/demuxers/demux_aac.c b/src/demuxers/demux_aac.c index b9e4c4084..ab71e8382 100644 --- a/src/demuxers/demux_aac.c +++ b/src/demuxers/demux_aac.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2005 the xine project + * Copyright (C) 2001-2007 the xine project * * This file is part of xine, a free video player. * @@ -21,7 +21,7 @@ * This demuxer detects ADIF and ADTS headers in AAC files. * Then it shovels buffer-sized chunks over to the AAC decoder. * - * $Id: demux_aac.c,v 1.12 2006/11/14 21:51:32 dsalt Exp $ + * $Id: demux_aac.c,v 1.17 2007/03/03 01:41:16 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -48,6 +48,8 @@ #include "bswap.h" #include "group_audio.h" +#include "id3.h" + typedef struct { demux_plugin_t demux_plugin; @@ -57,7 +59,6 @@ typedef struct { input_plugin_t *input; int status; - off_t data_start; off_t data_size; int seek_flag; /* this is set when a seek just occurred */ @@ -72,11 +73,30 @@ static int open_aac_file(demux_aac_t *this) { int i; uint8_t peak[MAX_PREVIEW_SIZE]; uint16_t syncword = 0; + uint32_t id3size = 0; + off_t data_start = 0; - /* Check for an ADIF header - should be at the start of the file */ - if (_x_demux_read_header(this->input, peak, 4) != 4) + _x_assert(MAX_PREVIEW_SIZE > 10); + + /* Get enough data to be able to check the size of ID3 tag */ + if (_x_demux_read_header(this->input, peak, 10) != 10) return 0; + /* Check if there's an ID3v2 tag at the start */ + if ( id3v2_istag(peak) ) { + id3size = id3v2_tagsize(&peak[6]); + + this->input->seek(this->input, 4, SEEK_SET); + + id3v2_parse_tag(this->input, this->stream, peak); + + lprintf("ID3v2 tag encountered, skipping %u bytes.\n", id3size); + } + + if ( this->input->read(this->input, peak, 4) != 4 ) + return 0; + + /* Check for an ADIF header - should be at the start of the file */ if ((peak[0] == 'A') && (peak[1] == 'D') && (peak[2] == 'I') && (peak[3] == 'F')) { lprintf("found ADIF header\n"); @@ -84,13 +104,20 @@ static int open_aac_file(demux_aac_t *this) { } /* Look for an ADTS header - might not be at the start of the file */ - if (_x_demux_read_header(this->input, peak, MAX_PREVIEW_SIZE) != - MAX_PREVIEW_SIZE) + if ( id3size != 0 && this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE ) { + lprintf("Getting a buffer of size %u starting from %u\n", MAX_PREVIEW_SIZE, id3size); + + this->input->seek(this->input, id3size, SEEK_SET); + if ( this->input->read(this->input, peak, MAX_PREVIEW_SIZE) != MAX_PREVIEW_SIZE ) + return 0; + this->input->seek(this->input, 0, SEEK_SET); + } else if (_x_demux_read_header(this->input, peak, MAX_PREVIEW_SIZE) != + MAX_PREVIEW_SIZE) return 0; for (i=0; i<MAX_PREVIEW_SIZE; i++) { if ((syncword & 0xfff6) == 0xfff0) { - this->data_start = i - 2; + data_start = i - 2; lprintf("found ADTS header at offset %d\n", i-2); break; } @@ -99,27 +126,27 @@ static int open_aac_file(demux_aac_t *this) { } /* Look for second ADTS header to confirm it's really aac */ - if (this->data_start + 5 < MAX_PREVIEW_SIZE) { - int frame_size = ((peak[this->data_start+3] & 0x03) << 11) | - (peak[this->data_start+4] << 3) | - ((peak[this->data_start+5] & 0xe0) >> 5); + if (data_start + 5 < MAX_PREVIEW_SIZE) { + int frame_size = ((peak[data_start+3] & 0x03) << 11) | + (peak[data_start+4] << 3) | + ((peak[data_start+5] & 0xe0) >> 5); lprintf("first frame size %d\n", frame_size); if ((frame_size > 0) && - (this->data_start+frame_size < MAX_PREVIEW_SIZE-1) && + (data_start+frame_size < MAX_PREVIEW_SIZE-1) && /* first 28 bits must be identical */ - (peak[this->data_start ] ==peak[this->data_start+frame_size ]) && - (peak[this->data_start+1] ==peak[this->data_start+frame_size+1]) && - (peak[this->data_start+2] ==peak[this->data_start+frame_size+2]) && - (peak[this->data_start+3]>>4==peak[this->data_start+frame_size+3]>>4)) + (peak[data_start ] ==peak[data_start+frame_size ]) && + (peak[data_start+1] ==peak[data_start+frame_size+1]) && + (peak[data_start+2] ==peak[data_start+frame_size+2]) && + (peak[data_start+3]>>4==peak[data_start+frame_size+3]>>4)) { lprintf("found second ADTS header\n"); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); - this->input->seek(this->input, this->data_start, SEEK_SET); + this->input->seek(this->input, data_start+id3size, SEEK_SET); return 1; } } @@ -255,7 +282,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -283,19 +310,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "ADIF/ADTS AAC demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "AAC"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "aac"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } |