[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    kdesupport/phonon
From:       Christoph Pfister <christophpfister () gmail ! com>
Date:       2009-10-03 17:55:12
Message-ID: 1254592512.709705.23904.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 1031004 by pfister:

add video effect support to phonon
this is important for deinterlacing, but allows other types of video effects as well
CCMAIL: kretz@kde.org


 M  +15 -0     phonon/backendcapabilities.cpp  
 M  +9 -7      phonon/backendcapabilities.h  
 M  +2 -3      phonon/effect.cpp  
 M  +10 -1     phonon/objectdescription.h  
 M  +17 -6     xine/backend.cpp  
 M  +88 -14    xine/effect.cpp  
 M  +5 -0      xine/effect.h  
 M  +0 -64     xine/xinestream.cpp  
 M  +0 -1      xine/xinestream.h  


--- trunk/kdesupport/phonon/phonon/backendcapabilities.cpp #1031003:1031004
@@ -110,6 +110,21 @@
 }
 #endif //QT_NO_PHONON_EFFECT
 
+#ifndef QT_NO_PHONON_EFFECT
+QList<EffectDescription> BackendCapabilities::availableVideoEffects()
+{
+    BackendInterface *backendIface = qobject_cast<BackendInterface \
*>(Factory::backend()); +    QList<EffectDescription> ret;
+    if (backendIface) {
+        QList<int> deviceIndexes = \
backendIface->objectDescriptionIndexes(Phonon::VideoEffectType); +        foreach \
(int i, deviceIndexes) { +            ret.append(EffectDescription::fromIndex(i, \
Phonon::VideoEffectType)); +        }
+    }
+    return ret;
+}
+#endif //QT_NO_PHONON_EFFECT
+
 } // namespace Phonon
 
 QT_END_NAMESPACE
--- trunk/kdesupport/phonon/phonon/backendcapabilities.h #1031003:1031004
@@ -172,13 +172,15 @@
     PHONON_EXPORT QList<EffectDescription> availableAudioEffects();
 #endif //QT_NO_PHONON_EFFECT
 
-//X     /**
-//X      * Returns descriptions for the video effects the backend supports.
-//X      *
-//X      * \return A list of VideoEffectDescription objects that give a name and
-//X      * description for every supported video effect.
-//X      */
-//X     PHONON_EXPORT QList<EffectDescription> availableVideoEffects();
+    /**
+     * Returns descriptions for the video effects the backend supports.
+     *
+     * \return A list of EffectDescription objects that give a name and
+     * description for every supported video effect.
+     */
+#ifndef QT_NO_PHONON_EFFECT
+    PHONON_EXPORT QList<EffectDescription> availableVideoEffects();
+#endif //QT_NO_PHONON_EFFECT
 
     /**
      * Returns descriptions for the audio codecs the backend supports.
--- trunk/kdesupport/phonon/phonon/effect.cpp #1031003:1031004
@@ -119,9 +119,8 @@
     Q_ASSERT(m_backendObject);
 
     // set up attributes
-    const QList<EffectParameter> parameters = pINTERFACE_CALL(parameters());
-    foreach (const EffectParameter &p, parameters) {
-        pINTERFACE_CALL(setParameterValue(p, parameterValues[p]));
+    for (QHash<EffectParameter, QVariant>::const_iterator it = \
parameterValues.constBegin(); it != parameterValues.constEnd(); ++it) { +        \
pINTERFACE_CALL(setParameterValue(it.key(), it.value()));  }
 }
 
--- trunk/kdesupport/phonon/phonon/objectdescription.h #1031003:1031004
@@ -76,8 +76,10 @@
          * devices even when they are unplugged and provide a unique identifier
          * that can make backends use the same identifiers.
          */
-        AudioCaptureDeviceType
+        AudioCaptureDeviceType,
 
+        VideoEffectType
+
         //VideoOutputDeviceType,
         //VideoCaptureDeviceType,
         //AudioCodecType,
@@ -188,6 +190,13 @@
             return ObjectDescription<T>(QExplicitlySharedDataPointer<ObjectDescriptionData>(ObjectDescriptionData::fromIndex(T, \
index)));  }
 
+        /** \internal
+         * This function is needed because video and audio effects share the \
EffectDescription class. +         */
+        static inline ObjectDescription<T> fromIndex(int index, \
ObjectDescriptionType type) { //krazy:exclude=inline +            return \
ObjectDescription<T>(QExplicitlySharedDataPointer<ObjectDescriptionData>(ObjectDescriptionData::fromIndex(type, \
index))); +        }
+
         /**
          * Returns \c true if this ObjectDescription describes the same
          * as \p otherDescription; otherwise returns \c false.
--- trunk/kdesupport/phonon/xine/backend.cpp #1031003:1031004
@@ -237,11 +237,16 @@
             const char *const *postPlugins = xine_list_post_plugins_typed(m_xine, \
XINE_POST_TYPE_AUDIO_FILTER);  for (int i = 0; postPlugins[i]; ++i)
                 list << 0x7F000000 + i;
-            /*const char *const *postVPlugins = xine_list_post_plugins_typed(m_xine, \
                XINE_POST_TYPE_VIDEO_FILTER);
-            for (int i = 0; postVPlugins[i]; ++i) {
+        }
+        break;
+    case Phonon::VideoEffectType:
+        {
+            const char *const *postPlugins = xine_list_post_plugins_typed(m_xine, \
XINE_POST_TYPE_VIDEO_FILTER); +            for (int i = 0; postPlugins[i]; ++i) {
                 list << 0x7E000000 + i;
-            } */
+            }
         }
+        break;
     case Phonon::AudioChannelType:
     case Phonon::SubtitleType:
         {
@@ -312,14 +317,20 @@
                     break;
                 }
             }
-            /*const char *const *postVPlugins = xine_list_post_plugins_typed(m_xine, \
                XINE_POST_TYPE_VIDEO_FILTER);
-            for (int i = 0; postVPlugins[i]; ++i) {
+        }
+        break;
+    case Phonon::VideoEffectType:
+        {
+            const char *const *postPlugins = xine_list_post_plugins_typed(m_xine, \
XINE_POST_TYPE_VIDEO_FILTER); +            for (int i = 0; postPlugins[i]; ++i) {
                 if (0x7E000000 + i == index) {
                     ret.insert("name", QLatin1String(postPlugins[i]));
+                    ret.insert("description", \
QLatin1String(xine_get_post_plugin_description(m_xine, postPlugins[i])));  break;
                 }
-            } */
+            }
         }
+        break;
     case Phonon::AudioChannelType:
     case Phonon::SubtitleType:
         {
--- trunk/kdesupport/phonon/xine/effect.cpp #1031003:1031004
@@ -33,6 +33,10 @@
 
 xine_audio_port_t *EffectXT::audioPort() const
 {
+    if (m_isVideoPlugin) {
+        return 0;
+    }
+
     const_cast<EffectXT *>(this)->ensureInstance();
     Q_ASSERT(m_plugin);
     Q_ASSERT(m_plugin->audio_input);
@@ -40,6 +44,19 @@
     return m_plugin->audio_input[0];
 }
 
+xine_video_port_t *EffectXT::videoPort() const
+{
+    if (!m_isVideoPlugin) {
+        return 0;
+    }
+
+    const_cast<EffectXT *>(this)->ensureInstance();
+    Q_ASSERT(m_plugin);
+    Q_ASSERT(m_plugin->video_input);
+    Q_ASSERT(m_plugin->video_input[0]);
+    return m_plugin->video_input[0];
+}
+
 xine_post_out_t *EffectXT::audioOutputPort() const
 {
     const_cast<EffectXT *>(this)->ensureInstance();
@@ -49,15 +66,37 @@
     return x;
 }
 
+xine_post_out_t *EffectXT::videoOutputPort() const
+{
+    const_cast<EffectXT *>(this)->ensureInstance();
+    Q_ASSERT(m_plugin);
+    const char *const *portNames = xine_post_list_outputs(m_plugin);
+    Q_ASSERT(portNames);
+    Q_ASSERT(portNames[0]);
+    xine_post_out_t *x = xine_post_output(m_plugin, portNames[0]);
+    Q_ASSERT(x);
+    return x;
+}
+
 void EffectXT::rewireTo(SourceNodeXT *source)
 {
-    if (!source->audioOutputPort()) {
-        return;
+    if (m_isVideoPlugin) {
+        if (!source->videoOutputPort()) {
+            return;
+        }
+        ensureInstance();
+        xine_post_in_t *x = xine_post_input(m_plugin, "video");
+        Q_ASSERT(x);
+        xine_post_wire(source->videoOutputPort(), x);
+    } else {
+        if (!source->audioOutputPort()) {
+            return;
+        }
+        ensureInstance();
+        xine_post_in_t *x = xine_post_input(m_plugin, "audio in");
+        Q_ASSERT(x);
+        xine_post_wire(source->audioOutputPort(), x);
     }
-    ensureInstance();
-    xine_post_in_t *x = xine_post_input(m_plugin, "audio in");
-    Q_ASSERT(x);
-    xine_post_wire(source->audioOutputPort(), x);
 }
 
 // lazy initialization
@@ -79,6 +118,14 @@
     return m_fakeAudioPort;
 }
 
+xine_video_port_t *EffectXT::fakeVideoPort()
+{
+    if (!m_fakeVideoPort) {
+        m_fakeVideoPort = xine_open_video_driver(m_xine, "none", \
XINE_VISUAL_TYPE_NONE, 0); +    }
+    return m_fakeVideoPort;
+}
+
 void EffectXT::createInstance()
 {
     debug() << Q_FUNC_INFO << "m_pluginName =" << m_pluginName;
@@ -88,8 +135,14 @@
         return;
     }
 
-    fakeAudioPort();
-    m_plugin = xine_post_init(m_xine, m_pluginName, 1, &m_fakeAudioPort, 0);
+    if (m_isVideoPlugin) {
+        fakeVideoPort();
+        m_plugin = xine_post_init(m_xine, m_pluginName, 1, 0, &m_fakeVideoPort);
+    } else {
+        fakeAudioPort();
+        m_plugin = xine_post_init(m_xine, m_pluginName, 1, &m_fakeAudioPort, 0);
+    }
+
     xine_post_in_t *paraInput = xine_post_input(m_plugin, "parameters");
     if (!paraInput) {
         return;
@@ -154,13 +207,26 @@
     SourceNode(static_cast<EffectXT *>(SinkNode::threadSafeObject().data()))
 {
     K_XT(Effect);
-    const char *const *postPlugins = xine_list_post_plugins_typed(xt->m_xine, \
                XINE_POST_TYPE_AUDIO_FILTER);
-    if (effectId >= 0x7F000000) {
+
+    if ((effectId & 0xff000000) == 0x7E000000) {
+        const char *const *postPlugins = xine_list_post_plugins_typed(xt->m_xine, \
XINE_POST_TYPE_VIDEO_FILTER); +        effectId -= 0x7E000000;
+        for(int i = 0; postPlugins[i]; ++i) {
+            if (i == effectId) {
+                // found it
+                xt->m_pluginName = postPlugins[i];
+                xt->m_isVideoPlugin = true;
+                break;
+            }
+        }
+    } else if ((effectId & 0xff000000) == 0x7F000000) {
+        const char *const *postPlugins = xine_list_post_plugins_typed(xt->m_xine, \
XINE_POST_TYPE_AUDIO_FILTER);  effectId -= 0x7F000000;
         for(int i = 0; postPlugins[i]; ++i) {
             if (i == effectId) {
                 // found it
                 xt->m_pluginName = postPlugins[i];
+                xt->m_isVideoPlugin = false;
                 break;
             }
         }
@@ -173,8 +239,8 @@
 }
 
 EffectXT::EffectXT(const char *name)
-    : SourceNodeXT("Effect"), SinkNodeXT("Effect"), m_plugin(0), m_pluginApi(0), \
                m_fakeAudioPort(0),
-    m_pluginName(name), m_pluginParams(0)
+    : SourceNodeXT("Effect"), SinkNodeXT("Effect"), m_plugin(0), m_pluginApi(0), \
m_fakeAudioPort(0), m_fakeVideoPort(0), +    m_pluginName(name), m_pluginParams(0), \
m_isVideoPlugin(false)  {
     m_xine = Backend::xine();
 }
@@ -189,6 +255,10 @@
             xine_close_audio_driver(m_xine, m_fakeAudioPort);
             m_fakeAudioPort = 0;
         }
+        if (m_fakeVideoPort) {
+            xine_close_video_driver(m_xine, m_fakeVideoPort);
+            m_fakeVideoPort = 0;
+        }
     }
     free(m_pluginParams);
     m_pluginParams = 0;
@@ -202,12 +272,14 @@
 
 MediaStreamTypes Effect::inputMediaStreamTypes() const
 {
-    return Phonon::Xine::Audio;
+    K_XT(const Effect);
+    return (xt->m_isVideoPlugin ? Phonon::Xine::Video : Phonon::Xine::Audio);
 }
 
 MediaStreamTypes Effect::outputMediaStreamTypes() const
 {
-    return Phonon::Xine::Audio;
+    K_XT(const Effect);
+    return (xt->m_isVideoPlugin ? Phonon::Xine::Video : Phonon::Xine::Audio);
 }
 
 QList<EffectParameter> Effect::parameters() const
@@ -337,9 +409,11 @@
         xt2->m_plugin = xt->m_plugin;
         xt2->m_pluginApi = xt->m_pluginApi;
         xt2->m_fakeAudioPort = xt->m_fakeAudioPort;
+        xt2->m_fakeVideoPort = xt->m_fakeVideoPort;
         xt->m_plugin = 0;
         xt->m_pluginApi = 0;
         xt->m_fakeAudioPort = 0;
+        xt->m_fakeVideoPort = 0;
         KeepReference<> *keep = new KeepReference<>;
         keep->addObject(static_cast<SinkNodeXT *>(xt2));
         keep->ready();
--- trunk/kdesupport/phonon/xine/effect.h #1031003:1031004
@@ -44,11 +44,14 @@
         EffectXT(const char *name);
         ~EffectXT();
         xine_audio_port_t *audioPort() const;
+        xine_video_port_t *videoPort() const;
         xine_post_out_t *audioOutputPort() const;
+        xine_post_out_t *videoOutputPort() const;
         void rewireTo(SourceNodeXT *source);
         virtual void createInstance();
     protected:
         xine_audio_port_t *fakeAudioPort();
+        xine_video_port_t *fakeVideoPort();
 
         xine_post_t *m_plugin;
         xine_post_api_t *m_pluginApi;
@@ -57,10 +60,12 @@
         void ensureInstance();
 
         xine_audio_port_t *m_fakeAudioPort;
+        xine_video_port_t *m_fakeVideoPort;
         mutable QMutex m_mutex;
         const char *m_pluginName;
         char *m_pluginParams;
         QList<Phonon::EffectParameter> m_parameterList;
+        bool m_isVideoPlugin;
 };
 
 class Effect : public QObject, public EffectInterface, public SinkNode, public \
                SourceNode
--- trunk/kdesupport/phonon/xine/xinestream.cpp #1031003:1031004
@@ -143,7 +143,6 @@
     SourceNodeXT("MediaObject"),
     m_stream(0),
     m_event_queue(0),
-    m_deinterlacer(0),
     m_xine(Backend::xineEngineForStream()),
     m_nullAudioPort(0),
     m_nullVideoPort(0),
@@ -180,9 +179,6 @@
 XineStream::~XineStream()
 {
     Q_ASSERT(QThread::currentThread() == XineThread::instance());
-    if (m_deinterlacer) {
-        xine_post_dispose(m_xine, m_deinterlacer);
-    }
     if(m_event_queue) {
         xine_event_dispose_queue(m_event_queue);
         m_event_queue = 0;
@@ -288,60 +284,7 @@
         return false;
     }
     debug() << Q_FUNC_INFO << "xine_open succeeded for m_mrl =" << \
                m_mrl.constData();
-    const bool needDeinterlacer =
-        (m_mrl.startsWith("dvd:/") && Backend::deinterlaceDVD()) ||
-        (m_mrl.startsWith("vcd:/") && Backend::deinterlaceVCD()) ||
-        (m_mrl.startsWith("file:/") && Backend::deinterlaceFile());
-    if (m_deinterlacer) {
-        if (!needDeinterlacer) {
-            xine_post_dispose(m_xine, m_deinterlacer);
-            m_deinterlacer = 0;
-        }
-    } else if (needDeinterlacer) {
-        xine_video_port_t *videoPort = 0;
-        Q_ASSERT(m_mediaObject);
-        QSet<SinkNode *> sinks = m_mediaObject->sinks();
-        foreach (SinkNode *sink, sinks) {
-            Q_ASSERT(sink->threadSafeObject());
-            if (sink->threadSafeObject()->videoPort()) {
-                Q_ASSERT(videoPort == 0);
-                videoPort = sink->threadSafeObject()->videoPort();
-            }
-        }
-        if (!videoPort) {
-            debug() << Q_FUNC_INFO << "creating xine_stream with null video port";
-            videoPort = nullVideoPort();
-        }
-        m_deinterlacer = xine_post_init(m_xine, "tvtime", 1, 0, &videoPort);
-        if (m_deinterlacer) {
-            // set method
-            xine_post_in_t *paraInput = xine_post_input(m_deinterlacer, \
                "parameters");
-            Q_ASSERT(paraInput);
-            Q_ASSERT(paraInput->data);
-            xine_post_api_t *api = reinterpret_cast<xine_post_api_t \
                *>(paraInput->data);
-            xine_post_api_descr_t *desc = api->get_param_descr();
-            char *pluginParams = static_cast<char *>(malloc(desc->struct_size));
-            api->get_parameters(m_deinterlacer, pluginParams);
-            for (int i = 0; desc->parameter[i].type != POST_PARAM_TYPE_LAST; ++i) {
-                xine_post_api_parameter_t &p = desc->parameter[i];
-                if (p.type == POST_PARAM_TYPE_INT && 0 == strcmp(p.name, "method")) \
                {
-                    int *value = reinterpret_cast<int *>(pluginParams + p.offset);
-                    *value = Backend::deinterlaceMethod();
-                    break;
-                }
-            }
-            api->set_parameters(m_deinterlacer, pluginParams);
-            free(pluginParams);
 
-            // connect to xine_stream_t
-            xine_post_in_t *x = xine_post_input(m_deinterlacer, "video");
-            Q_ASSERT(x);
-            xine_post_out_t *videoOutputPort = xine_get_video_source(m_stream);
-            Q_ASSERT(videoOutputPort);
-            xine_post_wire(videoOutputPort, x);
-        }
-    }
-
     m_lastTimeUpdate.tv_sec = 0;
     xine_get_pos_length(m_stream, 0, &m_currentTime, &m_totalTime);
     getStreamInfo();
@@ -1417,10 +1360,6 @@
         return true;
     case Event::UnloadCommand:
         ev->accept();
-        if (m_deinterlacer) {
-            xine_post_dispose(m_xine, m_deinterlacer);
-            m_deinterlacer = 0;
-        }
         if(m_event_queue) {
             xine_event_dispose_queue(m_event_queue);
             m_event_queue = 0;
@@ -1697,9 +1636,6 @@
     if (!m_stream) {
         return 0;
     }
-    if (m_deinterlacer) {
-        return xine_post_output(m_deinterlacer, "deinterlaced video");
-    }
     return xine_get_video_source(m_stream);
 }
 
--- trunk/kdesupport/phonon/xine/xinestream.h #1031003:1031004
@@ -207,7 +207,6 @@
 
         xine_stream_t *m_stream;
         xine_event_queue_t *m_event_queue;
-        xine_post_t *m_deinterlacer;
         mutable XineEngine m_xine;
         mutable xine_audio_port_t *m_nullAudioPort;
         mutable xine_video_port_t *m_nullVideoPort;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic