Make QGstreamerPlayerSession 'VAAPI-aware'.
At the moment the GStreamer player pipeline is not setup properly when the VAAPI plugin is available, resulting in no video being shown. Added 'video/x-surface' as one of the default raw formats for the decodebin. Don't use vaapidecode when the video sink is not compatible. This is a preliminary patch to support VAAPI. In the current state vaapidecode will never be used as none of our video sinks support the video/x-surface format. Change-Id: I39f339b483d4052dd1e29c2b0ef06343d5670224 Reviewed-by: Christian Stromme <christian.stromme@digia.com>
This commit is contained in:
committed by
The Qt Project
parent
bce5525cbb
commit
abcc107731
@@ -77,6 +77,19 @@ typedef enum {
|
|||||||
GST_PLAY_FLAG_BUFFERING = 0x000000100
|
GST_PLAY_FLAG_BUFFERING = 0x000000100
|
||||||
} GstPlayFlags;
|
} GstPlayFlags;
|
||||||
|
|
||||||
|
#define DEFAULT_RAW_CAPS \
|
||||||
|
"video/x-raw-yuv; " \
|
||||||
|
"video/x-raw-rgb; " \
|
||||||
|
"video/x-raw-gray; " \
|
||||||
|
"video/x-surface; " \
|
||||||
|
"audio/x-raw-int; " \
|
||||||
|
"audio/x-raw-float; " \
|
||||||
|
"text/plain; " \
|
||||||
|
"text/x-pango-markup; " \
|
||||||
|
"video/x-dvd-subpicture; " \
|
||||||
|
"subpicture/x-pgs"
|
||||||
|
static GstStaticCaps static_RawCaps = GST_STATIC_CAPS(DEFAULT_RAW_CAPS);
|
||||||
|
|
||||||
QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
|
QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
|
||||||
:QObject(parent),
|
:QObject(parent),
|
||||||
m_state(QMediaPlayer::StoppedState),
|
m_state(QMediaPlayer::StoppedState),
|
||||||
@@ -1548,6 +1561,63 @@ void QGstreamerPlayerSession::updateMuted()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (GST_VERSION_MAJOR == 0) && ((GST_VERSION_MINOR < 10) || (GST_VERSION_MICRO < 33))
|
||||||
|
static gboolean factory_can_src_any_caps (GstElementFactory *factory, const GstCaps *caps)
|
||||||
|
{
|
||||||
|
GList *templates;
|
||||||
|
|
||||||
|
g_return_val_if_fail(factory != NULL, FALSE);
|
||||||
|
g_return_val_if_fail(caps != NULL, FALSE);
|
||||||
|
|
||||||
|
templates = factory->staticpadtemplates;
|
||||||
|
|
||||||
|
while (templates) {
|
||||||
|
GstStaticPadTemplate *templ = (GstStaticPadTemplate *)templates->data;
|
||||||
|
|
||||||
|
if (templ->direction == GST_PAD_SRC) {
|
||||||
|
GstCaps *templcaps = gst_static_caps_get(&templ->static_caps);
|
||||||
|
|
||||||
|
if (gst_caps_can_intersect(caps, templcaps)) {
|
||||||
|
gst_caps_unref(templcaps);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
gst_caps_unref(templcaps);
|
||||||
|
}
|
||||||
|
templates = g_list_next(templates);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GstAutoplugSelectResult QGstreamerPlayerSession::handleAutoplugSelect(GstBin *bin, GstPad *pad, GstCaps *caps, GstElementFactory *factory, QGstreamerPlayerSession *session)
|
||||||
|
{
|
||||||
|
Q_UNUSED(bin);
|
||||||
|
Q_UNUSED(pad);
|
||||||
|
Q_UNUSED(caps);
|
||||||
|
|
||||||
|
GstAutoplugSelectResult res = GST_AUTOPLUG_SELECT_TRY;
|
||||||
|
|
||||||
|
// if VAAPI is available and can be used to decode but the current video sink cannot handle
|
||||||
|
// the decoded format, don't use it
|
||||||
|
const gchar *factoryName = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
|
||||||
|
if (g_str_has_prefix(factoryName, "vaapi")) {
|
||||||
|
GstPad *sinkPad = gst_element_get_static_pad(session->m_videoSink, "sink");
|
||||||
|
GstCaps *sinkCaps = gst_pad_get_caps(sinkPad);
|
||||||
|
|
||||||
|
#if (GST_VERSION_MAJOR == 0) && ((GST_VERSION_MINOR < 10) || (GST_VERSION_MICRO < 33))
|
||||||
|
if (!factory_can_src_any_caps(factory, sinkCaps))
|
||||||
|
#else
|
||||||
|
if (!gst_element_factory_can_src_any_caps(factory, sinkCaps))
|
||||||
|
#endif
|
||||||
|
res = GST_AUTOPLUG_SELECT_SKIP;
|
||||||
|
|
||||||
|
gst_object_unref(sinkPad);
|
||||||
|
gst_caps_unref(sinkCaps);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
void QGstreamerPlayerSession::handleElementAdded(GstBin *bin, GstElement *element, QGstreamerPlayerSession *session)
|
void QGstreamerPlayerSession::handleElementAdded(GstBin *bin, GstElement *element, QGstreamerPlayerSession *session)
|
||||||
{
|
{
|
||||||
@@ -1573,6 +1643,15 @@ void QGstreamerPlayerSession::handleElementAdded(GstBin *bin, GstElement *elemen
|
|||||||
}
|
}
|
||||||
} else if (g_str_has_prefix(elementName, "uridecodebin") ||
|
} else if (g_str_has_prefix(elementName, "uridecodebin") ||
|
||||||
g_str_has_prefix(elementName, "decodebin2")) {
|
g_str_has_prefix(elementName, "decodebin2")) {
|
||||||
|
|
||||||
|
if (g_str_has_prefix(elementName, "uridecodebin")) {
|
||||||
|
// Add video/x-surface (VAAPI) to default raw formats
|
||||||
|
g_object_set(G_OBJECT(element), "caps", gst_static_caps_get(&static_RawCaps), NULL);
|
||||||
|
// listen for uridecodebin autoplug-select to skip VAAPI usage when the current
|
||||||
|
// video sink doesn't support it
|
||||||
|
g_signal_connect(element, "autoplug-select", G_CALLBACK(handleAutoplugSelect), session);
|
||||||
|
}
|
||||||
|
|
||||||
//listen for queue2 element added to uridecodebin/decodebin2 as well.
|
//listen for queue2 element added to uridecodebin/decodebin2 as well.
|
||||||
//Don't touch other bins since they may have unrelated queues
|
//Don't touch other bins since they may have unrelated queues
|
||||||
g_signal_connect(element, "element-added",
|
g_signal_connect(element, "element-added",
|
||||||
|
|||||||
@@ -66,6 +66,12 @@ class QGstreamerVideoRendererInterface;
|
|||||||
class QGstreamerVideoProbeControl;
|
class QGstreamerVideoProbeControl;
|
||||||
class QGstreamerAudioProbeControl;
|
class QGstreamerAudioProbeControl;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GST_AUTOPLUG_SELECT_TRY,
|
||||||
|
GST_AUTOPLUG_SELECT_EXPOSE,
|
||||||
|
GST_AUTOPLUG_SELECT_SKIP
|
||||||
|
} GstAutoplugSelectResult;
|
||||||
|
|
||||||
class QGstreamerPlayerSession : public QObject,
|
class QGstreamerPlayerSession : public QObject,
|
||||||
public QGstreamerBusMessageFilter
|
public QGstreamerBusMessageFilter
|
||||||
{
|
{
|
||||||
@@ -182,6 +188,7 @@ private:
|
|||||||
static void insertColorSpaceElement(GstElement *element, gpointer data);
|
static void insertColorSpaceElement(GstElement *element, gpointer data);
|
||||||
static void handleElementAdded(GstBin *bin, GstElement *element, QGstreamerPlayerSession *session);
|
static void handleElementAdded(GstBin *bin, GstElement *element, QGstreamerPlayerSession *session);
|
||||||
static void handleStreamsChange(GstBin *bin, gpointer user_data);
|
static void handleStreamsChange(GstBin *bin, gpointer user_data);
|
||||||
|
static GstAutoplugSelectResult handleAutoplugSelect(GstBin *bin, GstPad *pad, GstCaps *caps, GstElementFactory *factory, QGstreamerPlayerSession *session);
|
||||||
|
|
||||||
void processInvalidMedia(QMediaPlayer::Error errorCode, const QString& errorString);
|
void processInvalidMedia(QMediaPlayer::Error errorCode, const QString& errorString);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user