Hi all!
Now i need to play udp stream on my imx6 boards and show image(logo) when no data on port. Server:gst-launch-1.0 -v filesrc location=/video/0001.mp4 ! decodebin ! vpuenc_h264 bitrate=8192 ! rtph264pay ! udpsink host=192.168.5.255 port=5555Client (C code):#define GST_PLAYER_UDP "udpsrc port=5555 caps=\"application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)96\"\ ! rtph264depay ! decodebin ! videoconvert ! autovideosink" .... static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data) { printf("msg=%s (from %s)\n",gst_message_type_get_name(GST_MESSAGE_TYPE(msg)), GST_MESSAGE_SRC_NAME(msg)); return TRUE; } ... GstElement* gstLaunch() { GstElement *pipeline; GError *error = NULL; pipeline = gst_parse_launch (GST_PLAYER_UDP, &error); if (!pipeline){ g_print ("\tParse error: %s\n", error->message); return 0; } gst_element_set_state (pipeline, GST_STATE_PLAYING); GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); guint watch_id = gst_bus_add_watch (bus, bus_call, NULL); gst_object_unref (bus); return pipeline; } ----------------------------------------------------------------------------------------------- When i start streaming all work fine and i can see when streamig start: display(/dev/fb0) resolution is (1280x800). ====== OVERLAYSINK: 4.0.9 build on May 12 2017 10:36:47. ====== display(/dev/fb0) resolution is (1280x800). display(/dev/fb0) resolution is (1280x800). msg=state-changed (from autovideosink0) msg=state-changed (from videoconvert0) msg=state-changed (from typefind) msg=state-changed (from decodebin0) msg=state-changed (from rtph264depay0) msg=state-changed (from udpsrc0) msg=state-changed (from pipeline0) msg=state-changed (from videoconvert0) msg=state-changed (from typefind) msg=state-changed (from rtph264depay0) msg=stream-status (from src) msg=state-changed (from udpsrc0) msg=state-changed (from pipeline0) msg=stream-status (from src) msg=new-clock (from pipeline0) msg=state-changed (from videoconvert0) msg=state-changed (from rtph264depay0) msg=state-changed (from udpsrc0) msg=state-changed (from h264parse0) msg=state-changed (from h264parse0) [INFO] Product Info: i.MX6Q/D/S msg=state-changed (from vpudec0) [INFO] Product Info: i.MX6Q/D/S ====== VPUDEC: 4.0.9 build on May 12 2017 10:36:53. ====== wrapper: 1.0.65 (VPUWRAPPER_ARM_LINUX Build on May 12 2017 10:30:05) vpulib: 5.4.33 firmware: 3.1.1.46072 msg=state-changed (from vpudec0) [INFO] bitstreamMode 1, chromaInterleave 1, mapType 0, tiled2LinearEnable 0 msg=state-changed (from decodebin0) msg=stream-start (from pipeline0)msg=state-changed (from autovideosink0-actual-sink-overlay)msg=state-changed (from autovideosink0) msg=async-done (from pipeline0) msg=state-changed (from autovideosink0-actual-sink-overlay) msg=state-changed (from autovideosink0) msg=state-changed (from vpudec0) msg=state-changed (from capsfilter0) msg=state-changed (from h264parse0) msg=state-changed (from typefind) msg=state-changed (from decodebin0) msg=state-changed (from pipeline0) msg=qos (from autovideosink0-actual-sink-overlay) msg=tag (from autovideosink0-actual-sink-overlay) but when file play all or server not available there is no message on bus What should I do to understand that the video data is not received by the client(and i need to show splashscreen)?? PS please, help! I spent a lot of time and start despair... |
Administrator
|
This post was updated on .
Looks like your using c++ so this is what is in c++. maybe this will give you at least a start. maybe even work. I don't understand what your saying is wrong. if its not playing or just doesn't quit after the video is done or what but this might work for a template for ya. you can play around with the debug function by replacing the number(max 5). the higher you go the more stuff you get. I don't usually use past 3 or 4.
#include <gst/gst.h> #include <iostream> /************* global values ***** ***********/ GstElement *pipeline; GMainLoop *loop; GstBus *bus; GstMessage* msg; GstStateChangeReturn ret; #define GST_PLAYER_UDP "udpsrc port=5555 caps=\"application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)96\"\ ! rtph264depay ! decodebin ! videoconvert ! autovideosink" static gboolean bus_cb (GstBus *bus, GstMessage *msg, gpointer *data); int main() { //debug level 1,2,3,4,5 gst_debug_set_threshold_from_string("*:3",TRUE); /* Initialize GStreamer */ gst_init (NULL,NULL); /* Build the pipeline */ pipeline = gst_parse_launch (GST_PLAYER_UDP, NULL); bus = gst_element_get_bus (pipeline); /* Start playing */ ret = gst_element_set_state (pipeline, GST_STATE_PLAYING); if (ret == GST_STATE_CHANGE_FAILURE) { g_printerr ("Unable to set the pipeline to the playing state.\n"); gst_object_unref (pipeline); return -1; } loop = g_main_loop_new (NULL, FALSE); gst_bus_add_signal_watch (bus); g_signal_connect (bus, "message", G_CALLBACK (bus_cb),NULL); g_main_loop_run (loop); /* Free resources */ g_main_loop_unref (loop); gst_object_unref (bus); gst_element_set_state (pipeline, GST_STATE_NULL); gst_object_unref (pipeline); return 0; } /********************** bus method ******************/ gboolean bus_cb (GstBus *bus, GstMessage *msg, gpointer *data) { switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_ERROR: { GError *err; gchar *debug; gst_message_parse_error (msg, &err, &debug); g_print ("Error: %s\n", err->message); g_error_free (err); g_free (debug); gst_element_set_state (pipeline, GST_STATE_READY); g_main_loop_quit (loop); return FALSE; } case GST_MESSAGE_EOS: /* end-of-stream */ gst_element_set_state (pipeline, GST_STATE_READY); g_main_loop_quit (loop); return FALSE; default: /* Unhandled message */ break; } return TRUE; }
------------------------------
Gstreamer 1.16.2 ------------------------------ Windows |
Thanks for the answer!
The video is played perfectly. My problem is that after the server has finished broadcasting I have no information that this happened. There are no messages on bus_сb and I do not have a chance to understand that I have to ыуе the splash screen and wait for the video to be played again. |
You mean at the receiving side? Since you are using UDP, there is no way of knowing when the stream has stopped except for waiting for a data timeout (and even in that case, that timeout could have happened due to a temporary interrupted connection) |
This post was updated on .
Yes, on the receiver side. Really in my pipeline there is no element that can give me information that the video is not currently playing?
|
All you can do afaik is adding a buffer probe on the udpsrc src-pad and track is data is flowing. Udp is connection-less, so there is no connection-close when the stream has ended. You could communicate the end of transmission over the top, or perhaps you can piggyback a magic marker in the udp stream signalling the end of stream.
|
Administrator
|
In reply to this post by Yaroslav
edited the code from what i gave you and may be that state change will give you a pause or ready or something. then maybe if it goes to paused 10 times and it will quit the loop.
/************* global values ***** ***********/ GstElement *pipeline; GMainLoop *loop; GstBus *bus; GstMessage* msg; GstState* state; #define GST_PLAYER_UDP "udpsrc port=5555 caps=\"application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)96\"\ ! rtph264depay ! decodebin ! videoconvert ! autovideosink" static gboolean bus_cb (GstBus *bus, GstMessage *msg, gpointer *data); int main() { /* Initialize GStreamer */ gst_init (&argc, &argv); /* Build the pipeline */ pipeline = gst_parse_launch (GST_PLAYER_UDP, &error); if (!pipeline){ g_print ("\tParse error: %s\n", error->message); return 0; } loop = g_main_loop_new (NULL, FALSE); /* Start playing */ gst_element_set_state (pipeline, GST_STATE_PLAYING); /* Wait until error or EOS */ bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); if(bus == NULL) { std::cout << "\nNo Bus\n"; return 0; } gst_bus_add_signal_watch(bus); g_signal_connect (bus, "message", G_CALLBACK (bus_cb), this->apPipeline); g_timeout_add_seconds (1, timeout_cb, loop); g_main_loop_run(loop); /* Free resources */ gst_object_unref (bus); gst_element_set_state (pipeline, GST_STATE_NULL); gst_object_unref (pipeline); } /********************** bus method ******************/ gboolean bus_cb (GstBus *bus, GstMessage *msg, gpointer *data) { switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_ERROR: { GError *err; gchar *debug; gst_message_parse_error (msg, &err, &debug); g_print ("Error: %s\n", err->message); g_error_free (err); g_free (debug); gst_element_set_state (pipeline, GST_STATE_READY); g_main_loop_quit (loop); return FALSE; } case GST_MESSAGE_EOS: /* end-of-stream */ gst_element_set_state (pipeline, GST_STATE_READY); g_main_loop_quit (loop); return FALSE; case GST_MESSAGE_STATE_CHANGED: { GstElement* source = gst_bin_get_by_name(GST_BIN(pipeline),"source"); if (GST_MESSAGE_SRC (msg) == GST_OBJECT(source)) { GstState old_state, new_state, pending_state; gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state); std::string oldstate(gst_element_state_get_name (old_state)); std::string newstate(gst_element_state_get_name (new_state)); std::string changestate = "Pipeline state changed from "+oldstate+" to " + newstate; std::cout << changestate; state = new_state; gst_object_unref(source); } break; default: /* Unhandled message */ break; } return TRUE; } gboolean PipelineClass::timeout_cb (gpointer user_data) { static int time = 0; static int timeout = 0; int MaxTimeout = 10; switch (state) { case GST_STATE_READY: { std::cout << "STATE Ready"; } case GST_STATE_PLAYING: { std::cout << "STATE Playing": timeout = 0; } break; case GST_STATE_PAUSED: { std::cout << "STATE Paused": if(timeout == MaxTimeout) { g_main_loop_quit(loop); } timeout++; break; } case GST_STATE_NULL: std::cout << "STATE Null": return FALSE; default: break; } return TRUE; }
------------------------------
Gstreamer 1.16.2 ------------------------------ Windows |
Thank you very much for your help, but this also does not work. Even when the stream does not exist, that state does not change.
STATE Ready STATE Playing STATE Ready STATE Playing .... STATE Ready STATE Playing |
Administrator
|
you might have to do some c++ application on the server side. i'll probably use the same pipeline you have and try for myself. see if I can figure it out.
------------------------------
Gstreamer 1.16.2 ------------------------------ Windows |
Administrator
|
In reply to this post by Yaroslav
okay I have figured it out and sending the link to the .cpp file.
UdpVideoPlayer.cpp this will tee the rtph264depay and go to the autovideosink then go to the appsink. as the appsink get buffer it will make a count for the appsinkCount. I have a preAppsinkCount the see if appsinkCount equals preAppsinkCount. if they are both same 4 times it will quit the application. finding: checking the appsinkCount to preAppsinkCount in timeout_cb function appsinkCount is counting in appsink_signal function appsinkCount and preAppsinkCount declared global at top. ImmediateLoopQuit function will g_main_quit(loop); I hope this works.
------------------------------
Gstreamer 1.16.2 ------------------------------ Windows |
It's work!!!!!!!!!!!!!!!!!! thanks a lot!!!!
I am infinitely grateful to you for your help. |
Administrator
|
glad it helped. there is probably a better way to do it.
------------------------------
Gstreamer 1.16.2 ------------------------------ Windows |
Free forum by Nabble | Edit this page |