Changeset 1088

Show
Ignore:
Timestamp:
07/01/09 23:40:26 (7 months ago)
Author:
astrange
Message:

Partial revert of r1082 because I'm dumb.
Import SBR properly using LC backwards-compatible signaling.
Fix mp3 import in Matroska, which was broken like FFusion was before.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/MatroskaCodecIDs.cpp

    r1083 r1088  
    365365        {"A_AAC/MPEG2/MAIN", 1}, 
    366366        {"A_AAC/MPEG2/LC", 2}, 
    367         {"A_AAC/MPEG2/LC/SBR", 5}, 
     367        {"A_AAC/MPEG2/LC/SBR", 2}, 
    368368        {"A_AAC/MPEG2/SSR", 3}, 
    369369        {"A_AAC/MPEG4/MAIN", 1}, 
    370370        {"A_AAC/MPEG4/LC", 2}, 
    371         {"A_AAC/MPEG4/LC/SBR", 5}, 
     371        {"A_AAC/MPEG4/LC/SBR", 2}, 
    372372        {"A_AAC/MPEG4/SSR", 3}, 
    373373        {"A_AAC/MPEG4/LTP", 4} 
     
    379379}; 
    380380 
     381static int FindAACFreqIndex(double freq) 
     382{ 
     383        unsigned ifreq = freq; 
     384         
     385        for (int i = 0; i < sizeof(kAACFrequencyIndexes)/sizeof(unsigned); i++) { 
     386                if (kAACFrequencyIndexes[i] == ifreq) return i; 
     387        } 
     388         
     389        return 15; 
     390} 
     391 
    381392static void RecreateAACVOS(KaxTrackEntry *tr_entry, uint8_t *vosBuf, size_t *vosLen) 
    382393{ 
    383         unsigned char profile = 2, freq_index = 15; 
    384394        KaxCodecID *tr_codec = FindChild<KaxCodecID>(*tr_entry); 
    385395        KaxTrackAudio & audioTrack = GetChild<KaxTrackAudio>(*tr_entry); 
    386396        KaxAudioSamplingFreq & sampleFreq = GetChild<KaxAudioSamplingFreq>(audioTrack); 
    387397        KaxAudioChannels & numChannels = GetChild<KaxAudioChannels>(audioTrack); 
    388         unsigned freq = unsigned((double)sampleFreq), channels = unsigned(numChannels); 
    389  
     398        KaxAudioOutputSamplingFreq * outputFreq = FindChild<KaxAudioOutputSamplingFreq>(audioTrack); 
     399        unsigned channels = unsigned(numChannels); 
     400        unsigned profile = 2, freq_index = FindAACFreqIndex(sampleFreq); 
     401        uint8_t *vosStart = vosBuf; 
    390402        string codecString(*tr_codec); 
    391403 
     
    395407        } 
    396408         
    397         for (int i = 0; i < sizeof(kAACFrequencyIndexes)/sizeof(unsigned); i++) { 
    398                 if (kAACFrequencyIndexes[i] == freq) {freq_index = i; break;} 
    399         } 
    400          
    401         if (profile == 5) 
    402                 profile = 2; // disable SBR 
    403          
    404         if (freq_index != 15) { 
    405                 *vosBuf++ = (profile << 3) | (freq_index >> 1); 
    406                 *vosBuf++ = (freq_index << 7) | (channels << 3); 
    407                 *vosLen = 2; 
    408         } else {                 
    409                 *vosBuf++ = (profile << 3) | (freq_index >> 1); 
    410                 *vosBuf++ = (freq_index << 7) | (freq >> (24 - 7)); 
    411                 *vosBuf++ = (freq >> (24 - 7 - 8)); 
    412                 *vosBuf++ = (freq >> (24 - 7 - 16)); 
    413                 *vosBuf++ = ((freq & 1) << 7) | (channels << 3); 
    414                 *vosLen = 5; 
    415         } 
    416          
    417         //FIXME for when SBR is supported: 
    418         //write the extension data here 
    419         //(see libavformat matroskadec.c) 
     409        *vosBuf++ = (profile << 3) | (freq_index >> 1); 
     410        *vosBuf++ = (freq_index << 7) | (channels << 3); 
     411         
     412        if (freq_index == 15) 
     413                Codecprintf(NULL, "unrecognized AAC frequency not supported\n"); 
     414         
     415        if (outputFreq) { 
     416                unsigned output_freq_index = FindAACFreqIndex(*outputFreq); 
     417                 
     418                //SBR extension 
     419                //not sure why we still use object type 2 (LC) instead of 5 (HE) 
     420                *vosBuf++ = 0x56; 
     421                *vosBuf++ = 0xE5; 
     422                *vosBuf++ = 0x80 | (output_freq_index << 3); 
     423        } 
     424         
     425        *vosLen = vosBuf - vosStart; 
    420426} 
    421427 
     
    520526        size_t esdsLen; 
    521527         
    522         // QT doesn't like most SBR setup data (5 bytes) so pretend it's LC 
    523         if (audio && (!vosBuf || vosLen > 2)) { 
     528        if (audio && !vosBuf) { 
    524529                RecreateAACVOS(tr_entry, aacBuf, &vosLen); 
    525530                vosBuf = aacBuf; 
    526531        } else if (!audio && !vosBuf) 
    527532                return NULL; 
    528  
     533         
    529534        uint8_t *esds = CreateEsdsFromSetupData(vosBuf, vosLen, &esdsLen, trackID, audio, !audio); 
    530535         
  • trunk/MatroskaImportPrivate.cpp

    r1021 r1088  
    517517        asbd.mSampleRate = Float64(sampleFreq); 
    518518        asbd.mChannelsPerFrame = uint32(numChannels); 
    519         asbd.mFramesPerPacket = 1;              // needed for mp3 and v1 SoundDescription, maybe others 
    520519         
    521520        MkvFinishAudioDescriptions(&kaxTrack, &asbd, &acl); 
     
    525524        if(asbd.mChannelsPerFrame == 0) 
    526525                asbd.mChannelsPerFrame = 1;             // avoid a div by zero 
     526        if(asbd.mFramesPerPacket == 0) 
     527                asbd.mFramesPerPacket = 1; //in case of PCM or broken codecs 
     528                                       //note: this is completely wrong, but less so than 0 
     529 
    527530         
    528531        // FIXME mChannelLayoutTag == 0 is valid