Package flumotion :: Package component :: Package converters :: Package overlay :: Module overlay
[hide private]

Source Code for Module flumotion.component.converters.overlay.overlay

  1  # -*- Mode: Python -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3  # 
  4  # Flumotion - a streaming media server 
  5  # Copyright (C) 2004,2005,2006,2007 Fluendo, S.L. (www.fluendo.com). 
  6  # All rights reserved. 
  7   
  8  # This file may be distributed and/or modified under the terms of 
  9  # the GNU General Public License version 2 as published by 
 10  # the Free Software Foundation. 
 11  # This file is distributed without any warranty; without even the implied 
 12  # warranty of merchantability or fitness for a particular purpose. 
 13  # See "LICENSE.GPL" in the source distribution for more information. 
 14   
 15  # Licensees having purchased or holding a valid Flumotion Advanced 
 16  # Streaming Server license may use this file in accordance with the 
 17  # Flumotion Advanced Streaming Server Commercial License Agreement. 
 18  # See "LICENSE.Flumotion" in the source distribution for more information. 
 19   
 20  # Headers in this file shall remain intact. 
 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: 8117 $" 
 31  T_ = gettexter() 
 32   
 33  # FIXME: This class only needed for gst-plugins-base < 0.10.22 
 34  # Remove when we do not need compatibility with < 0.10.22 
 35   
 36   
37 -class OverlayImageSource(gst.BaseSrc):
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
48 - def __init__(self):
49 gst.BaseSrc.__init__(self) 50 self.set_format(gst.FORMAT_TIME)
51
52 - def do_create(self, offset, length):
53 self.debug("Pushing buffer") 54 gstBuf = gst.Buffer(self.imgBuf) 55 padcaps = gst.caps_from_string(self.capsStr) 56 gstBuf.set_caps(padcaps) 57 gstBuf.timestamp = 0 58 gstBuf.duration = pow(2, 63) -1 59 return gst.FLOW_OK, gstBuf
60 61
62 -class Overlay(feedcomponent.ParseLaunchComponent):
63 checkTimestamp = True 64 checkOffset = True 65 _filename = None 66
67 - def get_pipeline_string(self, properties):
68 # the order here is important; to have our eater be the reference 69 # stream for videomixer it needs to be specified last 70 source_element = "" 71 if gstreamer.element_factory_exists("appsrc") and \ 72 gstreamer.get_plugin_version("app") >= (0, 10, 22, 0): 73 source_element = "appsrc name=source do-timestamp=true" 74 else: 75 #FIXME: fluoverlaysrc only needed on gst-plugins-base < 0.10.22 76 gobject.type_register(OverlayImageSource) 77 ret = gst.element_register(OverlayImageSource, "fluoverlaysrc", 78 gst.RANK_MARGINAL) 79 source_element = "fluoverlaysrc name=source " 80 pipeline = ( 81 '%s ! alphacolor ! ' 82 'videomixer name=mix ! @feeder:default@ ' 83 '@eater:default@ ! ffmpegcolorspace ! ' 84 'video/x-raw-yuv,format=(fourcc)AYUV ! mix.' % source_element) 85 86 return pipeline
87
88 - def configure_pipeline(self, pipeline, properties):
89 p = properties 90 self.fixRenamedProperties(p, [ 91 ('show_text', 'show-text'), 92 ('fluendo_logo', 'fluendo-logo'), 93 ('cc_logo', 'cc-logo'), 94 ('xiph_logo', 'xiph-logo')]) 95 96 text = None 97 if p.get('show-text', False): 98 text = p.get('text', 'set the "text" property') 99 self.imgBuf, imagesOverflowed, textOverflowed = \ 100 genimg.generateOverlay( 101 text=text, 102 showFlumotion=p.get('fluendo-logo', False), 103 showCC=p.get('cc-logo', False), 104 showXiph=p.get('xiph-logo', False), 105 width=p['width'], 106 height=p['height']) 107 108 if textOverflowed: 109 m = messages.Warning( 110 T_(N_("Overlayed text '%s' too wide for the video image."), 111 text), mid="text-too-wide") 112 self.addMessage(m) 113 114 if imagesOverflowed: 115 m = messages.Warning( 116 T_(N_("Overlayed logotypes too wide for the video image.")), 117 mid="image-too-wide") 118 self.addMessage(m) 119 self.capsStr = "video/x-raw-rgb,bpp=32,depth=32,width=%d,height=%d," \ 120 "red_mask=-16777216,green_mask=16711680,blue_mask=65280," \ 121 "alpha_mask=255,framerate=0/1" % (p['width'], p['height']) 122 padcaps = gst.caps_from_string(self.capsStr) 123 source = self.get_element('source') 124 if source.get_factory().get_name() == 'appsrc': 125 # push buffer when we need to, currently we push a duration of 126 # G_MAXINT_64 so we never need to push another one 127 # but if we want dynamic change of overlay, we should make 128 # duration tunable in properties 129 source.connect('need-data', self.push_buffer) 130 source.props.caps = padcaps 131 else: 132 # FIXME: fluoverlaysrc only needed on gst-plugins-base < 0.10.22 133 source.imgBuf = self.imgBuf 134 source.capsStr = self.capsStr 135 vmixerVersion = gstreamer.get_plugin_version('videomixer') 136 if vmixerVersion == (0, 10, 7, 0): 137 m = messages.Warning( 138 T_(N_("The 'videomixer' GStreamer element has a bug in this " 139 "version (0.10.7). You may see many errors in the debug " 140 "output, but it should work correctly anyway.")), 141 mid="videomixer-bug") 142 self.addMessage(m)
143
144 - def push_buffer(self, source, arg0):
145 """ 146 Pushes buffer to appsrc in GStreamer 147 148 @param source: the appsrc element to push to 149 @type source: GstElement 150 """ 151 self.debug("Pushing buffer") 152 gstBuf = gst.Buffer(self.imgBuf) 153 padcaps = gst.caps_from_string(self.capsStr) 154 gstBuf.set_caps(padcaps) 155 gstBuf.duration = pow(2, 63) -1 156 source.emit('push-buffer', gstBuf)
157