[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: kdereview/phonon/gstreamer
From: Jens Bache-Wiig <jbache () trolltech ! com>
Date: 2008-03-07 16:23:04
Message-ID: 1204906984.505838.8039.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 783276 by jbache:
* A bit more debug info
* Larger max-buffers for streams
* Fixed some x11 resizing issues
M +1 -2 audiooutput.cpp
M +13 -8 backend.cpp
M +8 -11 medianode.cpp
M +49 -20 mediaobject.cpp
M +2 -1 mediaobject.h
M +3 -2 videowidget.cpp
M +6 -0 x11renderer.cpp
--- trunk/kdereview/phonon/gstreamer/audiooutput.cpp #783275:783276
@@ -126,8 +126,7 @@
{
if (root()) {
root()->stop(); // We cannot currently change audiodevice while the stream \
is playing
- if (gst_element_get_state (root()->pipeline(), NULL, NULL, 3000) != \
GST_STATE_CHANGE_SUCCESS)
- return false;
+ root()->invalidateGraph();
}
bool success = false;
--- trunk/kdereview/phonon/gstreamer/backend.cpp #783275:783276
@@ -315,6 +315,7 @@
MediaNode *sinkNode = qobject_cast<MediaNode *>(sink);
if (sourceNode && sinkNode) {
if (sourceNode->connectNode(sink)) {
+ sourceNode->root()->invalidateGraph();
logMessage(QString("Backend connected %0 to \
%1").arg(source->metaObject()->className()).arg(sink->metaObject()->className())); \
return true; }
@@ -411,16 +412,20 @@
{
if (debugLevel() > 0) {
QString output;
- if (obj)
- output = QString("%0 (%1 \
%2)").arg(message).arg(obj->objectName()).arg(obj->metaObject()->className());
- else
+ if (obj) {
+ // Strip away namespace from className
+ QString className(obj->metaObject()->className());
+ int nameLength = className.length() - className.lastIndexOf(':') - 1;
+ className = className.right(nameLength);
+ output.sprintf("%s %s (%s %p)", message.toLatin1().constData(),
+ obj->objectName().toLatin1().constData(),
+ className.toLatin1().constData(), obj);
+ }
+ else {
output = message;
-
+ }
if (priority <= (int)debugLevel()) {
- if (priority == Backend::Warning)
- qDebug() << "PHONON_GST(warn): " << output;
- else
- qDebug() << "PHONON_GST(info): " << output;
+ qDebug() << QString("PGST(%1): %2").arg(priority).arg(output);
}
}
}
--- trunk/kdereview/phonon/gstreamer/medianode.cpp #783275:783276
@@ -293,6 +293,7 @@
if (!sinkElement)
return false;
+ GstState state = GST_STATE (root()->pipeline());
GstPad *srcPad = gst_element_get_request_pad (tee, "src%d");
GstPad *sinkPad = gst_element_get_pad (sinkElement, "sink");
@@ -304,14 +305,6 @@
return true;
}
- // Sync state with pipeline before adding
- // and fail if this is not possible
- GstState state = GST_STATE (root()->pipeline());
- if (gst_element_set_state(sinkElement, state) == GST_STATE_CHANGE_FAILURE) {
- success = false;
- m_backend->logMessage("Could not sync element state with pipeline, \
connection failed");
- }
-
if (success) {
if (output->description() & AudioSink)
gst_bin_add(GST_BIN(root()->audioGraph()), sinkElement);
@@ -319,10 +312,12 @@
gst_bin_add(GST_BIN(root()->videoGraph()), sinkElement);
}
- if (success)
+ if (success) {
gst_pad_link(srcPad, sinkPad);
- else
+ gst_element_set_state(sinkElement, state);
+ } else {
gst_element_release_request_pad(tee, srcPad);
+ }
gst_object_unref (GST_OBJECT (srcPad));
gst_object_unref (GST_OBJECT (sinkPad));
@@ -344,9 +339,10 @@
GstPad *srcPad = gst_element_get_request_pad (tee, "src%d");
gst_bin_add(GST_BIN(bin), sink);
- success = (gst_element_set_state(sink, GST_STATE(bin)) != \
GST_STATE_CHANGE_FAILURE); if (success)
success = (gst_pad_link (srcPad, sinkPad) == GST_PAD_LINK_OK);
+ if (success)
+ success = (gst_element_set_state(sink, GST_STATE(bin)) != \
GST_STATE_CHANGE_FAILURE); gst_object_unref (srcPad);
gst_object_unref (sinkPad);
return success;
@@ -379,6 +375,7 @@
gst_bin_add(GST_BIN(bin), tee);
if (!gst_element_link_pads(src, "src", tee, "sink"))
return false;
+ gst_element_set_state(tee, GST_STATE(bin));
}
if (list.isEmpty()) {
//connect node to a fake sink to avoid clogging the pipeline
--- trunk/kdereview/phonon/gstreamer/mediaobject.cpp #783275:783276
@@ -35,6 +35,7 @@
#include <QApplication>
#define ABOUT_TO_FINNISH_TIME 2000
+#define MAX_QUEUE_TIME 20 * GST_SECOND
QT_BEGIN_NAMESPACE
@@ -71,6 +72,7 @@
, m_audioGraph(0)
, m_videoGraph(0)
, m_previousTickTime(-1)
+ , m_resetNeeded(false)
{
qRegisterMetaType<GstCaps*>("GstCaps*");
@@ -222,15 +224,15 @@
if (addToPipeline(m_videoGraph)) {
GstPad *videopad = gst_element_get_pad (m_videoGraph, "sink");
if (!GST_PAD_IS_LINKED (videopad) && (gst_pad_link (pad, videopad) == \
GST_PAD_LINK_OK)) { + gst_element_set_state(m_videoGraph, \
GST_STATE_PAUSED); m_videoStreamFound = true;
- m_backend->logMessage("Video track connected");
+ m_backend->logMessage("Video track connected", Backend::Info, this);
// Note that the notify::caps _must_ be installed after linking to work \
with Dapper
m_capsHandler = g_signal_connect(pad, "notify::caps", \
G_CALLBACK(notifyVideoCaps), this);
- gst_element_set_state(m_videoGraph, GST_STATE_PAUSED);
}
gst_object_unref (videopad);
} else {
- m_backend->logMessage("The video stream could not be plugged.");
+ m_backend->logMessage("The video stream could not be plugged.", \
Backend::Info, this); }
}
@@ -239,13 +241,13 @@
if (addToPipeline(m_audioGraph)) {
GstPad *audiopad = gst_element_get_pad (m_audioGraph, "sink");
if (!GST_PAD_IS_LINKED (audiopad) && (gst_pad_link (pad, \
audiopad)==GST_PAD_LINK_OK)) { + gst_element_set_state(m_audioGraph, \
GST_STATE_PAUSED); m_hasAudio = true;
- m_backend->logMessage("Audio track connected");
- gst_element_set_state(m_audioGraph, GST_STATE_PAUSED);
+ m_backend->logMessage("Audio track connected", Backend::Info, this);
}
gst_object_unref (audiopad);
} else {
- m_backend->logMessage("The audio stream could not be plugged.");
+ m_backend->logMessage("The audio stream could not be plugged.", \
Backend::Info, this); }
}
@@ -332,7 +334,12 @@
gst_object_ref (GST_OBJECT (m_audioGraph));
gst_object_sink (GST_OBJECT (m_audioGraph));
- m_audioPipe = gst_element_factory_make("identity", NULL);
+ // Note that these queues are only required for streaming content
+ // And should ideally be created on demand as they will disable
+ // pull-mode access. Also note that the max-size-time are increased to
+ // reduce buffer overruns as these are not gracefully handled at the moment.
+ m_audioPipe = gst_element_factory_make("queue", NULL);
+ g_object_set(G_OBJECT(m_audioPipe), "max-size-time", MAX_QUEUE_TIME, NULL);
gst_bin_add(GST_BIN(m_audioGraph), m_audioPipe);
GstPad *audiopad = gst_element_get_pad (m_audioPipe, "sink");
gst_element_add_pad (m_audioGraph, gst_ghost_pad_new ("sink", audiopad));
@@ -343,7 +350,8 @@
gst_object_ref (GST_OBJECT (m_videoGraph));
gst_object_sink (GST_OBJECT (m_videoGraph));
- m_videoPipe = gst_element_factory_make("identity", NULL);
+ m_videoPipe = gst_element_factory_make("queue", NULL);
+ g_object_set(G_OBJECT(m_videoPipe), "max-size-time", MAX_QUEUE_TIME, NULL);
gst_bin_add(GST_BIN(m_videoGraph), m_videoPipe);
GstPad *videopad = gst_element_get_pad (m_videoPipe, "sink");
gst_element_add_pad (m_videoGraph, gst_ghost_pad_new ("sink", videopad));
@@ -494,6 +502,14 @@
break;
case Phonon::PlayingState:
+ if (m_resetNeeded) {
+ // ### Note this is a workaround and it should really be gracefully
+ // handled by medianode when we implement live connections.
+ // This generally happens if medianodes have been connected after the \
MediaSource was set + // Note that a side-effect of this is that we resend \
all meta data. + gst_element_set_state(m_pipeline, GST_STATE_NULL);
+ m_resetNeeded = false;
+ }
m_backend->logMessage("phonon state request: Playing", Backend::Info, this);
if (m_atEndOfStream) {
m_backend->logMessage("EOS already reached", Backend::Info, this);
@@ -570,7 +586,14 @@
m_error = error;
m_tickTimer->stop();
- changeState(Phonon::ErrorState);
+ if (error == Phonon::FatalError) {
+ emit hasVideoChanged(false);
+ gst_element_set_state(m_pipeline, GST_STATE_READY);
+ changeState(Phonon::ErrorState);
+ } else {
+ //Flag error after loading has completed
+ m_pendingState = Phonon::ErrorState;
+ }
}
qint64 MediaObject::totalTime() const
@@ -648,11 +671,11 @@
}
if (m_seekable)
- m_backend->logMessage("Stream is seekable");
+ m_backend->logMessage("Stream is seekable", Backend::Info, this);
else
- m_backend->logMessage("Stream is non-seekable");
+ m_backend->logMessage("Stream is non-seekable", Backend::Info, this);
} else {
- m_backend->logMessage("updateSeekable query failed");
+ m_backend->logMessage("updateSeekable query failed", Backend::Info, this);
}
gst_query_unref (query);
}
@@ -689,9 +712,6 @@
if (!isValid())
return;
- if (errorType() == FatalError)
- return;
-
// We have to reset the state completely here, otherwise
// remnants of the old pipeline can result in strangenes
// such as failing duration queries etc
@@ -709,6 +729,7 @@
// Go into to loading state
changeState(Phonon::LoadingState);
m_loading = true;
+ m_resetNeeded = false;
m_pendingState = Phonon::StoppedState;
// Make sure we start out unconnected
@@ -784,7 +805,7 @@
void MediaObject::beginLoad()
{
if (gst_element_set_state(m_pipeline, GST_STATE_PAUSED) != \
GST_STATE_CHANGE_FAILURE) {
- m_backend->logMessage("Begin source load");
+ m_backend->logMessage("Begin source load", Backend::Info, this);
} else {
setError(tr("Could not load source"));
}
@@ -985,6 +1006,14 @@
GstMessage *gstMessage = message.rawMessage();
Q_ASSERT(m_pipeline);
+ if (m_backend->debugLevel() >= Backend::Debug) {
+ int type = GST_MESSAGE_TYPE(gstMessage);
+ gchar* name = gst_element_get_name(gstMessage->src);
+ QString message = QString("Bus: %0 (%1)").arg(gst_message_type_get_name \
((GstMessageType)type)).arg(name); + g_free(name);
+ m_backend->logMessage(message, Backend::Debug, this);
+ }
+
switch (GST_MESSAGE_TYPE (gstMessage)) {
case GST_MESSAGE_EOS:
@@ -1065,7 +1094,10 @@
QString message;
message.sprintf("Error: %s", err->message);
m_backend->logMessage(message, Backend::Warning);
- setError(QString(err->message));
+ if (err->domain == GST_STREAM_ERROR) //Cannot continue
+ setError(QString(err->message), Phonon::FatalError);
+ else
+ setError(QString(err->message), Phonon::NormalError);
g_error_free (err);
break;
}
@@ -1122,9 +1154,6 @@
//case GST_MESSAGE_LATENCY: only from 0.10.12
//case GST_MESSAGE_ASYNC_DONE: only from 0.10.13
default:
- int type = GST_MESSAGE_TYPE(gstMessage);
- QString message = QString("Bus: %0").arg(gst_message_type_get_name \
((GstMessageType)type));
- //m_backend->logMessage(message, Backend::Debug, this);
break;
}
}
--- trunk/kdereview/phonon/gstreamer/mediaobject.h #783275:783276
@@ -143,6 +143,7 @@
void handleBusMessage(const Message &msg);
void handleEndOfStream();
void setState(State);
+ void invalidateGraph() {m_resetNeeded = true;}
static void cb_newpad (GstElement *decodebin, GstPad *pad, gboolean last, \
gpointer data);
static void cb_unknown_type (GstElement *decodebin, GstPad *pad, GstCaps *caps, \
gpointer data);
@@ -237,7 +238,7 @@
GstElement *m_audioGraph;
GstElement *m_videoGraph;
int m_previousTickTime;
-
+ bool m_resetNeeded;
QMultiMap<QString, QString> m_metaData;
};
}
--- trunk/kdereview/phonon/gstreamer/videowidget.cpp #783275:783276
@@ -134,11 +134,10 @@
// Disable overlays for graphics view
if (root() && parentWidget() && \
parentWidget()->testAttribute(Qt::WA_DontShowOnScreen) && \
!m_renderer->paintsOnWidget()) {
- m_backend->logMessage(QString("Overlays disabled"), Backend::Info);
+ m_backend->logMessage(QString("Widget rendering forced"), Backend::Info, \
this); GstElement *videoSink = m_renderer->videoSink();
Q_ASSERT(videoSink);
- gst_element_set_state (root()->pipeline(), GST_STATE_READY);
gst_element_set_state (videoSink, GST_STATE_NULL);
gst_bin_remove(GST_BIN(m_videoBin), videoSink);
delete m_renderer;
@@ -148,8 +147,10 @@
videoSink = m_renderer->videoSink();
gst_bin_add(GST_BIN(m_videoBin), videoSink);
gst_element_link(m_videoplug, videoSink);
+ gst_element_set_state (videoSink, GST_STATE_PAUSED);
// Request return to current state
+ root()->invalidateGraph();
root()->setState(root()->state());
}
QWidget::setVisible(val);
--- trunk/kdereview/phonon/gstreamer/x11renderer.cpp #783275:783276
@@ -124,7 +124,13 @@
if (e->type() == QEvent::Show) {
m_videoWidget->setAttribute(Qt::WA_PaintOnScreen, true);
setOverlay();
+ } else if (e->type() == QEvent::Resize) {
+ // This is a workaround for missing background repaints
+ // when reducing window size
+ QApplication::syncX();
+ windowExposed();
}
+
return false;
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic