1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import gobject
23 import gst
24
25 from flumotion.common import messages, gstreamer
26 from flumotion.common.i18n import N_, gettexter
27 from flumotion.component import feedcomponent
28 from flumotion.component.converters.overlay import genimg
29
30 __version__ = "$Rev: 8699 $"
31 T_ = gettexter()
32
33
34
35
36
38 __gstdetails__ = ('FluOverlaySrc', 'Source',
39 'Overlay Image source for flumotion', 'Zaheer Merali')
40 __gsttemplates__ = (
41 gst.PadTemplate("src",
42 gst.PAD_SRC,
43 gst.PAD_ALWAYS,
44 gst.caps_new_any()))
45 imgBuf = ""
46 capsStr = ""
47 duration = 1.0/25
48
50 gst.BaseSrc.__init__(self)
51 self.set_format(gst.FORMAT_TIME)
52
61
62
63 -class Overlay(feedcomponent.ParseLaunchComponent):
64 checkTimestamp = True
65 checkOffset = True
66 _filename = None
67 CAPS_TEMPLATE = "video/x-raw-rgb,bpp=32,depth=32,width=%d,height=%d," \
68 "red_mask=-16777216,green_mask=16711680,blue_mask=65280," \
69 "alpha_mask=255,endianness=4321,framerate=0/1"
70
72 pipeline = ('@eater:default@ ! ffmpegcolorspace !'
73 'video/x-raw-yuv,format=(fourcc)AYUV ! videomixer name=mix !'
74 '@feeder:default@')
75 return pipeline
76
78 imgBuf, imagesOverflowed, textOverflowed = \
79 genimg.generateOverlay(
80 text=self.text,
81 font=self.font,
82 showFlumotion=self.showFlumotion,
83 showCC=self.showCC,
84 showXiph=self.showXiph,
85 width=width, height=height)
86
87 if textOverflowed:
88 m = messages.Warning(
89 T_(N_("Overlayed text '%s' too wide for the video image."),
90 text), mid="text-too-wide")
91 self.addMessage(m)
92
93 if imagesOverflowed:
94 m = messages.Warning(
95 T_(N_("Overlayed logotypes too wide for the video image.")),
96 mid="image-too-wide")
97 self.addMessage(m)
98
99 if self.source.get_factory().get_name() == 'appsrc':
100 self.imgBuf = imgBuf
101 else:
102 self.source.imgBuf = imgBuf
103
110
115
117 caps = pad.get_negotiated_caps()
118 if caps is None:
119 return
120 struct = pad.get_negotiated_caps().get_structure(0)
121 height = struct['height']
122 width = struct['width']
123 framerate = struct['framerate']
124
125 self._set_source_image(width, height)
126 self._set_source_caps(width, height)
127 self._set_source_framerate(framerate)
128
129 if not self.sourceBin.get_pad("src").is_linked():
130 self.sourceBin.link_filtered(self.videomixer,
131 gst.Caps("video/x-raw-yuv, format=(fourcc)AYUV"))
132 self.sourceBin.set_locked_state(False)
133 self.sourceBin.set_state(gst.STATE_PLAYING)
134
136 if gstreamer.element_factory_exists("appsrc") and \
137 gstreamer.get_plugin_version("app") >= (0, 10, 22, 0):
138 self.source = gst.element_factory_make('appsrc', 'source')
139 self.source.set_property('do-timestamp', True)
140 self.source.connect('need-data', self.push_buffer)
141 else:
142
143 gobject.type_register(OverlayImageSource)
144 ret = gst.element_register(OverlayImageSource, "fluoverlaysrc",
145 gst.RANK_MARGINAL)
146 self.source = gst.element_factory_make('fluoverlaysrc', 'source')
147
148 self.sourceBin = gst.Bin()
149
150 alphacolor = gst.element_factory_make('alphacolor')
151
152 self.sourceBin.add_many(self.source, alphacolor)
153 self.source.link(alphacolor)
154 pipeline.add(self.sourceBin)
155
156 self.sourceBin.add_pad(gst.GhostPad('src', alphacolor.get_pad('src')))
157
158
159 self.sourceBin.set_locked_state(True)
160
201
203 """
204 Pushes buffer to appsrc in GStreamer
205
206 @param source: the appsrc element to push to
207 @type source: GstElement
208 """
209 self.debug("Pushing buffer")
210 gstBuf = gst.Buffer(self.imgBuf)
211 padcaps = gst.caps_from_string(self.capsStr)
212 gstBuf.set_caps(padcaps)
213 gstBuf.duration = int(self.duration * gst.SECOND)
214 source.emit('push-buffer', gstBuf)
215