diff options
| -rw-r--r-- | src/plugins/Input/aac/aacfile.cpp | 41 | ||||
| -rw-r--r-- | src/plugins/Input/aac/aacfile.h | 4 | ||||
| -rw-r--r-- | src/plugins/Input/aac/decoder_aac.cpp | 56 | ||||
| -rw-r--r-- | src/plugins/Input/aac/decoder_aac.h | 7 | ||||
| -rw-r--r-- | src/plugins/Input/aac/decoderaacfactory.cpp | 26 | ||||
| -rw-r--r-- | src/plugins/Input/aac/decoderaacfactory.h | 4 |
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; |
