aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/Input/aac/aacfile.cpp41
-rw-r--r--src/plugins/Input/aac/aacfile.h4
-rw-r--r--src/plugins/Input/aac/decoder_aac.cpp56
-rw-r--r--src/plugins/Input/aac/decoder_aac.h7
-rw-r--r--src/plugins/Input/aac/decoderaacfactory.cpp26
-rw-r--r--src/plugins/Input/aac/decoderaacfactory.h4
6 files changed, 77 insertions, 61 deletions
diff --git a/src/plugins/Input/aac/aacfile.cpp b/src/plugins/Input/aac/aacfile.cpp
index 6d1a67f48..2e1cc5dd6 100644
--- a/src/plugins/Input/aac/aacfile.cpp
+++ b/src/plugins/Input/aac/aacfile.cpp
@@ -31,13 +31,14 @@
static int adts_sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,7350,0,0,0};
-AACFile::AACFile(QIODevice *i, bool metaData)
+AACFile::AACFile(QIODevice *i, bool metaData, bool adts)
{
m_isValid = false;
m_length = 0;
m_bitrate = 0;
m_samplerate = 0;
m_input = i;
+ m_offset = 0;
uchar buf[AAC_BUFFER_SIZE];
qint64 buf_at = i->peek((char *) buf, AAC_BUFFER_SIZE);
@@ -55,26 +56,38 @@ AACFile::AACFile(QIODevice *i, bool metaData)
return;
}
memmove (buf, buf + tag_size, buf_at - tag_size);
+ buf_at -= tag_size;
+ m_offset = tag_size;
if (metaData)
parseID3v2(); //parse id3v2 tags
}
- //try to determnate header type;
- if (buf[0] == 0xff && ((buf[1] & 0xf6) == 0xf0))
+
+ int adts_offset = 0;
+
+ while(adts_offset < buf_at - 6)
{
- qDebug("AACFile: ADTS header found");
- if (!i->isSequential())
- parseADTS();
- m_isValid = true;
+ //try to determnate header type;
+ if (buf[adts_offset] == 0xff && ((buf[adts_offset+1] & 0xf6) == 0xf0))
+ {
+ qDebug("AACFile: ADTS header found");
+ if (!i->isSequential() && adts)
+ parseADTS();
+ m_isValid = true;
+ m_offset += adts_offset;
+ return;
+ }
+ adts_offset++;
}
- else if (memcmp(buf, "ADIF", 4) == 0)
+
+ if (memcmp(buf, "ADIF", 4) == 0)
{
qDebug("AACFile: ADIF header found");
int skip_size = (buf[4] & 0x80) ? 9 : 0;
m_bitrate = ((buf[4 + skip_size] & 0x0F)<<19) |
- (buf[5 + skip_size]<<11) |
- (buf[6 + skip_size]<<3) |
- (buf[7 + skip_size] & 0xE0);
+ (buf[5 + skip_size]<<11) |
+ (buf[6 + skip_size]<<3) |
+ (buf[7 + skip_size] & 0xE0);
if (!i->isSequential ())
m_length = (qint64) (((float)i->size()*8.f)/((float)m_bitrate) + 0.5f);
@@ -103,6 +116,11 @@ quint32 AACFile::samplerate()
return m_samplerate;
}
+int AACFile::offset() const
+{
+ return m_offset;
+}
+
bool AACFile::isValid()
{
return m_isValid;
@@ -238,3 +256,4 @@ void ID3v2Tag::read ()
TagLib::ByteVector v(array.data(), array.size());
parse(v);
}
+
diff --git a/src/plugins/Input/aac/aacfile.h b/src/plugins/Input/aac/aacfile.h
index 17c38e246..59eb4939c 100644
--- a/src/plugins/Input/aac/aacfile.h
+++ b/src/plugins/Input/aac/aacfile.h
@@ -42,13 +42,14 @@ class QBuffer;
class AACFile
{
public:
- AACFile(QIODevice *i, bool metaData = true);
+ AACFile(QIODevice *i, bool metaData = true, bool adts = true);
~AACFile();
qint64 length();
quint32 bitrate();
quint32 samplerate();
+ int offset() const;
bool isValid();
const QMap<Qmmp::MetaData, QString> metaData();
@@ -57,6 +58,7 @@ private:
void parseID3v2();
qint64 m_length;
quint32 m_bitrate;
+ int m_offset;
QIODevice *m_input;
bool m_isValid;
quint32 m_samplerate;
diff --git a/src/plugins/Input/aac/decoder_aac.cpp b/src/plugins/Input/aac/decoder_aac.cpp
index f78a54576..6c0ae2e90 100644
--- a/src/plugins/Input/aac/decoder_aac.cpp
+++ b/src/plugins/Input/aac/decoder_aac.cpp
@@ -42,6 +42,9 @@ DecoderAAC::DecoderAAC(QIODevice *i)
m_data = 0;
m_input_buf = 0;
m_input_at = 0;
+ m_sample_buf = 0;
+ m_sample_buf_at = 0;
+ m_sample_buf_size = 0;
}
@@ -88,6 +91,16 @@ bool DecoderAAC::initialize()
qWarning("DecoderAAC: unsupported AAC file");
return false;
}
+
+ //skip id3 tag and partial frame
+ if(aac_file.offset() > 0)
+ {
+ qDebug("DecoderAAC: header offset = %d bytes", aac_file.offset());
+
+ char data[aac_file.offset()];
+ input()->read(data, aac_file.offset());
+ }
+
m_totalTime = aac_file.length() * 1000;
m_bitrate = aac_file.bitrate();
@@ -107,26 +120,13 @@ bool DecoderAAC::initialize()
m_input_at = input()->read((char *)m_input_buf, AAC_BUFFER_SIZE);
- //skip id3 tag
- int tag_size = 0;
- if (!memcmp(m_input_buf, "ID3", 3))
- {
- /* high bit is not used */
- tag_size = (m_input_buf[6] << 21) | (m_input_buf[7] << 14) |
- (m_input_buf[8] << 7) | (m_input_buf[9] << 0);
-
- tag_size += 10;
- memmove (m_input_buf, m_input_buf + tag_size, m_input_at - tag_size);
- m_input_at -= tag_size;
- m_input_at += input()->read((char *)(m_input_buf + m_input_at), AAC_BUFFER_SIZE - m_input_at);
- }
- #ifdef FAAD_MODIFIED
+#ifdef FAAD_MODIFIED
uint32_t freq = 0;
uint8_t chan = 0;
- #else
+#else
unsigned long freq = 0;
unsigned char chan = 0;
- #endif
+#endif
int res = NeAACDecInit (data()->handle, (unsigned char*) m_input_buf, m_input_at, &freq, &chan);
if (res < 0)
@@ -151,11 +151,11 @@ qint64 DecoderAAC::read(char *audio, qint64 maxSize)
{
NeAACDecFrameInfo frame_info;
qint64 size = 0, to_read, read;
- void *out = 0;
bool eof = false;
- while (size <= 0 && !eof)
+ while(m_sample_buf_size <= 0 && !eof)
{
+ m_sample_buf_at = 0;
if (m_input_at < AAC_BUFFER_SIZE)
{
to_read = AAC_BUFFER_SIZE - m_input_at;
@@ -164,18 +164,30 @@ qint64 DecoderAAC::read(char *audio, qint64 maxSize)
m_input_at += read;
}
- out = NeAACDecDecode(data()->handle, &frame_info, (uchar *)m_input_buf, m_input_at);
- memmove(m_input_buf, m_input_buf + frame_info.bytesconsumed, m_input_at - frame_info.bytesconsumed);
+
+ m_sample_buf = NeAACDecDecode(data()->handle, &frame_info, (uchar *)m_input_buf, m_input_at);
+ memmove(m_input_buf, m_input_buf + frame_info.bytesconsumed,
+ m_input_at - frame_info.bytesconsumed);
m_input_at -= frame_info.bytesconsumed;
- if ((size = frame_info.samples * 2) > 0 && size <= maxSize)
- memcpy((void *) (audio), out, size);
if (frame_info.error > 0)
{
m_input_at = 0;
qDebug("DecoderAAC: %s", NeAACDecGetErrorMessage(frame_info.error));
+ return -1;
}
+
+ m_sample_buf_size = frame_info.samples * 2;
+ }
+
+ if(m_sample_buf_size > 0)
+ {
+ size = qMin(m_sample_buf_size, maxSize);
+ memcpy(audio, (char *)(m_sample_buf) + m_sample_buf_at, size);
+ m_sample_buf_at += size;
+ m_sample_buf_size -= size;
}
+
return size;
}
diff --git a/src/plugins/Input/aac/decoder_aac.h b/src/plugins/Input/aac/decoder_aac.h
index 7510f928a..78a4c6e2c 100644
--- a/src/plugins/Input/aac/decoder_aac.h
+++ b/src/plugins/Input/aac/decoder_aac.h
@@ -50,9 +50,12 @@ public:
qint64 read(char *audio, qint64 maxSize);
void seek(qint64 time);
-private:
+private:
struct aac_data *m_data;
- char *m_input_buf;
+ char* m_input_buf;
+ void* m_sample_buf;
+ int m_sample_buf_at;
+ qint64 m_sample_buf_size;
int m_bitrate;
ulong m_input_at, m_output_at;
double m_frameSize;
diff --git a/src/plugins/Input/aac/decoderaacfactory.cpp b/src/plugins/Input/aac/decoderaacfactory.cpp
index ebf48b6d1..6a11ba082 100644
--- a/src/plugins/Input/aac/decoderaacfactory.cpp
+++ b/src/plugins/Input/aac/decoderaacfactory.cpp
@@ -36,28 +36,8 @@ bool DecoderAACFactory::supports(const QString &source) const
bool DecoderAACFactory::canDecode(QIODevice *input) const
{
- uchar buf[4096];
- qint64 buf_at = input->peek((char *) buf, 4096);
-
- int tag_size = 0;
- if (!memcmp(buf, "ID3", 3)) //skip ID3 tag
- {
- /* high bit is not used */
- tag_size = (buf[6] << 21) | (buf[7] << 14) |
- (buf[8] << 7) | (buf[9] << 0);
-
- tag_size += 10;
- if (buf_at - tag_size < 4)
- return false;
-
- memmove (buf, buf + tag_size, buf_at - tag_size);
- }
- //try to determinate header type;
- if (buf[0] == 0xff && ((buf[1] & 0xf6) == 0xf0)) //ADTS header
- return true;
- else if (!memcmp(buf, "ADIF", 4)) //ADIF header
- return true;
- return false;
+ AACFile aac_file(input, false, false);
+ return aac_file.isValid();
}
const DecoderProperties DecoderAACFactory::properties() const
@@ -66,7 +46,7 @@ const DecoderProperties DecoderAACFactory::properties() const
properties.name = tr("AAC Plugin");
properties.filters << "*.aac";
properties.description = tr("AAC Files");
- //properties.contentType = ;
+ properties.contentTypes << "audio/aacp";
properties.shortName = "aac";
properties.hasAbout = true;
properties.hasSettings = false;
diff --git a/src/plugins/Input/aac/decoderaacfactory.h b/src/plugins/Input/aac/decoderaacfactory.h
index 1006ed781..2ef5c54e8 100644
--- a/src/plugins/Input/aac/decoderaacfactory.h
+++ b/src/plugins/Input/aac/decoderaacfactory.h
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2006-2008 by Ilya Kotov *
+ * Copyright (C) 2006-2012 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -34,7 +34,7 @@ class DecoderAACFactory : public QObject,
DecoderFactory
{
Q_OBJECT
-Q_INTERFACES(DecoderFactory);
+Q_INTERFACES(DecoderFactory)
public:
bool supports(const QString &source) const;