OSDN Git Service

implement traceback.
[rec10/rec10-git.git] / rec10 / trunk / src / ts2x264.py
1 #!/usr/bin/python
2 # coding: UTF-8
3 # Rec10 TS Recording Tools
4 # Copyright (C) 2009-2010 Yukikaze
5 import commands
6 import configreader
7 import os
8 import os.path
9 import re
10 import random
11 import time
12 import traceback
13
14 import recdblist
15 def ts2x264(pin, pout, opts):#sizeは"HD"か"SD"
16     """
17     pinで指定されたファイルをpoutにx264でエンコードして書き出す
18     """
19     dualpass = 0
20     is24fps=0
21     size="HD"
22     crf=18
23     quality=4
24     quality=int(configreader.getenv("x264_preset"))
25     crf=int(configreader.getenv("crf"))
26     deinterlace=1
27     if re.search("H", opts):
28         size = "HD"
29     if re.search("S", opts):
30         size = "WVGA"
31     if re.search("F", opts):
32         size = "FullHD"
33     if re.search("W",opts):
34         size = "WVGA"
35     if re.search("MW8", opts):
36         size = "QVGA_BASE"
37         crf=crf+4
38     if re.search("MW9", opts):
39         size = "WVGA_BASE"
40         crf=crf+2
41     if re.search("v", opts):
42         is24fps=1
43         crf=int(configreader.getenv("animation_crf"))
44     if re.search("a", opts):
45         is24fps=1
46         crf=int(configreader.getenv("animation_crf"))
47     if re.search("I", opts):
48         deinterlace=0
49     if re.search("q",opts):
50         quality=quality-2
51     if re.search("w",opts):
52         quality=quality-1
53     if re.search("e",opts):
54         quality=quality+1
55     if re.search("r",opts):
56         quality=quality+2
57     if re.search("u",opts):
58         crf=crf+2
59     if re.search("i",opts):
60         crf=crf+1
61     if re.search("o",opts):
62         crf=crf-1
63     if re.search("p",opts):
64         crf=crf-2
65     if re.search("d",opts):
66         encode_ffmpeg_sar(pin,pout,size,is24fps,quality,crf,deinterlace)
67     elif re.search("5",opts):
68         encode_ffmpeg_sar(pin,pout,size,is24fps,quality,crf,deinterlace)
69     elif re.search("b",opts):
70         try:
71             tm2v=pin.replace(".ts",".m2v")
72             encode_sar(tm2v, pout,size,is24fps,quality,crf,deinterlace)
73         except Exception, inst:
74             recdblist.Commonlogex("Error", "ts2x264(ts2x264.py)", str(type(inst)), str(inst)+traceback.format_exc(),log_level=200)
75     else:
76         try:
77             encode_sar(pin, pout,size,is24fps,quality,crf,deinterlace)
78         except Exception, inst:
79             recdblist.Commonlogex("Error", "ts2x264(ts2x264.py)", str(type(inst)), str(inst)+traceback.format_exc(),log_level=200)
80 def encode_sar(pin,pout,size,is24fps,quality,crf,deinterlace=1):
81     mencoder=configreader.getpath("mencoder")
82     encvf=""
83     txt=""
84     encvf="-sws 9 -vf yadif=0,pp=l5"
85     harddup=",hqdn3d=2:1:2,unsharp=l3x3:0.75:c3x3:0.75,harddup"
86     ofps="-ofps 30000/1001"
87     fps="-fps 30000/1001"
88     x264fps="30000/1001"
89     x264streamsize=""
90     x264preset=""
91     x264tune=""
92     x264_bitrate="5000"
93     tsar=getMoviePAR(pin)
94     x264sar=str(tsar[0])+":"+str(tsar[1])
95     if is24fps==1:
96         ofps="-ofps 24000/1001"
97         fps="-fps 30000/1001"
98         x264fps="24000/1001"
99         x264tune="--tune animation"
100         encvf="-sws 9 -vf pullup,softskip"
101         harddup=",pp=l5,unsharp=l3x3:0.75:c3x3:0.75,hqdn3d=2:1:2,harddup"
102     if size == "HD":
103         tsize=get_par_size(pin,720)
104         encvf = encvf + ",scale=-3:720::0:3"+harddup
105         x264streamsize=str(tsize[0])+u"x720"
106         x264_bitrate="2500"
107     elif size == "WVGA":
108         tsize=get_par_size(pin,480)
109         encvf = encvf + ",scale=-3:480::0:3"+harddup
110         x264streamsize=str(tsize[0])+u"x480"
111         x264_bitrate="1500"
112     elif size == "FullHD":
113         tsize=get_par_size(pin,1080)
114         encvf = encvf + ",scale=-3:1080::0:3"+harddup
115         x264streamsize=str(tsize[0])+u"x1080"
116         x264_bitrate="5000"
117     elif size == "QVGA_BASE":
118         tsize=get_par_size(pin,240)
119         encvf = encvf + ",scale=-3:240::0:3"+harddup
120         x264streamsize=str(tsize[0])+u"x240"
121         x264_bitrate="300"
122     elif size == "WVGA_BASE":
123         tsize=get_par_size(pin,480)
124         encvf = encvf + ",scale=-3:480::0:3"+harddup
125         x264streamsize=str(tsize[0])+u"x480"
126         x264_bitrate="1500"
127     else:
128         tsize=get_par_size(pin,720)
129         encvf = encvf + ",scale=-3:720::0:3"+harddup
130         x264streamsize=str(tsize[0])+u"x720"
131         x264_bitrate="2500"
132     if deinterlace==0:
133         tsize=getMovieBaseSize(pin)
134         ofps="-ofps 30000/1001"
135         #fps="-fps 30000/1001"
136         fps=""
137         x264fps="30000/1001"
138         x264tune=x264tune+" --tff --nal-hrd vbr"
139         encvf="-vf hqdn3d=2:1:2"
140         harddup=",harddup"
141         encvf=encvf+harddup
142         x264streamsize=str(tsize[0])+u"x"+str(tsize[1])
143     if tsize[0] <= 0 or tsize[1] <= 0:
144         encvf="-sws 9 -vf yadif=0,pp=l5"
145         harddup=",hqdn3d=2:1:2,unsharp=l3x3:0.75:c3x3:0.75,harddup"
146         ofps="-ofps 30000/1001"
147         fps="-fps 30000/1001"
148         x264fps="30000/1001"
149         tsize=[1280,720]
150         encvf = encvf + ",scale=-2:720::0:3,expand=1280:720"+harddup
151         x264streamsize=u"1280x720"
152         x264_bitrate="2500"
153     if quality==1:
154         x264preset=u"ultrafast"
155     elif quality==2:
156         x264preset=u"veryfast"
157     elif quality==3:
158         x264preset=u"fast"
159     elif quality==4:
160         x264preset=u"medium"
161     elif quality==5:
162         x264preset=u"slow"
163     elif quality==6:
164         x264preset=u"slower"
165     if size == "WVGA_BASE" or size == "QVGA_BASE":
166         x264profile=" --level 32 --profile baseline "
167     else:
168         x264profile=" --level 42 --profile high "
169     x264crf=str(crf)
170     os.environ['LANG']="ja_JP.UTF-8"
171     random.seed(pin)
172     random.jumpahead(10)
173     temptime=int(time.time())
174     temptime=temptime % 9697
175     random.jumpahead(temptime)
176     streampath=os.path.join(os.path.dirname(pin),str(random.randint(10000, 99999999)))
177     os.system(u"mkfifo "+streampath)
178     encexe=mencoder+u" \""+pin+u"\" -vfm ffmpeg -quiet "+encvf+u",format=i420 "+fps+" "+ofps+" -oac mp3lame -ovc raw -of rawvideo -o \""+streampath+"\" & "
179     encexe=encexe+get_x264_commandline(x264preset, x264sar, x264fps, x264profile, x264tune, pout, streampath, x264streamsize, crf=x264crf)
180     #encexe=encexe+u" nice -n 19 "+x264+" "+x264_sar+" "+x264crf+u" "+x264_addline+u"  --threads "+x264_thread+" "+x264profile+x264preset+" "+x264tune+" "+x264fps+" -o \""+pout+"\" "+streampath+" "+x264streamsize
181     encexe=u"nice -n 19 " +encexe
182     recdblist.printutf8(encexe)
183     txt=""
184     try:
185         txt=unicode(commands.getoutput(encexe.encode('utf-8')),'utf-8','ignore')
186     except:
187         ""
188     os.system("rm "+streampath)
189     recdblist.addCommandLog(pin, u"Mencoder", encexe, txt)
190
191
192 def encode_ffmpeg_sar(pin,pout,size,is24fps,quality,crf,deinterlace=1):
193     """
194
195     """
196     ffmpeg=configreader.getpath("ffmpeg")
197     fps=u"-r 29.970030 "
198     x264fps="30000/1001"
199     x264streamsize=""
200     x264preset=""
201     x264tune=""
202     x264_bitrate="2500"
203     x264_thread="auto"
204     tsar=getMoviePAR(pin)
205     filter="-deinterlace"
206     x264sar=str(tsar[0])+":"+str(tsar[1])
207     if size == "HD":
208         tsize=get_par_size(pin,720)
209         s = "-s "+str(tsize[0])+"x720 "
210         x264streamsize=str(tsize[0])+u"x720"
211         x264_bitrate="2500"
212     elif size == "WVGA":
213         tsize=get_par_size(pin,480)
214         s = "-s "+str(tsize[0])+"x480 "
215         x264streamsize=str(tsize[0])+u"x480"
216         x264_bitrate="1500"
217     elif size == "FullHD":
218         tsize=get_par_size(pin,1080)
219         s = "-s "+str(tsize[0])+"x1080 "
220         x264streamsize=str(tsize[0])+u"x1080"
221         x264_bitrate="5000"
222     elif size == "SD":
223         tsize=get_par_size(pin,480)
224         s = "-s "+str(tsize[0])+"x480 "
225         x264streamsize=str(tsize[0])+u"x480"
226         x264_bitrate="1250"
227     elif size == "QVGA_BASE":
228         tsize=get_par_size(pin,240)
229         s = "-s "+str(tsize[0])+"x240 "
230         x264streamsize=str(tsize[0])+u"x240"
231         x264_bitrate="300"
232     elif size == "WVGA_BASE":
233         tsize=get_par_size(pin,480)
234         s = "-s "+str(tsize[0])+"x480 "
235         x264streamsize=str(tsize[0])+u"x480"
236         x264_bitrate="1500"
237     else:
238         tsize=get_par_size(pin,720)
239         s = "-s "+str(tsize[0])+"x720 "
240         x264streamsize=str(tsize[0])+u"x720"
241         x264_bitrate="2500"
242     if deinterlace==0:
243         tsize=getMovieBaseSize(pin)
244         fps=""
245         s = "-s "+str(tsize[0])+"x"+str(tsize[1])+" "
246         x264fps="30000/1001"
247         x264tune=x264tune+" --tff --nal-hrd vbr"
248         filter=""
249         x264streamsize=str(tsize[0])+u"x"+str(tsize[1])
250     if quality==1:
251         x264preset=u"ultrafast"
252     elif quality==2:
253         x264preset=u"veryfast"
254     elif quality==3:
255         x264preset=u"fast"
256     elif quality==4:
257         x264preset=u"medium"
258     elif quality==5:
259         x264preset=u"slow"
260     elif quality==6:
261         x264preset=u"slower"
262     if size == "WVGA_BASE" or size == "QVGA_BASE":
263         x264profile=" --level 32 --profile baseline "
264     else:
265         x264profile=" --level 42 --profile high "
266     x264crf=str(crf)
267     txt=""
268     os.environ['LANG']="ja_JP.UTF-8"
269     exe=ffmpeg+u" -y -i \""+pin+"\" -vsync 400 -vcodec rawvideo -pix_fmt yuv420p "+s+fps+" "+filter+" -an -f rawvideo - | "
270     exe=exe+get_x264_commandline(x264preset, x264sar, x264fps, x264profile, x264tune, pout,"-", x264streamsize, crf=x264crf)
271     exe = "nice -n 19 " + exe
272     txt=""
273     recdblist.printutf8(exe)
274     try:
275         txt=unicode(commands.getoutput(exe.encode('utf-8')),'utf-8','ignore')
276     except:
277         ""
278     recdblist.addCommandLog(pin, u"FFmpeg動画エンコード", exe, txt)
279
280 def getMovieBaseSize(pin):
281     ffmpeg=configreader.getpath("ffmpeg")
282     os.environ['LANG']="ja_JP.UTF-8"
283     exe=ffmpeg+u" -i \""+pin+"\" 2>&1"
284     txts=unicode(commands.getoutput(exe.encode('utf-8')),'utf-8','ignore')
285     rT=re.compile(u".*Stream.*#.*:.*\D+([\d]+x[\d]+)\D+PAR\D+(\d+:\d+)\D+.*\Z")
286     sizeMaxX=0
287     sizeMaxY=0
288     txtls=txts.split("\n")
289     for t in txtls:
290         rM=rT.match(t)
291         if rM:
292             sizetxt=rM.group(1)
293             partxt=rM.group(2)
294             tX=int(sizetxt.split("x")[0])
295             tY=int(sizetxt.split("x")[1])
296             tEX=int(partxt.split(":")[0])
297             tEY=int(partxt.split(":")[1])
298             if sizeMaxX<tX:
299                 sizeMaxX=tX
300                 sizeMaxY=tY
301     return [sizeMaxX,sizeMaxY]
302 def getMoviePAR(pin):
303     ffmpeg=configreader.getpath("ffmpeg")
304     os.environ['LANG']="ja_JP.UTF-8"
305     exe=ffmpeg+u" -i \""+pin+"\" 2>&1"
306     txts=unicode(commands.getoutput(exe.encode('utf-8')),'utf-8','ignore')
307     rT=re.compile(u".*Stream.*#.*:.*\D+([\d]+x[\d]+)\D+PAR\D+(\d+:\d+)\D+.*\Z")
308     #rT=re.compile(u".*Stream.*#.*:.*\D+([\d]+x[\d]+)\D+.*DAR\D+(\d+:\d+)\D+.*\Z")
309     sizeMaxX=0
310     parx=0
311     pary=0
312     txtls=txts.split("\n")
313     for t in txtls:
314         rM=rT.match(t)
315         if rM:
316             sizetxt=rM.group(1)
317             dartxt=rM.group(2)
318             tX=int(sizetxt.split("x")[0])
319             tY=int(sizetxt.split("x")[1])
320             tEX=int(dartxt.split(":")[0])
321             tEY=int(dartxt.split(":")[1])
322             if sizeMaxX<tX:
323                 sizeMaxX=tX
324                 if tX==1920 and tY==1080:
325                     parx=1
326                     pary=1
327                 else:
328                     parx=tEX
329                     pary=tEY
330     return [parx,pary]
331 def getMovieDAR(pin):
332     ffmpeg=configreader.getpath("ffmpeg")
333     os.environ['LANG']="ja_JP.UTF-8"
334     exe=ffmpeg+u" -i \""+pin+"\" 2>&1"
335     txts=unicode(commands.getoutput(exe.encode('utf-8')),'utf-8','ignore')
336     rT=re.compile(u".*Stream.*#.*:.*\D+([\d]+x[\d]+)\D+.*DAR\D+(\d+:\d+)\D+.*\Z")
337     sizeMaxX=0
338     darx=0
339     dary=0
340     txtls=txts.split("\n")
341     for t in txtls:
342         rM=rT.match(t)
343         if rM:
344             sizetxt=rM.group(1)
345             dartxt=rM.group(2)
346             tX=int(sizetxt.split("x")[0])
347             tY=int(sizetxt.split("x")[1])
348             tEX=int(dartxt.split(":")[0])
349             tEY=int(dartxt.split(":")[1])
350             if sizeMaxX<tX:
351                 sizeMaxX=tX
352                 if tX==1920 and tY==1080:
353                     darx=16
354                     dary=9
355                 else:
356                     darx=tEX
357                     dary=tEY
358     return [darx,dary]
359 def get_par_size(pin,y):
360     tSize=getMovieBaseSize(pin)
361     if tSize[1] != 0 :
362         tX=tSize[0]*10*y/tSize[1]
363         tY=y
364         if tX>int(tX/10)*10:
365             tX=tX/10+1
366         else:
367             tX=tX/10
368     else:
369         tX=-1
370         tY=-1
371     return [tX,tY]
372
373 def get_x264core_version():
374     x264=configreader.getpath("x264")
375     t1=commands.getoutput(x264+" --help|grep core")
376     rT=re.compile(u"x264 core:(\d*)[\d]*.*\Z")
377     rM=rT.match(t1)
378     v=-1
379     if rM:
380         v=int(rM.group(1))
381     return v
382 def get_x264_commandline(preset,sar,fps,x264profile,x264tune,pout,pin,x264streamsize,crf=0,bitrate=0):
383     x264=configreader.getpath("x264")
384     os.environ['LANG']="ja_JP.UTF-8"
385     x264_sar="--sar "+sar
386     x264preset=u"--preset "+preset
387     x264fps="--fps "+fps
388     if crf==0:
389         x264bitrate=u"--bitrate "+str(bitrate)
390     else:
391         x264crf=u"--crf "+str(crf)
392     x264_addline=configreader.getenv("x264_addline")
393     x264_thread="auto"
394     try:
395         xtt=configreader.getenv("x264_thread")
396         xtt=int(xtt)
397         if xtt>0:
398             x264_thread=str(xtt)
399     except:
400         x264_thread="auto"
401     x264_addline=configreader.getenv("x264_addline")
402     if get_x264core_version()>103:
403         x264res=u"--input-res "+x264streamsize
404         exe=u"nice -n 19 "+x264+" "+x264_sar+" "+x264crf+u" "+x264_addline+u" --colormatrix bt709 --threads "+x264_thread+" "+x264profile+x264preset+" "+x264tune+" "+x264fps+" "+x264res+" -o \""+pout+"\" "+pin
405     else:
406         exe=u"nice -n 19 "+x264+" "+x264_sar+" "+x264crf+u" "+x264_addline+u" --colormatrix bt709 --threads "+x264_thread+" "+x264profile+x264preset+" "+x264tune+" "+x264fps+" -o \""+pout+"\" "+pin+" "+x264streamsize
407     return exe