Created
April 7, 2012 03:48
-
-
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 )
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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