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