Skip to content

Instantly share code, notes, and snippets.

@astrataro
Created April 7, 2012 03:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save astrataro/2324903 to your computer and use it in GitHub Desktop.
Save astrataro/2324903 to your computer and use it in GitHub Desktop.
avc_refcalc.py 0.20mod2 ( add level=5.2 and profile=high10/high422/high444p, update for python 3 )
#!/usr/bin/env python3
# coding: utf-8
#****************************************************************************
# avc_refcalc.py 0.20mod2
# written by Chikezun
# modified by 06_taro
# Reference literature:
# インプレス標準教科書シリーズ改訂版 H.264/AVC教科書
# 著者:(監修)大久保 榮/(編者)角野 眞也、菊池 義浩、鈴木 輝彦
# http://en.wikipedia.org/wiki/H.264/MPEG-4_AVC
# 猫科研究所(http://www.up-cat.net/FrontPage.html)
#  x264(vbv-maxrate,vbv-bufsize,profile,level),H.264(Profile/Level)
#
#****************************************************************************
import sys
import math
def usage():
print ( "Usage: avc_refcalc.py [options]\n" )
print ( " -r, --resolution <string> :set 'width x height' ('1280x720')" )
print ( " -l, --level <string> :set 'level' ('4.1')" )
print ( " -p, --profile <string> :set 'profile' ('high')" )
print ( " -i, --interlaced :specify interlaced mode (not specified)" )
print ( " -h, --help :display this help and exit\n" )
def check_prof(pr, ip):
for i in ['baseline', 'main', 'high', 'high10', 'high422', 'high444p']:
if i == pr:
if i != 'baseline' or ip != 'interlaced':
return i
else:
print ( "ERROR : baseline cannot accept interlaced." )
print ( "ERROR : invalid profile setting.\n" )
usage()
sys.exit()
def check_level(lv, ip, dic):
lvl = lv.replace('0','').replace('.','')
if lvl in dic:
if ip[0] != 'i' or dic.get(lvl)[0] == 'i':
return lvl
else:
print ( "ERROR : specified level cannot accept interlaced." )
print ( "ERROR : invalid level value.\n" )
usage()
sys.exit()
def calc_mbs(w, h, ip):
mbh = int(math.ceil(float(w) / 16))
mbv = int(math.ceil(float(h) / 16))
if mbv % 2 == 1 and ip == 'interlaced':
mbv += 1
mbs = mbh * mbv
if mbs > 0:
return mbs
else:
print ( "ERROR : invalid resolution setting.\n" )
usage()
sys.exit()
def calc_vbv(lv, pr, dic):
vbvmax = dic.get(lv)[1]
vbvbuf = dic.get(lv)[2]
if pr == 'high':
return [int(vbvmax * 1.25), int(vbvbuf * 1.25)]
elif pr == 'high10':
return [int(vbvmax * 3), int(vbvbuf * 3)]
elif pr == 'high422':
return [int(vbvmax * 4), int(vbvbuf * 4)]
elif pr == 'high444p':
return [int(vbvmax * 4), int(vbvbuf * 4)]
else:
return [vbvmax, vbvbuf]
def calc_maxref(lv, mbs, dic):
ref = int(dic.get(lv)[3] / mbs)
if ref > 16:
ref = 16
if ref > 0:
return ref
else:
print ( "ERROR : resolution is too large to level.\n" )
usage()
sys.exit()
options = sys.argv
len_opt = len(options)
#set default values
width = 1280
height = 720
level = '4.1'
prof = 'high'
mode = 'progressive'
help = 0
#H.264/AVC level dictionary {level: [interlaced flag, MaxBR, MaxCPB, MaxDbpMbs]}
avcdic = {'1' :['p', 64, 175, 396], '1b':['p', 128, 350, 396],
'11':['p', 192, 500, 900], '12':['p', 384, 1000, 2376],
'13':['p', 768, 2000, 2376], '2' :['p', 2000, 2000, 2376],
'21':['i', 4000, 4000, 4752], '22':['i', 4000, 4000, 8100],
'3' :['i', 10000, 10000, 8100], '31':['i', 14000, 14000, 18000],
'32':['i', 20000, 20000, 20480], '4' :['i', 20000, 25000, 32768],
'41':['i', 50000, 62500, 32768], '42':['p', 50000, 62500, 34816],
'5' :['p', 135000, 135000, 110400], '51':['p', 240000, 240000, 184320],
'52':['p', 240000, 240000, 184320]}
if len_opt > 1:
for i in range(len_opt):
try:
if options[i] == '-r' or options[i] == '--resolution':
res = options[i + 1].split('x')
width = int(res[0])
height = int(res[1])
if options[i] == '-l' or options[i] == '--level':
level = options[i + 1]
if options[i] == '-p' or options[i] == '--profile':
prof = options[i + 1]
if options[i] == '-i' or options[i] == '--interlaced':
mode = 'interlaced'
if options[i] == '-h' or options[i] == '--help':
help = 1
except:
print ( "ERROR : invalid arguments\n" )
help = 1
else:
pass
if help == 1:
usage()
sys.exit()
else:
usage()
profile = check_prof(prof, mode)
lv_tmp = check_level(level, mode, avcdic)
mbs = calc_mbs(width, height, mode)
vbv = calc_vbv(lv_tmp, profile, avcdic)
maxref = calc_maxref(lv_tmp, mbs, avcdic)
print ( " resolution : %i x %i" % (width, height) )
print ( " level : %s" % level )
print ( " profile : %s" % profile )
print ( " mode : %s" % mode )
print ( " vbv-maxrate(vlc) : %i" % vbv[0] )
print ( " vbv-bufsize(vlc) : %i" % vbv[1] )
print ( " max ref number : %i" % maxref )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment