Grabbing video frames via Appsink
Dušan Poizl
poizl at maindata.sk
Fri Aug 1 07:48:50 PDT 2014
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 <http://www.lasselaursen.com>
> FB: lasse.laursen <https://www.facebook.com/lasse.laursen>
> Twitter: @PMP_J <https://twitter.com/PMP_J>
>
>
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20140801/e46bd24e/attachment-0001.html>
More information about the gstreamer-devel
mailing list