How to change appsrc caps dynamically ?
comicfans44
comicfans44 at gmail.com
Tue May 6 07:36:02 PDT 2014
Hello everyone, I'm using appsrc to push some raw video frame, frame size
is changing dynamically, so I must changing appsrc caps before differenct
size buffer pushed to it, I created a simple demo like this:
#include <stdlib.h>
#include <gst/gst.h>
#include <gst/app/gstappsrc.h>
#include <glib-object.h>
GstAppSrc *appsrc;
gboolean enough=FALSE;
int width=512;
int height=256;
GstCaps* create_caps(){
return gst_caps_new_simple("video/x-raw",
"format", G_TYPE_STRING, "RGBA",
"width", G_TYPE_INT, width,
"height", G_TYPE_INT, height,
"framerate", GST_TYPE_FRACTION, 60, 1,
"pixel-aspect-ratio",GST_TYPE_FRACTION,1,1,
NULL) ;
}
static void
start_feed (GstElement * appSrc, guint size, void *nouse)
{
enough=FALSE;
while(enough==FALSE){
int buf_size=width*height*4;
char *buf=malloc(buf_size);
int i=0;
static counter=0;
//random buffer
for(;i<buf_size;++i){ buf[i]=(i+counter)%256; }
GstBuffer *gst_buf=gst_buffer_new_wrapped(buf,buf_size);
gst_app_src_push_buffer(appsrc,gst_buf);
++counter;
//changing caps
if(counter%100==0){
height+=10;
GstCaps* new_caps=create_caps();
gst_app_src_set_caps(appsrc,new_caps);
}
}
}
static void
stop_feed (GstElement * pipeline, void * dynamicCapsPipeline)
{
enough=TRUE;
}
int main(int argc, char *argv[])
{
g_type_init();
gst_init(&argc,&argv);
appsrc=gst_element_factory_make("appsrc",NULL);
g_signal_connect (appsrc, "need-data", G_CALLBACK (start_feed), NULL);
g_signal_connect (appsrc, "enough-data", G_CALLBACK (stop_feed), NULL);
GstCaps* caps=create_caps();
gst_app_src_set_caps(appsrc,caps);
gst_caps_unref(caps);
GstElement *pipeline=gst_pipeline_new(NULL);
GstElement *convert=gst_element_factory_make("videoconvert",NULL);
GstElement *sink=gst_element_factory_make("ximagesink",NULL);
gst_bin_add_many(pipeline,appsrc,convert,sink,NULL);
gst_element_link_many(appsrc,convert,sink,NULL);
gst_element_set_state(pipeline,GST_STATE_PLAYING);
GMainLoop *main_loop=g_main_loop_new(NULL,FALSE);
g_main_loop_run(main_loop);
}
every times caps changing, there is error like :
default
../../../../gst-libs/gst/video/video-frame.c:152:gst_video_frame_map_id:
invalid buffer size 585728 < 606208
and video flicked (1~2 frame) . seems some buffer have not flushed before
caps changed complete. I tried to use
GstPad* pad=gst_element_get_static_pad(appSrc,"src");
GstEvent *flushStart=gst_event_new_flush_start();
GstEvent *flushStop=gst_event_new_flush_stop(TRUE/FALSE);
gst_pad_push_event(pad,flushStart);
gst_pad_push_event(pad,flushStop);
before set new caps to appsrc, but error still happened. if pipeline is
videotestsrc ! capsfilter ! videoconvert ! ximagesink
I can changing capsfilter caps with no problem .
how could I do similar within appsrc correctly? Thank you.
More information about the gstreamer-devel
mailing list