#!/usr/bin/pythonimport sysimport osimport globimport subprocessimport rere_xvidpsnr=re.compile("xvid: Average.*All:(.*?) ")re_x264psnr=re.compile("x264 \[info\]: PSNR Mean.*Global:(.*?) ")def getvidinfo(vidfile): """returns the vid total frames (len,frames)""" p=subprocess.Popen(["mplayer","-vo", "null", "-identify",vidfile], \ stderr=subprocess.PIPE, \ stdout=subprocess.PIPE, \ stdin=subprocess.PIPE).communicate('q')[0] for line in p.split('\n'): if line.startswith("ID_LENGTH="): length=float(line.split("=")[1]) if line.startswith("ID_VIDEO_FPS"): fps=float(line.split("=")[1]) frames=int(length*fps) return length,framesdef getpsnr(vidfile, format, mplayeropts, fq): """Return the average psnr""" length,frames=getvidinfo(vidfile) frames_to_process=frames*.02 no_of_segments = 20 if frames_to_process<3000: frames_to_process = 3000 fpseg=int(frames_to_process/no_of_segments) segs=range(0,int(length),int(length/no_of_segments))[1:-1] quant_opt = "-xvidencopts" quant_string = "fixed_quant" if format=="x264": quant_opt = "-x264encopts" quant_string = "crf" psnrs=[] bitrates=[] program = ["mencoder"] quant = [quant_opt, "%s=%s:psnr"%(quant_string,fq)] options = ["-forceidx","-nosound"]+mplayeropts+quant+["-frames",str(fpseg)] outfile = ["-o","/dev/null"] for seg in segs: ss=["-ss",str(seg)] runlist=program+options+ss+[vidfile]+outfile p=subprocess.Popen(runlist,stderr=subprocess.PIPE, stdout=subprocess.PIPE) output=p.communicate()# print output[1]# print runlist if format=="xvid": psnr=float(re_xvidpsnr.search(output[0]).group(1)) elif format=="x264": psnr=float(re_x264psnr.search(output[1]).group(1)) bitrate=float([i.split()[2] for i in output[0].split('\n') if i.startswith('Video stream:')][0]) bitrates.append(bitrate) psnrs.append(psnr) sys.stdout.write("%s..."%psnr) sys.stdout.flush() average_psnr = sum(psnrs)/len(psnrs) average_bitrate = sum(bitrates)/len(bitrates) print print '%s: %.1f' %(quant_string, fq) print 'avg psnr:',average_psnr print 'avg bitrate:', average_bitrate return average_psnrdef processvid(vidfile,targetpsnr, format, mplayeropts, ask=True): """Return the average psnr for these segments""" fq=2.0 variance=2 quant_string="fixed_quant" if format=="x264": fq=18 variance*=2 quant_string="crf" targetpsnr=float(targetpsnr) print "Pass (1/2):" firstpsnr = getpsnr(vidfile, format, mplayeropts, fq) print "\nPass (2/2):" secondpsnr = getpsnr(vidfile, format, mplayeropts, fq+variance) guessfq = fq+(abs(firstpsnr-targetpsnr)/((firstpsnr-secondpsnr)/variance)) print print "%s: %.1f\nShould yield\nPSNR guess:%.3f"%(quant_string, guessfq, targetpsnr) if ask: print reply = raw_input('Would you like to test for bitrate (this will do another pass)? [Y/n]: ') if reply=='' or reply.lower()=='y': thirdpsnr = getpsnr(vidfile, format, mplayeropts, guessfq) else: thirdpsnr = getpsnr(vidfile, format, mplayeropts, guessfq)def getoptions(): """gets the options from user input""" if len(sys.argv)<5: print """usage: %s [MENCODER OPTIONS] [FILE] [PSNR] MENCODER OPTIONS = options excluding -o, crf, fixed_quant, and bitrate -profile is allowed PSNR = target psnrexample: %s -ovc xvid -xvidencopts chroma_opt:threads=2:autoaspect title1.vob 44"""\ %(os.path.basename(sys.argv[0]), os.path.basename(sys.argv[0])) sys.exit() targetpsnr = sys.argv[-1] vidfile = sys.argv[-2] mplayeropts = sys.argv[1:-2] #check for -ovc to find out what codec user is using if "-ovc" in mplayeropts: format = mplayeropts[mplayeropts.index("-ovc")+1] if not (format=="xvid" or format=="x264"): print "%s codec not supported by %s"%(format,os.path.basename(sys.argv[0])) sys.exit() #check if -profile is one of the options elif "-profile" in mplayeropts: profile = mplayeropts[mplayeropts.index("-profile")+1] for i in subprocess.Popen(("mencoder -show-profile %s"%profile).split(), \ stdout=subprocess.PIPE).stdout: if i.strip().startswith("ovc="): format=i.split('=')[1] if not (format=="xvid" or format=="x264"): print "%s codec not supported by %s" % \ (format, os.path.basename(sys.argv[0])) sys.exit() break else: print "no -profile or -ovc option present" sys.exit() return vidfile, targetpsnr, format, mplayeropts(vidfile, targetpsnr, format, mplayeropts) = getoptions()processvid(vidfile,targetpsnr, format, mplayeropts)for x in glob.glob('psnr*.log'): os.unlink(x)