Now can launch one process per core, and launch new ones when the old ones end

This commit is contained in:
Sergio Costas 2014-07-23 23:53:11 +02:00
parent 13f9e67eb1
commit 86f77faa3f
13 changed files with 761 additions and 77 deletions

129
data/interface/wcreate.ui Normal file
View file

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.1 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<object class="GtkDialog" id="dialog_create">
<property name="width_request">380</property>
<property name="height_request">270</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">devede</property>
<property name="icon_name">devede.svg</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox1">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area1">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="button1">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="accept">
<property name="label">gtk-ok</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Choose the folder where Devede will create the files and a name for it. Do not use a folder in a VFAT/FAT32 drive. Characters /, | and \ are not accepted and will be replaced by underscores.</property>
<property name="wrap">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkFileChooserButton" id="path">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action">select-folder</property>
<signal name="file-set" handler="on_iface_changed" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="name">
<property name="visible">True</property>
<property name="can_focus">True</property>
<signal name="changed" handler="on_iface_changed" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="shutdown">
<property name="label" translatable="yes">Shutdown computer when disc is done</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="0">button1</action-widget>
<action-widget response="1">accept</action-widget>
</action-widgets>
</object>
</interface>

View file

@ -728,6 +728,7 @@
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_create_disc_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>

View file

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.1 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<object class="GtkWindow" id="progress">
<property name="can_focus">False</property>
<property name="title" translatable="yes">Creating...</property>
<property name="resizable">False</property>
<property name="window_position">center</property>
<property name="icon_name">devede.svg</property>
<property name="deletable">False</property>
<property name="has_resize_grip">False</property>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkFrame" id="progress_frame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<placeholder/>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkProgressBar" id="progress_total">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_text">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="cancel">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_cancel_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="padding">8</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

View file

@ -17,14 +17,90 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
from gi.repository import GLib
import subprocess
import os
import devede.configuration_data
import devede.executor
class avconv_converter:
class avconv_converter(devede.executor.executor):
supports_analize = False
supports_play = False
supports_convert = False
supports_menu = True
display_name = "AVCONV"
@staticmethod
def check_is_installed():
handle = subprocess.Popen(["avconv","-version"], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
(stdout, stderr) = handle.communicate()
if 0==handle.wait():
return True
else:
return False
def __init__(self):
devede.executor.executor.__init__(self)
self.config = devede.configuration_data.configuration.get_config()
def create_mpg(self,n_page,background_music,sound_length,pal,output_path):
self.n_page = n_page
self.sound_length = float(sound_length)
self.text = _("Creating menu %(X)d") % {"X": self.n_page}
self.command_var=[]
self.command_var.append("avconv")
self.command_var.append("-loop")
self.command_var.append("1")
self.command_var.append("-f")
self.command_var.append("image2")
self.command_var.append("-i")
self.command_var.append(os.path.join(output_path,"menu_"+str(n_page)+"_bg.png"))
self.command_var.append("-i")
self.command_var.append(background_music)
self.command_var.append("-y")
self.command_var.append("-target")
if pal:
self.command_var.append("pal-dvd")
else:
self.command_var.append("ntsc-dvd")
self.command_var.append("-acodec")
self.command_var.append("mp2")
self.command_var.append("-s")
if pal:
self.command_var.append("720x576")
else:
self.command_var.append("720x480")
self.command_var.append("-g")
self.command_var.append("12")
self.command_var.append("-b:v")
self.command_var.append("2500k")
self.command_var.append("-b:a")
self.command_var.append("192k")
self.command_var.append("-aspect")
self.command_var.append("4:3")
self.command_var.append("-t")
self.command_var.append(str(1+sound_length))
self.command_var.append(os.path.join(output_path,"menu_"+str(n_page)+".mpg"))
def process_stdout(self,data):
pass
def process_stderr(self,data):
pos = data[0].find("time=")
if (pos != -1):
pos+=5
pos2 = data[0].find(" ",pos)
if (pos2 != -1):
t = float(data[0][pos:pos2])
self.progress_bar[1].set_fraction(t / self.sound_length)

View file

@ -33,6 +33,7 @@ class configuration(GObject.GObject):
configuration.current_configuration = None
return configuration.current_configuration
def fill_config(self):
GObject.GObject.__init__(self)
@ -78,7 +79,7 @@ class configuration(GObject.GObject):
self.PAL = True
self.tmp_folder = "/var/tmp"
self.multicore = True
self.final_folder = None
self.final_folder = os.environ.get("HOME")
self.sub_language = None
self.sub_codepage = None
self.film_analizer = None

View file

@ -17,6 +17,7 @@
import devede.configuration_data
import devede.mplayer_detector
import devede.avconv_converter
class converter:
@ -32,7 +33,8 @@ class converter:
def __init__(self):
self.config = devede.configuration_data.configuration.get_config()
self.c = [devede.mplayer_detector.mplayer_detector]
# List of classes with conversion capabilities, in order of preference
self.c = [devede.mplayer_detector.mplayer_detector, devede.avconv_converter.avconv_converter]
self.analizers = {}
self.default_analizer = None
@ -111,3 +113,11 @@ class converter:
return self.default_analizer
else:
return self.analizers[self.config.film_analizer]
def get_menu_converter(self):
""" returns a class for the desired menu converter, or the most priviledged if the desired is not installed """
if (self.config.menu_converter == None) or (self.analizers.has_key(self.config.menu_converter) == False):
return self.default_menuer
else:
return self.menuers[self.config.menu_converter]

View file

@ -0,0 +1,64 @@
# Copyright 2014 (C) Raster Software Vigo (Sergio Costas)
#
# This file is part of DeVeDe-NG
#
# DeVeDe-NG is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# DeVeDe-NG is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
from gi.repository import Gtk
import os
import devede.configuration_data
class create_disk_window:
def __init__(self):
self.config = devede.configuration_data.configuration.get_config()
def run(self):
builder = Gtk.Builder()
builder.set_translation_domain(self.config.gettext_domain)
builder.add_from_file(os.path.join(self.config.glade,"wcreate.ui"))
builder.connect_signals(self)
wcreate_window = builder.get_object("dialog_create")
self.wpath = builder.get_object("path")
self.wname = builder.get_object("name")
wshutdown = builder.get_object("shutdown")
self.waccept = builder.get_object("accept")
self.wname.set_text("movie")
self.wpath.set_current_folder(self.config.final_folder)
wcreate_window.show_all()
self.on_iface_changed(None)
retval = wcreate_window.run()
self.path = self.wpath.get_current_folder()
self.name = self.wname.get_text()
self.shutdown = wshutdown.get_active()
wcreate_window.destroy()
if (retval == 1):
return True
else:
return False
def on_iface_changed(self,b):
path = self.wpath.get_current_folder()
name = self.wname.get_text()
if ((path == None) or (path == "") or (name == None) or (name == "")):
self.waccept.set_sensitive(False)
else:
self.waccept.set_sensitive(True)

View file

@ -20,6 +20,7 @@ from gi.repository import Gtk,Gdk,GdkPixbuf
import os
import devede.configuration_data
import devede.interface_manager
import devede.message
class dvd_menu(devede.interface_manager.interface_manager):
@ -59,12 +60,28 @@ class dvd_menu(devede.interface_manager.interface_manager):
self.add_fontbutton("entry_font", "Sans 18", self.update_preview)
self.add_filebutton("background_picture", self.default_background, self.update_preview)
self.add_filebutton("background_music", self.default_sound, self.update_preview)
self.add_filebutton("background_music", self.default_sound, self.update_music)
self.cached_menu_font = None
self.cached_menu_size = 0
self.sound_length = 30
def update_music(self,b=None):
self.store_ui(self.builder)
cv = devede.converter.converter()
film_analizer = (cv.get_film_analizer())()
(video, audio, length) = film_analizer.analize_film_data(self.background_music,True)
if (video != 0):
devede.message.message_window(_("The selected file is a video, not an audio file"),_("Error"))
self.on_no_sound_clicked(None)
elif (audio == 0):
devede.message.message_window(_("The selected file is not an audio file"),_("Error"))
self.on_no_sound_clicked(None)
else:
self.sound_length = length
def update_preview(self,b=None):
self.store_ui(self.builder)
@ -80,6 +97,7 @@ class dvd_menu(devede.interface_manager.interface_manager):
def on_no_sound_clicked(self,b):
self.background_music = self.default_sound
self.sound_length = 30
self.update_ui(self.builder)
@ -118,10 +136,6 @@ class dvd_menu(devede.interface_manager.interface_manager):
self.wmenu.destroy()
def on_preview_menu_clicked(self,b):
pass
def get_font_params(self,font_name):
font_elements=font_name.split(" ")
@ -161,7 +175,7 @@ class dvd_menu(devede.interface_manager.interface_manager):
elif arrow_type == "menu_entry_selected":
fgcolor = self.selected_color
elif arrow_type == "menu_entry_activated":
fgcolor = ( 1.0 - self.selected_color[0], 1.0 - self.selected_color[1], 1.0 - self.selected_color[2] )
fgcolor = ( 1.0 - self.selected_color[0], 1.0 - self.selected_color[1], 1.0 - self.selected_color[2], self.selected_color[3])
else:
return
@ -210,7 +224,7 @@ class dvd_menu(devede.interface_manager.interface_manager):
hard_borders = True
font = self.entry_font
elif text_type == "menu_entry_activated":
fgcolor = ( 1.0 - self.selected_color[0], 1.0 - self.selected_color[1], 1.0 - self.selected_color[2] )
fgcolor = ( 1.0 - self.selected_color[0], 1.0 - self.selected_color[1], 1.0 - self.selected_color[2], self.selected_color[3])
bgcolor = None
hard_borders = True
font = self.entry_font
@ -256,7 +270,7 @@ class dvd_menu(devede.interface_manager.interface_manager):
""" This method sets data that can't be changed from the dvd settings window.
It must be called before painting a menu """
if self.config.PAL:
if self.project.pal:
self.y=576.0
else:
self.y=480.0
@ -270,6 +284,7 @@ class dvd_menu(devede.interface_manager.interface_manager):
self.sf = None
self.current_shown_page = 0
self.wcurrent_page = None
def paint_menu(self,paint_background, paint_selected, paint_activated, page_number):
@ -325,6 +340,7 @@ class dvd_menu(devede.interface_manager.interface_manager):
if (page_number >= self.pages) and (page_number > 0):
page_number -= 1
if self.wcurrent_page != None:
self.wcurrent_page.set_text(_("Page %(X)d of %(Y)d") % {"X":page_number+1 , "Y":self.pages})
xl = left_margin_p
xr = 720.0 - right_margin_p
@ -341,26 +357,26 @@ class dvd_menu(devede.interface_manager.interface_manager):
y += entry_height
if paint_arrows:
if page_number == 0:
self.paint_base(xl, xr, y, 0)
if paint_background:
self.paint_base(xl, xr, y, 0)
self.paint_arrow(xl, xr, y, "menu_entry", False)
if paint_selected:
self.paint_arrow(xl, xr, y, "menu_entry_selected", False)
if paint_activated:
self.paint_arrow(xl, xr, y, "menu_entry_activated", False)
elif page_number == (self.pages - 1):
self.paint_base(xl, xr, y, 0)
if paint_background:
self.paint_base(xl, xr, y, 0)
self.paint_arrow(xl, xr, y, "menu_entry", True)
if paint_selected:
self.paint_arrow(xl, xr, y, "menu_entry_selected", True)
if paint_activated:
self.paint_arrow(xl, xr, y, "menu_entry_activated", True)
else:
self.paint_base(xl, xr, y, 1)
self.paint_base(xl, xr, y, 2)
med = (xl + xr) / 2.0
if paint_background:
self.paint_base(xl, xr, y, 1)
self.paint_base(xl, xr, y, 2)
self.paint_arrow(med, xr, y, "menu_entry", False)
self.paint_arrow(xl, med, y, "menu_entry", True)
if paint_selected:
@ -411,9 +427,6 @@ class dvd_menu(devede.interface_manager.interface_manager):
""" Callback to repaint the menu preview window when it
sends the EXPOSE event """
if not self.config.menu_dynamic_preview:
return
if (self.sf == None):
self.paint_menu(True, self.wshow_as_selected.get_active(), False, self.current_shown_page)
if (self.current_shown_page >= self.pages):
@ -421,3 +434,36 @@ class dvd_menu(devede.interface_manager.interface_manager):
cr.set_source_surface(self.sf)
cr.paint()
def create_dvd_menus(self,base_path):
self.refresh_static_data()
cv = devede.converter.converter()
menu_folder = os.path.join(base_path,"menu")
try:
os.makedirs(menu_folder)
except:
pass
n_page = 0
self.pages = 1
processes = []
menu_converter = cv.get_menu_converter()
while n_page < self.pages:
self.sf = None
self.paint_menu(True, False, False, n_page)
self.sf.write_to_png(os.path.join(menu_folder,"menu_"+str(n_page)+"_bg.png"))
self.sf = None
self.paint_menu(False, False, False, n_page)
self.sf.write_to_png(os.path.join(menu_folder,"menu_"+str(n_page)+"_unselected_bg.png"))
self.sf = None
self.paint_menu(False, True, False, n_page)
self.sf.write_to_png(os.path.join(menu_folder,"menu_"+str(n_page)+"_selected_bg.png"))
self.sf = None
self.paint_menu(False, False, True, n_page)
self.sf.write_to_png(os.path.join(menu_folder,"menu_"+str(n_page)+"_active_bg.png"))
converter = menu_converter()
converter.create_mpg(n_page,self.background_music,self.sound_length,self.project.pal,menu_folder)
# add this process without dependencies
processes.append([converter, None])
n_page += 1
return processes

View file

@ -17,16 +17,132 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
from gi.repository import GLib,GObject
import subprocess
import os
import signal
import devede.configuration_data
class executor:
class executor(GObject.GObject):
""" This class encapsulates everything needed for launching processes """
__gsignals__ = {'ended': (GObject.SIGNAL_RUN_FIRST, None,(int,))}
def __init__(self):
GObject.GObject.__init__(self)
self.config = devede.configuration_data.configuration.get_config()
self.channel_stdout = None
self.channel_stderr = None
self.text = ""
self.stdout_data = ""
self.stderr_data = ""
def run(self, progress_bar):
self.progress_bar = progress_bar
self.launch_process(self.command_var)
self.progress_bar[0].set_label(self.text)
self.progress_bar[1].set_fraction(0.0)
self.progress_bar[0].show_all()
def remove_ansi(self,line):
output=""
while True:
pos=line.find("\033[") # try with double-byte ESC
jump=2
if pos==-1:
pos=line.find("\233") # if not, try with single-byte ESC
jump=1
if pos==-1: # no ANSI characters; we ended
output+=line
break
output+=line[:pos]
line=line[pos+jump:]
while True:
if len(line)==0:
break
if (ord(line[0])<64) or (ord(line[0])>126):
line=line[1:]
else:
line=line[1:]
break
return output
def launch_process(self,command):
self.config.append_log("Launching:",False)
for e in command:
self.config.append_log(e+" ")
self.handle = subprocess.Popen(command,stdout = subprocess.PIPE, stderr = subprocess.PIPE)
self.channel_stdout = GLib.IOChannel(self.handle.stdout.fileno())
self.channel_stderr = GLib.IOChannel(self.handle.stderr.fileno())
self.channel_stdout.add_watch(GLib.IO_IN | GLib.IO_HUP,self.read_stdout)
self.channel_stderr.add_watch(GLib.IO_IN | GLib.IO_HUP,self.read_stderr)
self.stdout_buf = ""
self.stderr_buf = ""
def read_stdout(self,source,condition):
if (condition != GLib.IO_IN):
self.channel_stdout = None
if (self.channel_stderr == None):
self.wait_end()
return False
else:
line_data = self.stdout_buf+(self.handle.stdout.read1(4096).decode("utf-8"))
self.stdout_data += line_data
data = (line_data).replace("\r","\n").split("\n")
if (len(data) == 1):
final_data = []
self.stdout_buf = data[0]
else:
final_data = data[:-1]
self.stdout_buf = data[-1]
if (len(final_data) != 0):
self.process_stdout(final_data)
return True
def read_stderr(self,source,condition):
if (condition != GLib.IO_IN):
self.channel_stderr = None
if (self.channel_stdout == None):
self.wait_end()
return False
else:
line_data = self.stderr_buf+(self.handle.stderr.read1(4096).decode("utf-8"))
self.stderr_data += line_data
data = (line_data).replace("\r","\n").split("\n")
if (len(data) == 1):
final_data = []
self.stderr_buf = data[0]
else:
final_data = data[:-1]
self.stderr_buf = data[-1]
if (len(final_data) != 0):
self.process_stderr(final_data)
return True
def cancel(self):
""" Called to kill this process. """
if self.handle==None:
return
os.kill(self.handle.pid,signal.SIGKILL)
def wait_end(self):
self.config.append_log(self.text)
self.config.append_log(self.stdout_data)
self.config.append_log(self.stderr_data)
retval = self.handle.wait()
self.emit("ended",retval)

View file

@ -116,9 +116,21 @@ class file_movie(devede.interface_manager.interface_manager):
cv = devede.converter.converter()
film_analizer = (cv.get_film_analizer())()
if (film_analizer.get_film_data(self)):
if (film_analizer.get_film_data(self.file_name)):
self.error = True
else:
self.audio_list = film_analizer.audio_list
self.audio_streams = film_analizer.audio_streams
self.video_streams = film_analizer.video_streams
self.original_width = film_analizer.original_width
self.original_height = film_analizer.original_height
self.original_length = film_analizer.original_length
self.original_size = film_analizer.original_size
self.original_aspect_ratio = film_analizer.original_aspect_ratio
self.original_videorate = film_analizer.original_videorate
self.original_audiorate = film_analizer.original_audiorate
self.original_audiorate_uncompressed = film_analizer.original_audiorate_uncompressed
self.original_fps = film_analizer.original_fps
self.error = False

View file

@ -17,8 +17,9 @@
import subprocess
import devede.configuration_data
import devede.executor
class mplayer_detector:
class mplayer_detector(devede.executor.executor):
supports_analize = True
supports_play = True
@ -39,81 +40,92 @@ class mplayer_detector:
self.config = devede.configuration_data.configuration.get_config()
def get_film_data(self,movie):
def get_film_data(self, file_name):
""" processes a file, refered by the FILE_MOVIE movie object, and fills its
main data (resolution, FPS, length...) """
video = self.get_film_data2(movie, True)
(video, audio, length) = self.analize_film_data(file_name, True)
if (video):
self.get_film_data2(movie, False)
if (video != 0):
self.analize_film_data(file_name, False)
return False # no error
else:
return True # the file is not a video file; maybe an audio-only file, or another thing
def get_film_data2(self,movie,check_audio):
def analize_film_data(self,file_name,check_audio):
if (check_audio):
frames = "0"
else:
frames = "1"
command_line = ["mplayer","-loop","1","-identify", "-vo", "null", "-ao", "null", "-frames", frames , movie.file_name]
command_line = ["mplayer","-loop","1","-identify", "-vo", "null", "-ao", "null", "-frames", frames , file_name]
handle = subprocess.Popen(command_line, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
(stdout, stderr) = handle.communicate()
minimum_audio=-1
movie.audio_list=[]
movie.audio_streams = 0
movie.video_streams = 0
movie.original_width = 0
movie.original_height = 0
self.audio_list=[]
self.audio_streams = 0
self.video_streams = 0
self.original_width = 0
self.original_height = 0
self.original_length = 0
self.original_videorate = 0
self.original_audiorate = 0
self.original_audiorate_uncompressed = 0
self.original_fps = 0
for line in str(stdout).split("\\n"):
#line=self.remove_ansi(line)
line=self.remove_ansi(line)
if line == "":
continue
position=line.find("ID_")
if position==-1:
continue
line=line[position:]
if (not check_audio):
if line[:16]=="ID_VIDEO_BITRATE":
movie.original_videorate=int(int(line[17:])/1000)
self.original_videorate=int(int(line[17:])/1000)
if line[:14]=="ID_VIDEO_WIDTH":
movie.original_width=int(line[15:])
self.original_width=int(line[15:])
if line[:15]=="ID_VIDEO_HEIGHT":
movie.original_height=int(line[16:])
self.original_height=int(line[16:])
if line[:15]=="ID_VIDEO_ASPECT":
movie.original_aspect_ratio=float(line[16:])
self.original_aspect_ratio=float(line[16:])
if line[:12]=="ID_VIDEO_FPS":
movie.original_fps=float(line[13:])
self.original_fps=float(line[13:])
if line[:16]=="ID_AUDIO_BITRATE":
movie.original_audiorate=int(int(line[17:])/1000)
self.original_audiorate=int(int(line[17:])/1000)
if line[:13]=="ID_AUDIO_RATE":
movie.original_audiorate_uncompressed=int(line[14:])
self.original_audiorate_uncompressed=int(line[14:])
if line[:9]=="ID_LENGTH":
movie.original_length=int(float(line[10:]))
self.original_length=int(float(line[10:]))
if line[:11]=="ID_VIDEO_ID":
movie.video_streams+=1
self.video_streams+=1
if line[:11]=="ID_AUDIO_ID":
movie.audio_streams+=1
self.audio_streams+=1
audio_track=int(line[12:])
if (minimum_audio == -1) or (minimum_audio>audio_track):
minimum_audio=audio_track
movie.audio_list.append(audio_track)
self.audio_list.append(audio_track)
movie.original_size = str(movie.original_width)+"x"+str(movie.original_height)
if (movie.original_aspect_ratio == None) or (movie.original_aspect_ratio <= 1.0):
if (movie.original_height != 0):
movie.original_aspect_ratio = (float(movie.original_width))/(float(movie.original_height))
if (check_audio):
if (movie.original_aspect_ratio != None):
movie.original_aspect_ratio = (float(int(movie.original_aspect_ratio*1000.0)))/1000.0
return (self.video_streams, self.audio_streams, self.original_length)
if (movie.video_streams == 0):
else:
self.original_size = str(self.original_width)+"x"+str(self.original_height)
if (self.original_aspect_ratio == None) or (self.original_aspect_ratio <= 1.0):
if (self.original_height != 0):
self.original_aspect_ratio = (float(self.original_width))/(float(self.original_height))
if (self.original_aspect_ratio != None):
self.original_aspect_ratio = (float(int(self.original_aspect_ratio*1000.0)))/1000.0
if (self.video_streams == 0):
return False
else:
return True

View file

@ -23,6 +23,8 @@ import devede.ask
import devede.add_files
import devede.message
import devede.dvd_menu
import devede.create_disk_window
import devede.runner
class devede_project:
@ -70,8 +72,10 @@ class devede_project:
if (self.config.PAL):
self.wuse_pal.set_active(True)
self.pal = True
else:
self.wuse_ntsc.set_active(True)
self.pal = False
self.wcreate_menu.set_active(True)
@ -140,11 +144,11 @@ class devede_project:
self.wproperties_file.set_sensitive(True)
self.wpreview_file.set_sensitive(True)
self.config.PAL = self.wuse_pal.get_active()
status = self.wcreate_menu.get_active()
self.wmenu_options.set_sensitive(status)
self.pal = self.wuse_pal.get_active()
(element, position, model, treeiter) = self.get_current_file()
if (element == None):
self.wdelete_file.set_sensitive(False)
@ -164,6 +168,7 @@ class devede_project:
def on_use_pal_toggled(self,b):
self.config.PAL = self.wuse_pal.get_active()
self.set_interface_status(None)
@ -248,3 +253,15 @@ class devede_project:
def on_menu_options_clicked(self,b):
self.menu.show_configuration()
def on_create_disc_clicked(self,b):
data = devede.create_disk_window.create_disk_window()
if (not data.run()):
return
run_window = devede.runner.runner()
p = self.menu.create_dvd_menus(data.path)
run_window.add_processes(p)
run_window.run()

132
src/devede/runner.py Normal file
View file

@ -0,0 +1,132 @@
# Copyright 2014 (C) Raster Software Vigo (Sergio Costas)
#
# This file is part of DeVeDe-NG
#
# DeVeDe-NG is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# DeVeDe-NG is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
from gi.repository import Gtk,GObject
import os
import devede.configuration_data
class runner(GObject.GObject):
def __init__(self):
self.config = devede.configuration_data.configuration.get_config()
if (self.config.multicore):
self.count_cores()
else:
self.cores = 1
self.proc_list = []
self.running = 0
self.builder = Gtk.Builder()
self.builder.set_translation_domain(self.config.gettext_domain)
self.builder.add_from_file(os.path.join(self.config.glade,"wprogress.ui"))
self.builder.connect_signals(self)
self.wprogress = self.builder.get_object("progress")
self.wprogress.show_all()
self.wtotal = self.builder.get_object("progress_total")
progress_frame = self.builder.get_object("progress_frame")
box = Gtk.Box(Gtk.Orientation.VERTICAL, 0)
progress_frame.add(box)
box.show()
self.progress_bars = []
self.used_progress_bars = []
for c in range(0,self.cores):
f = Gtk.Frame()
p = Gtk.ProgressBar()
p.set_orientation(Gtk.Orientation.HORIZONTAL)
f.add(p)
# A frame, a progress bar, and the process running in that bar
self.progress_bars.append([f, p, None])
box.pack_start(f,True,True,0)
box.set_orientation(Gtk.Orientation.VERTICAL)
self.total = 0
def add_processes(self,processes):
for p in processes:
p.append(None) # this will contain the progress bar being used by this process
self.proc_list.append(p)
self.total_processes = len(self.proc_list)
def on_cancel_clicked(self,b):
pass
def count_cores(self):
self.cores = 0
proc_file = open("/proc/cpuinfo","r")
for line in proc_file:
if (line.startswith("processor")):
self.cores += 1
def run(self):
for element in self.proc_list:
# each element has three items:
# * the process object
# * the list of dependencies, or None if there are no more dependencies
# * the progress bar being used by this process
if (element[1] == None) and (element[2] == None):
self.progress_bars[0][2] = element[0]
element[0].connect("ended",self.process_ended)
element[0].run(self.progress_bars[0])
element[2] = self.progress_bars[0]
self.used_progress_bars.append(self.progress_bars[0])
if (len(self.progress_bars) > 1):
self.progress_bars = self.progress_bars[1:]
else:
self.progress_bars = []
break
self.wtotal.set_text(str(len(self.proc_list)-self.total)+"/"+str(self.total))
def process_ended(self,process, retval):
# move the progress bar used by this process to the list of available progress bars
tmp = []
for e in self.used_progress_bars:
if (e[2] == process):
e[2] = None
self.progress_bars.append(e)
e[0].hide()
else:
tmp.append(e)
self.used_progress_bars = tmp
# remove this process from the list of processes, and remove it from the dependencies in other processes
tmp = []
for e in self.proc_list:
if (e[0] != process):
tmp.append(e)
if (e[1] != None):
tmp2 = []
for dep in e[1]:
if dep != process:
tmp2.append(dep)
if (len(tmp2) != 0):
e[1] = tmp2
else:
e[1] = None
self.proc_list = tmp
# launch a new process
if (len(self.proc_list) != 0):
self.run()
else:
self.wprogress.destroy()