Changeset 1015

Show
Ignore:
Timestamp:
01/19/09 18:50:57 (1 year ago)
Author:
gbooker
Message:

Check for existence of force subtitles, and import them as a separate track (with it given priority over total subtitles)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/Subtitles/SubImport.mm

    r1006 r1015  
    744744} 
    745745 
    746 static void ReadPacketTimes(uint8_t *packet, uint32_t length, uint16_t *startTime, uint16_t *endTime) { 
     746static void ReadPacketTimes(uint8_t *packet, uint32_t length, uint16_t *startTime, uint16_t *endTime, uint8_t *forced) { 
    747747        // to set whether the key sequences 0x01 - 0x02 have been seen 
    748748        Boolean loop = TRUE; 
    749749        *startTime = *endTime = 0; 
     750        *forced = 0; 
    750751 
    751752        int controlOffset = (packet[2] << 8) + packet[3]; 
     
    760761                        switch (controlSeq[i]) { 
    761762                                case 0x00: 
    762                                         // subpicture identifier, we don't care 
     763                                        *forced = 1; 
    763764                                        i++; 
    764765                                        break; 
     
    815816                } 
    816817        } 
    817 }        
     818
     819 
     820typedef struct { 
     821        Movie theMovie; 
     822        OSType dataRefType; 
     823        Handle dataRef; 
     824        int imageWidth; 
     825        int imageHeight; 
     826        Rect movieBox; 
     827        NSData *subFileData; 
     828} VobSubInfo; 
     829 
     830static OSErr loadTrackIntoMovie(VobSubTrack *track, VobSubInfo info, uint8_t onlyForced, Track *theTrack, uint8_t *hasForcedSubtitles) 
     831
     832        ImageDescriptionHandle imgDesc; 
     833        Media trackMedia = createVobSubMedia(info.theMovie, info.movieBox, &imgDesc, info.dataRef, info.dataRefType, track); 
     834        if(info.imageWidth != 0) 
     835        { 
     836                (*imgDesc)->width = info.imageWidth; 
     837                (*imgDesc)->height = info.imageHeight; 
     838        } 
     839         
     840        int sampleCount = [track->samples count]; 
     841        int totalSamples = 0; 
     842        SampleReference64Ptr samples = (SampleReference64Ptr)calloc(sampleCount*2, sizeof(SampleReference64Record)); 
     843        SampleReference64Ptr sample = samples; 
     844        int i; 
     845        uint32_t lastTime = 0; 
     846        VobSubSample *firstSample = nil; 
     847        for(i=0; i<sampleCount; i++) 
     848        { 
     849                VobSubSample *currentSample = [track->samples objectAtIndex:i]; 
     850                int offset = currentSample->fileOffset; 
     851                int nextOffset; 
     852                if(i == sampleCount - 1) 
     853                        nextOffset = [info.subFileData length]; 
     854                else 
     855                        nextOffset = ((VobSubSample *)[track->samples objectAtIndex:i+1])->fileOffset; 
     856                int size = nextOffset - offset; 
     857                if(size < 0) 
     858                        //Skip samples for which we cannot determine size 
     859                        continue; 
     860                 
     861                NSData *subData = [info.subFileData subdataWithRange:NSMakeRange(offset, size)]; 
     862                uint8_t *extracted = (uint8_t *)malloc(size); 
     863                int extractedSize = ExtractVobSubPacket(extracted, (const UInt8 *)[subData bytes], size, &size); 
     864                 
     865                uint16_t startTimestamp, endTimestamp; 
     866                uint8_t forced; 
     867                ReadPacketTimes(extracted, extractedSize, &startTimestamp, &endTimestamp, &forced); 
     868                if(onlyForced && !forced) 
     869                        continue; 
     870                if(forced) 
     871                        *hasForcedSubtitles = forced; 
     872                free(extracted); 
     873                uint32_t startTime = currentSample->timeStamp + startTimestamp; 
     874                uint32_t endTime = currentSample->timeStamp + endTimestamp; 
     875                int duration = endTimestamp - startTimestamp; 
     876                if(duration <= 0) 
     877                        //Skip samples which are broken 
     878                        continue; 
     879                if(firstSample == nil) 
     880                { 
     881                        currentSample->timeStamp = startTime; 
     882                        firstSample = currentSample; 
     883                } 
     884                else if(lastTime != startTime) 
     885                { 
     886                        //insert a sample with no real data, to clear the subs 
     887                        memset(sample, 0, sizeof(SampleReference64Record)); 
     888                        sample->durationPerSample = startTime - lastTime; 
     889                        sample->numberOfSamples = 1; 
     890                        sample->dataSize = 1; 
     891                        totalSamples++; 
     892                        sample++; 
     893                } 
     894                 
     895                sample->dataOffset.hi = 0; 
     896                sample->dataOffset.lo = offset; 
     897                sample->dataSize = size; 
     898                sample->sampleFlags = 0; 
     899                sample->durationPerSample = duration; 
     900                sample->numberOfSamples = 1; 
     901                lastTime = endTime; 
     902                totalSamples++; 
     903                sample++; 
     904        } 
     905        AddMediaSampleReferences64(trackMedia, (SampleDescriptionHandle)imgDesc, totalSamples, samples, NULL); 
     906        free(samples); 
     907        NSString *langStr = track->language; 
     908        int lang = langUnspecified; 
     909        if([langStr length] == 3) 
     910        { 
     911                char langCStr[4] = ""; 
     912                 
     913                CFStringGetCString((CFStringRef)langStr, langCStr, 4, kCFStringEncodingASCII); 
     914                lang = ISO639_2ToQTLangCode(langCStr); 
     915        } 
     916        else if([langStr length] == 2) 
     917        { 
     918                char langCStr[3] = ""; 
     919                 
     920                CFStringGetCString((CFStringRef)langStr, langCStr, 3, kCFStringEncodingASCII); 
     921                lang = ISO639_1ToQTLangCode(langCStr);                           
     922        } 
     923        SetMediaLanguage(trackMedia, lang); 
     924         
     925        TimeValue mediaDuration = GetMediaDuration(trackMedia); 
     926        TimeValue movieTimeScale = GetMovieTimeScale(info.theMovie); 
     927        *theTrack = GetMediaTrack(trackMedia); 
     928        if(firstSample == nil) 
     929                firstSample = [track->samples objectAtIndex:0]; 
     930        return InsertMediaIntoTrack(*theTrack, (firstSample->timeStamp * movieTimeScale)/1000, 0, mediaDuration, fixed1); 
     931
    818932 
    819933typedef enum { 
     
    9331047                while((track = [trackEnum nextObject]) != nil) 
    9341048                { 
    935                         ImageDescriptionHandle imgDesc; 
    936                         Media trackMedia = createVobSubMedia(theMovie, movieBox, &imgDesc, dataRef, dataRefType, track); 
    937                         if(imageWidth != 0) 
     1049                        Track theTrack; 
     1050                        VobSubInfo info = {theMovie, dataRefType, dataRef, imageWidth, imageHeight, movieBox, subFileData}; 
     1051                        uint8_t hasForced = 0; 
     1052                        err = loadTrackIntoMovie(track, info, 0, &theTrack, &hasForced); 
     1053                        if(hasForced) 
    9381054                        { 
    939                                 (*imgDesc)->width = imageWidth; 
    940                                 (*imgDesc)->height = imageHeight; 
     1055                                Track forcedTrack; 
     1056                                err = loadTrackIntoMovie(track, info, 1, &forcedTrack, &hasForced); 
     1057                                if(*firstSubTrack == NULL) 
     1058                                        *firstSubTrack = forcedTrack; 
     1059                                else 
     1060                                        SetTrackAlternate(*firstSubTrack, forcedTrack); 
    9411061                        } 
    9421062                         
    943                         int sampleCount = [track->samples count]; 
    944                         int totalSamples = sampleCount; 
    945                         SampleReference64Ptr samples = (SampleReference64Ptr)calloc(sampleCount*2, sizeof(SampleReference64Record)); 
    946                         SampleReference64Ptr sample = samples; 
    947                         int i; 
    948                         uint32_t lastTime = 0; 
    949                         for(i=0; i<sampleCount; i++) 
    950                         { 
    951                                 VobSubSample *currentSample = [track->samples objectAtIndex:i]; 
    952                                 int offset = currentSample->fileOffset; 
    953                                 int nextOffset; 
    954                                 if(i == sampleCount - 1) 
    955                                         nextOffset = subFileSize; 
    956                                 else 
    957                                         nextOffset = ((VobSubSample *)[track->samples objectAtIndex:i+1])->fileOffset; 
    958                                 int size = nextOffset - offset; 
    959                                 if(size < 0) 
    960                                         //Skip samples for which we cannot determine size 
    961                                         continue; 
    962                                  
    963                                 NSData *subData = [subFileData subdataWithRange:NSMakeRange(offset, size)]; 
    964                                 uint8_t *extracted = (uint8_t *)malloc(size); 
    965                                 int extractedSize = ExtractVobSubPacket(extracted, (const UInt8 *)[subData bytes], size, &size); 
    966                                  
    967                                 uint16_t startTimestamp, endTimestamp; 
    968                                 ReadPacketTimes(extracted, extractedSize, &startTimestamp, &endTimestamp); 
    969                                 free(extracted); 
    970                                 uint32_t startTime = currentSample->timeStamp + startTimestamp; 
    971                                 uint32_t endTime = currentSample->timeStamp + endTimestamp; 
    972                                 int duration = endTimestamp - startTimestamp; 
    973                                 if(duration <= 0) 
    974                                         //Skip samples which are broken 
    975                                         continue; 
    976                                 if(i == 0) 
    977                                         currentSample->timeStamp = startTime; 
    978                                 else if(lastTime != startTime) 
    979                                 { 
    980                                         //insert a sample with no real data, to clear the subs 
    981                                         memset(sample, 0, sizeof(SampleReference64Record)); 
    982                                         sample->durationPerSample = startTime - lastTime; 
    983                                         sample->numberOfSamples = 1; 
    984                                         sample->dataSize = 1; 
    985                                         totalSamples++; 
    986                                         sample++; 
    987                                 } 
    988                                  
    989                                 sample->dataOffset.hi = 0; 
    990                                 sample->dataOffset.lo = offset; 
    991                                 sample->dataSize = size; 
    992                                 sample->sampleFlags = 0; 
    993                                 sample->durationPerSample = duration; 
    994                                 sample->numberOfSamples = 1; 
    995                                 lastTime = endTime; 
    996                                  
    997                                 sample++; 
    998                         } 
    999                         AddMediaSampleReferences64(trackMedia, (SampleDescriptionHandle)imgDesc, totalSamples, samples, NULL); 
    1000                         free(samples); 
    1001                         NSString *langStr = track->language; 
    1002                         int lang = langUnspecified; 
    1003                         if([langStr length] == 3) 
    1004                         { 
    1005                                 char langCStr[4] = ""; 
    1006                                  
    1007                                 CFStringGetCString((CFStringRef)langStr, langCStr, 4, kCFStringEncodingASCII); 
    1008                                 lang = ISO639_2ToQTLangCode(langCStr); 
    1009                         } 
    1010                         else if([langStr length] == 2) 
    1011                         { 
    1012                                 char langCStr[3] = ""; 
    1013                                  
    1014                                 CFStringGetCString((CFStringRef)langStr, langCStr, 3, kCFStringEncodingASCII); 
    1015                                 lang = ISO639_1ToQTLangCode(langCStr);                           
    1016                         } 
    1017                         SetMediaLanguage(trackMedia, lang); 
    1018                          
    1019                         TimeValue mediaDuration = GetMediaDuration(trackMedia); 
    1020                         TimeValue movieTimeScale = GetMovieTimeScale(theMovie); 
    1021                         Track theTrack = GetMediaTrack(trackMedia); 
    1022                         VobSubSample *firstSample = [track->samples objectAtIndex:0]; 
    1023                         err = InsertMediaIntoTrack(theTrack, (firstSample->timeStamp * movieTimeScale)/1000, 0, mediaDuration, fixed1); 
    10241063                        if (*firstSubTrack == NULL) 
    10251064                                *firstSubTrack = theTrack;