text: '''
  GStreamer Camera
  ================
  
  Implement CameraBase with GStreamer, based on PyGST
  '''
  
  __all__ = ('CameraPyGst', )
  
  from kivy.clock import Clock
  from kivy.graphics.texture import Texture
  from kivy.core.camera import CameraBase
  
  try:
      import pygst
      if not hasattr(pygst, '_gst_already_checked'):
          pygst.require('0.10')
          pygst._gst_already_checked = True
      import gst
  except:
      raise
  
  # install the gobject iteration
  from kivy.support import install_gobject_iteration
  install_gobject_iteration()
  
  
  class CameraPyGst(CameraBase):
      '''Implementation of CameraBase using GStreamer
  
      :Parameters:
          `video_src`: str, default is 'v4l2src'
              Other tested options are: 'dc1394src' for firewire
              dc camera (e.g. firefly MV). Any gstreamer video source
              should potentially work.
              Theoretically a longer string using "!" can be used
              describing the first part of a gstreamer pipeline.
      '''
  
      def __init__(self, **kwargs):
          self._pipeline = None
          self._camerasink = None
          self._decodebin = None
          self._texturesize = None
          self._video_src = kwargs.get('video_src', 'v4l2src')
          super(CameraPyGst, self).__init__(**kwargs)
  
      def init_camera(self):
          # TODO: This doesn't work when camera resolution is resized at runtime.
          # There must be some other way to release the camera?
          if self._pipeline:
              self._pipeline = None
  
          video_src = self._video_src
          if video_src == 'v4l2src':
              video_src += ' device=/dev/video%d' % self._index
          elif video_src == 'dc1394src':
              video_src += ' camera-number=%d' % self._index
  
          GL_CAPS = 'video/x-raw-rgb,red_mask=(int)0xff0000,' + \
                    'green_mask=(int)0x00ff00,blue_mask=(int)0x0000ff'
          pl = '%s ! decodebin name=decoder ! ffmpegcolorspace ! appsink ' + \
               'name=camerasink emit-signals=True caps=%s'
          self._pipeline = gst.parse_launch(pl % (video_src, GL_CAPS))
          self._camerasink = self._pipeline.get_by_name('camerasink')
          self._camerasink.connect('new-buffer', self._gst_new_buffer)
          self._decodebin = self._pipeline.get_by_name('decoder')
  
          if self._camerasink and not self.stopped:
              self.start()
  
      def _gst_new_buffer(self, *largs):
          self._format = 'rgb'
          frame = self._camerasink.emit('pull-buffer')
          if frame is None:
              return
          self._buffer = frame.data
          if self._texturesize is None:
              # try to get the camera image size
              for x in self._decodebin.src_pads():
                  for cap in x.get_caps():
                      self._texturesize = (cap['width'], cap['height'])
                      Clock.schedule_once(self._update)
                      return
          Clock.schedule_once(self._update)
  
      def start(self):
          super(CameraPyGst, self).start()
          self._pipeline.set_state(gst.STATE_PLAYING)
  
      def stop(self):
          super(CameraPyGst, self).stop()
          self._pipeline.set_state(gst.STATE_PAUSED)
  
      def _update(self, dt):
          if self._buffer is None:
              return
          if self._texture is None and self._texturesize is not None:
              self._texture = Texture.create(
                  size=self._texturesize, colorfmt='rgb')
              self._texture.flip_vertical()
              self.dispatch('on_load')
          self._copy_to_gpu()
  