Commit c50066df authored by Edward Hervey's avatar Edward Hervey

past week's work, haven't got time for Changelog


git-svn-id: svn+ssh://svn.gnome.org/svn/pitivi/trunk@634 d3729300-e425-0410-8a4c-d956edccc248
parent 742ea9a6
......@@ -9,7 +9,7 @@ Timeline view design document (c) 2005 Edward Hervey
This design allows pitivi to have different 'views':
_ The 'Simple' View : à la iMovie
_ The 'Tracks' View : à la Premiere, or like the previous version of pitivi.
_ The 'Full' View : Allows every possible composition
* Simple View
......@@ -17,6 +17,33 @@ Timeline view design document (c) 2005 Edward Hervey
This view displays everything on one line. It is aimed to be very simple to
use.
* Display
* Timeline
_ The timeline contains one line, which acts as a summary of the underlying
timeline.
* Sources
_ All have the same width (which doesn't mean it's fixed)
_ Display a thumbnail of the source if it's video
_ In normal situations, the sources follow each others without any gaps.
_ Special Cases:
* Gap between two sources :
=> Black source (which can be removed)
* Source A overlaps part of Source B:
=> Display normally
* Source A is over and "inside" Source B
(A.start > B.start, A.stop < B.stop):
=> Display A inside B , but it cannot be moved in the simple View
* Effects
_ Effects applied on one source entirely have their icons displayed in the
corner of the source
* Transitions
_ Show like a source (maybe half-width)
_ Represent somewhat differently
* Actions
The simple view allows only SOME actions amongst all those available through
......@@ -55,34 +82,144 @@ Timeline view design document (c) 2005 Edward Hervey
_ if there's an audio transition, remove it too
_ Move the following sources back into place (just after the first source)
* Display
* Sources
_ All have the same width (which doesn't mean it's fixed)
_ In normal situations, the sources follow each others without any gaps.
_ Special Cases:
* Gap between two sources :
=> Black source (which can be removed)
* Source A overlaps part of Source B:
=> Display normally
* Source A is over and "inside" Source B
(A.start > B.start, A.stop < B.stop):
=> Display A inside B , but it cannot be moved in the simple View
* Effects
_ Effects applied on one source entirely have their icons displayed in the
corner of the source
* Transitions
_ Show like a source (maybe half-width)
_ Represent somewhat differently
* Tracks View
* Actions
* Display
* Model
\ No newline at end of file
* Complex View
* This is a representation of the actual model
********************************************************************************
* Model
The model must:
_ Have objects that offer a simpler interface to gnonlin.
_ Allow the views to do all the actions they wish to do.
* Object Hierarchy
Object
|
+---- Source
| |
| +---- FileSource
| |
| +---- LiveSource
| |
| +---- Composition
| |
| +---- Group
|
+---- Effect
|
+---- Simple Effect (1->1)
|
+---- Transition
|
+---- Complex Effect (N->1)
* Object
Base class for all timeline objects
* Properties
_ Start/Stop Time
_ Media Type (None, Audio, Video)
_ Gnonlin Object
_ Linked Object
_ Can be None
_ Must have same duration
_ Brother Object
_ This is the same object but with the other media_type
_ Factory containing more info on the object
* Signals
start-stop-changed : uint64 start, uint64 stop
linked-changed : linked_object
* Methods
link_object(object)
unlink_object(object)
relink_brother(object)
get_brother(object)
set_start_stop_time(start, stop)
* Virtual methods
_make_gnl_object()
_make_brother()
* Source
Base class for all sources (0 input, 1 output)
* Implemented Methods
_make_gnl_object()
* FileSource
Seekable sources (mostly files)
* Properties
_ Media Start/Stop Time
* Methods
set_media_start_stop_time(mediastart, mediastop)
* Implemented methods
_make_brother()
* LiveSource
Non-seekable sources (like cameras)
* Composition
Combines Source(s) and Effect(s)
_ Sets the priority of the GnlObject(s) contained within
_ Effects have always got priorities higher than the sources
_ Can contain global effects that have the highest priority
_ Those global effect spread the whole duration of the composition
_ Simple effects can overlap each other
_ Complex Effect(s) have a lower priority than Simple Effect(s)
_ For sanity reasons, Complex Effect(s) can't overlap each other
_ Transitions have the lowest effect priority
_ Source(s) contained in it follow each other if possible
_ Source can overlap each other
_ Knows the "visibility" of the sources contained within
* Sandwich view example (top: high priority):
[ Global Simple Effect(s) (RGB, YUV, Speed,...) ]
[ Simple Effect(s), can be several layers ]
[ Complex Effect(s), non-overlapping ]
[ Transition(s), non-overlapping ]
[ Layers of sources ]
* Properties:
_ Global Simple Effect(s) (Optionnal)
_ Simple Effect(s)
_ Complex Effect(s)
_ Transition(s)
* Methods:
add_global_effect(effect, order)
remove_global_effect(effect)
add_simple_effect(effect, order)
remove_simple_effect(effect)
add_transition(transition)
remove_transition(transition)
add_source(source, position)
remove_source(source)
* Implemented Methods:
_make_gnl_object()
* Group
Top-level composition
* Effect
Base class for effects
Belongs to a Composition
* Simple Effect
Only has 1 input
* Transition
Has 2 inputs, considered as begin and end sources
* Complex Effect
Has n inputs
# PiTiVi , Non-linear video editor
#
# pitivi/pitivi.py
# pitivi/bin.py
#
# Copyright (c) 2005, Edward Hervey <bilboed@bilboed.com>
#
......@@ -22,7 +22,7 @@
import gobject
import gst
class SmartBin(gst.Bin):
class SmartBin(gst.Thread):
"""
Self-contained Bin with playing/encoding ready places
It also has length information
......@@ -33,16 +33,20 @@ class SmartBin(gst.Bin):
width = 0
height = 0
def __init__(self, name):
def __init__(self, name, displayname=""):
gobject.GObject.__init__(self)
self.name = name
self.displayname = displayname
self.set_name(name)
self.vtee = gst.element_factory_make("tee", "vtee")
self.atee = gst.element_factory_make("tee", "atee")
self.add_many(self.vtee, self.atee)
if self.has_video:
self.vtee = gst.element_factory_make("tee", "vtee")
self.add(self.vtee)
if self.has_audio:
self.atee = gst.element_factory_make("tee", "atee")
self.add(self.atee)
self.add_source()
self.connect_source()
self.set_state(gst.STATE_READY)
self.set_state(gst.STATE_PAUSED)
self.asinkthread = None
self.vsinkthread = None
......@@ -57,20 +61,23 @@ class SmartBin(gst.Bin):
def set_audio_sink_thread(self, asinkthread):
""" set the audio sink thread """
print "setting asinkthread in", self.name
if self.get_state() >= gst.STATE_PAUSED:
if self.get_state() > gst.STATE_PAUSED:
print self.name, "is in PAUSED or higher"
return False
if self.asinkthread:
print self.name, "already has an asinkthread??"
return False
if self.has_audio:
self.asinkthread = asinkthread
self.add(self.asinkthread)
self.atee.get_pad("src%d").link(self.asinkthread.get_pad("sink"))
print "atee has now #pads", self.atee.get_property("num_pads")
return True
def set_video_sink_thread(self, vsinkthread):
""" set the video sink thread """
print "setting vsinkthread in ", self.name
if self.get_state() >= gst.STATE_PAUSED:
if self.get_state() > gst.STATE_PAUSED:
return False
if self.vsinkthread:
return False
......@@ -78,16 +85,18 @@ class SmartBin(gst.Bin):
self.vsinkthread = vsinkthread
self.add(self.vsinkthread)
if self.width and self.height:
filtcaps = gst.caps_from_string("video/x-raw-yuv,width=%d,height=%d;video/x-raw-rgb,width=%d,height=%d" % (self.width, self.height, self.width, self.height))
self.vtee.get_pad("src%d").link_filtered(self.vsinkthread.get_pad("sink"), filtcaps)
#filtcaps = gst.caps_from_string("video/x-raw-yuv,width=%d,height=%d;video/x-raw-rgb,width=%d,height=%d" % (self.width, self.height, self.width, self.height))
#self.vtee.get_pad("src%d").link_filtered(self.vsinkthread.get_pad("sink"), filtcaps)
self.vtee.get_pad("src%d").link(self.vsinkthread.get_pad("sink"))
else:
self.vtee.get_pad("src%d").link(self.vsinkthread.get_pad("sink"))
print "vtee has now #pads:", self.vtee.get_property("num_pads")
return True
def remove_audio_sink_thread(self):
""" remove the audio sink thread """
print "removing asinkthread in ", self.name
if self.get_state() >= gst.STATE_PAUSED:
if self.get_state() > gst.STATE_PAUSED:
return False
if not self.asinkthread:
return False
......@@ -99,7 +108,7 @@ class SmartBin(gst.Bin):
def remove_video_sink_thread(self):
""" remove the videos sink thread """
print "removing vsinkthread in ", self.name
if self.get_state() >= gst.STATE_PAUSED:
if self.get_state() > gst.STATE_PAUSED:
return False
if not self.vsinkthread:
return False
......@@ -116,6 +125,7 @@ class SmartFileBin(SmartBin):
"""
def __init__(self, factory):
print "new SmartFileBin for factory:%s, audio:%s, video:%s" % (factory, factory.is_audio, factory.is_video)
self.factory = factory
self.has_video = factory.is_video
self.has_audio = factory.is_audio
......@@ -125,16 +135,37 @@ class SmartFileBin(SmartBin):
self.height = struct["height"]
self.width = struct["width"]
self.source = self.factory.make_bin()
SmartBin.__init__(self, "smartfilebin-" + factory.name)
SmartBin.__init__(self, "smartfilebin-" + factory.name,
displayname=factory.displayname)
def add_source(self):
self.add(self.source)
def connect_source(self):
if self.has_video:
self.source.get_pad("vsrc").link(self.vtee.get_pad("sink"))
if self.has_audio:
self.source.get_pad("asrc").link(self.atee.get_pad("sink"))
print "connect_source for ", self.source.get_pad_list()
print "delayed to 'new-decoded-pad' signal"
self.source.connect("new-pad", self._bin_new_decoded_pad)
self.source.connect("pad-removed", self._bin_removed_decoded_pad)
## if self.has_video:
## if not self.source.get_pad("vsrc").link(self.vtee.get_pad("sink")):
## print "problem connecting source:vsrc to vtee:sink"
## if self.has_audio:
## if not self.source.get_pad("asrc").link(self.atee.get_pad("sink")):
## print "problem connection source:asrc to atee:sink"
def _bin_new_decoded_pad(self, bin, pad):
# connect to good tee
print "SmartFileBin's source has a new pad:", pad , pad.get_caps().to_string()
if "audio" in pad.get_caps().to_string():
pad.link(self.atee.get_pad("sink"))
elif "video" in pad.get_caps().to_string():
pad.link(self.vtee.get_pad("sink"))
def _bin_removed_decoded_pad(self, bin, pad):
if "audio" in pad.get_caps().to_string():
pad.unlink(self.atee)
elif "video" in pad.get_caps().to_string():
pad.unlink(self.vtee)
def do_destroy(self):
print "do_destroy"
......@@ -147,6 +178,37 @@ class SmartTimelineBin(SmartBin):
SmartBin for GnlTimeline
"""
def __init__(self, project):
print "new SmartTimelineBin for project", project
self.project = project
# TODO : change this to use the project settings
self.has_video = True
self.has_audio = True
# TODO : width/height depends on project settings
self.width = 320
self.height = 240
self.source = project.timeline.timeline
project.timeline.videocomp.connect("start-stop-changed", self._start_stop_changed)
self.length = project.timeline.videocomp.stop - project.timeline.videocomp.start
SmartBin.__init__(self, "project-" + project.name,
displayname = "Project: " + project.name)
def add_source(self):
self.add(self.source)
def connect_source(self):
print "connecting timeline to audio/video tees"
print self.project.timeline.timeline.get_pad_list()
self.source.get_pad("src_" + self.project.timeline.audiocomp.gnlobject.get_name()).link(self.atee.get_pad("sink"))
self.source.get_pad("src_" + self.project.timeline.videocomp.gnlobject.get_name()).link(self.vtee.get_pad("sink"))
def _start_stop_changed(self, videocomp, start, stop):
print "smart timeline bin: start stop changed", start, stop
self.length = stop - start
gobject.type_register(SmartTimelineBin)
class SmartDefaultBin(SmartBin):
......@@ -170,76 +232,42 @@ class SmartDefaultBin(SmartBin):
def connect_source(self):
print "connecting sources"
self.videotestsrc.get_pad("src").link(self.vtee.get_pad("sink"))
vcaps = gst.caps_from_string("video/x-raw-yuv,width=320,height=240,framerate=25.0")
self.videotestsrc.get_pad("src").link_filtered(self.vtee.get_pad("sink"), vcaps)
self.silence.get_pad("src").link(self.atee.get_pad("sink"))
print "finished connecting sources"
gobject.type_register(SmartDefaultBin)
## class SmartDefaultBin(SmartBin):
## class SmartTempUriBin(SmartBin):
## """
## SmartBin with videotestsrc and silenc output
## Can be used as a default source
## SmartBin for temporary uris
## """
## def __init__(self):
## print "Creating new smartdefaultbin"
## self.vthread = gst.Thread("vthread")
## self.athread = gst.Thread("athread")
## self.vqueue = gst.element_factory_make("queue", "vq")
## self.vqueue.set_property("max-size-buffers", 10)
## self.aqueue = gst.element_factory_make("queue", "aq")
## self.aqueue.set_property("max-size-buffers", 10)
## self.videotestsrc = gst.element_factory_make("videotestsrc", "vtestsrc")
## self.silence = gst.element_factory_make("silence", "silence")
## self.vthread.add_many(self.videotestsrc, self.vqueue)
## self.athread.add_many(self.silence, self.aqueue)
## self.videotestsrc.link_filtered(self.vqueue, gst.caps_from_string("video/x-raw-yuv,width=320,height=240"))
## self.silence.link_filtered(self.aqueue, gst.caps_from_string("audio/x-raw-int,rate=48000"))
## def __init__(self, uri):
## self.uri = uri
## self.has_audio = True
## self.has_video = True
## self.width = 320
## self.height = 240
## SmartBin.__init__(self, "smartdefaultbin")
## SmartBin.__init__(self, "temp-" + uri)
## def add_source(self):
## self.add_many(self.vthread)
## filesrc = gst.element_factory_make("gnomevfssrc", "src")
## filesrc.set_property("location", self.uri)
## self.dbin = gst.element_factory_make("decodebin", "dbin")
## self.dbin.connect("new-decoded-pad", self._bin_new_decoded_pad)
## self.aident = gst.element_factory_make("queue", "aident")
## self.vident = gst.element_factory_make("queue", "vident")
## self.add_many(filesrc, self.dbin, self.aident, self.vident)
## def connect_source(self):
## self.vqueue.get_pad("src").link(self.vtee.get_pad("sink"))
## #self.aqueue.get_pad("src").link(self.atee.get_pad("sink"))
## gobject.type_register(SmartDefaultBin)
## print "connecting ident to tee"
## print self.aident.get_pad("src").link(self.atee.get_pad("sink"))
## print self.vident.get_pad("src").link(self.vtee.get_pad("sink"))
class SmartTempUriBin(SmartBin):
"""
SmartBin for temporary uris
"""
def __init__(self, uri):
self.uri = uri
self.has_audio = True
self.has_video = True
SmartBin.__init__(self, "temp-" + uri)
def add_source(self):
filesrc = gst.element_factory_make("gnomevfssrc", "src")
filesrc.set_property("location", self.uri)
self.dbin = gst.element_factory_make("decodebin", "dbin")
self.dbin.connect("new-decoded-pad", self._bin_new_decoded_pad)
self.aident = gst.element_factory_make("identity", "aident")
self.vident = gst.element_factory_make("identity", "vident")
self.add_many(filesrc, self.dbin, self.aident, self.vident)
def connect_source(self):
print "connecting ident to tee"
print self.aident.get_pad("src").link(self.atee.get_pad("sink"))
print self.vident.get_pad("src").link(self.vtee.get_pad("sink"))
def _bin_new_decoded_pad(self, dbin, pad, is_last):
if "audio" in pad.get_caps().to_string():
pad.link(self.aident.get_caps("sink"))
elif "video" in pad.get_caps().to_string():
pad.link(self.vident.get_caps("sink"))
## def _bin_new_decoded_pad(self, dbin, pad, is_last):
## if "audio" in pad.get_caps().to_string():
## pad.link(self.aident.get_caps("sink"))
## elif "video" in pad.get_caps().to_string():
## pad.link(self.vident.get_caps("sink"))
gobject.type_register(SmartTempUriBin)
## gobject.type_register(SmartTempUriBin)
......@@ -42,7 +42,10 @@ class Discoverer(gobject.GObject):
(gobject.TYPE_PYOBJECT, )),
"not_media_file" : (gobject.SIGNAL_RUN_LAST,
gobject.TYPE_NONE,
(gobject.TYPE_STRING, ))
(gobject.TYPE_STRING, )),
"finished_analyzing" : ( gobject.SIGNAL_RUN_LAST,
gobject.TYPE_NONE,
(gobject.TYPE_PYOBJECT, ))
}
def __init__(self):
......@@ -96,6 +99,8 @@ class Discoverer(gobject.GObject):
self.pipeline.set_state(gst.STATE_NULL)
if not self.currentfactory:
self.emit("not_media_file", self.current)
else:
self.emit("finished_analyzing", self.currentfactory)
self._del_analyze_data()
self.working = False
......@@ -115,19 +120,19 @@ class Discoverer(gobject.GObject):
fakesink = gst.element_factory_make("fakesink")
vcsp = gst.element_factory_make("ffmpegcolorspace")
vscale = gst.element_factory_make("videoscale")
#vscale = gst.element_factory_make("videoscale")
vpng = gst.element_factory_make("jpegenc")
#vpng.set_property("snapshot", False)
vpngfakesink = gst.element_factory_make("fakesink")
vpngfakesink.set_property("signal-handoffs", True)
vident.connect("handoff", self._vident_handoff_cb,
(vident, fakesink, vcsp, vscale, vpng, vpngfakesink, pad))
(vident, fakesink, vcsp, vpng, vpngfakesink, pad))
vpngfakesink.connect("handoff", self._vpngsink_handoff_cb,
(vident, fakesink, vcsp, vscale, vpng, vpngfakesink, pad))
(vident, fakesink, vcsp, vpng, vpngfakesink, pad))
self.pipeline.set_state(gst.STATE_PAUSED)
self.pipeline.add_many(vident, fakesink, vcsp, vscale, vpng, vpngfakesink)
self.pipeline.add_many(vident, fakesink, vcsp, vpng, vpngfakesink)
pad.link(vident.get_pad("sink"))
vident.link(fakesink)
self.pipeline.set_state(gst.STATE_PLAYING)
......@@ -142,7 +147,7 @@ class Discoverer(gobject.GObject):
if self.thumbnailing:
return
if not isinstance(buffer, gst.Event):
vident, fakesink, vcsp, vscale, vpng, vpngfakesink, pad = data
vident, fakesink, vcsp, vpng, vpngfakesink, pad = data
if not self.currentfactory.length:
# Get the length
length = pad.query(gst.QUERY_TOTAL, gst.FORMAT_TIME)
......@@ -159,8 +164,8 @@ class Discoverer(gobject.GObject):
# Connect correct pipeline
self.pipeline.set_state(gst.STATE_PAUSED)
element.unlink(fakesink)
element.link(vscale)
vscale.link_filtered(vpng, gst.caps_from_string("video/x-raw-yuv,width=(int)%d,height=(int)%d" % (96, height)))
element.link(vpng)
#vscale.link_filtered(vpng, gst.caps_from_string("video/x-raw-yuv,width=(int)%d,height=(int)%d" % (96, height)))
vpng.link(vpngfakesink)
self.pipeline.set_state(gst.STATE_PLAYING)
self.thumbnailing = True
......@@ -170,7 +175,7 @@ class Discoverer(gobject.GObject):
if not self.thumbnailing:
print "ERROR !!! the png fakesink shouldn't be called here !!!"
return
vident, fakesink, vcsp, vscale, vpng, vpngfakesink, pad = data
vident, fakesink, vcsp, vpng, vpngfakesink, pad = data
# save the buffer to a file
filename = "/tmp/" + self.currentfactory.name.encode('base64').replace('\n','') + ".jpg"
pngfile = open(filename, "wb")
......@@ -179,7 +184,7 @@ class Discoverer(gobject.GObject):
self.currentfactory.set_thumbnail(filename)
# disconnect this pipeline
self.pipeline.set_state(gst.STATE_PAUSED)
vident.unlink(vscale)
vident.unlink(vpng)
# reconnect the fakesink
vident.link(fakesink)
self.pipeline.set_state(gst.STATE_PLAYING)
......
#!/usr/bin/python
# PiTiVi , Non-linear video editor
#
# effects.py
#
# Copyright (c) 2005, Edward Hervey <bilboed@bilboed.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This program 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
import gobject
import gst
from objectfactory import OperationFactory,TransitionFactory,SMPTETransitionFactory
# There are different types of effects available:
# _ Simple Audio/Video Effects
# GStreamer elements that only apply to audio OR video
# Only take the elements who have a straightforward meaning/action
# _ Expanded Audio/Video Effects
# These are the Gstreamer elements that don't have a easy meaning/action or
# that are too cumbersome to use as such
# _ Complex Audio/Video Effects
def get_effect_list():
""" Returns all available effects as a list of OperationFactory"""
pass
......@@ -20,6 +20,8 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
import os.path
from urllib import unquote
import string
import gobject
import gst
......@@ -64,6 +66,7 @@ class ObjectFactory(gobject.GObject):
def __init__(self):
gobject.GObject.__init__(self)
self.name = ""
self.displayname = ""
self.is_audio = False
self.is_video = False
self.is_effect = False
......@@ -92,10 +95,6 @@ class ObjectFactory(gobject.GObject):
else:
raise AttributeError, 'unknown property %s' % property.name
def do_discover(self):
""" discover properties about the element """
pass
def set_audio_info(self, caps):
""" sets the audio caps of the element """
self.set_property("audio-info", caps)
......@@ -160,51 +159,138 @@ class FileSourceFactory(ObjectFactory):
def __init__(self, filename):
ObjectFactory.__init__(self)
self.name = filename
self.displayname = os.path.basename(unquote(self.name))
self.lastbinid = 0
def make_bin(self):
""" returns a source bin with all pads """
# pipeline = gst.Pipeline()
bin = gst.Bin()
src = gst.element_factory_make("gnomevfssrc")
src.set_property("location", self.name)
dbin = gst.element_factory_make("decodebin")
bin.add_many(src, dbin)
src.link(dbin)
if self.is_audio:
aident = gst.element_factory_make("identity")
bin.add(aident)
bin.add_ghost_pad(aident.get_pad("src"), "asrc")
else:
aident = None
if self.is_video:
vident = gst.element_factory_make("identity")
bin.add(vident)
bin.add_ghost_pad(vident.get_pad("src"), "vsrc")
else:
vident = None
dbin.connect("new-decoded-pad", self._bin_new_decoded_pad,
(bin, aident, vident))
## if self.is_audio:
## aident = gst.element_factory_make("identity")
## bin.add(aident)
## bin.add_ghost_pad(aident.get_pad("src"), "asrc")
## else:
## aident = None
## if self.is_video:
## vident = gst.element_factory_make("identity")
## bin.add(vident)
## bin.add_ghost_pad(vident.get_pad("src"), "vsrc")
## else:
## vident = None
dbin.connect("new-decoded-pad", self._bin_new_decoded_pad, bin )
dbin.connect("removed-decoded-pad", self._bin_removed_decoded_pad, bin)
## pipeline.add(bin)
## pipeline.set_state(gst.STATE_PLAYING)
## for i in range(100):
## if not pipeline.iterate():
## break
## print bin.get_pad_list()
## pipeline.set_state(gst.STATE_PAUSED)
## bin.seek(gst.FORMAT_TIME, 0L)
## print bin.get_pad_list()
## pipeline.remove(bin)
## print bin.get_pad_list()
## dbin.disconnect(sig)
self.instances.append(bin)
return bin
def _bin_new_decoded_pad(self, dbin, pad, is_last, data):
bin, aident, vident = data
if "audio" in pad.get_caps().to_string() and aident:
pad.link(aident.get_pad("sink"))
elif "video" in pad.get_caps().to_string() and vident:
pad.link(vident.get_pad("sink"))
## def _aprobe(self, probe, data):
## print "aprobe", data
## return True
## def _vprobe(self, probe, data):
## print "vprobe", data
## return True
def _bin_new_decoded_pad(self, dbin, pad, is_last, bin):
print "decoded pad", pad.get_caps().to_string()
# add it as ghost_pad to the bin
if "audio" in pad.get_caps().to_string():
bin.add_ghost_pad(pad, "asrc")
elif "video" in pad.get_caps().to_string():
bin.add_ghost_pad(pad, "vsrc")
else:
return
#self.emit("new-decoded-pad", newpad)
def _bin_removed_decoded_pad(self, dbin, pad, bin):
print "pad", pad, "was removed"
if "audio" in pad.get_caps().to_string():
mypad = bin.get_pad("asrc")
elif "video" in pad.get_caps().to_string():
mypad = bin.get_pad("vsrc")
else: