Changeset 411

Show
Ignore:
Timestamp:
04/12/07 02:35:25 (1 year ago)
Author:
dconrad
Message:

Vorbis decoder (doesn't work with ogg-framed vorbis.) Refs #23

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/FFissionCodec/FFissionCodec.r

    r409 r411  
    5353#define kComponentInfo                                  "An AudioCodec that decodes Flash ADPCM into linear PCM" 
    5454#include "XCAResources.r" 
     55 
     56 
     57#define kComponentEntryPoint                    "FFissionVBRDecoderEntry" 
     58 
     59#define kPrimaryResourceID                              134 
     60#define kComponentType                                  'adec' 
     61#define kComponentSubtype                               kAudioFormatXiphVorbis 
     62#define kComponentName                                  "Vorbis" 
     63#define kComponentInfo                                  "An AudioCodec that decodes Vorbis audio into linear PCM" 
     64#include "XCAResources.r" 
  • trunk/FFissionCodec/FFissionDecoder.cpp

    r410 r411  
    2626#include "CodecIDs.h" 
    2727 
     28typedef struct CookieAtomHeader { 
     29    long           size; 
     30    long           type; 
     31    unsigned char  data[1]; 
     32} CookieAtomHeader; 
     33 
    2834struct CodecPair { 
    2935        OSType mFormatID; 
     
    3642        { kAudioFormatWMA2MS, CODEC_ID_WMAV2 }, 
    3743        { kAudioFormatFlashADPCM, CODEC_ID_ADPCM_SWF }, 
     44        { kAudioFormatXiphVorbis, CODEC_ID_VORBIS }, 
    3845        { 0, CODEC_ID_NONE } 
    3946}; 
     
    132139                        break; 
    133140                         
     141                case kAudioFormatXiphVorbis: 
     142                        avContext->extradata_size = ConvertXiphVorbisCookie(); 
     143                        avContext->extradata = magicCookie; 
     144                        break; 
     145                         
    134146                default: 
    135147                        return; 
     
    138150        // this is safe because we always allocate this amount of additional memory for our copy of the magic cookie 
    139151        memset(avContext->extradata + avContext->extradata_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); 
     152} 
     153 
     154int FFissionDecoder::ConvertXiphVorbisCookie() 
     155{ 
     156        Byte *ptr = magicCookie; 
     157        Byte *cend = magicCookie + magicCookieSize; 
     158        Byte *headerData[3] = {NULL}; 
     159        int headerSize[3] = {0}; 
     160         
     161        while (ptr < cend) { 
     162                CookieAtomHeader *aheader = reinterpret_cast<CookieAtomHeader *>(ptr); 
     163                int size = EndianU32_BtoN(aheader->size); 
     164                ptr += size; 
     165                if (ptr > cend || size <= 0) 
     166                        break; 
     167                 
     168                switch(EndianS32_BtoN(aheader->type)) { 
     169                        case kCookieTypeVorbisHeader: 
     170                                headerData[0] = aheader->data; 
     171                                headerSize[0] = size - 8; 
     172                                break; 
     173                                 
     174                        case kCookieTypeVorbisComments: 
     175                                headerData[1] = aheader->data; 
     176                                headerSize[1] = size - 8; 
     177                                break; 
     178                                 
     179                        case kCookieTypeVorbisCodebooks: 
     180                                headerData[2] = aheader->data; 
     181                                headerSize[2] = size - 8; 
     182                                break; 
     183                } 
     184        } 
     185         
     186    if (headerSize[0] <= 0 || headerSize[1] <= 0 || headerSize[2] <= 0) { 
     187                Codecprintf(NULL, "Invalid Vorbis extradata\n"); 
     188                return 0; 
     189        } 
     190         
     191        int len = headerSize[0] + headerSize[1] + headerSize[2]; 
     192        Byte *newCookie = new Byte[len + len/255 + 64]; 
     193        ptr = newCookie; 
     194         
     195        ptr[0] = 2;             // number of packets minus 1 
     196        int offset = 1; 
     197        offset += av_xiphlacing(&ptr[offset], headerSize[0]); 
     198        offset += av_xiphlacing(&ptr[offset], headerSize[1]); 
     199        for (int i = 0; i < 3; i++) { 
     200                memcpy(&ptr[offset], headerData[i], headerSize[i]); 
     201                offset += headerSize[i]; 
     202        } 
     203         
     204        delete[] magicCookie; 
     205        magicCookie = newCookie; 
     206        magicCookieSize = offset; 
     207         
     208        return offset; 
    140209} 
    141210 
     
    349418} 
    350419 
     420 
     421void FFissionVBRDecoder::GetProperty(AudioCodecPropertyID inPropertyID, UInt32& ioPropertyDataSize, void* outPropertyData) 
     422{ 
     423        switch (inPropertyID) { 
     424                case kAudioCodecPropertyPacketFrameSize: 
     425                case kAudioCodecPropertyHasVariablePacketByteSizes: 
     426                        if (ioPropertyDataSize != sizeof(UInt32)) 
     427                                CODEC_THROW(kAudioCodecBadPropertySizeError); 
     428                        break; 
     429        } 
     430         
     431        switch (inPropertyID) { 
     432                case kAudioCodecPropertyPacketFrameSize: 
     433                        *reinterpret_cast<UInt32*>(outPropertyData) = 0; 
     434                        break; 
     435                         
     436                case kAudioCodecPropertyHasVariablePacketByteSizes: 
     437                        *reinterpret_cast<UInt32*>(outPropertyData) = true; 
     438                        break; 
     439                         
     440                default: 
     441                        FFissionDecoder::GetProperty(inPropertyID, ioPropertyDataSize, outPropertyData); 
     442        } 
     443} 
     444 
     445 
    351446extern "C" 
    352447ComponentResult FFissionDecoderEntry(ComponentParameters* inParameters, FFissionDecoder* inThis) 
     
    354449        return ACCodecDispatch(inParameters, inThis); 
    355450} 
     451 
     452extern "C" 
     453ComponentResult FFissionVBRDecoderEntry(ComponentParameters* inParameters, FFissionVBRDecoder* inThis) 
     454{ 
     455        return ACCodecDispatch(inParameters, inThis); 
     456} 
  • trunk/FFissionCodec/FFissionDecoder.h

    r410 r411  
    4949private: 
    5050        void SetupExtradata(OSType formatID); 
     51        int ConvertXiphVorbisCookie(); 
    5152        void OpenAVCodec(); 
    5253         
     
    6162}; 
    6263 
     64// kAudioCodecPropertyHasVariablePacketByteSizes is queried before our input format is set, 
     65// so we can't use that to determine our answer... 
     66class FFissionVBRDecoder : public FFissionDecoder 
     67{ 
     68public: 
     69        FFissionVBRDecoder() : FFissionDecoder() { } 
     70        virtual void GetProperty(AudioCodecPropertyID inPropertyID, UInt32& ioPropertyDataSize, void* outPropertyData); 
     71}; 
     72 
    6373#endif 
  • trunk/exportedSymbols

    r219 r411  
    55_TextSubCodecComponentDispatch 
    66_FFissionDecoderEntry 
     7_FFissionVBRDecoderEntry 
  • trunk/ff_MovieImport.c

    r409 r411  
    8686                register_avcodec(&wmav2_decoder); 
    8787                register_avcodec(&adpcm_swf_decoder); 
     88                register_avcodec(&vorbis_decoder); 
    8889                 
    8990                av_log_set_callback(FFMpegCodecprintf);