<div dir="ltr">Hi all,<br><br>I don't know if this is the proper place for this.<br><br>But I'm having some trouble using SDL and gstreamer.<br><br>I want to stream a video (just the video) on a SDL_texture.<br><br>Here is what I am doing:<br><br>```<br>    auto pipeline = gst_pipeline_new ("audio-player");<br>    auto videoSrc = gst_element_factory_make("videotestsrc", "video_src");<br>    auto videoConvert = gst_element_factory_make("videoconvert", "video_convert");<br>    auto videoSink = GST_APP_SINK(gst_element_factory_make("appsink", "video_sink"));<br><br>   gst_app_sink_set_emit_signals(videoSink, true);<br>/ Get the sink pad of the videoconvert element<br>    GstPad *sinkPad = gst_element_get_static_pad(videoConvert, "sink");<br><br>// Create a new caps object with the desired capabilities<br>    GstCaps *caps = gst_caps_new_simple("video/x-raw",<br>                                        "format", G_TYPE_STRING, "RGBA",<br>                                        NULL);<br><br>// Set the capabilities on the sink pad<br>    gst_pad_set_caps(sinkPad, caps);<br><br>// Release the caps object<br>    gst_caps_unref(caps);<br><br>    g_signal_connect(videoSink, "new-sample", G_CALLBACK(onNewSample), this);<br>    g_signal_connect(videoSink, "eos", G_CALLBACK(onEos), this);<br>    //videoSink = gst_element_factory_make("autovideosink", "video_sink");<br><br>    gst_bin_add_many(GST_BIN (pipeline),<br>                     videoSrc,<br>                     videoConvert,<br>                     videoSink,<br>                     NULL);<br>    gst_element_link_many (videoSrc, videoConvert, videoSink, NULL);<div><br>```<br><br>Then on my main loop I try to get the data buffer from the appsink and set it to a texture:<br><br>```<br>    if (!_hasNewSample)<br>        return;<br><br>    GstSample* sample = gst_app_sink_pull_sample(videoSink);<br>    {<br>        std::lock_guard<std::mutex> lock(StreamGstreamerActivityUI::_mutex);<br>        _hasNewSample = false;<br>    }<br>    GstBuffer* buffer = gst_sample_get_buffer(sample);<br>    if (!buffer)<br>    {<br>        std::cout << ">>>>> Buffer is null!\n";<br>        return;<br>    }<br><br>    GstMapInfo info;<br>    gst_buffer_map(buffer, &info, GST_MAP_READ);<br>    GstCaps* caps = gst_sample_get_caps(sample);<br>    if (!caps)<br>    {<br>        std::cout << ">>>>> Caps is null!\n";<br>        return;<br>    }<br><br>// Get the structure for the first media type in the caps<br>    GstStructure* structure = gst_caps_get_structure(caps, 0);<br>    if (!structure)<br>    {<br>        std::cout << ">>>>> Structure is null!\n";<br>        return;<br>    }<br><br>// Get the width and height fields from the structure<br>    int width, height;<br>    gst_structure_get_int(structure, "width", &width);<br>    gst_structure_get_int(structure, "height", &height);<br><br><br>    if (!_texture)<br>    {<br>        _texture = SDL_CreateTexture(Display::getRenderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING,<br>                                     width, height);<br>        SDL_UpdateTexture(_texture, NULL, info.data, height);<br>        SDL_RenderCopy(Display::getRenderer(), _texture, NULL, NULL);<br>        return;<br>    }<br><br>    SDL_LockTexture(_texture, NULL, &_rawPixels, &_rawPitch);<br>//Copy to locked pixels<br>    memcpy(_rawPixels, info.data, _rawPitch * height);<br>    SDL_UnlockTexture(_texture);<br>    _rawPixels = NULL;<br>    _rawPitch = 0;<br>// Render the texture<br><br>    auto previousTarget = SDL_GetRenderTarget(Display::getRenderer());<br>    SDL_SetRenderTarget(Display::getRenderer(), _texture);<br><br>    SDL_RenderCopy(Display::getRenderer(), _texture, NULL, NULL);<br>    SDL_RenderPresent( Display::getRenderer() );<br><br>    SDL_SetRenderTarget(Display::getRenderer(), previousTarget);<br><br>    // free gst stuff<br>    gst_sample_unref(sample);<br>    gst_buffer_unref(buffer);<br>    gst_caps_unref(caps);<br>```<br>And this is my callback functions:<br>```<br><br>void StreamGstreamerActivityUI::onNewSample(GstAppSink *sink, gpointer userData)<br>{<br>    static auto sampleCount = 0;<br>    auto streamActivity = static_cast<StreamGstreamerActivityUI*>(userData);<br>    std::cout << ">>>>>>>>>>>>>> New Sample: " << ++sampleCount << "!\n";<br>    std::lock_guard<std::mutex> lock(StreamGstreamerActivityUI::_mutex);<br>    _hasNewSample = true;<br>}</div><div><br><br>void StreamGstreamerActivityUI::onEos(GstAppSink *sink, gpointer userData)<br>{<br>    std::cout << ">>>>>>>>>>>>>> End of Sample!\n";<br>    std::lock_guard<std::mutex> lock(StreamGstreamerActivityUI::_mutex);<br>    _hasNewSample = false;<br>}<br></div><div>```   <br><br>I'm surely doing something wrong. because I don't see any output on the SDL window and I got plenty of critical stuff from gst like this:<br><br>```<br>>>>>>>>>>>>>>> New Sample: 1!<br>>>>>>>>>>>>>>> New Sample: 2!<br>>>>>>>>>>>>>>> New Sample: 3!<br>>>>>>>>>>>>>>> New Sample: 4!<br>>>>>>>>>>>>>>> New Sample: 5!<br>>>>>>>>>>>>>>> New Sample: 6!<br>>>>>>>>>>>>>>> New Sample: 7!<br>>>>>>>>>>>>>>> New Sample: 8!<br>>>>>>>>>>>>>>> New Sample: 9!<br>>>>>>>>>>>>>>> New Sample: 10!<br>>>>>>>>>>>>>>> New Sample: 11!<br><br>(ProjectX.exe:31760): GStreamer-CRITICAL **: 15:37:49.790: gst_mini_object_unlock: assertion 'state >= SHARE_ONE' failed<br><br>(ProjectX.exe:31760): GStreamer-CRITICAL **: 15:37:49.790: gst_mini_object_unref: assertion 'GST_MINI_OBJECT_REFCOUNT_VA<br>LUE (mini_object) > 0' failed<br><br>(ProjectX.exe:31760): GStreamer-CRITICAL **: 15:37:49.811: gst_mini_object_unlock: assertion 'state >= SHARE_ONE' failed<br><br>(ProjectX.exe:31760): GStreamer-CRITICAL **: 15:37:49.811: gst_mini_object_unref: assertion 'GST_MINI_OBJECT_REFCOUNT_VA<br>LUE (mini_object) > 0' failed<br>```<br><br><br>Any thoughts or some direction on how I can achieve this? <br><br>Thank you.<br><br clear="all"><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div>--</div>Miguel Silvestre</div></div></div></div>