Skip to content

Commit

Permalink
fix sampling rate index in ADTS header (0.95 regression) + cosmetics
Browse files Browse the repository at this point in the history
  • Loading branch information
nu774 committed Nov 8, 2011
1 parent ba8f8e9 commit b640d20
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 67 deletions.
4 changes: 2 additions & 2 deletions alacenc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ bool ALACEncoderX::encodeChunk(UInt32 npackets)
return true;
}

void ALACEncoderX::getMagicCookie(std::vector<char> *cookie)
void ALACEncoderX::getMagicCookie(std::vector<uint8_t> *cookie)
{
uint32_t size =
m_encoder->GetMagicCookieSize(m_output_desc.asbd.mChannelsPerFrame);
std::vector<char> vec(size + 24);
std::vector<uint8_t> vec(size + 24);
static const char *const hd = "\x00\x00\x00\x0c" "frmaalac"
"\x00\x00\x00\x24" "alac" "\x00\x00\x00\x00";
std::memcpy(&vec[0], hd, 24);
Expand Down
2 changes: 1 addition & 1 deletion alacenc.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class ALACEncoderX: public IEncoder, public IEncoderStat {
ALACEncoderX(const AudioStreamBasicDescription &desc);
void setFastMode(bool fast) { m_encoder->SetFastMode(fast); }
bool encodeChunk(UInt32 npackets);
void getMagicCookie(std::vector<char> *cookie);
void getMagicCookie(std::vector<uint8_t> *cookie);
void setSource(const x::shared_ptr<ISource> &source) { m_src = source; }
void setSink(const x::shared_ptr<ISink> &sink) { m_sink = sink; }
ISource *src() { return m_src.get(); }
Expand Down
12 changes: 6 additions & 6 deletions alacsink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@
#include "alacsink.h"

static
bool get32BE(char const ** pos, const char *end, uint32_t *n)
bool get32BE(uint8_t const ** pos, const uint8_t *end, uint32_t *n)
{
if (end - *pos < 4) return false;
const unsigned char *p = reinterpret_cast<const unsigned char *>(*pos);
const uint8_t *p = *pos;
*n = ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
*pos += 4;
return true;
}

static
void parseMagicCookieALAC(const std::vector<char> &cookie,
void parseMagicCookieALAC(const std::vector<uint8_t> &cookie,
std::vector<uint8_t> *alac,
std::vector<uint8_t> *chan)
{
const char *beg = &cookie[0];
const char *end = beg + cookie.size();
const uint8_t *beg = &cookie[0];
const uint8_t *end = beg + cookie.size();
uint32_t chunk_size, chunk_name;

while (get32BE(&beg, end, &chunk_size)) {
Expand All @@ -35,7 +35,7 @@ void parseMagicCookieALAC(const std::vector<char> &cookie,
}

ALACSink::ALACSink(const std::wstring &path,
const std::vector<char> &magicCookie, bool temp)
const std::vector<uint8_t> &magicCookie, bool temp)
: MP4SinkBase(path, temp)
{
try {
Expand Down
2 changes: 1 addition & 1 deletion alacsink.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

class ALACSink: public ISink, public MP4SinkBase {
public:
ALACSink(const std::wstring &path, const std::vector<char> &magicCookie,
ALACSink(const std::wstring &path, const std::vector<uint8_t> &magicCookie,
bool temp=false);
void writeSamples(const void *data, size_t length, size_t nsamples)
{
Expand Down
2 changes: 1 addition & 1 deletion iencoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ struct IEncoderOutputInfo {
virtual ~IEncoderOutputInfo() {}
virtual void getBasicDescription(AudioStreamBasicDescription *asbd) = 0;
virtual void getChannelLayout(AudioChannelLayoutX *result) = 0;
virtual void getMagicCookie(std::vector<char> *result) = 0;
virtual void getMagicCookie(std::vector<uint8_t> *result) = 0;
};

class EncoderStat: public IEncoderStat {
Expand Down
17 changes: 8 additions & 9 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -526,16 +526,15 @@ x::shared_ptr<ISink> open_sink(StdAudioComponentX &encoder,
const std::wstring &ofilename, const Options &opts)
{
ISink *sink;
std::vector<uint8_t> cookie;
encoder.getMagicCookie(&cookie);
if (opts.is_adts)
sink = new ADTSSink(ofilename, &encoder);
else if (opts.isALAC()) {
std::vector<char> cookie;
encoder.getMagicCookie(&cookie);
sink = new ADTSSink(ofilename, cookie);
else if (opts.isALAC())
sink = new ALACSink(ofilename, cookie, !opts.no_optimize);
} else if (opts.isAAC())
sink = new MP4Sink(ofilename, &encoder, !opts.no_optimize);
x::shared_ptr<ISink> sinkp(sink);
return sinkp;
else if (opts.isAAC())
sink = new MP4Sink(ofilename, cookie, !opts.no_optimize);
return x::shared_ptr<ISink>(sink);
}

static
Expand Down Expand Up @@ -949,7 +948,7 @@ void encode_file(const x::shared_ptr<ISource> &src,

ALACEncoderX encoder(iasbd);
encoder.setFastMode(opts.alac_fast);
std::vector<char> cookie;
std::vector<uint8_t> cookie;
encoder.getMagicCookie(&cookie);

x::shared_ptr<ISink> sink(new ALACSink(ofilename, cookie,
Expand Down
83 changes: 42 additions & 41 deletions sink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ bool getDescripterHeader(const uint8_t **p, const uint8_t *end,
}

static
void parseMagicCookieAAC(const std::vector<char> &cookie,
void parseMagicCookieAAC(const std::vector<uint8_t> &cookie,
std::vector<uint8_t> *decSpecificConfig)
{
/*
* QT's "Magic Cookie" for AAC is just a esds descripter.
* We obtain only decSpecificConfig from it, and discard others.
*/
const uint8_t *p = reinterpret_cast<const uint8_t*>(&cookie[0]);
const uint8_t *p = &cookie[0];
const uint8_t *end = p + cookie.size();
int tag;
uint32_t size;
Expand Down Expand Up @@ -82,6 +82,30 @@ void parseMagicCookieAAC(const std::vector<char> &cookie,
"Magic cookie format is different from expected!!");
}

void parseDecSpecificConfig(const std::vector<uint8_t> &config,
unsigned *sampling_rate_index, unsigned *sampling_rate,
unsigned *channel_config)
{
static const unsigned tab[] = {
96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
16000, 12000, 11025, 8000, 7350, 0, 0, 0
};
const uint8_t *p = &config[0];
unsigned objtype = p[0] >> 3;
unsigned index = (p[0] & 7) << 1 | p[1] >> 7;
unsigned rate;
if (index == 0xf) {
rate = (p[1] & 0x7f) << 17 | p[2] << 9 | p[3] << 1 | p[4] >> 7;
p += 3;
} else {
rate = tab[index];
}
unsigned chconfig = (p[1] >> 3) & 0xf;
*sampling_rate_index = index;
*sampling_rate = rate;
*channel_config = chconfig;
}

using mp4v2::impl::MP4Atom;

MP4SinkBase::MP4SinkBase(const std::wstring &path, bool temp)
Expand Down Expand Up @@ -120,55 +144,36 @@ void MP4SinkBase::close()
}
}

MP4Sink::MP4Sink(const std::wstring &path, IEncoderOutputInfo *info, bool temp)
MP4Sink::MP4Sink(const std::wstring &path,
const std::vector<uint8_t> &cookie, bool temp)
: MP4SinkBase(path, temp)
{
AudioStreamBasicDescription format;
info->getBasicDescription(&format);
uint32_t sample_rate = static_cast<uint32_t>(format.mSampleRate);
uint32_t frame_length = format.mFramesPerPacket;
if (format.mFormatID == 'aach') {
sample_rate /= 2;
frame_length /= 2;
}
std::vector<uint8_t> config;
parseMagicCookieAAC(cookie, &config);
try {
m_mp4file.SetTimeScale(sample_rate);
unsigned index, rate, chconfig;
parseDecSpecificConfig(config, &index, &rate, &chconfig);
m_mp4file.SetTimeScale(rate);
m_track_id = m_mp4file.AddAudioTrack(
sample_rate, frame_length, MP4_MPEG4_AUDIO_TYPE);
rate, 1024, MP4_MPEG4_AUDIO_TYPE);
/*
* According to ISO 14496-12 8.16.3,
* ChannelCount of AusioSampleEntry is either 1 or 2.
*/
m_mp4file.SetIntegerProperty(
"moov.trak.mdia.minf.stbl.stsd.mp4a.channels",
format.mChannelsPerFrame == 1 ? 1 : 2);

uint8_t level;
if (format.mChannelsPerFrame < 3)
level = sample_rate <= 24000 ? 0x28 : 0x29;
else
level = sample_rate <= 48000 ? 0x2A : 0x2B;

//m_mp4file.SetAudioProfileLevel(level);

std::vector<char> cookie;
info->getMagicCookie(&cookie);
std::vector<uint8_t> decSpecificConfig;
parseMagicCookieAAC(cookie, &decSpecificConfig);
chconfig == 1 ? 1 : 2);

m_mp4file.SetTrackESConfiguration(
m_track_id,
&decSpecificConfig[0],
decSpecificConfig.size());

m_track_id, &config[0], config.size());
} catch (mp4v2::impl::Exception *e) {
handle_mp4error(e);
}
}

static void noop(void *) {}

ADTSSink::ADTSSink(const std::wstring &path, IEncoderOutputInfo *info)
ADTSSink::ADTSSink(const std::wstring &path, const std::vector<uint8_t> &cookie)
{
if (path == L"-") {
#if defined(_MSC_VER) || defined(__MINGW32__)
Expand All @@ -178,15 +183,11 @@ ADTSSink::ADTSSink(const std::wstring &path, IEncoderOutputInfo *info)
} else {
m_fp = file_ptr_t(wfopenx(path.c_str(), L"wb"), fclose);
}
std::vector<char> cookie;
info->getMagicCookie(&cookie);
std::vector<uint8_t> decSpecificConfig;
parseMagicCookieAAC(cookie, &decSpecificConfig);
unsigned objtype = decSpecificConfig[0] >> 3;
m_sample_rate_index
= ((decSpecificConfig[0] & 3)<<1) | (decSpecificConfig[1] >> 7);
unsigned offset = m_sample_rate_index == 0xf ? 3 : 0;
m_channel_config = (decSpecificConfig[1 + offset] >> 3) & 0xf;
std::vector<uint8_t> config;
parseMagicCookieAAC(cookie, &config);
unsigned rate;
parseDecSpecificConfig(config, &m_sample_rate_index, &rate,
&m_channel_config);
}

void ADTSSink::writeSamples(const void *data, size_t length, size_t nsamples)
Expand Down
4 changes: 2 additions & 2 deletions sink.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class MP4SinkBase {

class MP4Sink: public ISink, public MP4SinkBase {
public:
MP4Sink(const std::wstring &path, IEncoderOutputInfo *info,
MP4Sink(const std::wstring &path, const std::vector<uint8_t> &cookie,
bool temp=false);
void writeSamples(const void *data, size_t length, size_t nsamples)
{
Expand All @@ -41,7 +41,7 @@ class ADTSSink: public ISink {
uint32_t m_sample_rate_index;
uint32_t m_channel_config;
public:
ADTSSink(const std::wstring &path, IEncoderOutputInfo *info);
ADTSSink(const std::wstring &path, const std::vector<uint8_t> &cookie);
void writeSamples(const void *data, size_t length, size_t nsamples);
};

Expand Down
4 changes: 2 additions & 2 deletions stdaudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,15 @@ class StdAudioComponentX : public ComponentX, public IEncoderOutputInfo {
{
getVectorProperty(kSCAudio, kApplicableSampleRateList, result);
}
void getInputMagicCookie(std::vector<char> *result)
void getInputMagicCookie(std::vector<uint8_t> *result)
{
getVectorProperty(kSCAudio, kInputMagicCookie, result);
}
void setInputMagicCookie(const void *cookie, ByteCount size)
{
setProperty(kSCAudio, kInputMagicCookie, size, cookie);
}
void getMagicCookie(std::vector<char> *result)
void getMagicCookie(std::vector<uint8_t> *result)
{
getVectorProperty(kSCAudio, kMagicCookie, result);
}
Expand Down
4 changes: 2 additions & 2 deletions version.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const char *get_qaac_version()
{
#ifdef NO_QT
return "0.06";
return "0.07";
#else
return "0.97";
return "0.98";
#endif
}

0 comments on commit b640d20

Please sign in to comment.