Last active
September 2, 2021 03:21
-
-
Save SJRyu/eea639495e9750f7133d8834e3a9c4d7 to your computer and use it in GitHub Desktop.
GST rtspsrc example, bug on windows
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*** | |
https://bugzilla.gnome.org/show_bug.cgi?id=756818 | |
***/ | |
#include <gst/gst.h> | |
#include <gst/app/gstappsink.h> | |
#include <gst/gstpad.h> | |
#include <gst/rtsp/gstrtsp.h> | |
typedef struct myDataTag { | |
GstElement *pipeline; | |
GstElement *rtspsrc; | |
GstElement *depayloader; | |
GstElement *decoder; | |
GstElement *sink; | |
} myData_t; | |
myData_t appData; | |
static void pad_added_handler(GstElement *src, GstPad *new_pad, myData_t *pThis) | |
{ | |
GstPad *sink_pad = gst_element_get_static_pad(pThis->depayloader, "sink"); | |
GstPadLinkReturn ret; | |
GstCaps *new_pad_caps = NULL; | |
GstStructure *new_pad_struct = NULL; | |
const gchar *new_pad_type = NULL; | |
g_print("Received new pad '%s' from '%s':\n", GST_PAD_NAME(new_pad), GST_ELEMENT_NAME(src)); | |
/* Check the new pad's name */ | |
if (!g_str_has_prefix(GST_PAD_NAME(new_pad), "recv_rtp_src_")) { | |
g_print(" It is not the right pad. Need recv_rtp_src_. Ignoring.\n"); | |
goto exit; | |
} | |
/* If our converter is already linked, we have nothing to do here */ | |
if (gst_pad_is_linked(sink_pad)) { | |
g_print(" Sink pad from %s already linked. Ignoring.\n", GST_ELEMENT_NAME(src)); | |
goto exit; | |
} | |
/* Check the new pad's type */ | |
new_pad_caps = gst_pad_query_caps(new_pad, NULL); | |
new_pad_struct = gst_caps_get_structure(new_pad_caps, 0); | |
new_pad_type = gst_structure_get_name(new_pad_struct); | |
/* Attempt the link */ | |
ret = gst_pad_link(new_pad, sink_pad); | |
if (GST_PAD_LINK_FAILED(ret)) { | |
g_print(" Type is '%s' but link failed.\n", new_pad_type); | |
} | |
else { | |
g_print(" Link succeeded (type '%s').\n", new_pad_type); | |
} | |
exit: | |
/* Unreference the new pad's caps, if we got them */ | |
if (new_pad_caps != NULL) | |
gst_caps_unref(new_pad_caps); | |
/* Unreference the sink pad */ | |
gst_object_unref(sink_pad); | |
} | |
static gboolean select_stream_callback( | |
GstElement *rtspsrc, guint num, | |
GstCaps *caps, gpointer udata) | |
{ | |
g_print("connected stream %d from %s \n", | |
num, GST_ELEMENT_NAME(rtspsrc)); | |
int size = gst_caps_get_size(caps); | |
g_print("caps size = %d \n", size); | |
if (size > 0) | |
{ | |
const GstStructure* structure = gst_caps_get_structure(caps, 0); | |
g_print("parse first sturcture %s has %d fields \n", | |
gst_structure_get_name(structure), gst_structure_n_fields(structure)); | |
gchar* rstructure = gst_structure_to_string(structure); | |
g_print("%s \n", rstructure); | |
g_print("\n"); | |
#if 0 | |
for (int i = 0; i < gst_structure_n_fields(structure); i++) | |
{ | |
const char* fieldName = gst_structure_nth_field_name(structure, i); | |
const GValue* gval = gst_structure_get_value(); | |
g_print("%d) %s \n", i, fieldName); | |
} | |
#endif | |
} | |
return true; | |
} | |
int main(int argc, char *argv[]) | |
{ | |
GstBus *bus; | |
GstMessage *msg; | |
GstStateChangeReturn ret; | |
gst_init(NULL, NULL); | |
appData.pipeline = gst_pipeline_new("videoclient"); | |
appData.rtspsrc = gst_element_factory_make("rtspsrc", "rtspsrc"); | |
g_object_set( | |
G_OBJECT(appData.rtspsrc), | |
"location", | |
"rtsp://192.168.0.3:554/Streaming/Channels/101?transportmode=unicast&profile=Profile_1", | |
NULL); | |
g_object_set(G_OBJECT(appData.rtspsrc), "user-id", "admin", "user-pw", "passwd", NULL); | |
g_object_set(G_OBJECT(appData.rtspsrc), "udp-buffer-size", 2097152, NULL); | |
g_object_set(G_OBJECT(appData.rtspsrc), "udp-reconnect", false, NULL); | |
/*** | |
rsj: | |
UDP bug... Invalid pointer address | |
https://bugzilla.gnome.org/show_bug.cgi?id=756818 | |
***/ | |
g_object_set(G_OBJECT(appData.rtspsrc), "protocols", GST_RTSP_LOWER_TRANS_TCP, NULL); | |
g_object_set(G_OBJECT(appData.rtspsrc), "timeout", 500000, NULL); | |
appData.depayloader = gst_element_factory_make("rtph264depay", "depayloader"); | |
appData.decoder = gst_element_factory_make("avdec_h264", "h264-decoder"); | |
appData.sink = gst_element_factory_make("autovideosink", "sink"); | |
//then add all elements together | |
gst_bin_add_many(GST_BIN(appData.pipeline), | |
appData.rtspsrc, appData.depayloader, appData.decoder, appData.sink, NULL); | |
//link everythink after source | |
gst_element_link_many(appData.depayloader, appData.decoder, appData.sink, NULL); | |
//just for debug | |
g_signal_connect(appData.rtspsrc, "select-stream", G_CALLBACK(select_stream_callback), NULL); | |
/* | |
* Connect to the pad-added signal for the rtpbin. This allows us to link | |
* the dynamic RTP source pad to the depayloader when it is created. | |
*/ | |
g_signal_connect(appData.rtspsrc, "pad-added", G_CALLBACK(pad_added_handler), &appData); | |
/* Set the pipeline to "playing" state*/ | |
ret = gst_element_set_state(appData.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(appData.pipeline); | |
return -1; | |
} | |
/* Wait until error or EOS */ | |
bus = gst_element_get_bus(appData.pipeline); | |
msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, (GstMessageType)(GST_MESSAGE_ERROR | GST_MESSAGE_EOS)); | |
/* Parse message */ | |
if (msg != NULL) { | |
GError *err; | |
gchar *debug_info; | |
switch (GST_MESSAGE_TYPE(msg)) { | |
case GST_MESSAGE_ERROR: | |
gst_message_parse_error(msg, &err, &debug_info); | |
g_printerr("Error received from element %s: %s\n", GST_OBJECT_NAME(msg->src), err->message); | |
g_printerr("Debugging information: %s\n", debug_info ? debug_info : "none"); | |
g_clear_error(&err); | |
g_free(debug_info); | |
break; | |
case GST_MESSAGE_EOS: | |
g_print("End-Of-Stream reached.\n"); | |
break; | |
default: | |
/* We should not reach here because we only asked for ERRORs and EOS */ | |
g_printerr("Unexpected message received.\n"); | |
break; | |
} | |
gst_message_unref(msg); | |
} | |
/* Free resources */ | |
gst_object_unref(bus); | |
gst_element_set_state(appData.pipeline, GST_STATE_NULL); | |
gst_object_unref(appData.pipeline); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment