<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    Hey Dev's,<br>
    <br>
    I've been throwing myself at this problem for a few days without any
    significant progress. Hopefully someone can tell me what painfully
    obvious part I've overlooked.<br>
    <br>
    Essentially what I'm trying to do is just grab some frames of video
    during playback from an appsink, but it seems my simple pipeline is
    missing something vital, because when I get to changing the state to
    'paused' or 'playing' the GstStateChangeReturn I recieve is
    'GST_STATE_CHANGE_ASYNC (2)'. The debug log doesn't yield any error
    output, so I'm a bit unsure of what to look closer at?<br>
    <br>
    Have I perhaps not hooked something up correctly? What am I missing
    here?<br>
    <br>
    Below is my simple code for trying to hook up this simple pipeline
    and grab some frames.<br>
    <br>
    ---------<br>
    <br>
        std::string launchString = "uridecodebin uri=" + mVideoFileName
    + " ! appsink name=sink";<br>
    <br>
        mGstPipeline = gst_parse_launch( launchString.c_str(),
    &pstGErr1 );<br>
        printErrorToConsole( pstGErr1 != nullptr, "GStreamer Error:
    Could not construct pipeline", pstGErr1 );<br>
    <br>
    <br>
        GstElement *mPipeline_AppSink;<br>
        mPipeline_AppSink = gst_bin_get_by_name( GST_BIN( mGstPipeline
    ), "sink" );<br>
    <br>
       
    //////////////////////////////////////////////////////////////////////////
    VIDEO SINK<br>
        // Config Video Sink<br>
        gst_base_sink_set_sync( GST_BASE_SINK( mPipeline_AppSink ), true
    );<br>
        gst_app_sink_set_max_buffers( GST_APP_SINK( mPipeline_AppSink ),
    8 );<br>
        gst_app_sink_set_drop( GST_APP_SINK( mPipeline_AppSink ), true
    );<br>
        gst_base_sink_set_max_lateness( GST_BASE_SINK( mPipeline_AppSink
    ), -1 );<br>
    <br>
        // Set some fix caps for the video sink<br>
        // It would seem that GStreamer then tries to transform any
    incoming video stream according to these caps<br>
        GstCaps* caps = gst_caps_new_simple( "video/x-raw-rgb",<br>
            "bpp", G_TYPE_INT, 24,<br>
            "depth", G_TYPE_INT, 24,<br>
            "endianness", G_TYPE_INT, 4321,<br>
            "red_mask", G_TYPE_INT, 0xff0000,<br>
            "green_mask", G_TYPE_INT, 0x00ff00,<br>
            "blue_mask", G_TYPE_INT, 0x0000ff,<br>
            "alpha_mask", G_TYPE_INT, 0x000000ff,<br>
            NULL );<br>
    <br>
        gst_app_sink_set_caps( GST_APP_SINK( mPipeline_AppSink ), caps
    );<br>
        gst_caps_unref( caps );<br>
    <br>
        // Set the configured video appsink to the main pipeline<br>
        //g_object_set( m_GstPipeline, "video-sink", m_GstVideoSink,
    (void*) NULL );<br>
    <br>
        // Tell the video appsink that it should not emit signals as the
    buffer retrieving is handled via callback methods<br>
        g_object_set( mPipeline_AppSink, "emit-signals", false, "sync",
    true, (void*) NULL );<br>
    <br>
        GstAppSinkCallbacks cbs; // Does this need to be kept alive?<br>
    <br>
        // Set Video Sink callback methods<br>
        cbs.eos = &GSCinderApp::onEosFromVideoSource;<br>
        cbs.new_preroll = &GSCinderApp::onNewPrerollFromVideoSource;<br>
        cbs.new_sample = &GSCinderApp::onNewBufferFromVideoSource;<br>
        gst_app_sink_set_callbacks( GST_APP_SINK( mPipeline_AppSink ),
    &cbs, this, NULL );<br>
    <br>
    <br>
       
    //////////////////////////////////////////////////////////////////////////
    BUS<br>
        // Set GstBus<br>
        //m_GstBus = gst_pipeline_get_bus( GST_PIPELINE( m_GstPipeline )
    );<br>
    <br>
        if ( mGstPipeline != NULL )<br>
        {<br>
            // We need to stream the file a little bit in order to be
    able to retrieve information from it<br>
            GstStateChangeReturn nStateChgRet;<br>
    <br>
            nStateChgRet = gst_element_set_state( mGstPipeline,
    GST_STATE_READY );<br>
            printErrorToConsole( nStateChgRet ==
    GST_STATE_CHANGE_FAILURE, "GStreamer Error: State Change Failure 1"
    );<br>
    <br>
            nStateChgRet = gst_element_set_state( mGstPipeline,
    GST_STATE_PAUSED );<br>
            printErrorToConsole( nStateChgRet ==
    GST_STATE_CHANGE_FAILURE, "GStreamer Error: State Change Failure 1"
    );<br>
    <br>
            // For some reason this is needed in order to gather video
    information such as size, framerate etc ...<br>
            GstState state;<br>
            gst_element_get_state( mGstPipeline, &state, NULL, 2 *
    GST_SECOND );        // Erm... Why get state?<br>
    <br>
        }<br>
        else {<br>
            printErrorToConsole( true, "GStreamer Error: Pipeline
    Empty?!" );<br>
        }<br>
    <br>
        // Retrieve and store all relevant Media Information<br>
        //retrieveVideoInfo();<br>
    <br>
        // Check if we actually end up playing?<br>
        if ( mGstPipeline != NULL )<br>
        {<br>
            GstStateChangeReturn nStateChgRet;<br>
            nStateChgRet = gst_element_set_state( mGstPipeline,
    GST_STATE_PAUSED );<br>
            printErrorToConsole( nStateChgRet ==
    GST_STATE_CHANGE_FAILURE, "GStreamer Error: State Change Failure 3"
    );<br>
    <br>
        }<br>
        else {<br>
            printErrorToConsole( true, "GStreamer Error: Pipeline
    Empty?!" );<br>
        }<br>
    <br>
    ----------------<br>
    <br>
    Regards,<br>
    Lasse<br>
    <br>
    <div class="moz-signature">-- <br>
      Lasse Farnung Laursen<br>
      Post.doc at the University of Tokyo<br>
      <a href="http://www.lasselaursen.com">www.lasselaursen.com</a><br>
      FB: <a href="https://www.facebook.com/lasse.laursen">lasse.laursen
      </a><br>
      Twitter: <a href="https://twitter.com/PMP_J">@PMP_J</a></div>
  </body>
</html>