Changeset 1024

Show
Ignore:
Timestamp:
02/14/09 20:15:15 (1 year ago)
Author:
gbooker
Message:

Some initial DTS passthrough. It's messy, doesn't handle everything, but it at least works for some cases I tried.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/FFissionCodec/FFissionDecoder.cpp

    r1003 r1024  
    2525#include "Codecprintf.h" 
    2626#include "CodecIDs.h" 
     27#include "dca.h" 
     28 
     29#define MY_APP_DOMAIN CFSTR("org.perian.Perian") 
     30#define PASSTHROUGH_KEY CFSTR("attemptDTSPassthrough") 
    2731 
    2832typedef struct CookieAtomHeader { 
     
    8185        outBufSize = AVCODEC_MAX_AUDIO_FRAME_SIZE; 
    8286        outputBuffer = new Byte[outBufSize]; 
     87         
     88        CFStringRef myApp = MY_APP_DOMAIN; 
     89        CFPreferencesAppSynchronize(myApp); 
     90        CFTypeRef pass = CFPreferencesCopyAppValue(PASSTHROUGH_KEY, myApp); 
     91        if(pass != NULL) 
     92        { 
     93                CFTypeID type = CFGetTypeID(pass); 
     94                if(type == CFStringGetTypeID()) 
     95                        dtsPassthrough = CFStringGetIntValue((CFStringRef)pass); 
     96                else if(type == CFNumberGetTypeID()) 
     97                        CFNumberGetValue((CFNumberRef)pass, kCFNumberIntType, &dtsPassthrough); 
     98                else 
     99                        dtsPassthrough = 0; 
     100                CFRelease(pass); 
     101        } 
     102        else 
     103                dtsPassthrough = 0;      
    83104} 
    84105 
     
    303324                CODEC_THROW(kAudioCodecUnsupportedFormatError); 
    304325        } 
     326        if(mInputFormat.mFormatID != kAudioFormatDTS) 
     327                dtsPassthrough = 0; 
    305328} 
    306329 
     
    354377} 
    355378 
     379#define AV_RL16(x) EndianU16_LtoN(*(uint16_t *)(x)) 
     380#define AV_RB16(x) EndianU16_BtoN(*(uint16_t *)(x)) 
     381 
     382int produceDTSPassthroughPackets(Byte *outputBuffer, int *outBufUsed, uint8_t *packet, int packetSize, int channelCount) 
     383{ 
     384        if(packetSize < 96) 
     385                return 0; 
     386         
     387        uint32_t mrk = AV_RB16(packet) << 16 | AV_RB16(packet + 2); 
     388        unsigned int frameSize = 0; 
     389        unsigned int blockCount = 0; 
     390        bool repackage = 0; 
     391 
     392        switch (mrk) { 
     393                case DCA_MARKER_RAW_BE: 
     394                        blockCount = (AV_RB16(packet + 4) >> 2) & 0x7f; 
     395                        frameSize = (AV_RB16(packet + 4) & 0x3) << 12 | (AV_RB16(packet + 6) >> 4) & 0xfff; 
     396                        repackage = 1; 
     397                        break; 
     398                case DCA_MARKER_RAW_LE: 
     399                        blockCount = (AV_RL16(packet + 4) >> 2) & 0x7f; 
     400                        frameSize = (AV_RL16(packet + 4) & 0x3) << 12 | (AV_RL16(packet + 6) >> 4) & 0xfff; 
     401                        repackage = 1; 
     402                        break; 
     403                case DCA_MARKER_14B_BE: 
     404                case DCA_MARKER_14B_LE: 
     405                default: 
     406                        return -1; 
     407        } 
     408 
     409        blockCount++; 
     410        frameSize++; 
     411        int originalFrameSize = frameSize; 
     412        if(packetSize < frameSize) 
     413                return 0; 
     414 
     415        uint16_t newFrame[frameSize * 4 / 7]; 
     416        if(repackage) 
     417        { 
     418                int spareBitCount = 0; 
     419                uint16_t spareBits = 0; 
     420                uint16_t *newFrameData = newFrame; 
     421                int i; 
     422                 
     423                for(i=0; i<frameSize; i+= 2) 
     424                { 
     425                        uint16_t readBits = (mrk == DCA_MARKER_RAW_BE) ? AV_RB16(packet + i) : AV_RL16(packet + i); 
     426                        uint16_t newData = spareBits | readBits >> (2 + spareBitCount); 
     427                        if(newData & 0x2000) 
     428                                *newFrameData = newData | 0xc000; 
     429                        else 
     430                                *newFrameData = newData; 
     431                        spareBits = (readBits << (12 - spareBitCount)) & 0x3fff; 
     432                        spareBitCount += 2; 
     433                        if(spareBitCount == 14) 
     434                        { 
     435                                if(spareBits & 0x2000) 
     436                                        newFrameData[1] = spareBits | 0xc000; 
     437                                else 
     438                                        newFrameData[1] = spareBits; 
     439                                spareBitCount = 0; 
     440                                spareBits = 0; 
     441                                newFrameData += 2; 
     442                        } 
     443                        else 
     444                                newFrameData++; 
     445                } 
     446                if(spareBitCount != 0) 
     447                { 
     448                        spareBits << 14 - spareBitCount; 
     449                        if(spareBits & 0x2000) 
     450                                newFrameData[1] = spareBits | 0xc000; 
     451                        else 
     452                                newFrameData[1] = spareBits; 
     453                        newFrameData ++; 
     454                } 
     455                 
     456                packet = (uint8_t *)newFrame; 
     457                frameSize = (newFrameData - newFrame) * 2; 
     458        } 
     459                 
     460        int totalSize = blockCount * 256 * channelCount / 4; 
     461        if(channelCount == 2) 
     462        { 
     463                memcpy(outputBuffer, packet, frameSize); 
     464                memset(outputBuffer+frameSize, 0, totalSize - frameSize); 
     465        } 
     466        else 
     467        { 
     468                memset(outputBuffer, 0, totalSize); 
     469                int i; 
     470                int offset = 2; 
     471                for(i=0; i<frameSize; i+= 4) 
     472                { 
     473                        memcpy(outputBuffer + offset, packet + i, 4); 
     474                        offset += 2 * channelCount; 
     475                } 
     476        } 
     477         
     478        *outBufUsed = totalSize; 
     479         
     480        return originalFrameSize; 
     481} 
     482 
    356483UInt32 FFissionDecoder::ProduceOutputPackets(void* outOutputData, 
    357484                                                                                         UInt32& ioOutputDataByteSize,  // number of bytes written to outOutputData 
     
    388515                // decode one packet to our buffer 
    389516                outBufUsed = outBufSize; 
    390                 int len = avcodec_decode_audio2(avContext, (int16_t *)outputBuffer, &outBufUsed, packet, packetSize); 
     517                int len; 
     518                if(dtsPassthrough) 
     519                        len = produceDTSPassthroughPackets(outputBuffer, &outBufUsed, packet, packetSize, avContext->channels); 
     520                else 
     521                        len = avcodec_decode_audio2(avContext, (int16_t *)outputBuffer, &outBufUsed, packet, packetSize); 
    391522                 
    392523                if (len < 0) {