[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