Grabbing video frames via Appsink

Lasse Laursen lasse at lasselaursen.com
Fri Aug 8 03:29:13 PDT 2014


Hey Dusan and Tim,

I solved the problem by leaning more heavily on some previously created 
code. I intend to share it to help others in the form of an 
easy-to-follow instruction set :)

Tim - I think you were right that I was mixing some 0.10 and 1.0 stuffs :E

Much appreciate the answers!

Lasse

On 08-08-2014 07:47, Tim Müller wrote:
> 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

-- 
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/20140808/9935cb51/attachment.html>


More information about the gstreamer-devel mailing list