Grabbing video frames via Appsink

Lasse Laursen lasse at lasselaursen.com
Fri Aug 1 05:37:07 PDT 2014


Hey Dev's,

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.

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?

Have I perhaps not hooked something up correctly? What am I missing here?

Below is my simple code for trying to hook up this simple pipeline and 
grab some frames.

---------

     std::string launchString = "uridecodebin uri=" + mVideoFileName + " 
! appsink name=sink";

     mGstPipeline = gst_parse_launch( launchString.c_str(), &pstGErr1 );
     printErrorToConsole( pstGErr1 != nullptr, "GStreamer Error: Could 
not construct pipeline", pstGErr1 );


     GstElement *mPipeline_AppSink;
     mPipeline_AppSink = gst_bin_get_by_name( GST_BIN( mGstPipeline ), 
"sink" );

////////////////////////////////////////////////////////////////////////// 
VIDEO SINK
     // Config Video Sink
     gst_base_sink_set_sync( GST_BASE_SINK( mPipeline_AppSink ), true );
     gst_app_sink_set_max_buffers( GST_APP_SINK( mPipeline_AppSink ), 8 );
     gst_app_sink_set_drop( GST_APP_SINK( mPipeline_AppSink ), true );
     gst_base_sink_set_max_lateness( GST_BASE_SINK( mPipeline_AppSink ), 
-1 );

     // Set some fix caps for the video sink
     // It would seem that GStreamer then tries to transform any 
incoming video stream according to these caps
     GstCaps* caps = gst_caps_new_simple( "video/x-raw-rgb",
         "bpp", G_TYPE_INT, 24,
         "depth", G_TYPE_INT, 24,
         "endianness", G_TYPE_INT, 4321,
         "red_mask", G_TYPE_INT, 0xff0000,
         "green_mask", G_TYPE_INT, 0x00ff00,
         "blue_mask", G_TYPE_INT, 0x0000ff,
         "alpha_mask", G_TYPE_INT, 0x000000ff,
         NULL );

     gst_app_sink_set_caps( GST_APP_SINK( mPipeline_AppSink ), caps );
     gst_caps_unref( caps );

     // Set the configured video appsink to the main pipeline
     //g_object_set( m_GstPipeline, "video-sink", m_GstVideoSink, 
(void*) NULL );

     // Tell the video appsink that it should not emit signals as the 
buffer retrieving is handled via callback methods
     g_object_set( mPipeline_AppSink, "emit-signals", false, "sync", 
true, (void*) NULL );

     GstAppSinkCallbacks cbs; // Does this need to be kept alive?

     // Set Video Sink callback methods
     cbs.eos = &GSCinderApp::onEosFromVideoSource;
     cbs.new_preroll = &GSCinderApp::onNewPrerollFromVideoSource;
     cbs.new_sample = &GSCinderApp::onNewBufferFromVideoSource;
     gst_app_sink_set_callbacks( GST_APP_SINK( mPipeline_AppSink ), 
&cbs, this, NULL );


////////////////////////////////////////////////////////////////////////// 
BUS
     // Set GstBus
     //m_GstBus = gst_pipeline_get_bus( GST_PIPELINE( m_GstPipeline ) );

     if ( mGstPipeline != NULL )
     {
         // We need to stream the file a little bit in order to be able 
to retrieve information from it
         GstStateChangeReturn nStateChgRet;

         nStateChgRet = gst_element_set_state( mGstPipeline, 
GST_STATE_READY );
         printErrorToConsole( nStateChgRet == GST_STATE_CHANGE_FAILURE, 
"GStreamer Error: State Change Failure 1" );

         nStateChgRet = gst_element_set_state( mGstPipeline, 
GST_STATE_PAUSED );
         printErrorToConsole( nStateChgRet == GST_STATE_CHANGE_FAILURE, 
"GStreamer Error: State Change Failure 1" );

         // For some reason this is needed in order to gather video 
information such as size, framerate etc ...
         GstState state;
         gst_element_get_state( mGstPipeline, &state, NULL, 2 * 
GST_SECOND );        // Erm... Why get state?

     }
     else {
         printErrorToConsole( true, "GStreamer Error: Pipeline Empty?!" );
     }

     // Retrieve and store all relevant Media Information
     //retrieveVideoInfo();

     // Check if we actually end up playing?
     if ( mGstPipeline != NULL )
     {
         GstStateChangeReturn nStateChgRet;
         nStateChgRet = gst_element_set_state( mGstPipeline, 
GST_STATE_PAUSED );
         printErrorToConsole( nStateChgRet == GST_STATE_CHANGE_FAILURE, 
"GStreamer Error: State Change Failure 3" );

     }
     else {
         printErrorToConsole( true, "GStreamer Error: Pipeline Empty?!" );
     }

----------------

Regards,
Lasse

-- 
Lasse Farnung Laursen
Post.doc at the University of Tokyo
www.lasselaursen.com <http://www.lasselaursen.com>
FB: lasse.laursen <https://www.facebook.com/lasse.laursen>
Twitter: @PMP_J <https://twitter.com/PMP_J>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20140801/67a0ce6f/attachment.html>


More information about the gstreamer-devel mailing list