BestFit()_v1.0.1 - mixing different aspect ratio's

This forum is for questions and discussion of all the aspects of handling your footage. If you have questions about capturing/ripping footage, AviSynth, or compression/encoding/converting, look here.

BestFit()_v1.0.1 - mixing different aspect ratio's

Postby Phantasmagoriat » Sat Jun 05, 2010 1:05 pm

BestFit() v1.0.1

DESCRIPTION:
BestFit() is an avisynth function designed to make a video clip (of any height and width) fit a particular resolution by:
  • resizing
  • adding borders, or
  • cropping


COMMON USAGE:
Code: Select all
BestFit(640, 480)
BestFit(640, 480, "crop")
BestFit(640, 480, "addborders")
BestFit(848, 480)
BestFit(848, 480, "crop")
BestFit(848, 480, "addborders")
BestFit(960)

FULL USAGE & DEFAULT VALUES:
Spoiler :
BestFit( width, height, method, mod, modb, AR_in, percent, percent_area, full, DVD, wide, xwide, UNKNOWN, snap, range, gc, rs, stats )
BestFit( clip c, int "width", int "height", string "method", int "mod", int "modb", float "AR_in", int "percent", int "percent_area", float "full", float "DVD", float "wide", float "xwide", float "UNKNOWN", bool "snap", float "range", bool "gc", string "rs", int "stats" )
Code: Select all
#    VARIABLE        DEFAULT VALUE           OTHERS VALUES
#
#    width=           c.width()              any integer
#    height=          float(width)/AR_in     any integer
#    AR_in=           width()/height()       any float
#    method=         "resize"                "crop", "addborders", "addbottom"
#    mod=             4                      any integer
#    modb=            1                      any integer
#    percent=         100                    any integer
#    percent_area=    100                    any integer
#    full=            1.333333333            any float
#    DVD=             1.500000000            any float
#    wide=            1.777777777            any float
#    xwide=           2.350000000            any float
#    UNKNOWN=         AR_in                  any float
#    snap=            true                   false
#    range=           0.08                   any float [max 0.08]
#    gc=              false                  true
#    rs=             "spline36resize"        any existing resizer
#    stats=           0                      1,  2


EXAMPLES:
-top left = resultant width x height, ratio
-bottom left = reference to the documentation
-bottom right = command used

[WIDESCREEN SOURCE]
Image> you want to make this 'fit' fullscreen

Image> scales image until constrained by width or height # same as bestfit(640,480, "resize")

Image> sides are cropped to become 4:3


Image> borders added to top/bottom to be 4:3


Image> borders added to 'bottom only' to be 4:3

[FULLSCREEN SOURCE]
Image> you want to make this 'fit' widescreen

Image> top/bottom cropped to become 16:9

Image> borders added to sides to become 16:9

Image> there is no 'letterbox' to add here :|

[DVD SOURCE]
Image

Image> a substitute for your favorite resizer


FULL DOCUMENTATION & ADVANCED EXAMPLES:
Spoiler :
Code: Select all
################################### BestFit() ####################################
#                                                                                #
# BestFit() by Phantasmagoriat                                                   #
#                                                                                #
# project                                                                        #
#       started         : April 28, 2010                                         #
#       version updated :  June 11, 2010                                         #
#       version #       :          1.0.1                                         #
#                                                                                #
#### DESCRIPTION #################################################################
#
#
#    -BestFit() is an avisynth function designed to make a video clip (of any
#     height and width) fit a particular resolution by:
#        resizing, adding borders, or cropping.
#
#
#
#### SETUP #######################################################################
#
#                                         
#    A. All required functions are internal, so you just need AviSynth
#
#    1. copy/paste the Script into a blank .txt file
#    2. rename it "BestFit.avsi" ( OMG your file extensions are showing! )
#    3. put it into your avisynth plugins folder:       
#                    C:\Program Files\AviSynth 2.5\plugins <--
#
#    B. you should now be able to use BestFit() in your avisynth scripts :)
#
#
#
#
#### FEATURES ####################################################################
#
#    -choose your METHOD of 'fitting' a video to your desired resolution:
#               "resize",   "crop",   "addborders",   "addbottom"
#    -easily scale an image by specifying a new width (height is calculated)
#    -resize by PERCENT and PERCENT_AREA
#    -SNAP can round height/width to the nearest common AR (default is true)
#    -set new SAR (AR_in)
#    -option for MODXX output (default is mod4)
#    -custom GARBAGE CROP can get rid of tiny black borders (default is false)
#    -user can implement their own CUSTOM RESIZER (default is spline36resize)
#    -useful STATISTICS can be printed to the screen
#    -contains ADDITIONAL FUNCTIONS that you may find useful
#
#
#
#### USAGE / EXAMPLES ############################################################
#
#
#   For normal usage, just specify a width, height (optional), and desired
#   method of fitting the clip to said width/height.  The available arguments
#   for Method are "resize", "crop", "addborders", and "addbottom"
#
#
#   EXAMPLES:                                     [see accompanying pictures for details]
#    LETS SAY YOUR INPUT CLIP HAS A RESOLUTION OF
#     848 x 480 (~widescreen, ~16:9, ~1.77777) -->
#     avisource( "your_848x480_clip.avi" )      # [A]   > you want to make this 'fit' fullscreen
#
#       bestfit( 640 )                          # [1]   > scales image to a width of 640
#
#       bestfit( 1280 )                         # [1.1] > scales image to a width of 1280
#
#       bestfit( 640,480 )                      # [2]   > scales image until constrained by width or height
#                                                         same as bestfit(640,480, "resize")
#
#       bestfit( 640,480, "crop" )              # [3]   > sides are cropped to become 4:3
#
#       bestfit( 640,480, "addborders" )        # [4]   > borders added to top/bottom to be 4:3
#
#       bestfit( 640,480, "addbottom"  )        # [5]   > borders added to 'bottom only' to be 4:3
#                                               # [5.1] > useful for subtitles on portable devices
#       bestfit( 640,480, "addborders", modb=16)# [5.2] > ensures borders are also mod16 compliant
#
#
#    LETS SAY YOUR INPUT CLIP HAS A RESOLUTION OF
#     640 x 480 (fullscreen, 4:3, 1.333333) -->
#     avisource( "your_640x480_clip.avi" )      # [B]   > you want to make this 'fit' widescreen
#
#       bestfit( 848 )                          # [6]   > scales image to a width of 848
#
#       bestfit( 848,480 )                      # [7]   > scales image until constrained by width or height
#                                                         same as bestfit(848,480, "resize")
#
#       bestfit( 848,480, "crop")               # [8]   > top/bottom cropped to become 16:9
#
#       bestfit( 848,480, "addborders" )        # [9]   > borders added to sides to become 16:9
#
#       bestfit( 848,480, "addbottom"  )        # [10]  > there is no 'letterbox' to add here :|
#
#
#
#    LETS SAY YOUR INPUT CLIP HAS A RESOLUTION OF
#     720 x 480 (DVD, unspecified AR ) -->
#     avisource( "your_720x480_clip.avi" )      # [C]   > you want to make this look correct
#
#       bestfit( AR_in=1.77777 )                # [11]  > [correct] treats clip as if it was 16:9
#
#       bestfit( AR_in=1.33333 )                # [12]  > [wrong] treats clip as if it was 4:3
#
#       bestfit( 848, 480 )                     # [13]  > [wrong] scales image until constrained by height
#
#       bestfit( 848, 480, "addborders" )       # [14]  > [wrong] borders added to sides to become 16:9
#
#       I guess the point I'm trying to make here is that BestFit() will never stretch
#       or squish the original image unless you specify a new Aspect Ratio with AR_in.  This means:
#
#
#              !IT IS VERY IMPORTANT THAT YOUR FOOTAGE IS IN THE CORRECT SAR* TO BEGIN WITH!
#                       ( otherwise you will have to specify AR_in yourself )
#                    *Storage Aspect Ratio = the ratio of Width to Height in pixels
#
#
#
#    LETS SAY YOUR INPUT CLIP HAS AN IRREGULAR RESOLUTION LIKE
#     640 x 488 (irregular, 80:61, 1.3115 ) -->
#     avisource(" your_640x488_clip.avi" )      # [D]   > you want to make it normal
#
#       bestfit( mod=16, rs="bilinearresize")   # [15]  > resizes to mod16 values using bilinearresize
#
#       bestfit( gc=true, snap=true, range=0.06)# [16]  > crops 8 px from the left/right; 4 px top/bottom
#                                                       > then resizes to nearest common AR within 0.06
#
#       bestfit( percent=200, stats=2 )         # [17]  > scales image to 200% original width/height
#                                                       > displays full statistics about clip
#                       
#       bestfit( percent_area=200, stats=2 )    # [18]  > resizes image until it is 200% the original area
#                                                       > displays full statistics about clip
#
#
#### ADDITIONAL FUNCTIONS ########################################################
#   
#
#    The following are subroutines used by BestFit(), but instead of placing
#    them in the body of the function, I decided to make them separate
#    functions-- so if you want, you can use them too :)
#
#
#    avisource("Close Encounters.avi")       # [E]
#    rs( 640,480 )                           # [19]
#        This can be used as a substitute for your favorite resizer.
#        By default, it uses spline36resize, so instead of typing
#        out spline36rsize( 640,480 ), you can simply type rs( 640,480 )
#
#
#    avisource("futurama.avi")               # [F]
#    gc( 8,4 )                               # [20]
#        Does the same thing as crop( 8, 4, -8, -4 )
#
#
#    AR_in()                                 # [21]
#        Does not return a clip,
#        but rather, a float value of the SAR of your clip.
#
#
#    c.getmod(w)                             # [22]
#        Returns the highest mod value of clip c's width
#
#
#    c.getmod(h)                             # [23]
#        Returns the highest mod value of clip c's height
#
#
#    crop2mod(2)                             # [24]
#        Will crop your width and height until they comply with
#        the specified mod. Useful if your clip has Odd values
#        for height and/or width.
#        If you simply want to make your clip modxx compliant, do not use
#        this.  Simply use BestFit(mod=16)
#
#
#    echo( "c.getmod()", "c.AR_in()" )       # [25]
#        Hopefully nobody else has a function named echo() in their plugins
#        directory, otherwise avisynth will crash, but if you have ever wanted
#        to print a variable to the screen, you will find it is not easy...
#        [b/c Subtitle() only takes string values], so I use echo to convert the
#        variable to a string, which is then passed to Subtitle() and printed.
#               It's like an upgrade of Subtitle() :P
#               Prints a maximum of 6 consecutive variables.
#
#
#    bfstats( a, b, 2 )                      # [26]
#        Prints the statistics of 'clip a' and 'clip b' to the screen using
#        minimum stats (1) or full stats (2)
#
#
#
#### DEFAULTS ####################################################################
#
#       
#    VARIABLE        DEFAULT VALUE           OTHERS VALUES
#
#    method=         "resize"                "crop", "addborders", "addbottom"
#    mod=             4                      any integer
#    modb=            1                      any integer
#    percent=         100                    any integer
#    percent_area=    100                    any integer
#    full=            1.333333333            any float
#    DVD=             1.500000000            any float
#    wide=            1.777777777            any float
#    xwide=           2.350000000            any float
#    UNKNOWN=         AR_in                  any float
#    snap=            true                   false
#    range=           0.08                   any float [max 0.08]
#    gc=              false                  true
#    rs=             "spline36resize"        any existing resizer
#    stats=           0                      1,  2
#    AR_in=           c.AR_in()              any float
#    width=           c.width()              any integer
#    height=          float(width)/AR_in     any integer
#
#       IF YOU WOULD LIKE TO CHANGE THE DEFAULTS FOR BESTFIT(),
#       DO SO AFTER #### MAIN PROGRAM ####
#
#
#### LIMITATIONS #################################################################
#
#    It has already been mentioned that BestFit() can only detect SAR (height:width in pixels)
#    which can present problems if your footage uses AR flags to stretch during playback.
#
#    To overcome this limitation, I am currently looking for ways to feed
#    AR metadata from .d2v .mp4 .mkv etc. into avisynth so everything can be
#    dealt with automatically.  So far I have not found a way :(
#
#
#
#### ADDITIONAL NOTES ############################################################
#
#    BestFit() was originally intended to make it easier to mix footage (of different
#    sizes and aspect ratios) for video editing.  Granted, it can be used for
#    any situation when you require the output resolution of an image/video to
#    fit a particular display or window.  This makes it useful for converting
#    large numbers of videos for a particular device [like my Android phone :P]
#    or making thumbnails, or even quickly scaling a video to your monitor size.
#
#    I should probably note that I am not a programmer... just someone who wanted
#    an easier way to deal with clips of different sizes-- so this is my first avisynth
#    function ever. If you have any tips, comments, suggestions, maybe even
#    requests, I would gladly appreciate hearing from you.
#
#
############################################################


ADDITIONAL & ADVANCED EXAMPLES:
Image> scales image to a width of 640

Image> scales image to a width of 1280

Image> scales image to a width of 848

Image> scales image until constrained by width or height # same as bestfit(848,480, "resize")

Image

Image> Does the same thing as crop( 8, 4, -8, -4 )

Image> useful for subtitles on portable devices

Image> you want to make this look correct

Image> [correct] treats clip as if it was 16:9

Image> [wrong] treats clip as if it was 4:3

Image> [wrong] scales image until constrained by height

Image> [wrong] borders added to sides to become 16:9

Image> you want to make it normal

Image> resizes to mod16 values using bilinearresize

Image> crops 8 px from the left/right; 4 px top/bottom, then resizes to nearest common AR within 0.06

Image> scales image to 200% original width/height, and displays full statistics about clip

Image> resizes image until it is 200% the original area


INSTALLATION: [the usual]
  • copy/paste the below script into a .txt file,
  • rename to something like "BestFit().avsi"
  • put it in your avisynth plugins folder, usually:
    C:\Program Files\AviSynth 2.5\plugins or
    C:\Program Files (x86)\AviSynth 2.5\plugins


SCRIPT:
Spoiler :
Code: Select all
#####################
#### SUBROUTINES ####
##########################################################################
   function rs(
      \    clip    c
      \,   int     "width"
      \,   int     "height"
      \,   string  "rs"   )
   {
      rs   = default( rs, "spline36resize")
      eval("   c." + rs + "(width, height)   ")
   }

   ##########################################################################
   function gc(
      \   clip    c
      \,   int     "lr"
      \,   int     "tb")
   {
      lr   = default( lr,  8 )
      tb   = default( tb,  4 )
      c.crop(lr, tb, -lr, -tb)
   }

   ##########################################################################
   function AR_in(
      \   clip c      )
   {
      float(c.width())/float(c.height())
   }

   ##########################################################################
   function getmod(
         \       clip    c
         \,      val     "side"      
         \,      int     "test"   )
   {
                side    = default( side, "w" )
                length  = (side == "w" ) ? float(c.width())\
                                         : float(c.height())
                test    = default ( test, 1 )
                mod     = ( Frac(length/test) != 0.0  ) ? test/2\
                                                        : getmod(c, side, test*2)
      mod
   }

   ##########################################################################
   function crop2mod(
      \       clip    c
      \,      int     "mod")

   {
   mod     = default( mod, 2 )
   h       = c.height()
   w       = c.width()
   hfix    = (     h - ( (h/mod)*mod )     )
   wfix    = (     w - ( (w/mod)*mod )     )
   fix     = c.crop( wfix, hfix, 0, 0      )
   fix
   }


   ##########################################################################
   function echo(
      \    clip    c
      \,   val     "v1"
      \,   val     "v2"
      \,   val     "v3"
      \,   val     "v4"
      \,   val     "v5"
      \,   val     "v6"
      \,   int     "align"
      \,   int     "x"
      \,   int     "y"
      \,   float   "font"
      \,   int     "size"
      \            )
   {
      font      = default( font, "Lucida Console" )
      size      = default( size,  15              )
   
      c.Subtitle(
      \    String(v1)+String(v2)+String(v3)
      \   +String(v4)+String(v5)+String(v6)
      \,    x=x, y=y, align=align, font=font, size=size   )
   }

   ##########################################################################
   function bfstats(
      \    clip    "clip1"
      \,   clip    "clip2"
      \,   int     "stats"
      \,   val     "AR_snap"
      \            )
   {
      clip1   = default( clip1,       last    )
      clip2   = default( clip2,       last    )
      stats   = default( stats,       1       )
      AR_snap = default( AR_snap,     "???"   )
   
   A       = clip1         B       = clip2
   Aw      = A.width ()    Bw      = B.width ()
   Ah      = A.height()    Bh      = B.height()
   Apx     = Aw*Ah         Bpx     = Bw*Bh
   Aperc   = "100.0"       Bperc   = string(100*float(Bw )/float(Aw ), "%5.1f")
   Aperca  = "100.0"       Bperca  = string(100*float(Bpx)/float(Apx), "%5.1f")

      c1=005   c2a=070   c2b=124   c3=180   c4=275   c5=350   c6=410
      r1=005   r2 =030   r3 =045
   none    = B
   minimum = B.\
      echo( Bw," x ",Bh,"  SAR=",B.AR_in()    ,x=c1 , y=r1    )
   full    = B.\
      echo(   "clip1:"                        ,x=c1 , y=r2    ).\
      echo(   "clip2:"                        ,x=c1 , y=r3    ).\
      echo(   "Display"                       ,x=c2a, y=r1    ).\
      echo(    Aw," x "                       ,x=c2a, y=r2    ).\
      echo(    Bw," x "                       ,x=c2a, y=r3    ).\
      echo(    Ah                             ,x=c2b, y=r2    ).\
      echo(    Bh,"**"                        ,x=c2b, y=r3    ).\
      echo(   "SAR"                           ,x=c3 , y=r1    ).\
      echo(    A.AR_in(),"*"                  ,x=c3 , y=r2    ).\
      echo(    B.AR_in()                      ,x=c3 , y=r3    ).\
      echo(   "#pix"                          ,x=c4 , y=r1    ).\
      echo(    Apx                            ,x=c4 , y=r2    ).\
      echo(    Bpx                            ,x=c4 , y=r3    ).\
      echo(   "%"                             ,x=c5 , y=r1    ).\
      echo(    Aperc                          ,x=c5 , y=r2    ).\
      echo(    Bperc                          ,x=c5 , y=r3    ).\
      echo(   "%(Area)"                       ,x=c6 , y=r1    ).\
      echo(    Aperca                         ,x=c6 , y=r2    ).\
      echo(    Bperca                         ,x=c6 , y=r3    ).\
      echo(   " *AR_snap     = ", AR_snap     ,x=008, y=70    ).\
      echo(   "**mod(width)  = ",B.getmod("w"),x=008, y=85    ).\
      echo(   "  mod(height) = ",B.getmod("h"),x=008, y=100   )

   err_stat="""
          BestFit() stats can only be:  0, 1, or 2
          "(0)none"   "(1)minimum"   "(2)full"
       """
        stats   =       ( stats == 0 ) ? none   :\
                        ( stats == 1 ) ? minimum:\
                        ( stats == 2 ) ? full   :\
                                         assert(1==0,err_stat)
   stats
   }
##################################################################################



######################
#### MAIN PROGRAM ####
######################


   ##########################################################################
   function BestFit(
      \   clip     c
      \,   int     "width"
      \,   int     "height"
      \,   string  "method"
      \,   int     "mod"
      \,   int     "modb"
      \,   float   "AR_in"
      \,   int     "percent"
      \,   int     "percent_area"
      \,   float   "full"
      \,   float   "DVD"
      \,   float   "wide"
      \,   float   "xwide"
      \,   float   "UNKNOWN"
      \,   bool    "snap"
      \,   float   "range"
      \,   bool    "gc"
      \,   string  "rs"
      \,   int     "stats"
      \         )
{
   #### DEFAULT VARIABLES AND COMMON VALUES ################################

   c               = default (    c.crop2mod(2)                           )
   method          = default (    method,         "resize"                )
   mod             = default (    mod,             4                      )
   modb            = default (    modb,            1                      )
   AR_in           = default (    AR_in,           c.AR_in                )
   width           = default (    width,           c.width()              )
   height          = default (    height,          float(width)/AR_in     )
   percent         = default (    percent,         100                    )
   percent_area    = default (    percent_area,    100                    )
   full            = default (    full,            1.333333333            )
   DVD             = default (    DVD,             1.500000000            )
   wide            = default (    wide,            1.777777777            )
   xwide           = default (    xwide,           2.350000000            )
   UNKNOWN         = default (    UNKNOWN,         AR_in                  )
   snap            = default (    snap,            true                   )
   range           = default (    range,           0.08                   )
   gc              = default (    gc,              false                  )
   rs              = default (    rs,             "spline36resize"        )
   stats           = default (    stats,           0                      )

   #########################################################################


   AR_out          = float(width)/float(height)
   AR_snap         =
                \         (  ( full-range) <  AR_in  <= (full +range)  ) ? full
                \:        (  (  DVD-range) <  AR_in  <  (DVD  +range)  ) ? DVD
                \:        (  ( wide-range) <= AR_in  <  (wide +range)  ) ? wide
                \:        (  (xwide-range) <= AR_in  <  (xwide+range)  ) ? xwide
                \:                                                         UNKNOWN

   AR_in           = (  snap == true       ) ? AR_snap: AR_in
   rsf             = ( percent_area == 100 ) ? float(percent)/100
         \           : sqrt(float(percent_area)/100)

   width_calc      = round(  float(   rsf*height*AR_in     )/mod   )*mod
   height_calc     = round(  float(   rsf*width /AR_in     )/mod   )*mod
   width           = round(  float(   rsf*width            )/mod   )*mod
   height          = round(  float(   rsf*height           )/mod   )*mod

   wr              = ( AR_in <= AR_out ) ? width_calc    : width
   hr              = ( AR_in <= AR_out ) ? height        : height_calc
   wc              = ( AR_in <= AR_out ) ? width         : width_calc
   hc              = ( AR_in <= AR_out ) ? height_calc   : height

   bh              = ( modb == 1 ) ? (width- wr)/2 : round(float((width- wr)/2)/modb)*modb
   bv              = ( modb == 1 ) ? (height-hr)/2 : round(float((height-hr)/2)/modb)*modb
   wr              = ( modb == 1 ) ? wr : width- (2*bh)
   hr              = ( modb == 1 ) ? hr : height-(2*bv)


   ch              = (wc- width)/2
   cv              = (hc-height)/2

   c               = ( gc == true ) ? c.gc() : c

   err_met         =
              \"""
                 The only supported methods for BestFit() are:
                  "resize"   "crop"   "addborders"   and   "addbottom"
               """

        Fit  = (method == "resize"     ) ? c.rs(wr, hr, rs)
          \:   (method == "crop"       ) ? c.rs(wc, hc, rs).crop(ch,cv,-ch,-cv)
          \:   (method == "addborders" ) ? c.rs(wr, hr, rs).addborders(bh,bv,bh,bv)
          \:   (method == "addbottom"  ) ? c.rs(wr, hr, rs).addborders(00,0,00,2*bv)
          \:                               assert(1==0,err_met)

bfstats(c, Fit, stats, AR_snap)

}


__END__
#### END OF CODE ################################################################



CHANGELOG:
Code: Select all
v1.0.0 - BestFit() made public
v1.0.1 - added 'modb' to allow borders to be modXX compliant [Ala Qyot]
       - added useful lists: Changelog, TODO, and Known Bugs

TODO:
Code: Select all
- find ways to serve AR metadata from .d2v .mp4 .mkv files into avisynth to determine DAR
- figure out algorithm to compensate for Active Picture Region [Ala Mister Hatt]
- put subroutines into main code to avoid conflict with other scripts
- clean up bulky, unnecessary code
- add color parameter for borders
- "polaroid" "fillcrop" methods
- add DVD AR parameter

KNOWN BUGS:
Code: Select all
v1.0.1 - no known bugs ATM. Please report any.

See Documentation for full details.

##################################################################################


If you didn't read everything, I'll repeat here that BestFit() only detects height and width (SAR), so I am looking for ways to feed AR metadata from .dv2 .mp4 .mkv files into avisynth so that DAR can be detected. If you have any ideas, let me know.

Lastly, this is my first avisynth function, and mirko is probably the only other person to see this (thanks :) ), so please let me know if it works, fails or whatever etc...

~Phan
Last edited by Phantasmagoriat on Sun Apr 03, 2011 6:10 pm, edited 5 times in total.
Image
Org Profile | AMVGuide | Phan Picks! | THE424SHOW | YouTube | "Galactic Escape"

"Effort to Understand; Effort to be Understood; to See through Different Eyes."
User avatar
Phantasmagoriat
 
Joined: 06 Feb 2006
Status: ☁SteamPunked≈☂

Re: BestFit() and mixing footage with different aspect ratio's

Postby Zarxrax » Sat Jun 05, 2010 2:02 pm

Interesting. This might be worth including in amvapp
User avatar
Zarxrax
 
Joined: 01 Apr 2001
Location: Concord, NC

Re: BestFit() and mixing footage with different aspect ratio's

Postby Phantasmagoriat » Sat Jun 05, 2010 2:28 pm

Go ahead :D . That way people won't have to install it themselves (...not that it's difficult to set up or anything.)
Image
Org Profile | AMVGuide | Phan Picks! | THE424SHOW | YouTube | "Galactic Escape"

"Effort to Understand; Effort to be Understood; to See through Different Eyes."
User avatar
Phantasmagoriat
 
Joined: 06 Feb 2006
Status: ☁SteamPunked≈☂

Re: BestFit() and mixing footage with different aspect ratio's

Postby Qyot27 » Sat Jun 05, 2010 3:15 pm

In the example where the letterboxing from 848x480->640x360 occurs first, is there a variation that ensures mod16-ness in regard to the borders as well as the main picture? If we're arguing in favor of mod16 for simplicity, making sure letterbox borders lie on mod16 values optimizes compression. 640x360 (and 640x368, which is mod 16 but only for the main movie) isn't mod16, nor are the borders it generates, and needs to be cropped or resized to 640x352 in order to make everything click, as the borders on either side are 64 pixels. 352/16=22, 64/16=4.
My profile on MyAnimeList | Quasistatic Regret: yeah, yeah, I finally got a blog
User avatar
Qyot27
Surreptitious fluffy bunny
 
Joined: 30 Aug 2002
Location: St. Pete, FL
Status: Creepin' between the bullfrogs

Re: BestFit() and mixing footage with different aspect ratio's

Postby Phantasmagoriat » Sat Jun 05, 2010 4:38 pm

Hmm, didn't think about that.
So you want the borders to be mod16 too eh?
(I'm assuming you are talking about picture [4].)

I could make that option, but I wouldn't advise using it since you would probably miss your target resolution.
For one thing, BestFit() rounds to the *nearest* mod value that matches the original AR (or common AR_snap), so in this case 640x368 will be preferred over 640x352 since:
640/352=1.818181 (+0.0404)
target AR=1.777777
640/368=1.73913 (-0.0386) is closer

the borders in that case would be (480-368)/2=56 -->nearest mod16=64
368+64+64=496

whereas if you leave the borders as non-mod16, you would still have a nice 4:3 resolution (640x480)
Image
Org Profile | AMVGuide | Phan Picks! | THE424SHOW | YouTube | "Galactic Escape"

"Effort to Understand; Effort to be Understood; to See through Different Eyes."
User avatar
Phantasmagoriat
 
Joined: 06 Feb 2006
Status: ☁SteamPunked≈☂

Re: BestFit() and mixing footage with different aspect ratio's

Postby Qyot27 » Sun Jun 06, 2010 11:29 am

Well, if implementing the mod16 borders option, there would essentially be three checks performed:
A) Is the main movie area mod16? 368=yes, 352=yes
B) Are the borders mod16? 56=no, 64=yes
C) Is the height of the file 480? 368+64=no, 352+64=yes
And then force the selection of 352 based on that condition, and deal with it by either cropping 8 pixels or doing a normal resize.

There's distortion of the ratio in either the 640x368 or 640x352 case (unless you crop 8 pixels from 640x360, which just alters the technical ratio but not the perceptual ratio), you could make sure in such a situation that the height value is honored, so the mod16-borders option is given, with the height specifically declared to be 480, resulting in that the only viable option for the main picture is making it 352.
My profile on MyAnimeList | Quasistatic Regret: yeah, yeah, I finally got a blog
User avatar
Qyot27
Surreptitious fluffy bunny
 
Joined: 30 Aug 2002
Location: St. Pete, FL
Status: Creepin' between the bullfrogs

Re: BestFit() and mixing footage with different aspect ratio's

Postby Phantasmagoriat » Sun Jun 06, 2010 7:17 pm

The main problem for me is knowing when to tell the program to round up and when it needs to round down.
But I think if I make the program set it's borders as mod16 first, and the output height is mod16 to begin with, the resultant video height would have to be mod16, so this might not be too difficult. I might not get to it until next weekend though.

Thanks for the input so far :)
Image
Org Profile | AMVGuide | Phan Picks! | THE424SHOW | YouTube | "Galactic Escape"

"Effort to Understand; Effort to be Understood; to See through Different Eyes."
User avatar
Phantasmagoriat
 
Joined: 06 Feb 2006
Status: ☁SteamPunked≈☂

Re: BestFit() and mixing footage with different aspect ratio's

Postby Mister Hatt » Sun Jun 06, 2010 10:57 pm

Why do you care about mod16? Also, the DVD aspects are all wrong. You're not taking the active picture region into account.
Mister Hatt
 
Joined: 25 Dec 2007
Status: better than you

Re: BestFit() and mixing footage with different aspect ratio's

Postby mirkosp » Mon Jun 07, 2010 2:55 am

Mister Hatt wrote:Also, the DVD aspects are all wrong. You're not taking the active picture region into account.

This. A couple links that could help:
http://lipas.uwasa.fi/~f76998/video/conversion/
http://ps-auxw.de/cgi-bin/ar-calc.pl
Although, as far as PAL anime is concerned, I fear that some DVDs get an improper NTSC -> PAL conversion.
Image
User avatar
mirkosp
MODkip
 
Joined: 24 Apr 2006
Location: Gallarate (VA), Italy
Status: (」・ワ・)」(⊃・ワ・)⊃

Re: BestFit() and mixing footage with different aspect ratio's

Postby Mister Hatt » Mon Jun 07, 2010 3:50 am

All PAL conversions I have seen are wrong. Anime should never be converted to PAL from NTSC in the first place. Just a heads up, the document on aspect that mirko linked is a very very large amount of complicated tl;dr, while being very thorough it is intended for people who have a strong understanding of analog-digital video theory and backgrounds, and as such it will give everyone here a headache. Incidentally it also proves around half the avtech3 guide wrong. Happy reading.
Mister Hatt
 
Joined: 25 Dec 2007
Status: better than you

Re: BestFit() and mixing footage with different aspect ratio's

Postby Phantasmagoriat » Mon Jun 07, 2010 12:12 pm

Mister Hatt wrote:Why do you care about mod16?
The website above wrote:Modern digital video applications such as DV, DVD and digital television (DVB, ATSC) often use MPEG-1 or MPEG-2 formats (or their derivatives) which are all based on 16×16 pixel macroblocks. Having the height and width of the image readily divisible by 16 makes it easier and more efficient for an MPEG encoder to compress video.
Actually... I would say it's because in computing, 16 is a magical number :book:
so are 2, 4 , 8, 16, 32, 64, 128, 256, 512...



Mister Hatt wrote:Also, the DVD aspects are all wrong. You're not taking the active picture region into account.
The website above wrote:...the difference between the correct aspect ratio and a wrong aspect ratio is often small enough to go unnoticed unless you really start looking for it.
:aimkissyface:
Image
Org Profile | AMVGuide | Phan Picks! | THE424SHOW | YouTube | "Galactic Escape"

"Effort to Understand; Effort to be Understood; to See through Different Eyes."
User avatar
Phantasmagoriat
 
Joined: 06 Feb 2006
Status: ☁SteamPunked≈☂

Re: BestFit() and mixing footage with different aspect ratio's

Postby mirkosp » Mon Jun 07, 2010 12:20 pm

Phantasmagoriat wrote:
Mister Hatt wrote:Why do you care about mod16?
The website above wrote:Modern digital video applications such as DV, DVD and digital television (DVB, ATSC) often use MPEG-1 or MPEG-2 formats (or their derivatives) which are all based on 16×16 pixel macroblocks. Having the height and width of the image readily divisible by 16 makes it easier and more efficient for an MPEG encoder to compress video.
Actually... I would say it's because in computing, 16 is a magical number :book:
so are 2, 4 , 8, 16, 32, 64, 128, 256, 512...

mod8 and maybe even mod4 are more than fine with AVC though. Actually hell, even mod2 probably is. Anyway, for instance, 1920x1080 is mod8. x264 internally pads the image to mod16 (1088 in this case) and sets it so that those pixels get cropped over playback. Of course, letting x264 do this automatically gives better results that leaving the padding on or stretching the image to a mod16 resolution manually. So yes, resizing or cropping/letterboxing to mod16 is not nearly as much of a need as it used to be.

Mister Hatt wrote:Also, the DVD aspects are all wrong. You're not taking the active picture region into account.
The website above wrote:...the difference between the correct aspect ratio and a wrong aspect ratio is often small enough to go unnoticed unless you really start looking for it.
:aimkissyface:

This I can agree with... the difference is generally unnoticeable, unless you have some really wrong crop and resize parameters that make it obvious. Stuff that should be round but isn't quite right tends to be the giveaway for me... sometimes without the need to actually look for it.
Image
User avatar
mirkosp
MODkip
 
Joined: 24 Apr 2006
Location: Gallarate (VA), Italy
Status: (」・ワ・)」(⊃・ワ・)⊃

Re: BestFit() and mixing footage with different aspect ratio's

Postby Mister Hatt » Mon Jun 07, 2010 10:52 pm

Keep in mind how old that document is please. Mod16 is entirely useless with newer encoders due to them not being as horribly inefficient as DivX5 was. The whole mod16 thing became important due to MPEG2 and MPEG4-ASP codecs being pretty damn terrible, but with x264 it's not really a problem. As far as aspect differences go, you're right, very few people can notice it, but it DOES leave a rather large amount of aliasing on curving high-contrast lines which really isn't too difficult to see. If you're really going to go for the "nobody can tell the difference" angle, why not just ignore BestFit() altogether and just resize to whichever main AR you're gonna use on the project?
Mister Hatt
 
Joined: 25 Dec 2007
Status: better than you

Re: BestFit() and mixing footage with different aspect ratio's

Postby Phantasmagoriat » Tue Jun 08, 2010 1:50 am

That's kind of neat. I didn't know x264 adjusted for mod16 like that. But still, I think it's a nice option to have for backwards compatibility, and it's not difficult to implement either: It simply divides by 16, rounds, then multiplies by 16. (or whatever mod value you like).

Regarding this 'active picture region' thing... I'm gonna be honest with you-- I totally didn't read that. I started to... but it got a little absurd. Seriously how big of a difference are we talking about here? The 8 pixels from the left and right that I always crop off? For something that seems so small is there at least a simple algorithm for achieving the correct aspect without using those tables?

If you are worried about aliasing, try to keep in mind the purpose of BestFit()-- to mix footage of different shapes and sizes... so in the end no image will be in it's optimal resolution to begin with, which would likely contribute more to aliasing than a minute change in aspect. Not that I see this being a huge problem when using spline resizers by default.

Also, I'm not sure this issue is even relevant to BestFit(). It is assumed that the input aspect is correct to begin with. The original proportions of width/height are maintained regardless of resizing, cropping, or adding borders-- so I don't see how anything can go wrong, unless there was an error with the input video.
Image
Org Profile | AMVGuide | Phan Picks! | THE424SHOW | YouTube | "Galactic Escape"

"Effort to Understand; Effort to be Understood; to See through Different Eyes."
User avatar
Phantasmagoriat
 
Joined: 06 Feb 2006
Status: ☁SteamPunked≈☂

Re: BestFit()_v1.0.1 - mixing different aspect ratio's

Postby Phantasmagoriat » Fri Jun 11, 2010 10:08 pm

Script updated to v1.0.1 :)
-new parameter 'modb' should allow borders to be divisible by whatever integer you specify for modb (ex. modb=16)
-added lists to the first post: Changelog, TODO, and Known Bugs

Let me know if you have suggestions, or encounter any problems.
Image
Org Profile | AMVGuide | Phan Picks! | THE424SHOW | YouTube | "Galactic Escape"

"Effort to Understand; Effort to be Understood; to See through Different Eyes."
User avatar
Phantasmagoriat
 
Joined: 06 Feb 2006
Status: ☁SteamPunked≈☂

Next

Return to Footage Help

Who is online

Users browsing this forum: No registered users and 3 guests