3
# Copyright (C) 2008 Luis de Bethencourt
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2, or (at your option)
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
# GNU General Public License for more details.
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21
"""freemix engine class"""
24
gobject.threads_init()
29
'''freemix engine class. Encapsulates all the core gstreamer work
30
in nice function per feature for the frontend.'''
37
def start(self, filesrc):
40
def bus_handler(unused_bus, message):
42
if message.type == gst.MESSAGE_SEGMENT_DONE:
43
self.SeekToLocation(0)
44
if message.type == gst.MESSAGE_EOS:
46
if message.type == gst.MESSAGE_TAG:
47
self.SeekToLocation(0)
48
if message.type == gst.MESSAGE_ERROR:
53
self.pipeline = gst.Pipeline()
54
self.bus = self.pipeline.get_bus()
55
self.bus.add_signal_watch()
56
self.bus.connect ('message', bus_handler)
58
self.bin1 = self.VideoBin(filesrc)
60
self.imagesink = gst.element_factory_make("xvimagesink", "imagesink")
61
self.imagesink.set_property("force-aspect-ratio", True)
62
self.imagesink.set_property("handle-expose", True)
63
self.pipeline.add(self.bin1, self.imagesink)
65
self.bin1.link(self.imagesink)
68
self.pipeline.set_state(gst.STATE_PLAYING)
70
def VideoBin(self, filesrc):
72
self.src = gst.element_factory_make("filesrc", "src")
73
self.bin.add(self.src)
74
self.src.set_property("location", filesrc)
76
self.decodebin = gst.element_factory_make("decodebin", "decodebin")
77
self.decodebin.connect("new-decoded-pad", self.OnDynamicPad)
78
self.bin.add(self.decodebin)
80
self.src.link(self.decodebin)
82
self.colorspace = gst.element_factory_make("ffmpegcolorspace", "colorspace")
84
self.vqueue = gst.element_factory_make("queue", "vqueue")
85
self.vqueue.set_property ("max-size-buffers", 3)
87
self.videoscale = gst.element_factory_make("videoscale", "videoscale")
89
self.bin.add(self.colorspace, self.vqueue, self.videoscale)
91
self.colorspace.link(self.vqueue)
92
self.vqueue.link(self.videoscale)
94
target = self.videoscale.get_pad("src")
95
self.sinkpad = gst.GhostPad("sink", target)
96
self.sinkpad.set_active(True)
97
self.bin.add_pad(self.sinkpad)
101
def OnDynamicPad(self, dbin, pad, islast):
102
pad.link(self.colorspace.get_pad("sink"))
103
# print "OnDynamicPad called"
106
seek = self.pipeline.seek (self.speed, gst.FORMAT_TIME, \
107
gst.SEEK_FLAG_SEGMENT | gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE, \
108
gst.SEEK_TYPE_SET, 0, gst.SEEK_TYPE_NONE, 0)
109
# print "Async " + str(self.speed)
111
def SeekToLocation(self, location):
112
self.pipeline.seek(self.speed, gst.FORMAT_TIME, \
113
gst.SEEK_FLAG_SEGMENT, gst.SEEK_TYPE_SET, 0, gst.SEEK_TYPE_NONE, \
115
# print "seek to %r" % location
117
def switchVideo(self, filesrc):
118
self.pipeline.set_state(gst.STATE_READY)
119
self.src.set_property("location", filesrc)
120
self.pipeline.set_state(gst.STATE_PLAYING)
121
self.SeekToLocation(0)
123
def play(self, filesrc, speed):
124
# print "engine got call to play: " + filesrc
126
if self.running == False:
129
self.switchVideo(filesrc)
132
if __name__ == "__main__":
135
usage = """ engine.py -i [file]"""
137
parser = optparse.OptionParser(usage=usage)
138
parser.add_option("-i", "--input", action="store", type="string", dest="input", help="Input video file", default="")
139
(options, args) = parser.parse_args()
141
print "Playing: %r" % options.input
143
engine = Engine(options.input)
144
gobject.MainLoop().run()