1

I've looked for a while but can't seem to find an encoding/payload setup that would allow me to simply stream losslessly from my host to client (both are on setup where bandwidth is not a issue).

I'm currently using these two pipelines to get by, but I'm not thrilled with the jpeg artifacts introduced:

    cv::VideoWriter writer_h264(
        "appsrc ! videoconvert ! "
        "x264enc pass=quant quantizer=0 tune=zerolatency "
                "speed-preset=superfast byte-stream=true cabac=false ! "
        "rtph264pay ! udpsink host=127.0.0.1 port=5000",
        0,      // fourcc 
        30,     // fps
        cv::Size(200, 200), 
        false); // isColor
    // View with:
    // // gst-launch-1.0 -v udpsrc port=5000 ! "application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)96" ! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! autovideosink

    cv::VideoWriter writer_jpeg(
        "appsrc !"
        "videoconvert ! video/x-raw,format=YUY2 ! jpegenc ! rtpjpegpay ! udpsink host=127.0.0.1 port=5001",
        0,      // fourcc 
        30,     // fps
        cv::Size(200, 200),
        false); // isColor
    //  View with:
    //  gst-launch-1.0.exe udpsrc port=5001 ! application/x-rtp,media=video,encoding-name=JPEG ! rtpjpegdepay ! jpegdec ! videoconvert ! autovideosink

Our appsource is a simple CV_8UC1 grayscale bitmap, and I'd prefer it made it to the client in its original form (it's used for both display and analytic purposes). The png decoder/encoder seems like an obvious choice, except that there is no png payloader. The two pipelines above produce identical results, which tells me that its the jpegenc/rtpjpegpay that are likely introducing the problem. You can see this in the attached image (first image is original, latter two are from the clients).

streaming results

UPDATE:

Based on @Florian's advice below, I tried using the rtpvraw payload elements, using these pipelines:

GST_DEBUG=3 /d/gstreamer-x/1.0/msvc_x86_64/bin/gst-launch-1.0 -v multifilesrc location="frame%02d.png" loop=true index=10 caps="image/png,framerate=\(fraction\)30/1" ! pngdec ! videoconvert ! rtpvrawpay ! udpsink host="127.0.0.1" port="5000"
./gst-launch-1.0 udpsrc port=5000 caps="application/x-rtp,media=video,clock-rate=90000,encoding-name=RAW,sampling=BGR,depth=(string)8,width=(string)200,height=(string)200,colorimetry=SMPTE240M" ! rtpvrawdepay ! videoconvert ! queue ! autovideosink

(I derived the caps for the client by examining the debug output above). It seems better, although there is visible antialiasing in the output. Perhaps this is just something that autovideosink does?

rtpvraw

Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
Steve Broberg
  • 4,255
  • 3
  • 28
  • 40
  • 1
    please calculate the data rate of your lossless/uncompressed video stream. -- if you don't like compression artefacts, look for ways to adjust the quality. – Christoph Rackwitz Jul 12 '23 at 19:26
  • I don't understand what you mean by calculating the data rate. I'm not specifying it (nor do I care), and I'm not limited by bandwidth in these tests. Can you be more specific? – Steve Broberg Jul 12 '23 at 22:20

1 Answers1

2

rtpvrawpay and rtpvrawdepay should packetize via RFC 4175 (https://www.rfc-editor.org/rfc/rfc4175.html).

Florian Zwoch
  • 6,764
  • 2
  • 12
  • 21
  • Thanks for the tip. It took me a little while to figure out how to get the caps to configure the client side, although I still have a bit of a problem. I can get the caps when using gst-launch and a set of 8-bit .pngs, but when I use the same client with my app (which uses appsrc), it no longer works. Do you know how to get the output caps from a c++ or cv::VideoWriter source? – Steve Broberg Jul 12 '23 at 22:29
  • I don't know OpenCV. But it should work as with setting the correct caps as with any other appsrc pipeline. – Florian Zwoch Jul 13 '23 at 19:24