Changeset 586

Show
Ignore:
Timestamp:
06/20/07 01:56:13 (1 year ago)
Author:
dconrad
Message:

Support for VobSubs? compressed by zlib. Closes #31 for all common files

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/CodecIDs.h

    r409 r586  
    5757        kSampleDescriptionExtensionVobSubIdx = '.IDX', 
    5858        kSampleDescriptionExtensionReal = 'RVex', 
     59        kSampleDescriptionExtensionMKVCompression = 'Comp', 
    5960}; 
    6061 
  • trunk/MatroskaCodecIDs.cpp

    r377 r586  
    2727#include <matroska/KaxTracks.h> 
    2828#include <matroska/KaxTrackEntryData.h> 
    29 #include <matroska/KaxContentEncoding.h> 
    3029#include "MatroskaCodecIDs.h" 
    3130#include "CommonUtils.h" 
     
    736735        string codecString(*tr_codec); 
    737736         
    738         // how should we handle compressed tracks in general? 
    739         KaxContentEncodings *contentEncs = FindChild<KaxContentEncodings>(*tr_entry); 
    740         if (contentEncs) { 
    741                 OSType subtype = 0; 
    742                 for (int i = 0; i < sizeof(kMatroskaCodecIDs) / sizeof(MatroskaQT_Codec); i++) { 
    743                         if (codecString == kMatroskaCodecIDs[i].mkvID) 
    744                                 subtype = kMatroskaCodecIDs[i].cType; 
    745                 } 
    746                 return 'COMP'; 
    747         } 
    748          
    749737        if (codecString == MKV_V_MS) { 
    750738                // avi compatibility mode, 4cc is in private info 
  • trunk/MatroskaImport.h

    r564 r586  
    4141#include <matroska/KaxBlock.h> 
    4242#include <matroska/KaxAttachments.h> 
     43#include <matroska/KaxContentEncoding.h> 
    4344 
    4445using namespace libmatroska; 
     
    227228        ComponentResult ReadMetaSeek(KaxSeekHead &seekHead); 
    228229         
     230        // Adds a sample description extension if the content is compressed 
     231        // should only be the case for VobSub data. 
     232        ComponentResult ReadContentEncodings(KaxContentEncodings &encodings, MatroskaTrack &mkvTrack); 
     233         
    229234        // These three are called from ReadTracks to set up a track of the specific type,  
    230235        // modifying the MatroskaTrack structure to reflect the newly create track.  
  • trunk/MatroskaImportPrivate.cpp

    r577 r586  
    287287                        KaxTrackLanguage & trackLang = GetChild<KaxTrackLanguage>(track); 
    288288                        KaxTrackName & trackName = GetChild<KaxTrackName>(track); 
     289                        KaxContentEncodings * encodings = FindChild<KaxContentEncodings>(track); 
     290                         
     291                        if (encodings) { 
     292                                err = ReadContentEncodings(*encodings, mkvTrack); 
     293                                // just ignore the track if there's some problem with this element 
     294                                if (err) continue; 
     295                        } 
    289296                         
    290297                        long qtLang = ISO639_2ToQTLangCode(string(trackLang).c_str()); 
     
    331338} 
    332339 
     340ComponentResult MatroskaImport::ReadContentEncodings(KaxContentEncodings &encodings, MatroskaTrack &mkvTrack) 
     341{ 
     342        KaxContentEncoding & encoding = GetChild<KaxContentEncoding>(encodings); 
     343        int scope = uint32(GetChild<KaxContentEncodingScope>(encoding)); 
     344        int type = uint32(GetChild<KaxContentEncodingType>(encoding)); 
     345         
     346        if (scope != 1) { 
     347                Codecprintf(NULL, "Content encoding scope of %d not expected\n", scope); 
     348                return -1; 
     349        } 
     350        if (type != 0) { 
     351                Codecprintf(NULL, "Encrypted track\n"); 
     352                return -2; 
     353        } 
     354         
     355        KaxContentCompression & comp = GetChild<KaxContentCompression>(encoding); 
     356        int algo = uint32(GetChild<KaxContentCompAlgo>(comp)); 
     357         
     358        if (algo != 0) 
     359                Codecprintf(NULL, "MKV: warning, track compression algorithm %d not zlib\n", algo); 
     360         
     361        if ((*mkvTrack.desc)->dataFormat != kSubFormatVobSub) 
     362                Codecprintf(NULL, "MKV: warning, compressed track %4.4s probably won't work (not VobSub)\n", &(*mkvTrack.desc)->dataFormat); 
     363         
     364        Handle ext = NewHandle(1); 
     365        **ext = algo; 
     366         
     367        if (mkvTrack.type == track_audio) 
     368                AddSoundDescriptionExtension((SoundDescriptionHandle)mkvTrack.desc, ext, kSampleDescriptionExtensionMKVCompression); 
     369        else 
     370                AddImageDescriptionExtension((ImageDescriptionHandle)mkvTrack.desc, ext, kSampleDescriptionExtensionMKVCompression); 
     371         
     372        return noErr; 
     373} 
     374 
    333375ComponentResult MatroskaImport::AddVideoTrack(KaxTrackEntry &kaxTrack, MatroskaTrack &mkvTrack) 
    334376{ 
  • trunk/VobSubCodec.c

    r341 r586  
    1111#include "VobSubCodec.h" 
    1212#include "Codecprintf.h" 
     13#include <zlib.h> 
     14#include "avcodec.h" 
     15#include "intreadwrite.h" 
    1316 
    1417// Constants 
     
    2629         
    2730        uint8_t                                 *codecData; 
    28         long                                    bufferSize; 
     31        unsigned int                    bufferSize; 
     32        int                                             compressed; 
    2933} VobSubCodecGlobalsRecord, *VobSubCodecGlobals; 
    3034 
     
    232236    SetupColorPalette(glob, p->imageDescription); 
    233237 
     238        if (isImageDescriptionExtensionPresent(p->imageDescription, kSampleDescriptionExtensionMKVCompression)) 
     239                glob->compressed = 1; 
     240         
    234241        return noErr; 
    235242} 
     
    265272} 
    266273 
     274void DecompressZlib(VobSubCodecGlobals glob, uint8_t *data, int bufferSize) 
     275{ 
     276        ComponentResult err = noErr; 
     277        z_stream strm; 
     278        strm.zalloc = Z_NULL; 
     279        strm.zfree = Z_NULL; 
     280        strm.opaque = Z_NULL; 
     281        strm.avail_in = 0; 
     282        strm.next_in = Z_NULL; 
     283        err = inflateInit(&strm); 
     284        if (err != Z_OK) return; 
     285         
     286        strm.avail_in = bufferSize; 
     287        strm.next_in = data; 
     288         
     289        // first, get the size of the decompressed data 
     290        strm.avail_out = 2; 
     291        strm.next_out = glob->codecData; 
     292         
     293        err = inflate(&strm, Z_SYNC_FLUSH); 
     294        if (err < Z_OK) goto bail; 
     295        if (strm.avail_out != 0) goto bail; 
     296         
     297        glob->codecData = av_fast_realloc(glob->codecData, &glob->bufferSize, AV_RB16(glob->codecData)); 
     298         
     299        // then decompress the rest of it 
     300        strm.avail_out = glob->bufferSize - 2; 
     301        strm.next_out = glob->codecData + 2; 
     302         
     303        inflate(&strm, Z_SYNC_FLUSH); 
     304bail: 
     305        inflateEnd(&strm); 
     306} 
     307 
    267308pascal ComponentResult VobSubCodecDecodeBand(VobSubCodecGlobals glob, ImageSubCodecDecompressRecord *drp, unsigned long flags) 
    268309{ 
     
    271312         
    272313        if (glob->codecData == NULL) { 
    273                 glob->codecData = malloc(myDrp->bufferSize); 
    274                 glob->bufferSize = myDrp->bufferSize
     314                glob->codecData = malloc(myDrp->bufferSize + 2); 
     315                glob->bufferSize = myDrp->bufferSize + 2
    275316        } 
    276317         
    277         if (glob->bufferSize < myDrp->bufferSize) { 
    278                 free(glob->codecData); 
    279                 glob->codecData = malloc(myDrp->bufferSize); 
    280                 glob->bufferSize = myDrp->bufferSize; 
    281         } 
    282          
     318        glob->codecData = av_fast_realloc(glob->codecData, &glob->bufferSize, myDrp->bufferSize + 2); 
     319         
     320        if (glob->compressed) 
     321                DecompressZlib(glob, data, myDrp->bufferSize); 
    283322    // the header of a spu PS packet starts 0x000001bd 
    284323    // if it's raw spu data, the 1st 2 bytes are the length of the data 
    285         if (data[0] + data[1] == 0) 
     324        else if (data[0] + data[1] == 0) 
    286325                // remove the MPEG framing 
    287326                ExtractData(glob->codecData, data, myDrp->bufferSize); 
     
    318357        memset(drp->baseAddr, 0, myDrp->height * drp->rowBytes); 
    319358         
    320         if (EndianU16_BtoN(*(UInt16 *) glob->codecData) > myDrp->bufferSize) 
     359        if (EndianU16_BtoN(*(UInt16 *) glob->codecData) > glob->bufferSize) 
    321360                // invalid packet, not enough data 
    322361                return err;