OSDN Git Service

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