gstlal  0.8.1
 All Classes Namespaces Files Functions Variables Pages
matplotlibhelper.py
1 # Copyright (C) 2010 Leo Singer
2 #
3 # This program is free software; you can redistribute it and/or modify it
4 # under the terms of the GNU General Public License as published by the
5 # Free Software Foundation; either version 2 of the License, or (at your
6 # option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful, but
9 # WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
11 # Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License along
14 # with this program; if not, write to the Free Software Foundation, Inc.,
15 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 """
17 Classes and functions for building Matplotlib-based GStreamer elements
18 """
19 __author__ = "Leo Singer <leo.singer@ligo.org>"
20 __all__ = ("padtemplate", "figure", "render", "BaseMatplotlibTransform")
21 
22 
23 from gstlal.pipeutil import *
24 from gstlal import pipeio
25 
26 
27 """Pad template suitable for producing video frames using Matplotlib.
28 The Agg backend supports rgba, argb, and bgra."""
29 padtemplate = gst.PadTemplate(
30  "src",
31  gst.PAD_SRC, gst.PAD_ALWAYS,
32  gst.caps_from_string("""
33  video/x-raw-rgb,
34  bpp = (int) {24,32},
35  depth = (int) 24,
36  endianness = (int) BIG_ENDIAN,
37  red_mask = (int) 0xFF0000,
38  green_mask = (int) 0x00FF00,
39  blue_mask = (int) 0x0000FF;
40  video/x-raw-rgb,
41  bpp = (int) 32,
42  depth = (int) {24,32},
43  endianness = (int) BIG_ENDIAN,
44  red_mask = (int) 0x00FF0000,
45  green_mask = (int) 0x0000FF00,
46  blue_mask = (int) 0x000000FF,
47  alpha_mask = (int) 0xFF000000;
48  video/x-raw-rgb,
49  bpp = (int) 32,
50  depth = (int) {24,32},
51  endianness = (int) BIG_ENDIAN,
52  red_mask = (int) 0x0000FF00,
53  green_mask = (int) 0x00FF0000,
54  blue_mask = (int) 0xFF000000,
55  alpha_mask = (int) 0x000000FF;
56  """)
57 )
58 
59 
60 def figure():
61  """Create a Matplotlib Figure object suitable for rendering video frames."""
62  import matplotlib
63  matplotlib.rcParams.update({
64  "font.size": 8.0,
65  "axes.titlesize": 10.0,
66  "axes.labelsize": 10.0,
67  "xtick.labelsize": 8.0,
68  "ytick.labelsize": 8.0,
69  "legend.fontsize": 8.0,
70  "figure.dpi": 100,
71  "savefig.dpi": 100,
72  "text.usetex": False,
73  "path.simplify": True
74  })
75  from matplotlib import figure
76  from matplotlib.backends.backend_agg import FigureCanvasAgg
77  figure = figure.Figure()
78  FigureCanvasAgg(figure)
79  return figure
80 
81 
82 def render(fig, buf):
83  """Render a Matplotlib figure to a GStreamer buffer."""
84  caps = buf.caps[0]
85  fig.set_size_inches(
86  caps['width'] / float(fig.get_dpi()),
87  caps['height'] / float(fig.get_dpi())
88  )
89  fig.canvas.draw()
90  if caps['bpp'] == 24: # RGB
91  imgdata = fig.canvas.renderer._renderer.tostring_rgb()
92  elif caps['alpha_mask'] & 0xFF000000 == 0xFF000000: # ARGB
93  imgdata = fig.canvas.renderer._renderer.tostring_argb()
94  elif caps['red_mask'] == 0xFF: # RGBA
95  imgdata = fig.canvas.renderer._renderer.buffer_rgba()
96  else: # BGRA
97  imgdata = fig.canvas.renderer._renderer.tostring_bgra()
98  datasize = len(imgdata)
99  buf[:datasize] = imgdata
100  buf.datasize = datasize
101 
102 
103 class BaseMatplotlibTransform(gst.BaseTransform):
104  """Base class for transform elements that use Matplotlib to render video."""
105 
106  __gsttemplates__ = padtemplate
107 
108  def __init__(self):
109  self.figure = figure()
110  self.axes = self.figure.gca()
111 
112  def do_transform_caps(self, direction, caps):
113  """GstBaseTransform->transform_caps virtual method."""
114  if direction == gst.PAD_SRC:
115  return self.get_pad("sink").get_fixed_caps_func()
116  elif direction == gst.PAD_SINK:
117  return self.get_pad("src").get_fixed_caps_func()
118  raise ValueError(direction)
119 
120  def do_transform_size(self, direction, caps, size, othercaps):
121  """GstBaseTransform->transform_size virtual method."""
122  if direction == gst.PAD_SINK:
123  return pipeio.get_unit_size(self.get_pad("src").get_caps())
124  raise ValueError(direction)
125 
126 gobject.type_register(BaseMatplotlibTransform)