From 6f665ad312da7e80bd76dddc58f2b029e81d9e9e Mon Sep 17 00:00:00 2001 From: James Stembridge Date: Sat, 21 May 2005 09:50:32 +0000 Subject: Detection by content for AAC. CVS patchset: 7552 CVS date: 2005/05/21 09:50:32 --- src/demuxers/demux_aac.c | 76 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 7 deletions(-) diff --git a/src/demuxers/demux_aac.c b/src/demuxers/demux_aac.c index f1eda8597..7afbab94c 100644 --- a/src/demuxers/demux_aac.c +++ b/src/demuxers/demux_aac.c @@ -21,7 +21,7 @@ * This demuxer presently only detects a raw AAC file by the extension * '.aac'. Then it shovels buffer-sized chunks over to the AAC decoder. * - * $Id: demux_aac.c,v 1.5 2004/06/13 21:28:52 miguelfreitas Exp $ + * $Id: demux_aac.c,v 1.6 2005/05/21 09:50:32 jstembridge Exp $ */ #ifdef HAVE_CONFIG_H @@ -35,6 +35,12 @@ #include #include +#define LOG_MODULE "demux_aac" +#define LOG_VERBOSE +/* +#define LOG +*/ + #include "xine_internal.h" #include "xineutils.h" #include "demux.h" @@ -62,6 +68,60 @@ typedef struct { } demux_aac_class_t; +static int open_aac_file(demux_aac_t *this) { + int i; + uint8_t peak[MAX_PREVIEW_SIZE]; + uint16_t syncword = 0; + + /* Check for an ADIF header - should be at the start of the file */ + if (_x_demux_read_header(this->input, peak, 4) != 4) + return 0; + + if ((peak[0] == 'A') && (peak[1] == 'D') && + (peak[2] == 'I') && (peak[3] == 'F')) { + lprintf("found ADIF header\n"); + return 1; + } + + /* 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) + return 0; + + for (i=0; idata_start = i - 2; + lprintf("found ADTS header at offset %d\n", i-2); + break; + } + + syncword = (syncword << 8) | peak[i]; + } + + /* Look for second ADTS header to confirm it's really aac */ + if (idata_start+3] & 0x03) << 11) | + (peak[this->data_start+4] << 3) | + ((peak[this->data_start+5] & 0xe0) >> 5); + + lprintf("first frame size %d\n", frame_size); + + if ((this->data_start+frame_size < MAX_PREVIEW_SIZE-1) && + (peak[this->data_start+frame_size] == 0xff) && + ((peak[this->data_start+frame_size+1] & 0xf6) == 0xf0)) { + 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); + return 1; + } + } + + return 0; +} + static int demux_aac_send_chunk(demux_plugin_t *this_gen) { demux_aac_t *this = (demux_aac_t *) this_gen; int bytes_read; @@ -185,8 +245,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->status = DEMUX_FINISHED; switch (stream->content_detection_method) { - case METHOD_BY_EXTENSION: - case METHOD_EXPLICIT: { + case METHOD_BY_EXTENSION: { char *extensions, *mrl; mrl = input->get_mrl (input); @@ -197,12 +256,15 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return NULL; } } - break; + /* Falling through is intended */ case METHOD_BY_CONTENT: - free (this); - return NULL; - break; + case METHOD_EXPLICIT: + if (!open_aac_file(this)) { + free (this); + return NULL; + } + break; default: free (this); -- cgit v1.2.3