Changeset 857

Show
Ignore:
Timestamp:
04/20/08 13:09:23 (5 months ago)
Author:
astrange
Message:

Write the correct clap/pasp atoms, fixing 16:9 video when people turn on clean aperture mode. There are still problems with anamorphic 4:3, subtitles, and clean aperture, so don't do that.
Some experiment in recovering from stupidly rounded fractions in AVI video headers, but I don't know if we can change timebases randomly like this...

Files:

Legend:

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

    r854 r857  
    421421                        width = IntToFixed(uint32(disp_width)); 
    422422                        height = IntToFixed(uint32(disp_height)); 
    423                 }                
     423                }                               
    424424        } else if (pxl_width.ValueIsSet() && pxl_height.ValueIsSet()) { 
    425425                width = IntToFixed(uint32(pxl_width)); 
     
    449449    (*imgDesc)->clutID = -1; 
    450450         
    451         set_track_clean_aperture_ext(imgDesc, width, height); 
     451        set_track_clean_aperture_ext(imgDesc, width, height, IntToFixed(uint32(pxl_width)), IntToFixed(uint32(pxl_height))); 
    452452        mkvTrack.desc = (SampleDescriptionHandle) imgDesc; 
    453453         
  • trunk/ff_private.c

    r855 r857  
    117117} /* prepare_track() */ 
    118118 
     119/* A very large percent of movies have NTSC timebases (30/1.001) with misrounded fractions, so let's recover them. */ 
     120static void rescue_ntsc_timebase(AVRational *base) 
     121{ 
     122        av_reduce(&base->num, &base->den, base->num, base->den, INT_MAX); 
     123         
     124        double fTimebase = av_q2d(*base), nearest_ntsc = floor(fTimebase * 1001. + .5) / 1001.; 
     125        const double small_interval = 1./120.; 
     126         
     127        if (fabs(fTimebase - nearest_ntsc) < small_interval) 
     128        { 
     129                base->num = 1001; 
     130                base->den = (1001. / fTimebase) + .5; 
     131        } 
     132} 
     133 
    119134/* Initializes the map & targetTrack to receive video data */ 
    120135void initialize_video_map(NCStream *map, Track targetTrack, Handle dataRef, OSType dataRefType, AVPacket *firstFrame) 
     
    129144         
    130145        map->base = map->str->time_base; 
    131         if(map->base.den > 100000) { 
     146         
     147        rescue_ntsc_timebase(&map->base); 
     148        if(map->base.num != 1001 && map->base.den > 100000) { 
    132149                /* if that's the case, then we probably ran out of timevalues! 
    133150                * a timescale of 100000 allows a movie duration of 5-6 hours 
     
    530547} 
    531548 
    532 void set_track_clean_aperture_ext(ImageDescriptionHandle imgDesc, Fixed cleanW, Fixed cleanH) 
    533 
    534         CleanApertureImageDescriptionExtension **clap = (CleanApertureImageDescriptionExtension**)NewHandle(sizeof(CleanApertureImageDescriptionExtension)); 
    535          
    536         int wN, wD, hN, hD; 
    537          
    538         av_reduce(&wN, &wD, cleanW, fixed1, UINT_MAX); 
    539         av_reduce(&hN, &hD, cleanH, fixed1, UINT_MAX); 
     549void set_track_clean_aperture_ext(ImageDescriptionHandle imgDesc, Fixed displayW, Fixed displayH, Fixed pixelW, Fixed pixelH) 
     550
     551        CleanApertureImageDescriptionExtension    **clap = (CleanApertureImageDescriptionExtension**)NewHandle(sizeof(CleanApertureImageDescriptionExtension)); 
     552        PixelAspectRatioImageDescriptionExtension **pasp = (PixelAspectRatioImageDescriptionExtension**)NewHandle(sizeof(PixelAspectRatioImageDescriptionExtension)); 
     553         
     554        int wN = pixelW, wD = fixed1, hN = pixelH, hD = fixed1; 
     555 
     556        av_reduce(&wN, &wD, wN, wD, INT_MAX); 
     557        av_reduce(&hN, &hD, hN, hD, INT_MAX); 
    540558         
    541559        **clap = (CleanApertureImageDescriptionExtension){EndianU32_NtoB(wN), EndianU32_NtoB(wD), 
    542560                                                                                                      EndianU32_NtoB(hN), EndianU32_NtoB(hD),  
    543                                                                                                           EndianU32_NtoB(0), EndianU32_NtoB(1), 
    544                                                                                                           EndianU32_NtoB(0), EndianU32_NtoB(1)}; 
     561                                                                                                          EndianS32_NtoB(0), EndianU32_NtoB(1), 
     562                                                                                                          EndianS32_NtoB(0), EndianU32_NtoB(1)}; 
     563         
     564        AVRational dar, invPixelSize, sar; 
     565         
     566        dar                        = (AVRational){displayW, displayH}; 
     567        invPixelSize   = (AVRational){pixelH, pixelW}; 
     568        sar = av_mul_q(dar, invPixelSize); 
     569         
     570        av_reduce(&sar.num, &sar.den, sar.num, sar.den, fixed1); 
     571         
     572        **pasp = (PixelAspectRatioImageDescriptionExtension){EndianU32_NtoB(sar.num), EndianU32_NtoB(sar.den)}; 
    545573         
    546574        AddImageDescriptionExtension(imgDesc, (Handle)clap, kCleanApertureImageDescriptionExtension); 
     575        AddImageDescriptionExtension(imgDesc, (Handle)pasp, kPixelAspectRatioImageDescriptionExtension); 
    547576         
    548577        DisposeHandle((Handle)clap); 
     578        DisposeHandle((Handle)pasp); 
    549579} 
    550580 
     
    586616                         
    587617                        initialize_video_map(&map[j], track, dataRef, dataRefType, storage->firstFrames + j); 
    588                         set_track_clean_aperture_ext((ImageDescriptionHandle)map[j].sampleHdl, width, height); 
     618                        set_track_clean_aperture_ext((ImageDescriptionHandle)map[j].sampleHdl, width, height, IntToFixed(st->codec->width), IntToFixed(st->codec->height)); 
    589619                } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) { 
    590620                        if (st->codec->sample_rate > 0) { 
  • trunk/ff_private.h

    r853 r857  
    111111uint8_t *create_cookie(AVCodecContext *codec, size_t *cookieSize, UInt32 formatID); 
    112112Handle create_strf_ext(AVCodecContext *codec); 
    113 void set_track_clean_aperture_ext(ImageDescriptionHandle imgDesc, Fixed cleanW, Fixed cleanH); 
     113void set_track_clean_aperture_ext(ImageDescriptionHandle imgDesc, Fixed displayW, Fixed displayH, Fixed pixelW, Fixed pixelH); 
    114114 
    115115uint8_t *write_int32(uint8_t *target, int32_t data);