예제 #1
0
파일: proxy.py 프로젝트: isabella232/pitivi
from gi.repository import GstPbutils
from gi.repository import GstTranscoder

from pitivi.check import GstDependency
from pitivi.configure import get_gstpresets_dir
from pitivi.dialogs.prefs import PreferencesDialog
from pitivi.settings import GlobalSettings
from pitivi.utils.loggable import Loggable
from pitivi.utils.misc import ASSET_DURATION_META
from pitivi.utils.misc import asset_get_duration
# Remove check when we depend on Gst >= 1.20
HAS_GST_1_19 = GstDependency("Gst", apiversion="1.0",
                             version_required="1.19").check()

# Make sure gst knowns about our own GstPresets
Gst.preset_set_app_dir(get_gstpresets_dir())


class ProxyingStrategy:
    AUTOMATIC = "automatic"
    ALL = "all"
    NOTHING = "nothing"


GlobalSettings.add_config_section("proxy")
GlobalSettings.add_config_option('proxying_strategy',
                                 section='proxy',
                                 key='proxying-strategy',
                                 default=ProxyingStrategy.AUTOMATIC)

GlobalSettings.add_config_option('num_transcoding_jobs',
예제 #2
0
import time

from gi.repository import GES
from gi.repository import Gio
from gi.repository import GLib
from gi.repository import GObject
from gi.repository import Gst
from gi.repository import GstPbutils
from gi.repository import GstTranscoder

from pitivi.configure import get_gstpresets_dir
from pitivi.settings import GlobalSettings
from pitivi.utils.loggable import Loggable

# Make sure gst knowns about our own GstPresets
Gst.preset_set_app_dir(get_gstpresets_dir())


class ProxyingStrategy:
    AUTOMATIC = "automatic"
    ALL = "all"
    NOTHING = "nothing"


GlobalSettings.addConfigSection("proxy")
GlobalSettings.addConfigOption('proxyingStrategy',
                               section='proxy',
                               key='proxying-strategy',
                               default=ProxyingStrategy.AUTOMATIC)
GlobalSettings.addConfigOption('numTranscodingJobs',
                               section='proxy',
예제 #3
0
    def __init__(self, STREAMDATA, AUDIODATA, VIDEODATA):
        GObject.GObject.__init__(self)

        # Choose plugin based on Container name
        self.audiodata = AUDIODATA
        self.videodata = VIDEODATA
        self.streamdata = STREAMDATA

        # set preset directory
        Gst.preset_set_app_dir("/usr/share/transmageddon/presets/")

        # Choose plugin based on Codec Name
        # or switch to remuxing mode if any of the values are set to 'pastr'
        self.stoptoggle = False

        self.doaudio = False
        self.preset = self.streamdata['devicename']
        self.blackborderflag = False
        self.missingplugin = False
        self.probestreamid = False
        self.sinkpad = None
        self.usedstreamids = []

        # switching width and height around for rotationchoices where it makes sense
        if int(self.videodata[0]['rotationvalue']) == 1 or int(
                self.videodata[0]['rotationvalue']) == 3:
            nwidth = self.videodata[0]['videoheight']
            nheight = self.videodata[0]['videowidth']
            self.videodata[0]['videoheight'] = nheight
            self.videodata[0]['videowidth'] = nwidth

        # if needed create a variable to store the filename of the multipass \
        # statistics file
        if self.streamdata['multipass'] != 0:
            videoencoderplugin = codecfinder.get_video_encoder_element(
                self.videodata[0]['outputvideocaps'])
            videoencoder = Gst.ElementFactory.make(videoencoderplugin,
                                                   "videoencoder")
            properties = videoencoder.get_property_names()
            if "multipass-cache-file" in properties:
                self.cachefile = (str (GLib.get_user_cache_dir()) + "/transmageddon/" + \
                    "multipass-cache-file" + ".log")
            else:
                self.streamdata['multipass'] = 0

        # gather preset data if relevant
        if self.preset != "nopreset":
            self.provide_presets()

        # Create transcoding pipeline
        self.pipeline = Gst.Pipeline()
        self.pipeline.set_state(Gst.State.PAUSED)

        # first check if we have a container format, if not set up output
        # for possible outputs should not be hardcoded

        if self.streamdata['container'] == False:
            x = 0
            while x < len(self.audiodata):
                if self.audiodata[x]['outputaudiocaps'] != False:
                    if not (self.audiodata[x]['outputaudiocaps'].intersect(
                            Gst.caps_from_string(
                                "audio/mpeg, mpegversion=1, layer=3"))
                            ).is_empty():
                        self.streamdata['container'] = Gst.caps_from_string(
                            "application/x-id3")
                x = x + 1
        else:
            self.encodebinprofile = GstPbutils.EncodingContainerProfile.new(
                "containerformat", None, self.streamdata['container'], None)

            # What to do if we are not doing video passthrough (we only support video inside a
            # container format
            if self.videodata[0]['outputvideocaps'] != False:
                if (self.videodata[0]['dopassthrough']
                        == False) and (self.streamdata['passcounter']
                                       == int(0)):
                    self.videoflipper = Gst.ElementFactory.make(
                        'videoflip', None)
                    self.videoflipper.set_property(
                        "method", int(self.videodata[0]['rotationvalue']))
                    self.pipeline.add(self.videoflipper)

                    self.colorspaceconverter = Gst.ElementFactory.make(
                        "videoconvert", None)
                    self.pipeline.add(self.colorspaceconverter)

                    self.deinterlacer = Gst.ElementFactory.make(
                        'avdeinterlace', None)
                    self.pipeline.add(self.deinterlacer)

                    self.deinterlacer.link(self.colorspaceconverter)
                    self.colorspaceconverter.link(self.videoflipper)
                    self.deinterlacer.set_state(Gst.State.PAUSED)
                    self.colorspaceconverter.set_state(Gst.State.PAUSED)
                    self.videoflipper.set_state(Gst.State.PAUSED)
            # this part of the pipeline is used for both passthrough and re-encoding
            if (self.videodata[0]['outputvideocaps'] != False):
                videopreset = None
                self.videoprofile = GstPbutils.EncodingVideoProfile.new(
                    self.videodata[0]['outputvideocaps'], videopreset,
                    Gst.Caps.new_any(), 0)
                self.encodebinprofile.add_profile(self.videoprofile)

        # We do not need to do anything special for passthrough for audio, since we are not
        # including any extra elements between uridecodebin and encodebin
        x = 0
        while x < len(self.audiodata):
            # print(self.audiodata[x]['outputaudiocaps'])
            if self.audiodata[x]['outputaudiocaps'] != False:
                audiopreset = None
                if self.streamdata['container'] == False:
                    self.encodebinprofile = GstPbutils.EncodingAudioProfile.new(
                        self.audiodata[x]['outputaudiocaps'], audiopreset,
                        Gst.Caps.new_any(), 0)
                else:
                    audioprofile = GstPbutils.EncodingAudioProfile.new(
                        self.audiodata[x]['outputaudiocaps'], audiopreset,
                        Gst.Caps.new_any(), 0)
                    audioprofile.set_name("audioprofilename" + str(x))
                    self.encodebinprofile.add_profile(audioprofile)
            x = x + 1

        # Dealing with Video multipass encoding
        if (self.streamdata['passcounter'] != int(0)
                and self.streamdata['multipass'] != int(0)):
            videoencoderplugin = codecfinder.get_video_encoder_element(
                self.videodata[0]['outputvideocaps'])
            self.videoencoder = Gst.ElementFactory.make(
                videoencoderplugin, "videoencoder")
            self.pipeline.add(self.videoencoder)
            GstPresetType = GObject.type_from_name("GstPreset")
            if GstPresetType in GObject.type_interfaces(self.videoencoder):
                self.videoencoder.load_preset(
                    "Pass " + str(self.streamdata['passcounter']))
                properties = self.videoencoder.get_property_names()
                if "multipass-cache-file" in properties:
                    self.videoencoder.set_property("multipass-cache-file",
                                                   self.cachefile)
                else:
                    self.streamdata['multipass'] = 0
            self.multipassfakesink = Gst.ElementFactory.make(
                "fakesink", "multipassfakesink")
            self.pipeline.add(self.multipassfakesink)
            self.videoencoder.set_state(Gst.State.PAUSED)
            self.multipassfakesink.set_state(Gst.State.PAUSED)

        else:
            self.encodebin = Gst.ElementFactory.make("encodebin", None)
            self.encodebin.connect("element-added", self.OnEncodebinElementAdd)
            self.encodebin.set_property("profile", self.encodebinprofile)
            self.encodebin.set_property("avoid-reencoding", True)
            self.pipeline.add(self.encodebin)
            self.encodebin.set_state(Gst.State.PAUSED)
            self.audiopads = {}
            x = 0
            while x < len(self.audiodata):
                if self.audiodata[x]['outputaudiocaps'] != False:
                    if self.streamdata['container'] != False:
                        self.audiopads[x] = self.encodebin.emit(
                            "request-profile-pad", "audioprofilename" + str(x))
                x = x + 1

        self.uridecoder = Gst.ElementFactory.make("uridecodebin", "uridecoder")
        self.uridecoder.set_property("uri", self.streamdata['filechoice'])
        self.uridecoder.connect('autoplug-continue', self.on_autoplug_continue)
        self.uridecoder.connect("pad-added", self.OnDynamicPad)
        self.uridecoder.connect('source-setup', self.dvdreadproperties)

        self.uridecoder.set_state(Gst.State.PAUSED)
        self.pipeline.add(self.uridecoder)

        if self.streamdata['passcounter'] != int(0):
            self.videoencoder.link(self.multipassfakesink)
        else:
            self.transcodefileoutput = Gst.ElementFactory.make("filesink", \
                "transcodefileoutput")
            self.transcodefileoutput.set_property("location", \
                (self.streamdata['outputdirectory']+"/"+self.streamdata['outputfilename']))
            self.pipeline.add(self.transcodefileoutput)
            self.encodebin.link(self.transcodefileoutput)
            self.transcodefileoutput.set_state(Gst.State.PAUSED)
        self.uridecoder.set_state(Gst.State.PAUSED)
        self.BusMessages = self.BusWatcher()
        Gst.debug_bin_to_dot_file(self.pipeline, Gst.DebugGraphDetails.ALL,
                                  'transmageddon-debug-graph')
        # we need to wait on this one before going further
        self.uridecoder.connect("no-more-pads", self.noMorePads)
예제 #4
0
    def __init__(self, STREAMDATA, AUDIODATA, VIDEODATA):
        GObject.GObject.__init__(self)

        # Choose plugin based on Container name
        self.audiodata = AUDIODATA
        self.videodata = VIDEODATA
        self.streamdata = STREAMDATA

        # set preset directory
        Gst.preset_set_app_dir("/usr/share/transmageddon/presets/")

        # Choose plugin based on Codec Name
        # or switch to remuxing mode if any of the values are set to 'pastr'
        self.stoptoggle = False

        self.doaudio = False
        self.preset = self.streamdata["devicename"]
        self.blackborderflag = False
        self.missingplugin = False
        self.probestreamid = False
        self.sinkpad = None
        self.usedstreamids = []

        # switching width and height around for rotationchoices where it makes sense
        if int(self.videodata[0]["rotationvalue"]) == 1 or int(self.videodata[0]["rotationvalue"]) == 3:
            nwidth = self.videodata[0]["videoheight"]
            nheight = self.videodata[0]["videowidth"]
            self.videodata[0]["videoheight"] = nheight
            self.videodata[0]["videowidth"] = nwidth

        # if needed create a variable to store the filename of the multipass \
        # statistics file
        if self.streamdata["multipass"] != 0:
            videoencoderplugin = codecfinder.get_video_encoder_element(self.videodata[0]["outputvideocaps"])
            videoencoder = Gst.ElementFactory.make(videoencoderplugin, "videoencoder")
            properties = videoencoder.get_property_names()
            if "multipass-cache-file" in properties:
                self.cachefile = str(GLib.get_user_cache_dir()) + "/transmageddon/" + "multipass-cache-file" + ".log"
            else:
                self.streamdata["multipass"] = 0

        # gather preset data if relevant
        if self.preset != "nopreset":
            self.provide_presets()

        # Create transcoding pipeline
        self.pipeline = Gst.Pipeline()
        self.pipeline.set_state(Gst.State.PAUSED)

        # first check if we have a container format, if not set up output
        # for possible outputs should not be hardcoded

        if self.streamdata["container"] == False:
            x = 0
            while x < len(self.audiodata):
                if self.audiodata[x]["outputaudiocaps"] != False:
                    if not (
                        self.audiodata[x]["outputaudiocaps"].intersect(
                            Gst.caps_from_string("audio/mpeg, mpegversion=1, layer=3")
                        )
                    ).is_empty():
                        self.streamdata["container"] = Gst.caps_from_string("application/x-id3")
                x = x + 1
        else:
            self.encodebinprofile = GstPbutils.EncodingContainerProfile.new(
                "containerformat", None, self.streamdata["container"], None
            )

            # What to do if we are not doing video passthrough (we only support video inside a
            # container format
            if self.videodata[0]["outputvideocaps"] != False:
                if (self.videodata[0]["dopassthrough"] == False) and (self.streamdata["passcounter"] == int(0)):
                    self.videoflipper = Gst.ElementFactory.make("videoflip", None)
                    self.videoflipper.set_property("method", int(self.videodata[0]["rotationvalue"]))
                    self.pipeline.add(self.videoflipper)

                    self.colorspaceconverter = Gst.ElementFactory.make("videoconvert", None)
                    self.pipeline.add(self.colorspaceconverter)

                    self.deinterlacer = Gst.ElementFactory.make("avdeinterlace", None)
                    self.pipeline.add(self.deinterlacer)

                    self.deinterlacer.link(self.colorspaceconverter)
                    self.colorspaceconverter.link(self.videoflipper)
                    self.deinterlacer.set_state(Gst.State.PAUSED)
                    self.colorspaceconverter.set_state(Gst.State.PAUSED)
                    self.videoflipper.set_state(Gst.State.PAUSED)
            # this part of the pipeline is used for both passthrough and re-encoding
            if self.videodata[0]["outputvideocaps"] != False:
                videopreset = None
                self.videoprofile = GstPbutils.EncodingVideoProfile.new(
                    self.videodata[0]["outputvideocaps"], videopreset, Gst.Caps.new_any(), 0
                )
                self.encodebinprofile.add_profile(self.videoprofile)

        # We do not need to do anything special for passthrough for audio, since we are not
        # including any extra elements between uridecodebin and encodebin
        x = 0
        while x < len(self.audiodata):
            # print(self.audiodata[x]['outputaudiocaps'])
            if self.audiodata[x]["outputaudiocaps"] != False:
                audiopreset = None
                if self.streamdata["container"] == False:
                    self.encodebinprofile = GstPbutils.EncodingAudioProfile.new(
                        self.audiodata[x]["outputaudiocaps"], audiopreset, Gst.Caps.new_any(), 0
                    )
                else:
                    audioprofile = GstPbutils.EncodingAudioProfile.new(
                        self.audiodata[x]["outputaudiocaps"], audiopreset, Gst.Caps.new_any(), 0
                    )
                    audioprofile.set_name("audioprofilename" + str(x))
                    self.encodebinprofile.add_profile(audioprofile)
            x = x + 1

        # Dealing with Video multipass encoding
        if self.streamdata["passcounter"] != int(0) and self.streamdata["multipass"] != int(0):
            videoencoderplugin = codecfinder.get_video_encoder_element(self.videodata[0]["outputvideocaps"])
            self.videoencoder = Gst.ElementFactory.make(videoencoderplugin, "videoencoder")
            self.pipeline.add(self.videoencoder)
            GstPresetType = GObject.type_from_name("GstPreset")
            if GstPresetType in GObject.type_interfaces(self.videoencoder):
                self.videoencoder.load_preset("Pass " + str(self.streamdata["passcounter"]))
                properties = self.videoencoder.get_property_names()
                if "multipass-cache-file" in properties:
                    self.videoencoder.set_property("multipass-cache-file", self.cachefile)
                else:
                    self.streamdata["multipass"] = 0
            self.multipassfakesink = Gst.ElementFactory.make("fakesink", "multipassfakesink")
            self.pipeline.add(self.multipassfakesink)
            self.videoencoder.set_state(Gst.State.PAUSED)
            self.multipassfakesink.set_state(Gst.State.PAUSED)

        else:
            self.encodebin = Gst.ElementFactory.make("encodebin", None)
            self.encodebin.connect("element-added", self.OnEncodebinElementAdd)
            self.encodebin.set_property("profile", self.encodebinprofile)
            self.encodebin.set_property("avoid-reencoding", True)
            self.pipeline.add(self.encodebin)
            self.encodebin.set_state(Gst.State.PAUSED)
            self.audiopads = {}
            x = 0
            while x < len(self.audiodata):
                if self.audiodata[x]["outputaudiocaps"] != False:
                    if self.streamdata["container"] != False:
                        self.audiopads[x] = self.encodebin.emit("request-profile-pad", "audioprofilename" + str(x))
                x = x + 1

        self.uridecoder = Gst.ElementFactory.make("uridecodebin", "uridecoder")
        self.uridecoder.set_property("uri", self.streamdata["filechoice"])
        self.uridecoder.connect("autoplug-continue", self.on_autoplug_continue)
        self.uridecoder.connect("pad-added", self.OnDynamicPad)
        self.uridecoder.connect("source-setup", self.dvdreadproperties)

        self.uridecoder.set_state(Gst.State.PAUSED)
        self.pipeline.add(self.uridecoder)

        if self.streamdata["passcounter"] != int(0):
            self.videoencoder.link(self.multipassfakesink)
        else:
            self.transcodefileoutput = Gst.ElementFactory.make("filesink", "transcodefileoutput")
            self.transcodefileoutput.set_property(
                "location", (self.streamdata["outputdirectory"] + "/" + self.streamdata["outputfilename"])
            )
            self.pipeline.add(self.transcodefileoutput)
            self.encodebin.link(self.transcodefileoutput)
            self.transcodefileoutput.set_state(Gst.State.PAUSED)
        self.uridecoder.set_state(Gst.State.PAUSED)
        self.BusMessages = self.BusWatcher()
        Gst.debug_bin_to_dot_file(self.pipeline, Gst.DebugGraphDetails.ALL, "transmageddon-debug-graph")
        # we need to wait on this one before going further
        self.uridecoder.connect("no-more-pads", self.noMorePads)