C code for rtp h264 decoding. I can't find how to solve the error. Read is insteresting

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

C code for rtp h264 decoding. I can't find how to solve the error. Read is insteresting

giorgino
Hi All.
I have two pc where one is the sender and the other the receiver. In the sender I use this pipe

gst-launch -v gstrtpbin name=rtpbin v4l2src ! video/x-raw-yuv,width=320,height=240! queue ! videorate ! ffmpegcolorspace ! x264enc byte-stream=true bitrate=300 ! rtph264pay ! rtpbin.send_rtp_sink_0 rtpbin.send_rtp_src_0 ! udpsink port=5000 host=192.168.100.196 ts-offset=0 name=vrtpsink rtpbin.send_rtcp_src_0 ! udpsink port=5001 host=192.168.100.196 sync=false async=false name=vrtcpsink udpsrc port=5005 name=vrtpsrc ! rtpbin.recv_rtcp_sink_0

and it works well. If in the receiver I use the following pipe the receiver works well

st-launch -v gstrtpbin name=rtpbin latency=200 udpsrc caps=application/x-rtp,media=video,clock-rate=90000,encoding-name=H264 port=5000 ! rtpbin.recv_rtp_sink_0 rtpbin. ! rtph264depay ! ffdec_h264 ! ffmpegcolorspace ! autovideosink udpsrc port=5001 ! rtpbin.recv_rtcp_sink_0 rtpbin.send_rtcp_src_0 ! udpsink port=5005 host=127.0.0.1 sync=false async=false

Now I need to map this pipe into a C file and I use the following source

#include <string.h>
#include <math.h>

#include <gst/gst.h>

/* the caps of the sender RTP stream. This is usually negotiated out of band with
 * SDP or RTSP. */
#define VIDEO_CAPS "application/x-rtp,media=(string)video,clock-rate=(int)9000,encoding-name=(string)H264"
//#define VIDEO_CAPS "application/x-rtp,media=video,clock-rate=9000,encoding-name=H264"

#define VIDEO_DEPAY "rtph264depay"
#define VIDEO_DEC   "ffdec_h264"
#define VIDEO_SINK  "autovideosink"

/* the destination machine to send RTCP to. This is the address of the sender and
 * is used to send back the RTCP reports of this receiver. If the data is sent
 * from another machine, change this address. */
#define DEST_HOST "127.0.0.1"

/* print the stats of a source */
static void print_source_stats (GObject * source) {
  GstStructure *stats;
  gchar *str;

  g_return_if_fail (source != NULL);

  /* get the source stats */
  g_object_get (source, "stats", &stats, NULL);

  /* simply dump the stats structure */
  str = gst_structure_to_string (stats);
  g_print ("source stats: %s\n", str);

  gst_structure_free (stats);
  g_free (str);
}

/* will be called when gstrtpbin signals on-ssrc-active. It means that an RTCP
 * packet was received from another source. */
static void on_ssrc_active_cb (GstElement * rtpbin, guint sessid, guint ssrc, GstElement * depay) {

    GObject *session, *isrc, *osrc;
    g_print ("got RTCP from session %u, SSRC %u\n", sessid, ssrc);

  /* get the right session */
  g_signal_emit_by_name (rtpbin, "get-internal-session", sessid, &session);

  /* get the internal source (the SSRC allocated to us, the receiver */
  g_object_get (session, "internal-source", &isrc, NULL);
  print_source_stats (isrc);

  /* get the remote source that sent us RTCP */
  g_signal_emit_by_name (session, "get-source-by-ssrc", ssrc, &osrc);
  print_source_stats (osrc);
}

/* will be called when rtpbin has validated a payload that we can depayload */
static void
pad_added_cb (GstElement * rtpbin, GstPad * new_pad, GstElement * depay)
{
  GstPad *sinkpad;
  GstPadLinkReturn lres;

  g_print ("new payload on pad: %s\n", GST_PAD_NAME (new_pad));

  sinkpad = gst_element_get_static_pad (depay, "sink");
  g_assert (sinkpad);

  lres = gst_pad_link (new_pad, sinkpad);
  g_assert (lres == GST_PAD_LINK_OK);
  gst_object_unref (sinkpad);

}


int main (int argc, char *argv[])
{
  GstElement *rtpbin, *rtpsrc, *rtcpsrc, *rtcpsink;
  GstElement *videodepay,
             *videodec,
             //*videores,
             *videoconv,
             *videosink;

  GstElement *pipeline;
  GMainLoop *loop;
  GstCaps *caps;
  gboolean res;
  GstPadLinkReturn lres;
  GstPad *srcpad, *sinkpad;

  /* always init first */
  gst_init (&argc, &argv);

  /* the pipeline to hold everything */
  pipeline = gst_pipeline_new (NULL);
  g_assert (pipeline);

  /* the udp src and source we will use for RTP and RTCP */
  rtpsrc = gst_element_factory_make ("udpsrc", "rtpsrc");
  g_assert (rtpsrc);
  g_object_set (rtpsrc, "port", 5000, NULL);
  /* we need to set caps on the udpsrc for the RTP data */
  caps = gst_caps_from_string (VIDEO_CAPS);
  g_object_set (rtpsrc, "caps", caps, NULL);
  gst_caps_unref (caps);

  rtcpsrc = gst_element_factory_make ("udpsrc", "rtcpsrc");
  g_assert (rtcpsrc);
  g_object_set (rtcpsrc, "port", 5001, NULL);

  rtcpsink = gst_element_factory_make ("udpsink", "rtcpsink");
  g_assert (rtcpsink);
  g_object_set (rtcpsink, "port", 5005, "host", DEST_HOST, NULL);
  /* no need for synchronisation or preroll on the RTCP sink */
  g_object_set (rtcpsink, "async", FALSE, "sync", FALSE, NULL);

  gst_bin_add_many (GST_BIN (pipeline), rtpsrc, rtcpsrc, rtcpsink, NULL);

  /* the depayloading and decoding */
  videodepay = gst_element_factory_make (VIDEO_DEPAY, "videodepay");
  g_assert (videodepay);
  videodec = gst_element_factory_make (VIDEO_DEC, "videodec");
  g_assert (videodec);
  /* the audio playback and format conversion */
  videoconv = gst_element_factory_make ("ffmpegcolorspace", "videoconv");
  g_assert (videoconv);
/*
  audiores = gst_element_factory_make ("audioresample", "audiores");
  g_assert (audiores);
*/
  videosink = gst_element_factory_make (VIDEO_SINK, "videosink");
  g_assert (videosink);

  /* add depayloading and playback to the pipeline and link */
  gst_bin_add_many (GST_BIN (pipeline), videodepay, videodec, videoconv, /*videores,*/ videosink, NULL);

  res = gst_element_link_many (videodepay, videodec, videoconv, /*videores,*/videosink, NULL);
  g_assert (res == TRUE);

  /* the rtpbin element */
  rtpbin = gst_element_factory_make ("gstrtpbin", "rtpbin");
  g_assert (rtpbin);

  g_object_set (G_OBJECT (rtpbin),"latency",200,NULL);

  gst_bin_add (GST_BIN (pipeline), rtpbin);

  /* now link all to the rtpbin, start by getting an RTP sinkpad for session 0 */
  srcpad = gst_element_get_static_pad (rtpsrc, "src");
  sinkpad = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_0");
  lres = gst_pad_link (srcpad, sinkpad);
  g_assert (lres == GST_PAD_LINK_OK);
  gst_object_unref (srcpad);

  /* get an RTCP sinkpad in session 0 */
  srcpad = gst_element_get_static_pad (rtcpsrc, "src");
  sinkpad = gst_element_get_request_pad (rtpbin, "recv_rtcp_sink_0");
  lres = gst_pad_link (srcpad, sinkpad);
  g_assert (lres == GST_PAD_LINK_OK);
  gst_object_unref (srcpad);
  gst_object_unref (sinkpad);

  /* get an RTCP srcpad for sending RTCP back to the sender */
  srcpad = gst_element_get_request_pad (rtpbin, "send_rtcp_src_0");
  sinkpad = gst_element_get_static_pad (rtcpsink, "sink");
  lres = gst_pad_link (srcpad, sinkpad);
  g_assert (lres == GST_PAD_LINK_OK);
  gst_object_unref (sinkpad);

  /* the RTP pad that we have to connect to the depayloader will be created
   * dynamically so we connect to the pad-added signal, pass the depayloader as
   * user_data so that we can link to it. */
  g_signal_connect (rtpbin, "pad-added", G_CALLBACK (pad_added_cb), videodepay);

  /* give some stats when we receive RTCP */
  //g_signal_connect (rtpbin, "on-ssrc-active", G_CALLBACK (on_ssrc_active_cb),videodepay);

  /* set the pipeline to playing */
  g_print ("starting receiver pipeline\n");
  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  /* we need to run a GLib main loop to get the messages */
  loop = g_main_loop_new (NULL, FALSE);
  g_main_loop_run (loop);

  g_print ("stopping receiver pipeline\n");
  gst_element_set_state (pipeline, GST_STATE_NULL);

  gst_object_unref (pipeline);

  return 0;
}


When I launch it I receive the following error
ERROR:rtpclient.c::pad_added_cb: assertion failed: (lres == GST_PAD_LINK_OK)

How I can solve the problem? Do you have any ideas?

G.

Reply | Threaded
Open this post in threaded view
|

Re: C code for rtp h264 decoding. I can't find how to solve the error. Read is insteresting

Nathanael D. Noblet
On 01/27/2011 04:34 AM, giorgino wrote:
> When I launch it I receive the following error
> ERROR:rtpclient.c::pad_added_cb: assertion failed: (lres == GST_PAD_LINK_OK)
>
> How I can solve the problem? Do you have any ideas?


How bout you compare the GST_PAD_X return to something so you know why
it failed?

http://library.gnome.org/devel/gstreamer/unstable/GstPad.html#GstPadLinkReturn

------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires
February 28th, so secure your free ArcSight Logger TODAY!
http://p.sf.net/sfu/arcsight-sfd2d
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: C code for rtp h264 decoding. I can't find how to solve the error. Read is insteresting

Marco Ballesio
In reply to this post by giorgino
Hi,

On Thu, Jan 27, 2011 at 1:34 PM, giorgino <[hidden email]> wrote:
..snip..

> #define VIDEO_CAPS
> "application/x-rtp,media=(string)video,clock-rate=(int)9000,encoding-name=(string)H264"

typo, s/9000/90000 or, that is the same:

"application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H264"

Regards

> //#define VIDEO_CAPS
> "application/x-rtp,media=video,clock-rate=9000,encoding-name=H264"
>
> #define VIDEO_DEPAY "rtph264depay"
> #define VIDEO_DEC   "ffdec_h264"
> #define VIDEO_SINK  "autovideosink"
>
> /* the destination machine to send RTCP to. This is the address of the
> sender and
>  * is used to send back the RTCP reports of this receiver. If the data is
> sent
>  * from another machine, change this address. */
> #define DEST_HOST "127.0.0.1"
>
> /* print the stats of a source */
> static void print_source_stats (GObject * source) {
>  GstStructure *stats;
>  gchar *str;
>
>  g_return_if_fail (source != NULL);
>
>  /* get the source stats */
>  g_object_get (source, "stats", &stats, NULL);
>
>  /* simply dump the stats structure */
>  str = gst_structure_to_string (stats);
>  g_print ("source stats: %s\n", str);
>
>  gst_structure_free (stats);
>  g_free (str);
> }
>
> /* will be called when gstrtpbin signals on-ssrc-active. It means that an
> RTCP
>  * packet was received from another source. */
> static void on_ssrc_active_cb (GstElement * rtpbin, guint sessid, guint
> ssrc, GstElement * depay) {
>
>    GObject *session, *isrc, *osrc;
>    g_print ("got RTCP from session %u, SSRC %u\n", sessid, ssrc);
>
>  /* get the right session */
>  g_signal_emit_by_name (rtpbin, "get-internal-session", sessid, &session);
>
>  /* get the internal source (the SSRC allocated to us, the receiver */
>  g_object_get (session, "internal-source", &isrc, NULL);
>  print_source_stats (isrc);
>
>  /* get the remote source that sent us RTCP */
>  g_signal_emit_by_name (session, "get-source-by-ssrc", ssrc, &osrc);
>  print_source_stats (osrc);
> }
>
> /* will be called when rtpbin has validated a payload that we can depayload
> */
> static void
> pad_added_cb (GstElement * rtpbin, GstPad * new_pad, GstElement * depay)
> {
>  GstPad *sinkpad;
>  GstPadLinkReturn lres;
>
>  g_print ("new payload on pad: %s\n", GST_PAD_NAME (new_pad));
>
>  sinkpad = gst_element_get_static_pad (depay, "sink");
>  g_assert (sinkpad);
>
>  lres = gst_pad_link (new_pad, sinkpad);
>  g_assert (lres == GST_PAD_LINK_OK);
>  gst_object_unref (sinkpad);
>
> }
>
>
> int main (int argc, char *argv[])
> {
>  GstElement *rtpbin, *rtpsrc, *rtcpsrc, *rtcpsink;
>  GstElement *videodepay,
>             *videodec,
>             //*videores,
>             *videoconv,
>             *videosink;
>
>  GstElement *pipeline;
>  GMainLoop *loop;
>  GstCaps *caps;
>  gboolean res;
>  GstPadLinkReturn lres;
>  GstPad *srcpad, *sinkpad;
>
>  /* always init first */
>  gst_init (&argc, &argv);
>
>  /* the pipeline to hold everything */
>  pipeline = gst_pipeline_new (NULL);
>  g_assert (pipeline);
>
>  /* the udp src and source we will use for RTP and RTCP */
>  rtpsrc = gst_element_factory_make ("udpsrc", "rtpsrc");
>  g_assert (rtpsrc);
>  g_object_set (rtpsrc, "port", 5000, NULL);
>  /* we need to set caps on the udpsrc for the RTP data */
>  caps = gst_caps_from_string (VIDEO_CAPS);
>  g_object_set (rtpsrc, "caps", caps, NULL);
>  gst_caps_unref (caps);
>
>  rtcpsrc = gst_element_factory_make ("udpsrc", "rtcpsrc");
>  g_assert (rtcpsrc);
>  g_object_set (rtcpsrc, "port", 5001, NULL);
>
>  rtcpsink = gst_element_factory_make ("udpsink", "rtcpsink");
>  g_assert (rtcpsink);
>  g_object_set (rtcpsink, "port", 5005, "host", DEST_HOST, NULL);
>  /* no need for synchronisation or preroll on the RTCP sink */
>  g_object_set (rtcpsink, "async", FALSE, "sync", FALSE, NULL);
>
>  gst_bin_add_many (GST_BIN (pipeline), rtpsrc, rtcpsrc, rtcpsink, NULL);
>
>  /* the depayloading and decoding */
>  videodepay = gst_element_factory_make (VIDEO_DEPAY, "videodepay");
>  g_assert (videodepay);
>  videodec = gst_element_factory_make (VIDEO_DEC, "videodec");
>  g_assert (videodec);
>  /* the audio playback and format conversion */
>  videoconv = gst_element_factory_make ("ffmpegcolorspace", "videoconv");
>  g_assert (videoconv);
> /*
>  audiores = gst_element_factory_make ("audioresample", "audiores");
>  g_assert (audiores);
> */
>  videosink = gst_element_factory_make (VIDEO_SINK, "videosink");
>  g_assert (videosink);
>
>  /* add depayloading and playback to the pipeline and link */
>  gst_bin_add_many (GST_BIN (pipeline), videodepay, videodec, videoconv,
> /*videores,*/ videosink, NULL);
>
>  res = gst_element_link_many (videodepay, videodec, videoconv,
> /*videores,*/videosink, NULL);
>  g_assert (res == TRUE);
>
>  /* the rtpbin element */
>  rtpbin = gst_element_factory_make ("gstrtpbin", "rtpbin");
>  g_assert (rtpbin);
>
>  g_object_set (G_OBJECT (rtpbin),"latency",200,NULL);
>
>  gst_bin_add (GST_BIN (pipeline), rtpbin);
>
>  /* now link all to the rtpbin, start by getting an RTP sinkpad for session
> 0 */
>  srcpad = gst_element_get_static_pad (rtpsrc, "src");
>  sinkpad = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_0");
>  lres = gst_pad_link (srcpad, sinkpad);
>  g_assert (lres == GST_PAD_LINK_OK);
>  gst_object_unref (srcpad);
>
>  /* get an RTCP sinkpad in session 0 */
>  srcpad = gst_element_get_static_pad (rtcpsrc, "src");
>  sinkpad = gst_element_get_request_pad (rtpbin, "recv_rtcp_sink_0");
>  lres = gst_pad_link (srcpad, sinkpad);
>  g_assert (lres == GST_PAD_LINK_OK);
>  gst_object_unref (srcpad);
>  gst_object_unref (sinkpad);
>
>  /* get an RTCP srcpad for sending RTCP back to the sender */
>  srcpad = gst_element_get_request_pad (rtpbin, "send_rtcp_src_0");
>  sinkpad = gst_element_get_static_pad (rtcpsink, "sink");
>  lres = gst_pad_link (srcpad, sinkpad);
>  g_assert (lres == GST_PAD_LINK_OK);
>  gst_object_unref (sinkpad);
>
>  /* the RTP pad that we have to connect to the depayloader will be created
>   * dynamically so we connect to the pad-added signal, pass the depayloader
> as
>   * user_data so that we can link to it. */
>  g_signal_connect (rtpbin, "pad-added", G_CALLBACK (pad_added_cb),
> videodepay);
>
>  /* give some stats when we receive RTCP */
>  //g_signal_connect (rtpbin, "on-ssrc-active", G_CALLBACK
> (on_ssrc_active_cb),videodepay);
>
>  /* set the pipeline to playing */
>  g_print ("starting receiver pipeline\n");
>  gst_element_set_state (pipeline, GST_STATE_PLAYING);
>
>  /* we need to run a GLib main loop to get the messages */
>  loop = g_main_loop_new (NULL, FALSE);
>  g_main_loop_run (loop);
>
>  g_print ("stopping receiver pipeline\n");
>  gst_element_set_state (pipeline, GST_STATE_NULL);
>
>  gst_object_unref (pipeline);
>
>  return 0;
> }
>
>
> When I launch it I receive the following error
> ERROR:rtpclient.c::pad_added_cb: assertion failed: (lres == GST_PAD_LINK_OK)
>
> How I can solve the problem? Do you have any ideas?
>
> G.
>
>
> --
> View this message in context: http://gstreamer-devel.966125.n4.nabble.com/C-code-for-rtp-h264-decoding-I-can-t-find-how-to-solve-the-error-Read-is-insteresting-tp3242017p3242017.html
> Sent from the GStreamer-devel mailing list archive at Nabble.com.
>
> ------------------------------------------------------------------------------
> Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
> Finally, a world-class log management solution at an even better price-free!
> Download using promo code Free_Logger_4_Dev2Dev. Offer expires
> February 28th, so secure your free ArcSight Logger TODAY!
> http://p.sf.net/sfu/arcsight-sfd2d
> _______________________________________________
> gstreamer-devel mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
>

------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires
February 28th, so secure your free ArcSight Logger TODAY!
http://p.sf.net/sfu/arcsight-sfd2d
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: C code for rtp h264 decoding. I can't find how to solve the error. Read is insteresting

giorgino
Yes you identified the error. The value is 90000 for that reason previuosly it doesn't work.

Thanks and have a nice day
G.
Reply | Threaded
Open this post in threaded view
|

Re: C code for rtp h264 decoding. I can't find how to solve the error. Read is insteresting

gagankumarnigam
In reply to this post by Marco Ballesio
hi,
i tried your programe with modification as suggested by you in your blog as put 90000
"application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H264"
still i am getting the same error----------------

ERROR:rtpclient.c::pad_added_cb: assertion failed: (lres == GST_PAD_LINK_OK)
in function

static void pad_added_cb (GstElement * rtpbin, GstPad * new_pad, GstElement * depay)
{
  GstPad *sinkpad;
  GstPadLinkReturn lres;

  g_print ("new payload on pad: %s\n", GST_PAD_NAME (new_pad));

  sinkpad = gst_element_get_static_pad (depay, "sink");
  g_assert (sinkpad);

  lres = gst_pad_link (new_pad, sinkpad);
  g_assert (lres == GST_PAD_LINK_OK);
  gst_object_unref (sinkpad);

}


Reply | Threaded
Open this post in threaded view
|

how to stream video recieved on udpsrc

gagankumarnigam
In reply to this post by giorgino
hi all

can some body tell me how to forward again live stream recieved from udpsrc(rtp).

like that :

v4l2src->x264enc->udpsink
udpsrc->ffdec_h264->autovideosink->x264enc-udpsink