| | 344 | } |
|---|
| | 345 | |
|---|
| | 346 | // c.f. http://wiki.multimedia.cx/index.php?title=Understanding_AAC |
|---|
| | 347 | |
|---|
| | 348 | struct MatroskaQT_AACProfileName |
|---|
| | 349 | { |
|---|
| | 350 | char *name; |
|---|
| | 351 | char profile; |
|---|
| | 352 | }; |
|---|
| | 353 | |
|---|
| | 354 | static const MatroskaQT_AACProfileName kMatroskaAACProfiles[] = { |
|---|
| | 355 | {"A_AAC/MPEG2/MAIN", 1}, |
|---|
| | 356 | {"A_AAC/MPEG2/LC", 2}, |
|---|
| | 357 | {"A_AAC/MPEG2/LC/SBR", 5}, |
|---|
| | 358 | {"A_AAC/MPEG2/SSR", 3}, |
|---|
| | 359 | {"A_AAC/MPEG4/MAIN", 1}, |
|---|
| | 360 | {"A_AAC/MPEG4/LC", 2}, |
|---|
| | 361 | {"A_AAC/MPEG4/LC/SBR", 5}, |
|---|
| | 362 | {"A_AAC/MPEG4/SSR", 3}, |
|---|
| | 363 | {"A_AAC/MPEG4/LTP", 4} |
|---|
| | 364 | }; |
|---|
| | 365 | |
|---|
| | 366 | static const unsigned kAACFrequencyIndexes[] = { |
|---|
| | 367 | 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, |
|---|
| | 368 | 11025, 8000, 7350 |
|---|
| | 369 | }; |
|---|
| | 370 | |
|---|
| | 371 | static void RecreateAACVOS(KaxTrackEntry *tr_entry, uint8_t *vosBuf, size_t *vosLen) |
|---|
| | 372 | { |
|---|
| | 373 | unsigned char profile = 0, freq_index = 15; |
|---|
| | 374 | KaxCodecID *tr_codec = FindChild<KaxCodecID>(*tr_entry); |
|---|
| | 375 | KaxTrackAudio & audioTrack = GetChild<KaxTrackAudio>(*tr_entry); |
|---|
| | 376 | KaxAudioSamplingFreq & sampleFreq = GetChild<KaxAudioSamplingFreq>(audioTrack); |
|---|
| | 377 | KaxAudioChannels & numChannels = GetChild<KaxAudioChannels>(audioTrack); |
|---|
| | 378 | unsigned freq = unsigned((double)sampleFreq), channels = unsigned(numChannels); |
|---|
| | 379 | |
|---|
| | 380 | string codecString(*tr_codec); |
|---|
| | 381 | |
|---|
| | 382 | for (int i = 0; i < sizeof(kMatroskaAACProfiles)/sizeof(MatroskaQT_AACProfileName); i++) { |
|---|
| | 383 | const MatroskaQT_AACProfileName *prof = &kMatroskaAACProfiles[i]; |
|---|
| | 384 | if (strcmp(codecString.c_str(), prof->name) == 0) {profile = prof->profile; break;} |
|---|
| | 385 | } |
|---|
| | 386 | |
|---|
| | 387 | for (int i = 0; i < sizeof(kAACFrequencyIndexes)/sizeof(unsigned); i++) { |
|---|
| | 388 | if (kAACFrequencyIndexes[i] == freq) {freq_index = i; break;} |
|---|
| | 389 | } |
|---|
| | 390 | |
|---|
| | 391 | if (freq_index != 15) { |
|---|
| | 392 | *vosBuf++ = (profile << 3) | (freq_index >> 1); |
|---|
| | 393 | *vosBuf++ = (freq_index << 7) | (channels << 3); |
|---|
| | 394 | *vosLen = 2; |
|---|
| | 395 | } else { |
|---|
| | 396 | freq = EndianU32_NtoB(freq); |
|---|
| | 397 | |
|---|
| | 398 | *vosBuf++ = (profile << 3) | (freq_index >> 1); |
|---|
| | 399 | *vosBuf++ = (freq_index << 7) | (freq >> (24 - 7)); |
|---|
| | 400 | *vosBuf++ = (freq >> (24 - 7 - 8)) & 0xff; |
|---|
| | 401 | *vosBuf++ = (freq >> (24 - 7 - 16)) & 0xff; |
|---|
| | 402 | *vosBuf++ = ((freq & 1) << 7) | (channels << 3); |
|---|
| | 403 | *vosLen = 5; |
|---|
| | 404 | } |
|---|