diff --git a/src/QGst/CMakeLists.txt b/src/QGst/CMakeLists.txt
index 00cc20b..abad0ee 100644
--- a/src/QGst/CMakeLists.txt
+++ b/src/QGst/CMakeLists.txt
@@ -31,6 +31,7 @@ set(QtGStreamer_SRCS
     taglist.cpp
     bufferlist.cpp
     discoverer.cpp
+    tuner.cpp
     ${CMAKE_CURRENT_BINARY_DIR}/gen.cpp
 )
 
@@ -89,6 +90,7 @@ set(QtGStreamer_INSTALLED_HEADERS
     taglist.h           TagList
     bufferlist.h        BufferList
     discoverer.h        Discoverer
+    tuner.h             Tuner
 
     Ui/global.h
     Ui/videowidget.h            Ui/VideoWidget
@@ -120,6 +122,7 @@ set(QtGStreamer_CODEGEN_INCLUDES
     -Igst/interfaces/colorbalance.h
     -Igst/interfaces/videoorientation.h
     -Igst/interfaces/propertyprobe.h
+    -Igst/interfaces/tuner.h
     -Igst/app/gstappsrc.h
     -Igst/pbutils/gstdiscoverer.h
     -Igst/pbutils/pbutils-enumtypes.h
diff --git a/src/QGst/enums.h b/src/QGst/enums.h
index 76f40b1..951220a 100644
--- a/src/QGst/enums.h
+++ b/src/QGst/enums.h
@@ -427,5 +427,15 @@ namespace QGst {
 }
 QGST_REGISTER_TYPE(QGst::DiscovererResult)
 
+namespace QGst {
+    enum TunerChannelFlag {
+        TunerChannelInput = (1 << 0),
+        TunerChannelOutput = (1 << 1),
+        TunerChannelFrequency = (1 << 2),
+        TunerChannelAudio = (1 << 3)
+    };
+    Q_DECLARE_FLAGS(TunerChannelFlags, TunerChannelFlag);
+}
+QGST_REGISTER_TYPE(QGst::TunerChannelFlags)
 
 #endif
diff --git a/src/QGst/global.h b/src/QGst/global.h
index f94f359..b719b14 100644
--- a/src/QGst/global.h
+++ b/src/QGst/global.h
@@ -139,6 +139,9 @@ QGST_WRAPPER_REFPOINTER_DECLARATION(StepEvent)
 QGST_WRAPPER_DECLARATION(StreamVolume)
 QGST_WRAPPER_GSTCLASS_DECLARATION(Structure)
 QGST_WRAPPER_DIFFERENT_GSTCLASS_DECLARATION(TagList,Structure)
+QGST_WRAPPER_DECLARATION(Tuner)
+QGST_WRAPPER_DECLARATION(TunerChannel)
+QGST_WRAPPER_DECLARATION(TunerNorm)
 
 namespace QGst {
     class Structure;
diff --git a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt
index f86b8f7..9eba078 100644
--- a/tests/auto/CMakeLists.txt
+++ b/tests/auto/CMakeLists.txt
@@ -30,3 +30,4 @@ qgst_test(eventtest)
 qgst_test(messagetest)
 qgst_test(taglisttest)
 qgst_test(discoverertest)
+qgst_test(tunertest)
diff --git a/src/QGst/Tuner b/src/QGst/Tuner
new file mode 100644
index 0000000..0b5c308
--- /dev/null
+++ b/src/QGst/Tuner
@@ -0,0 +1 @@
+#include "tuner.h" 
diff --git a/src/QGst/tuner.cpp b/src/QGst/tuner.cpp
new file mode 100644
index 0000000..1120a8f
--- /dev/null
+++ b/src/QGst/tuner.cpp
@@ -0,0 +1,149 @@
+/*
+    Copyright (C) 2011 Lukas Schrangl <schrangl@gmx.net>
+
+    This library is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "tuner.h"
+#include "structs.h"
+#include <gst/interfaces/tuner.h>
+
+namespace QGst {
+
+QString TunerChannel::label() const
+{
+    return QString::fromUtf8(object<GstTunerChannel>()->label);
+}
+
+TunerChannelFlags TunerChannel::flags() const
+{
+    return TunerChannelFlags(object<GstTunerChannel>()->flags);
+}
+
+float TunerChannel::freqMultiplicator() const
+{
+    return object<GstTunerChannel>()->freq_multiplicator;
+}
+
+ulong TunerChannel::minFrequency() const
+{
+    return object<GstTunerChannel>()->min_frequency;
+}
+
+ulong TunerChannel::maxFrequency() const
+{
+    return object<GstTunerChannel>()->max_frequency;
+}
+
+int TunerChannel::minSignal() const
+{
+    return object<GstTunerChannel>()->min_signal;
+}
+
+int TunerChannel::maxSignal() const
+{
+    return object<GstTunerChannel>()->max_signal;
+}
+
+QString TunerNorm::label() const
+{
+    return QString::fromUtf8(object<GstTunerNorm>()->label);
+}
+
+Fraction TunerNorm::framerate() const
+{
+    return QGlib::Value(&(object<GstTunerNorm>()->framerate)).get<Fraction>();
+}
+
+QList<TunerChannelPtr> Tuner::channels() const
+{
+    QList<TunerChannelPtr> result;
+    const GList *list = gst_tuner_list_channels(object<GstTuner>());
+    while(list) {
+        result.append(TunerChannelPtr::wrap(GST_TUNER_CHANNEL(list->data)));
+        list=list->next;
+    }
+    return result;
+}
+
+TunerChannelPtr Tuner::currentChannel() const
+{
+    return TunerChannelPtr::wrap(gst_tuner_get_channel(object<GstTuner>()));
+}
+
+void Tuner::setCurrentChannel(const TunerChannelPtr &channel)
+{
+    gst_tuner_set_channel(object<GstTuner>(), channel);
+}
+
+TunerChannelPtr Tuner::findChannelByName(const char *name) const
+{
+    // gst_tuner_find_channel_by_name is bogus, so make a copy
+    gchar *copy = strdup(name);
+
+    TunerChannelPtr channel = TunerChannelPtr::wrap(
+        gst_tuner_find_channel_by_name(object<GstTuner>(), copy)
+        );
+    free(copy);
+    return channel;
+}
+
+QList<TunerNormPtr> Tuner::norms() const
+{
+    QList<TunerNormPtr> result;
+    const GList *list = gst_tuner_list_norms(object<GstTuner>());
+    while(list) {
+        result.append(TunerNormPtr::wrap(GST_TUNER_NORM(list->data)));
+        list=list->next;
+    }
+    return result;
+}
+
+TunerNormPtr Tuner::currentNorm() const
+{
+    return TunerNormPtr::wrap(gst_tuner_get_norm(object<GstTuner>()));
+}
+
+void Tuner::setCurrentNorm(const TunerNormPtr &norm)
+{
+    gst_tuner_set_norm(object<GstTuner>(), norm);
+}
+
+TunerNormPtr Tuner::findNormByName(const char *name) const
+{
+    // gst_tuner_find_norm_by_name is bogus, so make a copy
+    gchar *copy = strdup(name);
+
+    TunerNormPtr norm = TunerNormPtr::wrap(
+       gst_tuner_find_norm_by_name(object<GstTuner>(), copy)
+       );
+    free(copy);
+    return norm;
+}
+
+ulong Tuner::frequency(const TunerChannelPtr &channel) const
+{
+    return gst_tuner_get_frequency(object<GstTuner>(), channel);
+}
+
+void Tuner::setFrequency(const TunerChannelPtr &channel, ulong freq)
+{
+    gst_tuner_set_frequency(object<GstTuner>(), channel, freq);
+}
+
+int Tuner::signalStrength(const TunerChannelPtr &channel) const
+{
+    return gst_tuner_signal_strength(object<GstTuner>(), channel);
+}
+
+} //namespace QGst
diff --git a/src/QGst/tuner.h b/src/QGst/tuner.h
new file mode 100644
index 0000000..53fe5bc
--- /dev/null
+++ b/src/QGst/tuner.h
@@ -0,0 +1,85 @@
+/*
+    Copyright (C) 2011 Lukas Schrangl <schrangl@gmx.net>
+
+    This library is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef QGST_TUNER_H
+#define QGST_TUNER_H
+
+#include "global.h"
+#include "../QGlib/object.h"
+
+namespace QGst {
+
+struct Fraction;
+
+/*! \headerfile tuner.h <QGst/Tuner>
+ * \brief Wrapper class for GstTunerChannel
+ */
+class QTGSTREAMER_EXPORT TunerChannel : public QGlib::Object
+{
+    QGST_WRAPPER(TunerChannel)
+public:
+    QString label() const;
+    TunerChannelFlags flags() const;
+    float freqMultiplicator() const;
+    ulong minFrequency() const;
+    ulong maxFrequency() const;
+    int minSignal() const;
+    int maxSignal() const;
+};
+
+/*! \headerfile tuner.h <QGst/Tuner>
+ * \brief Wrapper class for GstTunerNorm
+ */
+class QTGSTREAMER_EXPORT TunerNorm : public QGlib::Object
+{
+    QGST_WRAPPER(TunerNorm)
+public:
+    QString label() const;
+    Fraction framerate() const;
+};
+
+/*! \headerfile tuner.h <QGst/Tuner>
+ * \brief Wrapper class for GstTunerNorm
+ */
+class QTGSTREAMER_EXPORT Tuner : public QGlib::Interface
+{
+    QGST_WRAPPER(Tuner)
+public:
+    QList<TunerChannelPtr> channels() const;
+    TunerChannelPtr currentChannel() const;
+    void setCurrentChannel(const TunerChannelPtr &channel);
+    TunerChannelPtr findChannelByName(const char *name) const;
+
+    QList<TunerNormPtr> norms() const;
+    TunerNormPtr currentNorm() const;
+    void setCurrentNorm(const TunerNormPtr &norm);
+    TunerNormPtr findNormByName(const char *name) const;
+    
+    ulong frequency(const TunerChannelPtr &channel) const;
+    void setFrequency(const TunerChannelPtr &channel, ulong freq);
+
+    int signalStrength(const TunerChannelPtr &channel) const;
+};
+
+} //namespace QGst
+
+QGLIB_REGISTER_INTERFACE(QGst::Tuner)
+QGST_REGISTER_TYPE(QGst::Tuner)
+QGST_REGISTER_TYPE(QGst::TunerChannel)
+QGST_REGISTER_TYPE(QGst::TunerNorm)
+
+#endif // QGST_TUNER_H
diff --git a/tests/auto/tunertest.cpp b/tests/auto/tunertest.cpp
new file mode 100644
index 0000000..0e4093d
--- /dev/null
+++ b/tests/auto/tunertest.cpp
@@ -0,0 +1,102 @@
+/*
+    Copyright (C) 2014  Pavel Bludov <pbludov@gmail.com>
+
+    This library is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "qgsttest.h"
+#include <QGst/Tuner>
+#include <QGst/Element>
+#include <QGst/ElementFactory>
+#include <QGst/Fraction>
+
+class TunerTest : public QGstTest
+{
+    Q_OBJECT
+private Q_SLOTS:
+    void interfaceTest();
+};
+
+void TunerTest::interfaceTest()
+{
+    QGst::ElementPtr e = QGst::ElementFactory::make("v4l2src");
+    QVERIFY(!e.isNull());
+    
+    e->setState(QGst::StateReady);
+    e->getState(nullptr, nullptr, GST_SECOND * 10);
+    
+    QGst::TunerPtr t = e.dynamicCast<QGst::Tuner>();
+    QVERIFY(!t.isNull());
+
+    QGst::TunerChannelPtr cc = t->currentChannel();
+    if (!cc.isNull())
+    {
+        Q_FOREACH(QGst::TunerChannelPtr c, t->channels())
+        {
+            qDebug() << "Found a channel" << c->label() << c->flags();
+
+            if (c->flags().testFlag(QGst::TunerChannelFlag::TunerChannelFrequency))
+            {
+                unsigned long cf = t->frequency(c);
+                int ss = t->signalStrength(c);
+                float fm = c->freqMultiplicator();
+                unsigned long minf = c->minFrequency();
+                unsigned long maxf = c->maxFrequency();
+                int mins = c->minSignal();
+                int maxs = c->maxSignal();
+
+                qDebug() << "Current frequency" << cf
+                    << "signal strength" << ss
+                    << "frequency multiplicator" << fm
+                    << "min frequency" << minf
+                    << "max frequency" << maxf
+                    << "min signal" << mins
+                    << "max signal" << maxs
+                    ;
+
+                t->setFrequency(c, cf);
+            }
+
+            // Must be the same channel
+            QVERIFY(c == t->findChannelByName(c->label().toUtf8()));
+        }
+
+        // Should be noop, since 'cc' is the current channel
+        t->setCurrentChannel(cc);
+    }
+
+    QGst::TunerNormPtr cn = t->currentNorm();
+    if (!cn.isNull())
+    {
+        Q_FOREACH(QGst::TunerNormPtr n, t->norms())
+        {
+            qDebug() << "Found a norm" << n->label() << n->framerate();
+
+            // Must be the same norm
+            QVERIFY(n == t->findNormByName(n->label().toUtf8()));
+        }
+
+        // Should be noop, since 'cn' is the current norm
+        t->setCurrentNorm(cn);
+    }
+
+    // Now switch the device back to Null state (release resources)
+    //
+    e->setState(QGst::StateNull);
+    e->getState(nullptr, nullptr, GST_SECOND * 10);
+}
+
+QTEST_APPLESS_MAIN(TunerTest)
+
+#include "moc_qgsttest.cpp"
+#include "tunertest.moc"
