~ubuntu-branches/ubuntu/lucid/pitivi/lucid

« back to all changes in this revision

Viewing changes to pitivi/elements/singledecodebin.py

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Dröge
  • Date: 2009-05-27 14:22:49 UTC
  • mfrom: (1.2.1 upstream) (3.1.13 experimental)
  • Revision ID: james.westby@ubuntu.com-20090527142249-tj0qnkc37320ylml
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
 
26
26
import gobject
27
27
import gst
 
28
from pitivi.stream import get_pad_id, pad_compatible_stream
28
29
 
29
30
def is_raw(caps):
30
31
    """ returns True if the caps are RAW """
36
37
    return False
37
38
 
38
39
class SingleDecodeBin(gst.Bin):
 
40
    """
 
41
    A variant of decodebin.
 
42
 
 
43
    * Only outputs one stream
 
44
    * Doesn't contain any internal queue
 
45
    """
 
46
 
 
47
    QUEUE_SIZE = 1 * gst.SECOND
39
48
 
40
49
    __gsttemplates__ = (
41
50
        gst.PadTemplate ("sinkpadtemplate",
47
56
                         gst.PAD_SOMETIMES,
48
57
                         gst.caps_new_any())
49
58
        )
50
 
    def __init__(self, caps=None, uri=None, *args, **kwargs):
 
59
    def __init__(self, caps=None, uri=None, stream=None, *args, **kwargs):
51
60
        gst.Bin.__init__(self, *args, **kwargs)
52
61
        if not caps:
53
62
            caps = gst.caps_new_any()
54
63
        self.caps = caps
 
64
        self.stream = stream
55
65
        self.typefind = gst.element_factory_make("typefind", "internal-typefind")
56
66
        self.add(self.typefind)
57
67
 
77
87
 
78
88
        self._factories = self._getSortedFactoryList()
79
89
 
 
90
        self.debug("stream:%r" % self.stream)
 
91
 
80
92
 
81
93
    ## internal methods
82
94
 
91
103
        Returns the list of demuxers, decoders and parsers available, sorted
92
104
        by rank
93
105
        """
94
 
        def myfilter(fact):
 
106
        def _myfilter(fact):
95
107
            if fact.get_rank() < 64 :
96
108
                return False
97
109
            klass = fact.get_klass()
99
111
                return False
100
112
            return True
101
113
        reg = gst.registry_get_default()
102
 
        res = [x for x in reg.get_feature_list(gst.ElementFactory) if myfilter(x)]
 
114
        res = [x for x in reg.get_feature_list(gst.ElementFactory) if _myfilter(x)]
103
115
        res.sort(lambda a, b: int(b.get_rank() - a.get_rank()))
104
116
        return res
105
117
 
151
163
        for pad in to_connect:
152
164
            self._closePadLink(element, pad, pad.get_caps())
153
165
 
 
166
    def _isDemuxer(self, element):
 
167
        if not 'Demux' in element.get_factory().get_klass():
 
168
            return False
 
169
 
 
170
        potential_src_pads = 0
 
171
        for template in element.get_pad_template_list():
 
172
            if template.direction != gst.PAD_SRC:
 
173
                continue
 
174
 
 
175
            if template.presence == gst.PAD_REQUEST or \
 
176
                    "%" in template.name_template:
 
177
                potential_src_pads += 2
 
178
                break
 
179
            else:
 
180
                potential_src_pads += 1
 
181
 
 
182
        return potential_src_pads > 1
 
183
 
 
184
    def _plugDecodingQueue(self, pad):
 
185
        queue = gst.element_factory_make("queue")
 
186
        queue.props.max_size_time = self.QUEUE_SIZE
 
187
        self.add(queue)
 
188
        queue.sync_state_with_parent()
 
189
        pad.link(queue.get_pad("sink"))
 
190
        pad = queue.get_pad("src")
 
191
 
 
192
        return pad
 
193
 
154
194
    def _tryToLink1(self, source, pad, factories):
155
195
        """
156
196
        Tries to link one of the factories' element to the given pad.
160
200
        self.debug("source:%s, pad:%s , factories:%r" % (source.get_name(),
161
201
                                                         pad.get_name(),
162
202
                                                         factories))
 
203
 
 
204
        if self._isDemuxer(source):
 
205
            pad = self._plugDecodingQueue(pad)
 
206
 
163
207
        result = None
164
208
        for factory in factories:
165
209
            element = factory.create()
172
216
                continue
173
217
 
174
218
            self.add(element)
 
219
            element.set_state(gst.STATE_READY)
175
220
            try:
176
221
                pad.link(sinkpad)
177
222
            except:
202
247
        if caps.is_any():
203
248
            self.log("type is not know yet, waiting")
204
249
            return
205
 
        if caps.intersect(self.caps):
 
250
 
 
251
        self.debug("stream %r" % (self.stream))
 
252
        if caps.intersect(self.caps) and (self.stream is None or
 
253
                (self.stream.pad_name == get_pad_id(pad))):
206
254
            # This is the desired caps
207
255
            if not self._srcpad:
208
256
                self._wrapUp(element, pad)
 
257
        elif is_raw(caps) and pad_compatible_stream(pad, self.stream):
 
258
            self.log ("not the target stream, but compatible")
 
259
            if not self._srcpad:
 
260
                self._wrapUp(element, pad)
209
261
        elif is_raw(caps):
210
262
            self.log("We hit a raw caps which isn't the wanted one")
211
263
            # FIXME : recursively remove everything until demux/typefind
231
283
            return
232
284
        self._markValidElements(element)
233
285
        self._removeUnusedElements(self.typefind)
234
 
        self.log("ghosting pad %s" % pad.get_name)
 
286
        self.log("ghosting pad %s" % pad.get_name())
235
287
        self._srcpad = gst.GhostPad("src", pad)
236
288
        self._srcpad.set_active(True)
237
289
        self.add_pad(self._srcpad)
254
306
        """
255
307
        Remove unused elements connected to srcpad(s) of element
256
308
        """
257
 
        self.log("element:%s" % element)
 
309
        self.log("element:%r" % element)
258
310
        for pad in element.src_pads():
259
311
            if pad.is_linked():
260
312
                peer = pad.get_peer().get_parent()
280
332
    def do_change_state(self, transition):
281
333
        self.debug("transition:%r" % transition)
282
334
        res = gst.Bin.do_change_state(self, transition)
283
 
        if transition in [gst.STATE_CHANGE_PAUSED_TO_READY, gst.STATE_CHANGE_READY_TO_NULL]:
 
335
        if transition == gst.STATE_CHANGE_PAUSED_TO_READY:
284
336
            self._cleanUp()
285
337
        return res
286
338