Grabbing video frames via Appsink

Tim Müller tim at centricular.com
Thu Aug 7 15:47:19 PDT 2014


On Sat, 2014-08-02 at 00:04 +0900, Lasse Laursen wrote:

> But to clarify, no - none of the callback functions are ever called.
> The pipeline just doesn't seem to start.

Do you get an error message on the pipeline's bus?

Are you using 1.x or 0.10? Your caps are 0.10-specific raw video caps,
they will need to look different in 1.x.

http://cgit.freedesktop.org/gstreamer/gst-plugins-base/tree/tests/examples/snapshot/snapshot.c

Has an example that looks pretty similar to yours.

Cheers
 -Tim


> On 01-08-2014 23:48, Dušan Poizl wrote:
> 
> > GST_STATE_CHANGE_ASYNC is ok. it means that pipeline doesn't
> > finished changing state before gst_element_set_state() return. whole
> > pipeline run in separate thread. when you get state you practically
> > wait until pipeline finish transition to desired state. so check in
> > which state return gst_element_get_state() and does your callbacks
> > end up called?
> > 
> > Dňa 01.08.2014 o 14:37 Lasse Laursen napísal(a):
> > 
> > > 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
> > > FB: lasse.laursen 
> > > Twitter: @PMP_J
> > > 
> > > 
> > > _______________________________________________
> > > gstreamer-devel mailing list
> > > gstreamer-devel at lists.freedesktop.org
> > > http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
> > 
> > 
> > 
> > _______________________________________________
> > gstreamer-devel mailing list
> > gstreamer-devel at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
> 
> -- 
> Lasse Farnung Laursen
> Post.doc at the University of Tokyo
> www.lasselaursen.com
> FB: lasse.laursen 
> Twitter: @PMP_J
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

-- 
Tim Müller, Centricular Ltd - http://www.centricular.com



More information about the gstreamer-devel mailing list