Re: Issue with rtsp server source h264 encoded

Michael Gruner via gstreamer-devel <[email protected]>
Newsgroups gmane.comp.video.gstreamer.devel
Message-ID <[email protected]>
Hi

Try sending periodic I frames, "x264enc key-int-max=10" or, programmatically:

>     g_object_set( lEncoder, "key-int-max", 10, NULL ); // 4 = zerolatency


10 is just a made up number to send a reference frame every second (given that your framerate is 10/1). You may space them according to your needs.

Michael.

> On 21 Sep 2023, at 09:59, LEVY David via gstreamer-devel <[email protected]> wrote:
> 
> Hello,
> i'm new to gstreamer / rtsp so, sorry if it's a basic mistake.
>  
> Im trying to set up a pipeline that end with an appsink that push data into a rtsp server starting with an appsrc.
>  
> It would be:
> videotestsrc -> x264enc -> appsink (push data to src as soon as received)
> and
> appsrc -> rtph264pay
>  
> I can’t find any example similar, but I found this one:
> https://github.com/GStreamer/gst-rtsp-server/blob/master/examples/test-appsrc.c
>  
> Which does:
> appsrc-> videoconvert -> x264enc -> rtph264pay (and uses “need-data”) 
>  
> I have successfully tweaked it to
> videotestsrc -> appsink
> appsrc-> videoconvert -> x264enc -> rtph264pay (and uses “need-data”)
>  
> My next step would be
> Videotestsrc -> x264enc -> appsink 
> appsrc-> rtph264pay (and uses “need-data”)
>  
> but when I try to read the stream from either 
>     gst-launch-1.0 --gst-debug=rtspsrc:2 rtspsrc location=rtsp://127.0.0.1:8554/test ! queue ! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! videoscale ! autovideosink
> or ffplay rtsp://127.0.0.1:8554/test
>  
> I don’t have any playback:
> 
> Setting pipeline to PAUSED ...
> Pipeline is live and does not need PREROLL ...
> Got context from element 'autovideosink0': gst.gl.GLDisplay=context, gst.gl.GLDisplay=(GstGLDisplay)"\(GstGLDisplayWayland\)\ gldisplaywayland0";
> Progress: (open) Opening Stream
> Pipeline is PREROLLED ...
> Prerolled, waiting for progress to finish...
> Progress: (connect) Connecting to rtsp://127.0.0.1:8554/test
> Progress: (open) Retrieving server options
> Progress: (open) Retrieving media info
> Progress: (request) SETUP stream 0
> Progress: (open) Opened Stream
> Setting pipeline to PLAYING ...
> New clock: GstSystemClock
> Progress: (request) Sending PLAY request
> Redistribute latency...
> Progress: (request) Sending PLAY request
> Redistribute latency...
> Progress: (request) Sent PLAY request
> Redistribute latency...
> Redistribute latency...
> 0:00:05.945770874 15996 0x55c83ec97f60 WARN                 rtspsrc gstrtspsrc.c:5964:gst_rtspsrc_reconnect:<rtspsrc0> warning: Could not receive any UDP packets for 5.0000 seconds, maybe your firewall is blocking it. Retrying using a tcp connection.
> WARNING: from element /GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0: Could not read from resource.
> Additional debug info:
> ../gst/rtsp/gstrtspsrc.c(5964): gst_rtspsrc_reconnect (): /GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0:
> Could not receive any UDP packets for 5.0000 seconds, maybe your firewall is blocking it. Retrying using a tcp connection.
> Redistribute latency...
>  
> And it is stuck here
> 
> I’m using the code below:
> 
> 
> #include <gst/gst.h>
>  
> #include <gst/app/gstappsink.h>
> #include <gst/app/gstappsrc.h>
> #include <gst/rtsp-server/rtsp-server.h>
>  
> GstElement *gSink = nullptr;
>  
> static void InitPipeline()
> {
>     GstElement *lPipeline = gst_pipeline_new( "x264-pipeline" );
>  
>     GstElement *lSource  = gst_element_factory_make( "videotestsrc", "source" );
>     GstElement *lEncoder = gst_element_factory_make( "x264enc", "x264-encoder" );
>     GstElement *lSink    = gst_element_factory_make( "appsink", "appsink" );
>  
>     gst_bin_add_many( GST_BIN( lPipeline ), lSource, lEncoder, lSink, NULL );
>     // gst_bin_add_many( GST_BIN( lPipeline ), lSource, lSink, NULL );
>     g_object_set( lEncoder, "tune", 4, NULL ); // 4 = zerolatency
>  
>     GstCaps *lCaps =
>         gst_caps_new_simple( "video/x-raw", "width", G_TYPE_INT, 384, "height", G_TYPE_INT, 288, "framerate", GST_TYPE_FRACTION, 10, 1, NULL );
>     if( !gst_element_link_filtered( lSource, lEncoder, lCaps ) )
>     // if( !gst_element_link_filtered( lSource, lSink, lCaps ) )
>     {
>         gst_caps_unref( lCaps );
>         throw;
>     }
>     gst_caps_unref( lCaps );
>     gst_element_link( lEncoder, lSink );
>  
>     GstStateChangeReturn ret = gst_element_set_state( lPipeline, GST_STATE_PLAYING );
>     if( ret == GST_STATE_CHANGE_FAILURE )
>     {
>         throw;
>     }
>     gSink = lSink;
> }
>  
> static void need_data( GstElement *appsrc, guint unused, void *aUnused )
> {
>     GstSample *lSample = gst_app_sink_pull_sample( GST_APP_SINK_CAST( gSink ) );
>     GstFlowReturn lRet = gst_app_src_push_sample( GST_APP_SRC( appsrc ), lSample );
>     gst_sample_unref( lSample );
>     return;
> }
>  
> static void media_configure( GstRTSPMediaFactory *factory, GstRTSPMedia *media, gpointer user_data )
> {
>     GstElement *element, *appsrc;
>  
>     element = gst_rtsp_media_get_element( media );
>     appsrc = gst_bin_get_by_name_recurse_up( GST_BIN( element ), "mysrc" );
>  
>     gst_util_set_object_arg( G_OBJECT( appsrc ), "format", "time" );
>  
>     if( GstPad *pad = gst_element_get_static_pad( gSink, "sink" ) )
>     {
>         g_print( "Got pad\n" );
>         GstCaps *caps = gst_pad_get_current_caps( pad );
>         if( caps )
>         {
>             auto *caps_str = gst_caps_to_string( caps );
>             g_print( "Got caps %s\n", caps_str );
>             g_object_set( G_OBJECT( appsrc ), "caps", caps, NULL );
>  
>             gst_caps_unref( caps );
>         }
>     }
>  
>     g_signal_connect( appsrc, "need-data", (GCallback)need_data, NULL );
>     gst_object_unref( appsrc );
>     gst_object_unref( element );
> }
>  
> int main( int argc, char *argv[] )
> {
>     GMainLoop *loop;
>     GstRTSPServer *server;
>     GstRTSPMountPoints *mounts;
>     GstRTSPMediaFactory *factory;
>  
>     gst_init( &argc, &argv );
>  
>     loop = g_main_loop_new( NULL, FALSE );
>  
>     InitPipeline();
>  
>     server = gst_rtsp_server_new();
>     mounts = gst_rtsp_server_get_mount_points( server );
>     factory = gst_rtsp_media_factory_new();
>  
>     // gst_rtsp_media_factory_set_launch( factory, "( appsrc name=mysrc ! videoconvert ! x264enc ! rtph264pay name=pay0 pt=96 )" );
>     gst_rtsp_media_factory_set_launch( factory, "( appsrc name=mysrc ! rtph264pay name=pay0 pt=96 )" );
>  
>     g_signal_connect( factory, "media-configure", (GCallback)media_configure, NULL );
>     gst_rtsp_mount_points_add_factory( mounts, "/test", factory );
>     g_object_unref( mounts );
>  
>     gst_rtsp_server_attach( server, NULL );
>  
>     g_print( "stream ready at rtsp://127.0.0.1:8554/test <rtsp://127.0.0.1:8554/test\n>\n <rtsp://127.0.0.1:8554/test\n>" );
>     g_main_loop_run( loop );
>  
>     return 0;
> }
>  
>  
> Is it a good idea to convert before the appsink?
>  
> Thanks for your time
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.