Changeset 242
- Timestamp:
- 01/06/07 00:44:26 (2 years ago)
- Files:
-
- trunk/CommonUtils.c (modified) (2 diffs)
- trunk/CommonUtils.h (modified) (1 diff)
- trunk/DataHandlerCallback.cpp (modified) (12 diffs)
- trunk/DataHandlerCallback.h (modified) (1 diff)
- trunk/MatroskaCodecIDs.cpp (modified) (3 diffs)
- trunk/MatroskaCodecIDs.h (modified) (1 diff)
- trunk/MatroskaImport.c (deleted)
- trunk/MatroskaImport.cpp (added)
- trunk/MatroskaImport.h (modified) (2 diffs)
- trunk/MatroskaImportPrivate.cpp (added)
- trunk/MkvImportPrivate.cpp (deleted)
- trunk/MkvImportPrivate.h (deleted)
- trunk/MkvMovieSetup.cpp (deleted)
- trunk/MkvMovieSetup.h (deleted)
- trunk/Perian.xcodeproj/project.pbxproj (modified) (7 diffs)
- trunk/SubImport.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/CommonUtils.c
r210 r242 157 157 }; 158 158 159 short TwoCharLangCodeToQTLangCode(char *lang)159 short ISO639_1ToQTLangCode(const char *lang) 160 160 { 161 161 int i; … … 170 170 } 171 171 172 short ThreeCharLangCodeToQTLangCode(char *lang)172 short ISO639_2ToQTLangCode(const char *lang) 173 173 { 174 174 int i; trunk/CommonUtils.h
r210 r242 17 17 18 18 // ISO 639-1 to language ID expected by SetMediaLanguage 19 short TwoCharLangCodeToQTLangCode(char *lang);19 short ISO639_1ToQTLangCode(const char *lang); 20 20 21 21 // ISO 639-2 to language ID expected by SetMediaLanguage 22 short ThreeCharLangCodeToQTLangCode(char *lang);22 short ISO639_2ToQTLangCode(const char *lang); 23 23 24 24 /* write the int32_t data to target & then return a pointer which points after that data */ trunk/DataHandlerCallback.cpp
r203 r242 22 22 * 23 23 */ 24 25 #include <sstream>26 24 27 25 #include "DataHandlerCallback.h" … … 51 49 this->dataHandler = NULL; 52 50 mCurrentPosition = 0; 51 filesize = 0; 53 52 this->aMode = aMode; 54 53 … … 78 77 dataHComponent = NULL; 79 78 mCurrentPosition = 0; 79 filesize = 0; 80 80 this->aMode = aMode; 81 81 … … 89 89 err = OpenAComponent(dataHComponent, &dataHandler); 90 90 if (err) { 91 stringstream Msg; 92 Msg << "Error opening data handler component " << err; 93 throw CRTError(Msg.str()); 91 throw CRTError("Error opening data handler component", err); 94 92 } 95 93 96 94 err = DataHSetDataRef(dataHandler, dataRef); 97 95 if (err) { 98 stringstream Msg; 99 Msg << "Error setting data handler ref " << err; 100 throw CRTError(Msg.str()); 96 throw CRTError("Error setting data handler ref", err); 101 97 } 102 98 … … 104 100 err = DataHOpenForRead(dataHandler); 105 101 if (err) { 106 stringstream Msg; 107 Msg << "Error opening data handler for read " << err; 108 throw CRTError(Msg.str()); 102 throw CRTError("Error opening data handler for read", err); 109 103 } 110 104 } else if (aMode == MODE_WRITE) { 111 105 err = DataHOpenForWrite(dataHandler); 112 106 if (err) { 113 stringstream Msg; 114 Msg << "Error opening data handler for write " << err; 115 throw CRTError(Msg.str()); 107 throw CRTError("Error opening data handler for write", err); 116 108 } 117 109 } else { … … 133 125 uint32 DataHandlerCallback::read(void *Buffer, size_t Size) 134 126 { 135 assert(dataHandler != 0);136 137 127 ComponentResult err = noErr; 138 128 … … 146 136 147 137 if (err) { 148 stringstream Msg; 149 Msg << "Error reading data " << err; 150 throw CRTError(Msg.str(), err); 138 throw CRTError("Error reading data", err); 151 139 } 152 140 mCurrentPosition += Size; 141 142 if (mCurrentPosition > filesize) { 143 Size -= mCurrentPosition - filesize; 144 mCurrentPosition = filesize; 145 } 153 146 154 147 // does QuickTime tell us how much it's read? … … 158 151 void DataHandlerCallback::setFilePointer(int64 Offset, LIBEBML_NAMESPACE::seek_mode Mode) 159 152 { 160 assert(Offset <= LONG_MAX);161 assert(Offset >= LONG_MIN);162 163 assert(Mode==SEEK_CUR||Mode==SEEK_END||Mode==SEEK_SET);164 165 153 switch ( Mode ) 166 154 { … … 180 168 size_t DataHandlerCallback::write(const void *Buffer, size_t Size) 181 169 { 182 assert(dataHandler != NULL);183 184 170 ComponentResult err = noErr; 185 171 … … 193 179 194 180 if (err) { 195 stringstream Msg; 196 Msg << "Error writing data " << err; 197 throw CRTError(Msg.str(), err); 181 throw CRTError("Error writing data", err); 198 182 } 199 183 mCurrentPosition += Size; … … 205 189 uint64 DataHandlerCallback::getFilePointer() 206 190 { 207 assert(dataHandler != NULL);208 209 191 return mCurrentPosition; 210 192 } … … 224 206 { 225 207 ComponentResult err = noErr; 226 SInt64 filesize;227 208 wide wideFilesize; 209 210 if (filesize > 0) 211 return filesize; 228 212 229 213 err = DataHGetFileSize64(dataHandler, &wideFilesize); trunk/DataHandlerCallback.h
r203 r242 58 58 bool supportsWideOffsets; 59 59 open_mode aMode; 60 SInt64 filesize; 60 61 61 62 public: trunk/MatroskaCodecIDs.cpp
r218 r242 30 30 #include "MatroskaCodecIDs.h" 31 31 #include "CommonUtils.h" 32 #include "Codecprintf.h" 32 33 #include <string> 33 34 … … 441 442 ComponentResult MkvFinishSampleDescription(KaxTrackEntry *tr_entry, SampleDescriptionHandle desc, DescExtDirection dir) 442 443 { 443 switch ((*desc)->dataFormat) { 444 case kH264CodecType: 445 return DescExt_H264(tr_entry, desc, dir); 446 447 case kAudioFormatXiphVorbis: 448 return DescExt_XiphVorbis(tr_entry, desc, dir); 449 450 case kAudioFormatXiphFLAC: 451 return DescExt_XiphFLAC(tr_entry, desc, dir); 452 453 case kSubFormatVobSub: 454 return DescExt_VobSub(tr_entry, desc, dir); 455 456 case kVideoFormatReal5: 457 case kVideoFormatRealG2: 458 case kVideoFormatReal8: 459 case kVideoFormatReal9: 460 return DescExt_Real(tr_entry, desc, dir); 461 462 case kMPEG4VisualCodecType: 463 return DescExt_mp4v(tr_entry, desc, dir); 464 } 465 return noErr; 444 KaxCodecID & tr_codec = GetChild<KaxCodecID>(*tr_entry); 445 446 string codecString(tr_codec); 447 448 if (codecString == MKV_V_MS) { 449 // BITMAPINFOHEADER is stored in the private data, and some codecs (WMV) 450 // need it to decode 451 KaxCodecPrivate & codecPrivate = GetChild<KaxCodecPrivate>(*tr_entry); 452 453 Handle imgDescExt = NewHandle(codecPrivate.GetSize()); 454 memcpy(*imgDescExt, codecPrivate.GetBuffer(), codecPrivate.GetSize()); 455 456 AddImageDescriptionExtension((ImageDescriptionHandle) desc, imgDescExt, 'strf'); 457 458 } else if (codecString == MKV_V_QT) { 459 // This seems to work fine, but there's something it's missing to get the 460 // image description to match perfectly (last 2 bytes are different) 461 // Figure it out later... 462 KaxCodecPrivate & codecPrivate = GetChild<KaxCodecPrivate>(*tr_entry); 463 if (codecPrivate.GetSize() < sizeof(ImageDescription)) { 464 Codecprintf(NULL, "MatroskaQT: QuickTime track %hu doesn't have needed stsd data\n", 465 uint16(tr_entry->TrackNumber())); 466 return -1; 467 } 468 469 ImageDescriptionHandle imgDesc = (ImageDescriptionHandle) desc; 470 SetHandleSize((Handle) imgDesc, codecPrivate.GetSize()); 471 memcpy(&(*imgDesc)->cType, codecPrivate.GetBuffer(), codecPrivate.GetSize()); 472 // it's stored in big endian, so flip endian to native 473 // I think we have to do this, need to check on Intel without them 474 (*imgDesc)->idSize = codecPrivate.GetSize(); 475 (*imgDesc)->cType = EndianU32_BtoN((*imgDesc)->cType); 476 (*imgDesc)->resvd1 = EndianS32_BtoN((*imgDesc)->resvd1); 477 (*imgDesc)->resvd2 = EndianS16_BtoN((*imgDesc)->resvd2); 478 (*imgDesc)->dataRefIndex = EndianS16_BtoN((*imgDesc)->dataRefIndex); 479 (*imgDesc)->version = EndianS16_BtoN((*imgDesc)->version); 480 (*imgDesc)->revisionLevel = EndianS16_BtoN((*imgDesc)->revisionLevel); 481 (*imgDesc)->vendor = EndianS32_BtoN((*imgDesc)->vendor); 482 (*imgDesc)->temporalQuality = EndianU32_BtoN((*imgDesc)->temporalQuality); 483 (*imgDesc)->spatialQuality = EndianU32_BtoN((*imgDesc)->spatialQuality); 484 (*imgDesc)->width = EndianS16_BtoN((*imgDesc)->width); 485 (*imgDesc)->height = EndianS16_BtoN((*imgDesc)->height); 486 (*imgDesc)->vRes = EndianS32_BtoN((*imgDesc)->vRes); 487 (*imgDesc)->hRes = EndianS32_BtoN((*imgDesc)->hRes); 488 (*imgDesc)->dataSize = EndianS32_BtoN((*imgDesc)->dataSize); 489 (*imgDesc)->frameCount = EndianS16_BtoN((*imgDesc)->frameCount); 490 (*imgDesc)->depth = EndianS16_BtoN((*imgDesc)->depth); 491 (*imgDesc)->clutID = EndianS16_BtoN((*imgDesc)->clutID); 492 #if 0 493 } else if (codecString == MKV_V_THEORA) { 494 // we need 3 setup packets for the image description extension, but 495 // the sample files I muxed have only 2 packets in the Codec Private element. 496 // Despite the Matroska specs agreeing with me about the 3 packets. 497 // Will figure out later. 498 } else if (codecString.compare(0, strlen(MKV_A_AAC), string(MKV_A_AAC)) == 0) { 499 // esds extension gives us the channel mapping for AAC 500 SoundDescriptionHandle sndDesc = (SoundDescriptionHandle) desc; 501 502 KaxCodecPrivate *codecPrivate = FindChild<KaxCodecPrivate>(*tr_entry); 503 if (codecPrivate == NULL) 504 return; 505 506 Handle sndDescExt = NewHandle(codecPrivate->GetSize()); 507 memcpy(*sndDescExt, codecPrivate->GetBuffer(), codecPrivate->GetSize()); 508 509 AddSoundDescriptionExtension(sndDesc, sndDescExt, 'esds'); 510 511 DisposeHandle((Handle) sndDescExt); 512 #endif 513 } else { 514 switch ((*desc)->dataFormat) { 515 case kH264CodecType: 516 return DescExt_H264(tr_entry, desc, dir); 517 518 case kAudioFormatXiphVorbis: 519 return DescExt_XiphVorbis(tr_entry, desc, dir); 520 521 case kAudioFormatXiphFLAC: 522 return DescExt_XiphFLAC(tr_entry, desc, dir); 523 524 case kSubFormatVobSub: 525 return DescExt_VobSub(tr_entry, desc, dir); 526 527 case kVideoFormatReal5: 528 case kVideoFormatRealG2: 529 case kVideoFormatReal8: 530 case kVideoFormatReal9: 531 return DescExt_Real(tr_entry, desc, dir); 532 533 case kMPEG4VisualCodecType: 534 return DescExt_mp4v(tr_entry, desc, dir); 535 } 536 } 537 return noErr; 538 } 539 540 // some default channel layouts for up to 8 channels 541 // vorbis and aac should be correct unless extradata specifices something else for aac 542 static const AudioChannelLayout vorbisChannelLayouts[9] = { 543 { 0 }, 544 { kAudioChannelLayoutTag_Mono }, 545 { kAudioChannelLayoutTag_Stereo }, 546 { kAudioChannelLayoutTag_UseChannelBitmap, kAudioChannelBit_Left | kAudioChannelBit_Right | kAudioChannelBit_CenterSurround }, 547 { kAudioChannelLayoutTag_Quadraphonic }, 548 { kAudioChannelLayoutTag_MPEG_5_0_C }, 549 { kAudioChannelLayoutTag_MPEG_5_1_C } 550 }; 551 552 // these should be the default for the number of channels; esds can specify other mappings 553 static const AudioChannelLayout aacChannelLayouts[9] = { 554 { 0 }, 555 { kAudioChannelLayoutTag_Mono }, 556 { kAudioChannelLayoutTag_Stereo }, 557 { kAudioChannelLayoutTag_MPEG_3_0_B }, // C L R according to wiki.multimedia.cx 558 { kAudioChannelLayoutTag_AAC_4_0 }, 559 { kAudioChannelLayoutTag_AAC_5_0 }, 560 { kAudioChannelLayoutTag_AAC_5_1 }, 561 { kAudioChannelLayoutTag_AAC_6_1 }, 562 { kAudioChannelLayoutTag_AAC_7_1 } 563 }; 564 565 static const AudioChannelLayout ac3ChannelLayouts[9] = { 566 { 0 }, 567 { kAudioChannelLayoutTag_ITU_1_0 }, 568 { kAudioChannelLayoutTag_ITU_2_0 }, 569 { kAudioChannelLayoutTag_ITU_3_0 }, 570 { kAudioChannelLayoutTag_ITU_3_1 }, 571 { kAudioChannelLayoutTag_ITU_3_2 }, 572 { kAudioChannelLayoutTag_ITU_3_2_1 } 573 }; 574 575 576 AudioChannelLayout GetDefaultChannelLayout(AudioStreamBasicDescription *asbd) 577 { 578 AudioChannelLayout acl = {0}; 579 580 if (asbd->mChannelsPerFrame <= 8) { 581 switch (asbd->mFormatID) { 582 case kAudioFormatXiphVorbis: 583 case kAudioFormatXiphFLAC: // FLAC doesn't have official mappings, but the author said Vorbis's were likely to be used 584 acl = vorbisChannelLayouts[asbd->mChannelsPerFrame]; 585 break; 586 587 case kAudioFormatMPEG4AAC: 588 // TODO: use extradata to make ACL 589 acl = aacChannelLayouts[asbd->mChannelsPerFrame]; 590 break; 591 592 case kAudioFormatAC3: 593 // TODO: implement channel layout choosing based on an AC3 frame 594 acl = ac3ChannelLayouts[asbd->mChannelsPerFrame]; 595 break; 596 } 597 } 598 599 return acl; 466 600 } 467 601 … … 480 614 return noErr; 481 615 } 482 483 484 short GetTrackLanguage(KaxTrackEntry *tr_entry) {485 KaxTrackLanguage *trLang = FindChild<KaxTrackLanguage>(*tr_entry);486 if (trLang != NULL) {487 char lang[4];488 string langStr(*trLang);489 strncpy(lang, langStr.c_str(), 3);490 lang[3] = '\0';491 492 return ThreeCharLangCodeToQTLangCode(lang);493 }494 return langUnspecified;495 }496 497 616 498 617 trunk/MatroskaCodecIDs.h
r218 r242 52 52 ComponentResult MkvFinishSampleDescription(KaxTrackEntry *tr_entry, SampleDescriptionHandle desc, DescExtDirection dir); 53 53 ComponentResult MkvFinishASBD(KaxTrackEntry *tr_entry, AudioStreamBasicDescription *asbd); 54 short GetTrackLanguage(KaxTrackEntry *tr_entry);55 54 FourCharCode GetFourCC(KaxTrackEntry *tr_entry); 55 AudioChannelLayout GetDefaultChannelLayout(AudioStreamBasicDescription *asbd); 56 56 57 57 #endif trunk/MatroskaImport.h
r119 r242 26 26 #define __MATROSKAIMPORT_H__ 27 27 28 #include <vector> 28 29 #include <QuickTime/QuickTime.h> 30 #include "DataHandlerCallback.h" 29 31 30 struct MkvBlock; 31 struct KaxPrivate; 32 #include <ebml/EbmlStream.h> 33 #include <matroska/KaxSeekHead.h> 34 #include <matroska/KaxInfo.h> 35 #include <matroska/KaxTracks.h> 36 #include <matroska/KaxChapters.h> 37 #include <matroska/KaxBlock.h> 32 38 33 typedef struct { 34 UInt16 trackNumber; 35 Track theTrack; 36 Media theMedia; 37 SampleDescriptionHandle sampleHdl; 38 AudioStreamBasicDescription asbd; 39 UInt64 defaultDuration; 40 // this is so the last block of a track that has no DefaultDuration can be imported 41 // with the same duration as the preceding block 42 // any better solutions? 43 UInt64 lastDuration; 44 UInt64 uid; 45 SInt64 timecodeScale; 39 using namespace libmatroska; 40 using namespace std; 41 42 43 struct MatroskaFrame { 44 TimeValue64 timecode; 45 // TimeValue64 duration; 46 UInt32 duration; // hack so that H.264 tracks kinda work 47 SInt64 offset; 48 SInt64 size; 49 short flags; 50 }; 51 52 class MatroskaTrack { 53 public: 54 MatroskaTrack(); 46 55 47 QTMutableSampleTableRef sampleTable; 48 QTSampleDescriptionID qtSampleDesc; 56 // retains the sampleTable if it exists, allocates a new SampleDescriptionHandle 57 // and copies it if necessary 58 MatroskaTrack(const MatroskaTrack ©); 59 60 // releases the sampleTable and sample description 61 ~MatroskaTrack(); 62 63 // adds the all the frames in the block group to the sample table if it exists, 64 // the media otherwise. If this track type is subtitle, also inserts it into the track. 65 void AddBlock(KaxBlockGroup &blockGroup); 66 67 UInt16 number; 68 UInt8 type; 69 Track theTrack; 70 Media theMedia; 71 SampleDescriptionHandle desc; 72 QTMutableSampleTableRef sampleTable; 73 QTSampleDescriptionID qtSampleDesc; 74 SInt64 timecodeScale; 75 76 private: 77 // adds an individual frame from a block group into the sample table if it exists, 78 // the media otherwise, and into the track if the track is a subtitle track. 79 SInt64 AddFrame(MatroskaFrame &frame); 80 81 // Since the duration in Matroska files is generally rather unreliable, rely only on 82 // the difference in timestamps between two frames. Thus, AddBlock() buffers frames 83 // from one block group until the next block group is found to set the duration of the 84 // previous ones to be the difference in timestamps. 85 vector<MatroskaFrame> lastFrames; 86 }; 87 88 89 class MatroskaImport { 90 public: 91 // public interface functions, simply called from the C equivalents defined 92 // by ComponentDispatchHelper.c and implemented in MatroskaImport.cpp 93 94 // MatroskaImportOpen() 95 MatroskaImport(ComponentInstance self); 96 97 // MatrosakImportClose() 98 ~MatroskaImport(); 99 100 // MatroskaImportDataRef() 101 ComponentResult ImportDataRef(Handle dataRef, OSType dataRefType, Movie theMovie, 102 Track targetTrack, Track *usedTrack, 103 TimeValue atTime, TimeValue *durationAdded, 104 long inFlags, long *outFlags); 105 106 // MatroskaImportValidateDataRef() 107 ComponentResult ValidateDataRef(Handle dataRef, OSType dataRefType, UInt8 *valid); 108 109 // we need to get our component instance to get our mime type resource 110 ComponentInstance Component() { return self; } 111 112 private: 113 // open the ioHandler and EBML stream, and read the EBML head to verify it's a matroska file 114 // returns true if it's a valid file and false otherwise 115 bool OpenFile(); 116 117 // create all the tracks and their sample descriptions as described by the file header 118 // also create chapters if any. Leaves el_l1 pointing to the first cluster, unread. 119 void SetupMovie(); 120 121 // This finds the next level 1 element and both replaces the el_l1 variable with it and 122 // returns it. Does not read the data. 123 EbmlElement *NextLevel1Element(); 124 125 // sets up timescale & file name metadata 126 void ReadSegmentInfo(KaxInfo &segmentInfo); 127 128 // sets up all the movie tracks and media 129 void ReadTracks(KaxTracks &trackEntries); 130 131 // Creates a chapter track, but doesn't actually add the chapter reference to the other 132 // enabled tracks in case some weird file has this element before the Tracks element 133 void ReadChapters(KaxChapters &chapterEntries); 134 135 // These three are called from ReadTracks to set up a track of the specific type, 136 // modifying the MatroskaTrack structure to reflect the newly create track. 137 // They return an error if the track couldn't be created or noErr on success. 138 ComponentResult AddVideoTrack(KaxTrackEntry &kaxTrack, MatroskaTrack &mkvTrack); 139 ComponentResult AddAudioTrack(KaxTrackEntry &kaxTrack, MatroskaTrack &mkvTrack); 140 ComponentResult AddSubtitleTrack(KaxTrackEntry &kaxTrack, MatroskaTrack &mkvTrack); 141 142 // this is called recursively to add only the leaves on the chapter tree to 143 // chapter track, since QT doesn't support chapter nesting. 144 void AddChapterAtom(KaxChapterAtom *atom, Track chapterTrack); 145 49 146 50 UInt8 trackType;51 52 struct MkvBlock *lastBlock;53 } MkvTrackRecord, *MkvTrackPtr, **MkvTrackHandle;54 55 // Component globals56 typedef struct {57 147 ComponentInstance self; 58 148 Handle dataRef; … … 60 150 61 151 Movie theMovie; 62 Track baseTrack; // so that the duration of the movie remains 63 // constant while idle importing 64 SInt64 segmentTimecodeScale; 65 TimeValue64 movieDuration; // in the timescale of segmentTimecodeScale 66 67 CFStringRef filename; 68 bool useIdle; 69 TimeValue maxLoadedTime; 70 TimeValue lastIdleTime; 71 struct KaxPrivate *kaxPrivate; 72 } MatroskaImportGlobalsRecord, *MatroskaImportGlobals; 152 Track chapterTrack; 153 Track baseTrack; // fake track created to set the duration 154 // of a movie while idle importing 155 SInt64 timecodeScale; 156 TimeValue64 movieDuration; // in the timescale of timecodeScale 157 158 DataHandlerCallback *ioHandler; 159 EbmlStream *aStream; 160 161 EbmlElement *el_l0; 162 EbmlElement *el_l1; 163 164 vector<MatroskaTrack> tracks; 165 }; 73 166 74 167 #endif trunk/Perian.xcodeproj/project.pbxproj
r240 r242 164 164 61CB11F30ACE0F6D007994BD /* libebml.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 61CB10FF0ACDF350007994BD /* libebml.a */; }; 165 165 61CB11F40ACE0F73007994BD /* libmatroska.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 61CB11770ACDF4D8007994BD /* libmatroska.a */; }; 166 61CB12090ACE0F85007994BD /* MatroskaImport.c in Sources */ = {isa = PBXBuildFile; fileRef = 61D691570AC8E382000EFC7D /* MatroskaImport.c */; }; 167 61CB120A0ACE0F86007994BD /* MkvImportPrivate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61D6915E0AC8E382000EFC7D /* MkvImportPrivate.cpp */; }; 168 61CB120B0ACE0F87007994BD /* MkvMovieSetup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61D691600AC8E382000EFC7D /* MkvMovieSetup.cpp */; }; 166 61CB12090ACE0F85007994BD /* MatroskaImport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61D691570AC8E382000EFC7D /* MatroskaImport.cpp */; }; 169 167 61CB120C0ACE0F8A007994BD /* DataHandlerCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61D6914E0AC8E382000EFC7D /* DataHandlerCallback.cpp */; }; 170 168 61CB120D0ACE0F8D007994BD /* MatroskaCodecIDs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61D691500AC8E382000EFC7D /* MatroskaCodecIDs.cpp */; }; … … 172 170 61D514DE0ADF3DBA00A671E1 /* SubImport.c in Sources */ = {isa = PBXBuildFile; fileRef = 61D514DD0ADF3DBA00A671E1 /* SubImport.c */; }; 173 171 61D517730AE0402E00A671E1 /* CommonUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = 61D517720AE0402E00A671E1 /* CommonUtils.c */; }; 172 61FD41330B4F6F0800BEEFEA /* MatroskaImportPrivate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61FD41320B4F6F0800BEEFEA /* MatroskaImportPrivate.cpp */; }; 174 173 83D1D6CF0B4C7AC400E09EC9 /* PreferencePanes.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83D1D6CE0B4C7AC400E09EC9 /* PreferencePanes.framework */; }; 175 174 83D1D6DE0B4C7F8300E09EC9 /* PerianPrefPane.nib in Resources */ = {isa = PBXBuildFile; fileRef = 83D1D6DD0B4C7F8300E09EC9 /* PerianPrefPane.nib */; }; … … 395 394 61D691550AC8E382000EFC7D /* MatroskaExportDispatch.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MatroskaExportDispatch.h; sourceTree = "<group>"; }; 396 395 61D691560AC8E382000EFC7D /* MatroskaExportVersion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MatroskaExportVersion.h; sourceTree = "<group>"; }; 397 61D691570AC8E382000EFC7D /* MatroskaImport.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = MatroskaImport.c; sourceTree = "<group>"; };396 61D691570AC8E382000EFC7D /* MatroskaImport.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MatroskaImport.cpp; sourceTree = "<group>"; }; 398 397 61D691580AC8E382000EFC7D /* MatroskaImport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MatroskaImport.h; sourceTree = "<group>"; }; 399 398 61D691590AC8E382000EFC7D /* MatroskaImport.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; path = MatroskaImport.r; sourceTree = "<group>"; }; … … 402 401 61D6915C0AC8E382000EFC7D /* MkvExportPrivate.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MkvExportPrivate.cpp; sourceTree = "<group>"; }; 403 402 61D6915D0AC8E382000EFC7D /* MkvExportPrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MkvExportPrivate.h; sourceTree = "<group>"; }; 404 61D6915E0AC8E382000EFC7D /* MkvImportPrivate.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MkvImportPrivate.cpp; sourceTree = "<group>"; }; 405 61D6915F0AC8E382000EFC7D /* MkvImportPrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MkvImportPrivate.h; sourceTree = "<group>"; }; 406 61D691600AC8E382000EFC7D /* MkvMovieSetup.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MkvMovieSetup.cpp; sourceTree = "<group>"; }; 407 61D691610AC8E382000EFC7D /* MkvMovieSetup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MkvMovieSetup.h; sourceTree = "<group>"; }; 403 61FD41320B4F6F0800BEEFEA /* MatroskaImportPrivate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MatroskaImportPrivate.cpp; sourceTree = "<group>"; }; 408 404 83D1D6C80B4C794700E09EC9 /* PerianPane.prefPane */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PerianPane.prefPane; sourceTree = BUILT_PRODUCTS_DIR; }; 409 405 83D1D6C90B4C794800E09EC9 /* PerianPane-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "PerianPane-Info.plist"; sourceTree = "<group>"; }; … … 739 735 isa = PBXGroup; 740 736 children = ( 741 61D691570AC8E382000EFC7D /* MatroskaImport.c */,737 61D691570AC8E382000EFC7D /* MatroskaImport.cpp */, 742 738 61D691580AC8E382000EFC7D /* MatroskaImport.h */, 739 61FD41320B4F6F0800BEEFEA /* MatroskaImportPrivate.cpp */, 743 740 61D6915A0AC8E382000EFC7D /* MatroskaImportDispatch.h */, 744 741 61D6915B0AC8E382000EFC7D /* MatroskaImportVersion.h */, 745 61D6915E0AC8E382000EFC7D /* MkvImportPrivate.cpp */,746 61D6915F0AC8E382000EFC7D /* MkvImportPrivate.h */,747 61D691600AC8E382000EFC7D /* MkvMovieSetup.cpp */,748 61D691610AC8E382000EFC7D /* MkvMovieSetup.h */,749 742 ); 750 743 name = Import; … … 1080 1073 112E0C820A6436BA00DB4C29 /* FFusionCodec.c in Sources */, 1081 1074 113F589A0A6B091600509987 /* Codecprintf.c in Sources */, 1082 61CB12090ACE0F85007994BD /* MatroskaImport.c in Sources */, 1083 61CB120A0ACE0F86007994BD /* MkvImportPrivate.cpp in Sources */, 1084 61CB120B0ACE0F87007994BD /* MkvMovieSetup.cpp in Sources */, 1075 61CB12090ACE0F85007994BD /* MatroskaImport.cpp in Sources */, 1085 1076 61CB120C0ACE0F8A007994BD /* DataHandlerCallback.cpp in Sources */, 1086 1077 61CB120D0ACE0F8D007994BD /* MatroskaCodecIDs.cpp in Sources */, … … 1098 1089 6116E6200B44A5B30020F1CE /* CADebugMacros.cpp in Sources */, 1099 1090 6116E6220B44A5BC0020F1CE /* CABundleLocker.cpp in Sources */, 1091 61FD41330B4F6F0800BEEFEA /* MatroskaImportPrivate.cpp in Sources */, 1100 1092 ); 1101 1093 runOnlyForDeploymentPostprocessing = 0; trunk/SubImport.c
r217 r242 38 38 langStr = CFStringCreateWithSubstring(NULL, baseName, findResult); 39 39 CFStringGetCString(langStr, langCStr, 4, kCFStringEncodingASCII); 40 lang = ThreeCharLangCodeToQTLangCode(langCStr);40 lang = ISO639_2ToQTLangCode(langCStr); 41 41 42 42 CFRelease(langStr); … … 48 48 langStr = CFStringCreateWithSubstring(NULL, baseName, findResult); 49 49 CFStringGetCString(langStr, langCStr, 3, kCFStringEncodingASCII); 50 lang = TwoCharLangCodeToQTLangCode(langCStr);50 lang = ISO639_1ToQTLangCode(langCStr); 51 51 52 52 CFRelease(langStr);
