GNOME Bugzilla – Bug 654469
command-line base64 encoding parse error module rtpgstdepay
Last modified: 2012-12-11 22:55:45 UTC
Possibly related to Bug 641101, the command-line parser fails to parse base64 data ending in '='. This occurs in plugin rtpgsypay/depay where the caps to be transmitted over a UDP communications channel is encoded base64, ending typically in one or two '='. This presents a problem in the parsing of the caps at the receiver.
I will propose a patch for this problem and test case tomorrow - raymond
Created attachment 191850 [details] [review] Patch to eliminate symbol "=" from caps and command line of rtpgstpay I suggest the problem can be resolved with a simple fix to rtpgstpay instead of implementing a new feature in the parser. As modern flavors of base64 codings do not explicitly include the one or two padding nulls (written as "="), the solution might be acceptable in any case. In reconstruction, two nulls ("=") are appended to the string to force correct reconstruction. In production of the encoded caps string, all trailing nulls ("=") are removed, this will not affect any non-null string coding.
Re #641101, gstreamer doesn't use GScanner. Could you give an example of the gst-launch line that is not working? This sounds like a parser problem, so i'd like to at least construct a test case before working around the problem. (Because nobody likes to touch the parser :))
Command line to generate uncompressed source to rtpgstpay. gst-launch -v --gst-plugin-path=/usr/local/lib/gstreamer-0.10 videotestsrc is-live=TRUE ! "video/x-raw-rgb, format=(fourcc)RGB, width=640, height=480, framerate=(fraction)30/1" ! timeoverlay halign=left valign=bottom text="ViewPhone Time:" shaded-background=true ! ffmpegcolorspace ! "video/x-raw-yuv, format=(fourcc)YUY2" ! zpegenc ! rtpgstpay ! udpsink host=localhost port=9001 Use -v to generate caps for rtpgstdepay. The resulting caps negotiation looks like: /GstPipeline:pipeline0/GstRtpGSTPay:rtpgstpay0.GstPad:src: caps = application/x-rtp, media=(string)application, clock-rate=(int)90000, encoding-name=(string)X-GST, caps=(string)dmlkZW8veC1yYXcteXV2LCBmb3JtYXQ9KGZvdXJjYylZVVkyLCB3aWR0aD0oaW50KTY0MCwgaGVpZ2h0PShpbnQpNDgwLCBmcmFtZXJhdGU9KGZyYWN0aW9uKTMwLzE==, payload=(int)96, ssrc=(uint)4251288658, clock-base=(uint)3054966174, seqnum-base=(uint)16380 /GstPipeline:pipeline0/GstRtpGSTPay:rtpgstpay0.GstPad:sink: caps = video/x-raw-yuv, format=(fourcc)YUY2, width=(int)640, height=(int)480, framerate=(fraction)30/1 Now start the receiver: gst-launch -v udpsrc port=9001 reuse=true caps=" application/x-rtp, media=(string)application, clock-rate=(int)90000, encoding-name=(string)X-GST, caps=(string)dmlkZW8veC1yYXcteXV2LCBmb3JtYXQ9KGZvdXJjYylZVVkyLCBjb21wcmVzc2lvbj0oZm91cmNjKVpQRUcsIGZyYW1lcmF0ZT0oZnJhY3Rpb24pMzAvMSwgd2lkdGg9KGludCk2NDAsIGhlaWdodD0oaW50KTQ4MA==, payload=(int)96" ! rtpgstdepay ! zpegdec ! ffmpegcolorspace ! ximagesink sync=FALSE The receiver will not negotiate, no matter how one quotes the "=".
Comment on attachment 191850 [details] [review] Patch to eliminate symbol "=" from caps and command line of rtpgstpay >diff --git a/gst/rtp/gstrtpgstdepay.c b/gst/rtp/gstrtpgstdepay.c >index 6dc5e51..074f7e0 100644 >--- a/gst/rtp/gstrtpgstdepay.c >+++ b/gst/rtp/gstrtpgstdepay.c >@@ -158,8 +158,12 @@ gst_rtp_gst_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps) > capsenc = gst_structure_get_string (structure, "caps"); > if (capsenc) { > gsize out_len; >- >- capsstr = (gchar *) g_base64_decode (capsenc, &out_len); >+ gchar *capsenctmp; >+ capsenctmp = malloc(strlen(capsenc)+3); >+ strcpy(capsenctmp, capsenc); >+ strcat(capsenctmp, "=="); >+ capsstr = (gchar *) g_base64_decode (capsenctmp, &out_len); >+ free(capsenctmp); > outcaps = gst_caps_from_string (capsstr); > g_free (capsstr); > >diff --git a/gst/rtp/gstrtpgstpay.c b/gst/rtp/gstrtpgstpay.c >index e6e23de..ffb183d 100644 >--- a/gst/rtp/gstrtpgstpay.c >+++ b/gst/rtp/gstrtpgstpay.c >@@ -115,6 +115,10 @@ gst_rtp_gst_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps) > > capsstr = gst_caps_to_string (caps); > capsenc = g_base64_encode ((guchar *) capsstr, strlen (capsstr)); >+ while (capsenc[strlen(capsenc)-1]=='=') >+ { >+ capsenc[strlen(capsenc)-1]='\0'; >+ } > g_free (capsstr); > > gst_basertppayload_set_options (payload, "application", TRUE, "X-GST", 90000);
What is zpegenc/dec? Should that be jpegenc/dec? When I try this I get WARNING: erroneous pipeline: could not set property "caps" in element "udpsrc0" to " application/x-rtp,media=(string)application, clock-rate=(int)90000, encoding-name=(string)X-GST,caps=(string)aW1hZ2UvanBlZywgd2lkdGg9KGludCk2NDAsIGhlaWdodD0oaW50KTQ4MCwgZnJhbWVyYXRlPShmcmFjdGlvbikzMC8xLCBwaXhlbC1hc3BlY3QtcmF0aW89KGZyYWN0aW9uKTEvMQ==,payload=(int)96"
This seems to work fine for me now in 1.0, since the string is escaped in this case, so closing as OBSOLETE. Please re-open if you still experience issues with 1.0. $ gst-launch-1.0 videotestsrc ! rtpgstpay ! fakesink -v Setting pipeline to PAUSED ... Pipeline is PREROLLING ... /GstPipeline:pipeline0/GstVideoTestSrc:videotestsrc0.GstPad:src: caps = video/x-raw, format=(string)I420, width=(int)320, height=(int)240, framerate=(fraction)30/1 /GstPipeline:pipeline0/GstRtpGSTPay:rtpgstpay0.GstPad:src: caps = application/x-rtp, media=(string)application, clock-rate=(int)90000, encoding-name=(string)X-GST, caps=(string)"dmlkZW8veC1yYXcsIGZvcm1hdD0oc3RyaW5nKUk0MjAsIHdpZHRoPShpbnQpMzIwLCBoZWlnaHQ9KGludCkyNDAsIGZyYW1lcmF0ZT0oZnJhY3Rpb24pMzAvMQ\=\=", capsversion=(string)0, payload=(int)96, ssrc=(uint)266090623, timestamp-offset=(uint)272616731, seqnum-offset=(uint)24405 /GstPipeline:pipeline0/GstFakeSink:fakesink0.GstPad:sink: caps = application/x-rtp, media=(string)application, clock-rate=(int)90000, encoding-name=(string)X-GST, caps=(string)"dmlkZW8veC1yYXcsIGZvcm1hdD0oc3RyaW5nKUk0MjAsIHdpZHRoPShpbnQpMzIwLCBoZWlnaHQ9KGludCkyNDAsIGZyYW1lcmF0ZT0oZnJhY3Rpb24pMzAvMQ\=\=", capsversion=(string)0, payload=(int)96, ssrc=(uint)266090623, timestamp-offset=(uint)272616731, seqnum-offset=(uint)24405 $ gst-launch-1.0 udpsrc caps='application/x-rtp, media=(string)application, clock-rate=(int)90000, encoding-name=(string)X-GST, caps=(string)"dmlkZW8veC1yYXcsIGZvcm1hdD0oc3RyaW5nKUk0MjAsIHdpZHRoPShpbnQpMzIwLCBoZWlnaHQ9KGludCkyNDAsIGZyYW1lcmF0ZT0oZnJhY3Rpb24pMzAvMQ\=\=", capsversion=(string)0, payload=(int)96, ssrc=(uint)266090623, timestamp-offset=(uint)272616731, seqnum-offset=(uint)24405' ! rtpgstdepay ! fakesink -v Setting pipeline to PAUSED ... Pipeline is live and does not need PREROLL ... /GstPipeline:pipeline0/GstUDPSrc:udpsrc0.GstPad:src: caps = application/x-rtp, media=(string)application, clock-rate=(int)90000, encoding-name=(string)X-GST, caps=(string)"dmlkZW8veC1yYXcsIGZvcm1hdD0oc3RyaW5nKUk0MjAsIHdpZHRoPShpbnQpMzIwLCBoZWlnaHQ9KGludCkyNDAsIGZyYW1lcmF0ZT0oZnJhY3Rpb24pMzAvMQ\=\=", capsversion=(string)0, payload=(int)96, ssrc=(uint)266090623, timestamp-offset=(uint)272616731, seqnum-offset=(uint)24405 Setting pipeline to PLAYING ... /GstPipeline:pipeline0/GstRtpGSTDepay:rtpgstdepay0.GstPad:src: caps = video/x-raw, format=(string)I420, width=(int)320, height=(int)240, framerate=(fraction)30/1 /GstPipeline:pipeline0/GstFakeSink:fakesink0.GstPad:sink: caps = video/x-raw, format=(string)I420, width=(int)320, height=(int)240, framerate=(fraction)30/1