<html><head></head><body><div style="color:#000; background-color:#fff; font-family:Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif;font-size:13px"><div id="yui_3_16_0_ym19_1_1493360010957_419539"><span id="yui_3_16_0_ym19_1_1493360010957_419689">Ah, glad to know the difference. I'm using 1.2.4-1, where vaapi is not the default.</span></div><div id="yui_3_16_0_ym19_1_1493360010957_419539" dir="ltr"><span id="yui_3_16_0_ym19_1_1493360010957_419697">For versions before 1.9.0, maybe we can try with "</span><span style="font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; font-size: 13.44px;" id="yui_3_16_0_ym19_1_1493360010957_419698">autoplug-select</span>" signal, from <a href="http://gstreamer-devel.966125.n4.nabble.com/Change-the-ranking-of-an-element-td4674437.html" style="background-color: rgb(255, 255, 255);" id="yui_3_16_0_ym19_1_1493360010957_419699">http://gstreamer-devel.966125.n4.nabble.com/Change-the-ranking-of-an-element-td4674437.html</a></div> <div class="qtdSeparateBR"><br><br></div><div class="yahoo_quoted" style="display: block;"> <div style="font-family: Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif; font-size: 13px;"> <div style="font-family: HelveticaNeue, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif; font-size: 16px;"> <div dir="ltr"><font size="2" face="Arial"> On Tuesday, May 9, 2017 7:08 PM, Victor Toso <victortoso@redhat.com> wrote:<br></font></div> <br><br> <div class="y_msg_container">On Mon, May 08, 2017 at 03:41:59AM +0000, Daimon Wang wrote:<br clear="none">> Hi,<br clear="none">> Is there anything prevent playbin from working with previous versions<br clear="none">> of Gstreamer? I'm trying to use palybin similarly on another program,<br clear="none">> for the vaapi support.<br clear="none"><br clear="none">For versions 1.9.0 onwards and if you have supported hw with drivers and<br clear="none">gstreamer1-vaapi (elements) installed, then playbin should be using<br clear="none">either vaapidecodebin or vaapipostproc first, to verify if it can do hw<br clear="none">decoding otherwise it fallback to sw decoding (with avdec_h264 for<br clear="none">instance).<br clear="none"><br clear="none">For version before 1.9.0, as far as I understood, it'll not use the<br clear="none">vaapielements first, so it should do sw decoding by default.<br clear="none"><br clear="none">I did not test with 1.9.0 or earlier versions to say it for sure.<div class="yqt0861898272" id="yqtfd98148"><br clear="none"><br clear="none">> Regards,Daimon<br clear="none">><br clear="none">> On Thursday, May 4, 2017 9:44 PM, Victor Toso <<a shape="rect" ymailto="mailto:victortoso@redhat.com" href="mailto:victortoso@redhat.com">victortoso@redhat.com</a>> wrote:<br clear="none">> <br clear="none">> <br clear="none">> From: Victor Toso <<a shape="rect" ymailto="mailto:me@victortoso.com" href="mailto:me@victortoso.com">me@victortoso.com</a>><br clear="none">> <br clear="none">> The Playbin can provide the full pipeline which reduces the<br clear="none">> overall maintenance in the code as we don't need to track which<br clear="none">> decoder can work with our stream type.<br clear="none">> <br clear="none">> We need to maintain the GstCaps per SPICE_VIDEO_CODEC_TYPE in order to<br clear="none">> tell Playbin the type of data we expect. This much should be covered<br clear="none">> by spice-protocol and very likely we will need to extend it in the<br clear="none">> future to allow more settings that might not possible to verify at<br clear="none">> runtime.<br clear="none">> <br clear="none">> This patch keeps previous code for compatibility reasons.<br clear="none">> <br clear="none">> Note that we have to wait Playbin to emit "source-setup" in order to<br clear="none">> configure GstAppSrc with the capabilities of input stream. If in the<br clear="none">> unlikely event of frames arriving while GstAppSrc is not setup, we<br clear="none">> will drop those frames.<br clear="none">> <br clear="none">> Signed-off-by: Victor Toso <<a shape="rect" ymailto="mailto:victortoso@redhat.com" href="mailto:victortoso@redhat.com">victortoso@redhat.com</a>><br clear="none">> Signed-off-by: Victor Toso <<a shape="rect" ymailto="mailto:me@victortoso.com" href="mailto:me@victortoso.com">me@victortoso.com</a>><br clear="none">> ---<br clear="none">> src/channel-display-gst.c | 88 +++++++++++++++++++++++++++++++++++++++++++++--<br clear="none">> 1 file changed, 86 insertions(+), 2 deletions(-)<br clear="none">> <br clear="none">> diff --git a/src/channel-display-gst.c b/src/channel-display-gst.c<br clear="none">> index 2a20763..2b14745 100644<br clear="none">> --- a/src/channel-display-gst.c<br clear="none">> +++ b/src/channel-display-gst.c<br clear="none">> @@ -50,6 +50,9 @@ typedef struct SpiceGstDecoder {<br clear="none">> guint timer_id;<br clear="none">> } SpiceGstDecoder;<br clear="none">> <br clear="none">> +/* FIXME: With gstreamer version 1.9.0 and higher, we are using playbin to<br clear="none">> + * create the pipeline for us and for that reason we don't need to keep track of<br clear="none">> + * decoder's name anymore. */<br clear="none">> static struct {<br clear="none">> const gchar *dec_name;<br clear="none">> const gchar *dec_caps;<br clear="none">> @@ -256,10 +259,13 @@ static GstFlowReturn new_sample(GstAppSink *gstappsink, gpointer video_decoder)<br clear="none">> }<br clear="none">> l = l->next;<br clear="none">> }<br clear="none">> +#if !GST_CHECK_VERSION(1,9,0)<br clear="none">> + /* We down own this sample when using playbin, no need to unref it */<br clear="none">> if (!l) {<br clear="none">> spice_warning("got an unexpected decoded buffer!");<br clear="none">> gst_sample_unref(sample);<br clear="none">> }<br clear="none">> +#endif<br clear="none">> <br clear="none">> g_mutex_unlock(&decoder->queues_mutex);<br clear="none">> schedule_frame(decoder);<br clear="none">> @@ -276,8 +282,11 @@ static void free_pipeline(SpiceGstDecoder *decoder)<br clear="none">> }<br clear="none">> <br clear="none">> gst_element_set_state(decoder->pipeline, GST_STATE_NULL);<br clear="none">> +#if !GST_CHECK_VERSION(1,9,0)<br clear="none">> + /* Owned by playbin on 1.9.0 onwards */<br clear="none">> gst_object_unref(decoder->appsrc);<br clear="none">> gst_object_unref(decoder->appsink);<br clear="none">> +#endif<br clear="none">> gst_object_unref(decoder->pipeline);<br clear="none">> gst_object_unref(decoder->clock);<br clear="none">> decoder->pipeline = NULL;<br clear="none">> @@ -305,13 +314,79 @@ static gboolean handle_pipeline_message(GstBus *bus, GstMessage *msg, gpointer v<br clear="none">> return TRUE;<br clear="none">> }<br clear="none">> <br clear="none">> +#if GST_CHECK_VERSION(1,9,0)<br clear="none">> +static void app_source_setup(GstElement *pipeline, GstElement *source, SpiceGstDecoder *decoder)<br clear="none">> +{<br clear="none">> + GstCaps *caps;<br clear="none">> +<br clear="none">> + /* - We schedule the frame display ourselves so set sync=false on appsink<br clear="none">> + * so the pipeline decodes them as fast as possible. This will also<br clear="none">> + * minimize the risk of frames getting lost when we rebuild the<br clear="none">> + * pipeline.<br clear="none">> + * - Set max-bytes=0 on appsrc so it does not drop frames that may be<br clear="none">> + * needed by those that follow.<br clear="none">> + */<br clear="none">> + caps = gst_caps_from_string(gst_opts[decoder->base.codec_type].dec_caps);<br clear="none">> + g_object_set(source,<br clear="none">> + "caps", caps,<br clear="none">> + "is-live", TRUE,<br clear="none">> + "format", GST_FORMAT_TIME,<br clear="none">> + "max-bytes", 0,<br clear="none">> + "block", TRUE,<br clear="none">> + NULL);<br clear="none">> + gst_caps_unref(caps);<br clear="none">> + decoder->appsrc = GST_APP_SRC(source);<br clear="none">> +}<br clear="none">> +#endif<br clear="none">> +<br clear="none">> static gboolean create_pipeline(SpiceGstDecoder *decoder)<br clear="none">> {<br clear="none">> - gchar *desc;<br clear="none">> GstAppSinkCallbacks appsink_cbs = { NULL };<br clear="none">> - GError *err = NULL;<br clear="none">> GstBus *bus;<br clear="none">> +#if GST_CHECK_VERSION(1,9,0)<br clear="none">> + GstElement *playbin, *sink;<br clear="none">> + gint flags;<br clear="none">> + GstCaps *caps;<br clear="none">> <br clear="none">> + playbin = gst_element_factory_make("playbin", "playbin");<br clear="none">> + if (playbin == NULL) {<br clear="none">> + spice_warning("error upon creation of 'playbin' element");<br clear="none">> + return FALSE;<br clear="none">> + }<br clear="none">> +<br clear="none">> + sink = gst_element_factory_make("appsink", "sink");<br clear="none">> + if (sink == NULL) {<br clear="none">> + spice_warning("error upon creation of 'appsink' element");<br clear="none">> + gst_object_unref(playbin);<br clear="none">> + return FALSE;<br clear="none">> + }<br clear="none">> +<br clear="none">> + caps = gst_caps_from_string("video/x-raw,format=BGRx");<br clear="none">> + g_object_set(sink,<br clear="none">> + "caps", caps,<br clear="none">> + "sync", FALSE,<br clear="none">> + "drop", FALSE,<br clear="none">> + NULL);<br clear="none">> + gst_caps_unref(caps);<br clear="none">> +<br clear="none">> + g_object_set(playbin,<br clear="none">> + "uri", "appsrc://",<br clear="none">> + "video-sink", sink,<br clear="none">> + NULL);<br clear="none">> +<br clear="none">> + g_signal_connect(playbin, "source-setup", G_CALLBACK(app_source_setup), decoder);<br clear="none">> +<br clear="none">> + /* Disable audio in playbin */<br clear="none">> + g_object_get(playbin, "flags", &flags, NULL);<br clear="none">> + flags &= ~(1 << 1);<br clear="none">> + g_object_set(playbin, "flags", flags, NULL);<br clear="none">> +<br clear="none">> + decoder->appsrc = NULL;<br clear="none">> + decoder->appsink = GST_APP_SINK(sink);<br clear="none">> + decoder->pipeline = playbin;<br clear="none">> +#else<br clear="none">> + gchar *desc;<br clear="none">> + GError *err = NULL;<br clear="none">> <br clear="none">> /* - We schedule the frame display ourselves so set sync=false on appsink<br clear="none">> * so the pipeline decodes them as fast as possible. This will also<br clear="none">> @@ -337,6 +412,7 @@ static gboolean create_pipeline(SpiceGstDecoder *decoder)<br clear="none">> <br clear="none">> decoder->appsrc = GST_APP_SRC(gst_bin_get_by_name(GST_BIN(decoder->pipeline), "src"));<br clear="none">> decoder->appsink = GST_APP_SINK(gst_bin_get_by_name(GST_BIN(decoder->pipeline), "sink"));<br clear="none">> +#endif<br clear="none">> <br clear="none">> appsink_cbs.new_sample = new_sample;<br clear="none">> gst_app_sink_set_callbacks(decoder->appsink, &appsink_cbs, decoder, NULL);<br clear="none">> @@ -447,6 +523,14 @@ static gboolean spice_gst_decoder_queue_frame(VideoDecoder *video_decoder,<br clear="none">> return FALSE;<br clear="none">> }<br clear="none">> <br clear="none">> +#if GST_CHECK_VERSION(1,9,0)<br clear="none">> + if (decoder->appsrc == NULL) {<br clear="none">> + spice_warning("Error: Playbin has not yet initialized the Appsrc element");<br clear="none">> + stream_dropped_frame_on_playback(decoder->base.stream);<br clear="none">> + return TRUE;<br clear="none">> + }<br clear="none">> +#endif<br clear="none">> +<br clear="none">> /* ref() the frame_msg for the buffer */<br clear="none">> spice_msg_in_ref(frame_msg);<br clear="none">> GstBuffer *buffer = gst_buffer_new_wrapped_full(GST_MEMORY_FLAG_PHYSICALLY_CONTIGUOUS,<br clear="none">> -- <br clear="none">> 2.12.2<br clear="none">> <br clear="none">> _______________________________________________<br clear="none">> Spice-devel mailing list<br clear="none">> <a shape="rect" ymailto="mailto:Spice-devel@lists.freedesktop.org" href="mailto:Spice-devel@lists.freedesktop.org">Spice-devel@lists.freedesktop.org</a><br clear="none">> <a shape="rect" href="https://lists.freedesktop.org/mailman/listinfo/spice-devel" target="_blank">https://lists.freedesktop.org/mailman/listinfo/spice-devel</a><br clear="none">> <br clear="none">> <br clear="none">> </div><br><br></div> </div> </div> </div></div></body></html>