private bool OnProgressTimeout()
    {
        long duration, position;

        Gst.Format fmt = Gst.Format.Time;

        if (pipeline.QueryDuration(ref fmt, out duration) && fmt == Gst.Format.Time && encoder.QueryPosition(ref fmt, out position) && fmt == Gst.Format.Time)
        {
            OnProgress(position, duration);
        }

        return(true);
    }
  bool UpdatePos () {
    Gst.Format fmt = Gst.Format.Time;
    long duration, pos;
    if ( (_playbin != null) && _pipelineOK &&
         _playbin.QueryDuration (ref fmt, out duration) &&
         _playbin.QueryPosition (ref fmt, out pos)) {
      _lbl.Text = string.Format ("{0} / {1}", TimeString (pos), TimeString (duration));

      _updatingScale = true;
      _scale.Value = (double) pos / duration;
      _updatingScale = false;
    }

    return true;
  }
  void ScaleValueChanged (object sender, EventArgs args) {
    if (_updatingScale)
      return;

    long duration;
    Gst.Format fmt = Gst.Format.Time;
    Console.WriteLine ("Trying to seek");

    if ( (_playbin != null) && _pipelineOK && _playbin.QueryDuration (ref fmt, out duration) && duration != -1) {
      long pos = (long) (duration * _scale.Value);
      Console.WriteLine ("Seek to {0}/{1} ({2}%)", pos, duration, _scale.Value);

      bool ret = _playbin.Seek (Format.Time, SeekFlags.Flush | SeekFlags.KeyUnit, pos);

      Console.WriteLine ("Seeked {0}successfully", (ret ? "" : "not "));
    }
  }