Changeset 312

Show
Ignore:
Timestamp:
01/28/07 20:31:53 (2 years ago)
Author:
astrange
Message:

Make Handle data references work properly.
Solves temporary-file problems with SSA, fixes a bug in Matroska chapters.

Files:

Legend:

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

    r311 r312  
    478478{ 
    479479        KaxEditionEntry & edition = GetChild<KaxEditionEntry>(chapterEntries); 
     480        UInt32 emptyDataRefExtension[2]; 
    480481         
    481482        chapterTrack = NewMovieTrack(theMovie, 0, 0, kNoVolume); 
     
    488489        // sample references (TextMediaAddTextSample() will behave the same as AddSample() 
    489490        // in that it modifies the original file if that's the data reference of the media) 
    490         Handle dataRef = NULL; 
    491         Handle dataRefData = NewHandle(0); 
    492         PtrToHand(&dataRefData, &dataRef, sizeof(Handle)); 
     491        Handle dataRef = NewHandleClear(sizeof(Handle) + 1); 
     492 
     493        emptyDataRefExtension[0] = EndianU32_NtoB(sizeof(UInt32)*2); 
     494        emptyDataRefExtension[1] = EndianU32_NtoB(kDataRefExtensionInitializationData); 
     495         
     496        PtrAndHand(&emptyDataRefExtension[0], dataRef, sizeof(emptyDataRefExtension)); 
     497         
    493498        Media chapterMedia = NewTrackMedia(chapterTrack, TextMediaType, GetMovieTimeScale(theMovie),  
    494499                                                                           dataRef, HandleDataHandlerSubType); 
  • trunk/Perian.xcodeproj/project.pbxproj

    r310 r312  
    107107                3D211A300B6B1AD80051299D /* SSATagParsing.m.rl in Resources */ = {isa = PBXBuildFile; fileRef = 3D211A2F0B6B1AD80051299D /* SSATagParsing.m.rl */; }; 
    108108                3D4A7A990B5533BC004C5D6A /* ColorConversions.c in Sources */ = {isa = PBXBuildFile; fileRef = 3D4A7A980B5533BC004C5D6A /* ColorConversions.c */; }; 
     109                3DB2BB290B6C92F000416863 /* SSARenderCodec.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB2BB280B6C92F000416863 /* SSARenderCodec.m */; }; 
    109110                6116E5510B43C27B0020F1CE /* ACBaseCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6116E5370B43C27B0020F1CE /* ACBaseCodec.cpp */; }; 
    110111                6116E5520B43C27B0020F1CE /* ACCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6116E5390B43C27B0020F1CE /* ACCodec.cpp */; }; 
     
    443444                3D4A7A970B5533BC004C5D6A /* ColorConversions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ColorConversions.h; sourceTree = "<group>"; }; 
    444445                3D4A7A980B5533BC004C5D6A /* ColorConversions.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ColorConversions.c; sourceTree = "<group>"; }; 
     446                3DB2BB270B6C92F000416863 /* SSARenderCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSARenderCodec.h; sourceTree = "<group>"; }; 
     447                3DB2BB280B6C92F000416863 /* SSARenderCodec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSARenderCodec.m; sourceTree = "<group>"; }; 
    445448                6116E5370B43C27B0020F1CE /* ACBaseCodec.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ACBaseCodec.cpp; sourceTree = "<group>"; }; 
    446449                6116E5380B43C27B0020F1CE /* ACBaseCodec.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ACBaseCodec.h; sourceTree = "<group>"; }; 
     
    876879                                61D514DC0ADF3DBA00A671E1 /* SubImport.h */, 
    877880                                61D514DD0ADF3DBA00A671E1 /* SubImport.c */, 
     881                                3DB2BB270B6C92F000416863 /* SSARenderCodec.h */, 
     882                                3DB2BB280B6C92F000416863 /* SSARenderCodec.m */, 
    878883                        ); 
    879884                        name = Subtitles; 
     
    15121517                                3D211A200B6B1A540051299D /* SSADocument.m in Sources */, 
    15131518                                3D211A230B6B1A660051299D /* Categories.m in Sources */, 
     1519                                3DB2BB290B6C92F000416863 /* SSARenderCodec.m in Sources */, 
    15141520                        ); 
    15151521                        runOnlyForDeploymentPostprocessing = 0; 
  • trunk/SSADocument.m

    r311 r312  
    473473@end 
    474474 
    475 //based on Apple sample code http://developer.apple.com/samplecode/QTKitCreateMovie/listing5.html 
    476  
    477 static Movie CreateQuicktimeMovieFromTempFile(DataHandler * outDataHandler, OSErr *outErr, NSString **movieName) 
    478 { 
    479         *outErr = -1; 
    480         char *c_tempName = tempnam(NULL,"perian-subtitle-"); 
    481          
    482         // generate a name for our movie file 
    483         NSString *tempName = [NSString stringWithCString:c_tempName  
    484                                                                                         encoding:[NSString defaultCStringEncoding]]; 
    485         if (nil == tempName) goto nostring; 
    486         free(c_tempName); 
    487          
    488         Handle  dataRefH    = nil; 
    489         OSType  dataRefType; 
    490          
    491         // create a file data reference for our movie 
    492         *outErr = QTNewDataReferenceFromFullPathCFString((CFStringRef)tempName, 
    493                                                                                                          kQTNativeDefaultPathStyle, 
    494                                                                                                          0, 
    495                                                                                                          &dataRefH, 
    496                                                                                                          &dataRefType); 
    497         if (*outErr != noErr) goto nodataref; 
    498          
    499         // create a QuickTime movie from our file data reference 
    500         Movie  qtMovie  = nil; 
    501         CreateMovieStorage (dataRefH, 
    502                                                 dataRefType, 
    503                                                 'TVOD', 
    504                                                 smSystemScript, 
    505                                                 newMovieActive,  
    506                                                 outDataHandler, 
    507                                                 &qtMovie); 
    508         *outErr = GetMoviesError(); 
    509         if (*outErr != noErr) goto cantcreatemovstorage; 
    510          
    511         return qtMovie; 
    512          
    513         // error handling 
    514 cantcreatemovstorage: 
    515                 DisposeHandle(dataRefH); 
    516 nodataref: 
    517 nostring: 
    518                  
    519                 return nil; 
    520 } 
    521  
    522 /* 
    523  We import SSA by creating a temporary movie, adding samples to it, and copying it to the current movie, which can't have samples added to it as it's read-only. 
    524   
    525  I tried to use an in-memory temporary, but it completely failed to work. 
    526   
    527  This works except for saving reference movies, which include a dependency on the temporary file. They will break when it's deleted upon restart. 
    528  I don't see any apparent workaround. 
    529  */ 
    530475ComponentResult LoadSubStationAlphaSubtitles(const FSRef *theDirectory, CFStringRef filename, Movie theMovie, Track *firstSubTrack) 
    531476{ 
    532477        ComponentResult err = noErr; 
    533         Track theTrack = NULL, track2 = NULL
    534         Media theMedia = NULL, media2 = NULL
     478        Track theTrack = NULL
     479        Media theMedia = NULL
    535480        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    536481        SSADocument *ssa = [[SSADocument alloc] init]; 
    537         static UInt8 path[PATH_MAX]
    538         Handle sampleHndl = NULL, headerHndl=NULL
    539         char *data = NULL; const char *header; 
     482        Handle sampleHndl = NULL, headerHndl=NULL, drefHndl
     483        Ptr initData = NewPtr(0)
     484        const char *header; 
    540485        int i, packetCount, sampleLen; 
    541486        ImageDescriptionHandle textDesc; 
    542         DataHandler tempStor; 
    543         Movie tempMovie; 
    544         OSErr oErr; 
    545         NSString *movieName; 
    546487        Rect movieBox; 
    547          
     488        static UInt8 path[PATH_MAX]; 
     489        UInt32 emptyDataRefExtension[2]; 
     490 
    548491        FSRefMakePath(theDirectory, path, PATH_MAX); 
    549492         
     
    558501        PtrToHand(header, &headerHndl, sampleLen); 
    559502         
    560         tempMovie = CreateQuicktimeMovieFromTempFile(&tempStor,&oErr,&movieName); 
    561  
    562         GetMovieBox(theMovie, &movieBox); 
    563          
    564         theTrack = CreatePlaintextSubTrack(tempMovie, textDesc, 100, NULL, 0, kSubFormatSSA, headerHndl, movieBox); 
     503        drefHndl = NewHandleClear(sizeof(Handle) + 1); 
     504         
     505        /* Explanation of next three lines: 
     506         * The magic 'data' atom, added to an in-memory data handler, allows its data to be saved by value to a reference movie. 
     507         * It does this by saving the whole thing in the MOV header. 
     508         * This is imperfectly documented. 
     509         */ 
     510        emptyDataRefExtension[0] = EndianU32_NtoB(sizeof(UInt32)*2); 
     511        emptyDataRefExtension[1] = EndianU32_NtoB(kDataRefExtensionInitializationData); 
     512         
     513        PtrAndHand(&emptyDataRefExtension[0], drefHndl, sizeof(emptyDataRefExtension)); 
     514                 
     515        GetMovieBox(theMovie,&movieBox); 
     516        theTrack = CreatePlaintextSubTrack(theMovie, textDesc, 100, drefHndl, HandleDataHandlerSubType, 'SSA ', headerHndl, movieBox); 
    565517        if (theTrack == NULL) { 
    566518                err = GetMoviesError(); 
    567519                goto bail; 
    568520        } 
    569                 
     521         
    570522        theMedia = GetTrackMedia(theTrack); 
    571523        if (theMedia == NULL) { 
     
    575527         
    576528        BeginMediaEdits(theMedia); 
    577  
     529         
    578530        for (i = 0; i < packetCount; i++) { 
    579531                SSAEvent *p = [ssa movPacket:i]; 
    580                 TimeRecord movieStartTime = { SInt64ToWide(p->begin_time), 100, 0 }; 
    581532                const char *str = [p->line UTF8String]; 
    582533                sampleLen = strlen(str); 
    583534                 
    584535                PtrToHand(str,&sampleHndl,sampleLen); 
    585  
     536                 
    586537                err=AddMediaSample(theMedia,sampleHndl,0,sampleLen, p->end_time - p->begin_time,(SampleDescriptionHandle)textDesc, 1, 0, NULL); 
    587                 if (err != noErr) {goto bail;} 
    588  
     538                if (err != noErr) {NSLog(@"a %d",GetMoviesError()); goto bail;} 
     539                 
    589540                DisposeHandle(sampleHndl); 
    590541        } 
    591542         
    592543        EndMediaEdits(theMedia); 
    593                  
    594         InsertMediaIntoTrack(theTrack,0,0,GetMediaDuration(theMedia),fixed1); 
    595         if (err != noErr) {goto bail;} 
    596  
    597         track2 = CreatePlaintextSubTrack(theMovie, textDesc, 100, NULL, 0, kSubFormatSSA, headerHndl, movieBox); 
    598          
    599         media2 = GetTrackMedia(track2); 
    600          
    601         BeginMediaEdits(media2); 
    602         err=InsertTrackSegment(theTrack,track2,0,GetTrackDuration(theTrack),0); 
    603         EndMediaEdits(media2); 
    604          
    605          
     544         
     545        InsertMediaIntoTrack(theTrack,0,0,GetMediaDuration(theMedia),fixed1);  
     546        if (err != noErr) NSLog(@"i %d",GetMoviesError()); 
     547 
    606548        if (*firstSubTrack == NULL) 
    607                 *firstSubTrack = track2
     549                *firstSubTrack = theTrack
    608550        else 
    609                 SetTrackAlternate(*firstSubTrack, track2); 
    610          
    611         SetMediaLanguage(media2, GetFilenameLanguage(filename)); 
     551                SetTrackAlternate(*firstSubTrack, theTrack); 
     552         
     553        SetMediaLanguage(theMedia, GetFilenameLanguage(filename)); 
    612554         
    613555bail: 
     556                 
     557        [ssa release]; 
     558        [pool release]; 
    614559         
    615560        if (err) { 
     
    625570         
    626571        if (headerHndl) DisposeHandle((Handle)headerHndl); 
    627         CloseMovieStorage(tempStor); 
    628         DisposeMovieTrack(theTrack); 
    629         DisposeMovie(tempMovie); 
    630         //unlink([movieName UTF8String]); 
    631          
    632         [ssa release]; 
    633         [pool release]; 
     572        DisposeHandle((Handle)drefHndl); 
    634573         
    635574        return err; 
  • trunk/SSATagParsing.m.rl

    r310 r312  
    8787                BOOL ldirty = NO; 
    8888                 
    89                 if ([ar count] < 9) {continue;} 
     89                if ([ar count] < 9) continue; 
    9090                 
    9191                re = [[[SSARenderEntity alloc] init] autorelease]; 
     
    147147                re->styles[re->style_count-1]->astyle = cur_style;\ 
    148148                re->styles[re->style_count-1]->range = cur_range;\ 
     149                re->styles[re->style_count-1]->outlineblur = cur_be;\ 
     150                re->styles[re->style_count-1]->color = cur_color;\ 
    149151                parsetmp = [NSString stringWithCharacters:skipbegin length:p-skipbegin];\ 
    150152                [output appendString:parsetmp]; \