Problem with format for rtph264depay

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

Problem with format for rtph264depay

stfl
I am writing my own network plugin that should transfer packets over SCTP.
I am passing the data into the SCTP socket from rtph264pay and on the receiver from the SCTP socket into rtph264depay but the stream cannot be decoded.
I checked hex dumps of the data and the incoming packets (from rtppay) are equivalent to the once outgoing (into rtpdepay).
The one message that really bothers me and I couldn't find any solution is:

I don't have all the debug output enabled:
sender:
GST_DEBUG="4,basesink:4,sctpsink:6,gstutils:5,basesrc:4,pushsrc:5,sctpsrc:5,rtph264pay:5,rtpbasepayload:5" ./build/rtpsctp /rtpsctpsend
send.txt

receiver:
GST_DEBUG="4,basesink:4,sctpsink:6,gstutils:5,basesrc:4,pushsrc:5,sctpsrc:5,rtph264depay:8,rtpbasedepayload:8"
recv.txt

I am also dumpung the first 16bytes form the packet as a hex dump on every packet..
It seems like the RTP header starts at byte 3 -> what are the first 2 bytes?

I create the pipelines like this:

sender:
   GstElement *pipeline, *source, *sink, *encoder, *rtppay;

   /* create pipeline */
   pipeline = gst_pipeline_new ("pipeline");

   /* create element */
   source = gst_element_factory_make("videotestsrc", "source");
   if (!source) {
      /* g_print ("Failed to create element of type 'videotestsrc'\n"); */
      g_print ("Failed to create element of type 'videotestsrc'\n");
      /* return -1; */
   }
   g_object_set(G_OBJECT(source),
         /* "pattern",   GstVideoTestSrcPattern.GST_VIDEO_TEST_SRC_SNOW, */
         "is-live",   TRUE,
         NULL);
   gst_util_set_object_arg(G_OBJECT(source), "pattern", "snow");
   GstCaps *src_caps = gst_caps_new_simple ("video/x-raw",
         "width", G_TYPE_INT, 1280,
         "height", G_TYPE_INT, 720,
         "framerate", GST_TYPE_FRACTION, 25, 1,
         NULL);

   encoder = gst_element_factory_make("x264enc", "encoder");
   if (!encoder) {
      g_print ("failed to create element of type 'x264enc'\n");
      /* return -1; */
   }
   gst_util_set_object_arg(G_OBJECT(encoder), "tune", "zerolatency");
   /* g_object_set(encoder, "tune", (GstX264EncTune)"zerolatency", NULL); */


   rtppay = gst_element_factory_make("rtph264pay", "rtppay");
   if (!rtppay) {
      g_print ("failed to create element of type 'rtph264pay'\n");
      /* return -1; */
   }

receiver:
   GstElement *pipeline = gst_pipeline_new ("pipeline");

   /* create element */
   GstElement *source = gst_element_factory_make("sctpsrc", "source");
   if (!source) {
      g_critical ("Failed to create element of type 'sctpsrc'\n");
      /* return -1; */
   }
   g_object_set(G_OBJECT(source),
         "port",   1117,
         NULL);

   GstCaps *src_caps = gst_caps_new_simple("application/x-rtp",
         "media", G_TYPE_STRING, "video",
         "clock-rate", G_TYPE_INT, 90000,
         "encoding-name", G_TYPE_STRING, "H264",
         "a-framerate", G_TYPE_STRING, "25",
         "packetization-mode", G_TYPE_STRING, "1",
         "payload", G_TYPE_INT, 96,
         NULL);

   GstElement *rtpdepay = gst_element_factory_make("rtph264depay", "rtpdepay");
   if (!rtpdepay) {
      g_critical ("failed to create element of type 'rtph264depay'\n");
      /* return -1; */
   }

   GstElement *decoder = gst_element_factory_make("avdec_h264", "decoder");
   if (!decoder) {
      g_critical ("failed to create element of type 'avdec_h264'\n");
      /* return -1; */
   }

   GstCaps *decode_caps = gst_caps_new_simple("video/x-h264",
         "stream-format", G_TYPE_STRING, "avc",
         "alignment", G_TYPE_STRING, "au",
         "level", G_TYPE_STRING, "3.1",
         "width", G_TYPE_INT, 1280,
         "height", G_TYPE_INT, 720,
         "framerate", GST_TYPE_FRACTION, 25, 1,
         "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,        
         NULL);


   GstElement *videoconvert = gst_element_factory_make("videoconvert", "videoconvert");
   if (!videoconvert) {
      g_critical ("failed to create element of type 'videoconvert'\n");
      /* return -1; */
   }

   GstElement *videosink = gst_element_factory_make("ximagesink", "videsink");
   if (!videosink) {
      g_critical ("Failed to create element of type 'ximagesink'\n");
      /* return -1; */
   }

   /* add to pipeline */
   gst_bin_add_many(GST_BIN(pipeline), source, rtpdepay, decoder, videoconvert, videosink, NULL);

   /* link */
 /* rtpdepay, decoder, */

   if (!gst_element_link_filtered(source, rtpdepay, src_caps)) {
      g_warning ("Failed to link filterd source and rtpdepay!\n");
   }
   gst_caps_unref(src_caps);

   if (!gst_element_link_filtered(rtpdepay, decoder, decode_caps)) {
      g_critical ("Failed to link source and rtpdepay'\n");
   }
   gst_caps_unref(decode_caps);

   if (!gst_element_link(decoder, videoconvert)) {
      g_critical ("Failed to link source and rtpdepay'\n");
   }

   if (!gst_element_link(videoconvert, videosink)) {
      g_critical ("Failed to link source and rtpdepay'\n");
   }

I've implemented the .create() methos of PushSrc where I retrieve the data from the socket and store it into the give buffer:

static GstFlowReturn gst_sctpsrc_create(GstPushSrc *src, GstBuffer **buf) {
   GstSctpSrc *sctpsrc = GST_SCTPSRC(src);
   ssize_t n;
   int flags;

   char name[INET6_ADDRSTRLEN];
   /* char *buffer = g_malloc(BUFFER_SIZE); */
   /* buf = g_malloc(BUFFER_SIZE); */
   /* [BUFFER_SIZE]; // FIXME: change to a malloc! */

   socklen_t infolen;
   struct sctp_rcvinfo rcv_info;
   unsigned int infotype;
   struct sockaddr_in6 from;
   socklen_t from_len;

   // allocate the buffer
   GstMapInfo map;
   *buf = gst_buffer_new_and_alloc (BUFFER_SIZE);
   gst_buffer_map (*buf, &map, GST_MAP_READWRITE);

   from_len = (socklen_t)sizeof(struct sockaddr_in6);
   flags    = 0;
   infolen  = (socklen_t)sizeof(struct sctp_rcvinfo);

   n = usrsctp_recvv(sctpsrc->sock, (void *)map.data, BUFFER_SIZE, (struct sockaddr *)&from,
                     &from_len, (void *)&rcv_info, &infolen, &infotype, &flags);
   if (n > 0) {
      if (flags & MSG_NOTIFICATION) {
         union sctp_notification *sn=(union sctp_notification*)map.data;
            /* switch(sn->sn_header.sn_type) { */
            /*     case SCTP_COMM_UP: { */
         GST_DEBUG_OBJECT(sctpsrc, "Notificatjion of type %u length %llu received.",
               sn->sn_header.sn_type, (unsigned long long)n);
      } else {
         if (infotype == SCTP_RECVV_RCVINFO) {
            GST_DEBUG_OBJECT(sctpsrc, "Msg len %4llu from [%s]:%u SID %d "
                  "SSN %u TSN %u PPID %u contxt %u compl %d",
                  (unsigned long long)n, inet_ntop(AF_INET6, &from.sin6_addr, name, INET6_ADDRSTRLEN),
                  ntohs(from.sin6_port), rcv_info.rcv_sid, rcv_info.rcv_ssn, rcv_info.rcv_tsn,
                  ntohl(rcv_info.rcv_ppid), rcv_info.rcv_context, (flags & MSG_EOR) ? 1 : 0);
         } else {
            GST_DEBUG_OBJECT(sctpsrc, "Msg of length %llu received from %s:%u, complete %d.",
                  (unsigned long long)n,
                  inet_ntop(AF_INET6, &from.sin6_addr, name, INET6_ADDRSTRLEN),
                  ntohs(from.sin6_port), (flags & MSG_EOR) ? 1 : 0);
         }
         print_rtp_header(sctpsrc, map.data+2);
         hexDump(NULL, map.data, MIN(16, n));
         /* hexDump(NULL, map.data, n); */
   }
   } else {
      GST_WARNING_OBJECT(sctpsrc, "GST_FLOW_EOS");
      return GST_FLOW_EOS;
   }

  gst_buffer_unmap (*buf, &map);

   /* *buf = buffer; */
   return GST_FLOW_OK;
}
Reply | Threaded
Open this post in threaded view
|

Re: Problem with format for rtph264depay

stfl
What I forgot to say.. The following line in the debug output bothers me:

ERROR       rtpbasedepayload gstrtpbasedepayload.c:618:gst_rtp_base_depayload_handle_event:<rtpdepay> Non-TIME segments are not supported and will likely fail
Reply | Threaded
Open this post in threaded view
|

Re: Problem with format for rtph264depay [SOLVED]

stfl
ok it seems really like it has something to do with the rtp header:

having a look at gstrtpbuffer.c
DEBUG                default gstrtpbuffer.c:463:gst_rtp_buffer_map: version check failed (64 != 2)

I got it to work now.. on the render function in the sctpsink I took the GstBuffer and just sent it out to the socket..
I managed to make it work with using the proper mapping..

gst_buffer_map (buffer, &map, GST_MAP_READ);
and map.data

not really well documented to be honest... or did I miss that somewhere in the doc?.....
Reply | Threaded
Open this post in threaded view
|

Re: Problem with format for rtph264depay [SOLVED]

Nicolas Dufresne-5
Le samedi 18 mars 2017 à 14:12 -0700, stfl a écrit :

> ok it seems really like it has something to do with the rtp header:
>
> having a look at gstrtpbuffer.c
>
>
> I got it to work now.. on the render function in the sctpsink I took
> the
> GstBuffer and just sent it out to the socket..
> I managed to make it work with using the proper mapping..
>
> gst_buffer_map (buffer, &map, GST_MAP_READ);
> and map.data
>
> not really well documented to be honest... or did I miss that
> somewhere in
> the doc?.....
High level concept of GstBuffer containing GstMemory (for application
writers)
https://gstreamer.freedesktop.org/documentation/application-development/basics/data.html#buffers

The Plugin Writer explanation (with examples):
https://gstreamer.freedesktop.org/documentation/plugin-development/advanced/allocation.html#memory-allocation

A tutorial that map GstBuffer:
https://gstreamer.freedesktop.org/documentation/tutorials/basic/short-cutting-the-pipeline.html

The reference documentation for GstBuffer:
https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstBuffer.html

The reference documentation for GstMemory:
https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstMemory.html

And that without listing the countless existing example code through
all the similar plugins, notably udpsink, tcpsink etc.

regards,
Nicolas
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

signature.asc (188 bytes) Download Attachment