Lossless end-to-end 16-bit grayscale compression?

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

Lossless end-to-end 16-bit grayscale compression?

Ryan Talbot
Hi list,

I'm trying to losslessy compress the output of the disparity plugin.  Its source caps say it outputs RGB, but the algorithm itself is supposed to generate 16-bit grayscale.  After a lot of headache, I finally found a combo of avenc_ljpeg and avdec_mjpeg that would work to encode and then decode the RGB stream and get the exact same data on both ends.  Now, I would like to do the same for a 16-bit grayscale stream of images, but am having little luck.  avenc_mjpeg does support GRAY16_BE/LE, but I don't know how to make it lossless.

Does such a solution exist, or do we need to roll our own/modify a codec?

Thanks,
Ryan Talbot

_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

RE: Lossless end-to-end 16-bit grayscale compression?

Ryan Talbot
> avenc_mjpeg does support GRAY16_BE/LE, but I don't know how to make it lossless.

My mistake, avdec_mjpeg supports GRAY16_BE/LE, the encoder only supports I420,Y42B, and Y444.  The conversion from GRAY16_LE->I420 seems to be lossless, so that's good.  The trouble I'm running into now, though, is that avenc_ljpeg doesn't seem to want to accept YUV-colorspace buffers, even though its sink pad template says it can:

Pad Templates:
  SINK template: 'sink'
    Availability: Always
    Capabilities:
      video/x-raw
                 format: { BGR, BGRA, I420, Y444, Y42B }

This pipeline works fine:
gst-launch-1.0 -vvv filesrc location=source.g16 ! videoparse width=640 height=480 format=27 framerate=30/1 ! video/x-raw,format=GRAY16_LE,width=640,height=480,framerate=30/1 ! videoconvert ! video/x-raw,format=BGR ! avenc_ljpeg ! filesink location=losslessgr16.mjpg

This does not:
gst-launch-1.0 -vvv filesrc location=source.g16 ! videoparse width=640 height=480 format=27 framerate=30/1 ! video/x-raw,format=GRAY16_LE,width=640,height=480,framerate=30/1 ! videoconvert ! video/x-raw,format=I420 ! avenc_ljpeg ! filesink location=losslessgr16.mjpg
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
/GstPipeline:pipeline0/GstVideoParse:videoparse0.GstPad:src: caps = "video/x-raw\,\ format\=\(string\)GRAY16_LE\,\ width\=\(int\)640\,\ height\=\(int\)480\,\ interlace-mode\=\(string\)progressive\,\ pixel-aspect-ratio\=\(fraction\)1/1\,\ colorimetry\=\(string\)1:4:0:0\,\ framerate\=\(fraction\)30/1"
/GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = "video/x-raw\,\ format\=\(string\)GRAY16_LE\,\ width\=\(int\)640\,\ height\=\(int\)480\,\ interlace-mode\=\(string\)progressive\,\ pixel-aspect-ratio\=\(fraction\)1/1\,\ colorimetry\=\(string\)1:4:0:0\,\ framerate\=\(fraction\)30/1"
/GstPipeline:pipeline0/GstVideoConvert:videoconvert0.GstPad:src: caps = "video/x-raw\,\ width\=\(int\)640\,\ height\=\(int\)480\,\ interlace-mode\=\(string\)progressive\,\ pixel-aspect-ratio\=\(fraction\)1/1\,\ framerate\=\(fraction\)30/1\,\ format\=\(string\)I420"
/GstPipeline:pipeline0/GstCapsFilter:capsfilter1.GstPad:src: caps = "video/x-raw\,\ width\=\(int\)640\,\ height\=\(int\)480\,\ interlace-mode\=\(string\)progressive\,\ pixel-aspect-ratio\=\(fraction\)1/1\,\ framerate\=\(fraction\)30/1\,\ format\=\(string\)I420"
/GstPipeline:pipeline0/GstCapsFilter:capsfilter1.GstPad:sink: caps = "video/x-raw\,\ width\=\(int\)640\,\ height\=\(int\)480\,\ interlace-mode\=\(string\)progressive\,\ pixel-aspect-ratio\=\(fraction\)1/1\,\ framerate\=\(fraction\)30/1\,\ format\=\(string\)I420"
/GstPipeline:pipeline0/GstVideoConvert:videoconvert0.GstPad:sink: caps = "video/x-raw\,\ format\=\(string\)GRAY16_LE\,\ width\=\(int\)640\,\ height\=\(int\)480\,\ interlace-mode\=\(string\)progressive\,\ pixel-aspect-ratio\=\(fraction\)1/1\,\ colorimetry\=\(string\)1:4:0:0\,\ framerate\=\(fraction\)30/1"
/GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:sink: caps = "video/x-raw\,\ format\=\(string\)GRAY16_LE\,\ width\=\(int\)640\,\ height\=\(int\)480\,\ interlace-mode\=\(string\)progressive\,\ pixel-aspect-ratio\=\(fraction\)1/1\,\ colorimetry\=\(string\)1:4:0:0\,\ framerate\=\(fraction\)30/1"
ERROR: from element /GstPipeline:pipeline0/GstVideoParse:videoparse0: Internal data stream error.
Additional debug info:
gstrawparse.c(487): gst_raw_parse_loop (): /GstPipeline:pipeline0/GstVideoParse:videoparse0:
stream stopped, reason not-negotiated
ERROR: pipeline doesn't want to preroll.
Setting pipeline to NULL ...
/GstPipeline:pipeline0/GstCapsFilter:capsfilter1.GstPad:src: caps = "NULL"
/GstPipeline:pipeline0/GstCapsFilter:capsfilter1.GstPad:sink: caps = "NULL"
/GstPipeline:pipeline0/GstVideoConvert:videoconvert0.GstPad:src: caps = "NULL"
/GstPipeline:pipeline0/GstVideoConvert:videoconvert0.GstPad:sink: caps = "NULL"
/GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = "NULL"
/GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:sink: caps = "NULL"
/GstPipeline:pipeline0/GstVideoParse:videoparse0.GstPad:src: caps = "NULL"
Freeing pipeline ...

Is this a bug in avenc_ljpeg, or did I not constrain the caps correctly?

From: gstreamer-devel [[hidden email]] on behalf of Ryan Talbot [[hidden email]]
Sent: Friday, February 3, 2017 11:12 AM
To: [hidden email]
Subject: Lossless end-to-end 16-bit grayscale compression?

This sender failed our fraud detection checks and may not be who they appear to be. Learn about spoofing Feedback
Hi list,

I'm trying to losslessy compress the output of the disparity plugin.  Its source caps say it outputs RGB, but the algorithm itself is supposed to generate 16-bit grayscale.  After a lot of headache, I finally found a combo of avenc_ljpeg and avdec_mjpeg that would work to encode and then decode the RGB stream and get the exact same data on both ends.  Now, I would like to do the same for a 16-bit grayscale stream of images, but am having little luck.  avenc_mjpeg does support GRAY16_BE/LE, but I don't know how to make it lossless.

Does such a solution exist, or do we need to roll our own/modify a codec?

Thanks,
Ryan Talbot

_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

RE: Lossless end-to-end 16-bit grayscale compression?

Ryan Talbot
Nevermind, had to go digging in the gst-libav code, but I solved it... YUV colorspace is only supported by avenc_ljpeg if you set compliance=-1.

This pipeline works:
gst-launch-1.0 -vvv filesrc location=source.g16 ! videoparse width=640 height=480 format=27 framerate=30/1 ! video/x-raw,format=GRAY16_LE,width=640,height=480,framerate=30/1 ! videoconvert ! video/x-raw,format=I420 ! avenc_ljpeg compliance=-1 ! filesink location=losslessgr16.mjpg

Hope this helps somebody out if a similar use case ever crops up!

From: gstreamer-devel [[hidden email]] on behalf of Ryan Talbot [[hidden email]]
Sent: Saturday, February 4, 2017 5:01 PM
To: Discussion of the development of and with GStreamer
Subject: RE: Lossless end-to-end 16-bit grayscale compression?

This sender failed our fraud detection checks and may not be who they appear to be. Learn about spoofing Feedback
> avenc_mjpeg does support GRAY16_BE/LE, but I don't know how to make it lossless.

My mistake, avdec_mjpeg supports GRAY16_BE/LE, the encoder only supports I420,Y42B, and Y444.  The conversion from GRAY16_LE->I420 seems to be lossless, so that's good.  The trouble I'm running into now, though, is that avenc_ljpeg doesn't seem to want to accept YUV-colorspace buffers, even though its sink pad template says it can:

Pad Templates:
  SINK template: 'sink'
    Availability: Always
    Capabilities:
      video/x-raw
                 format: { BGR, BGRA, I420, Y444, Y42B }

This pipeline works fine:
gst-launch-1.0 -vvv filesrc location=source.g16 ! videoparse width=640 height=480 format=27 framerate=30/1 ! video/x-raw,format=GRAY16_LE,width=640,height=480,framerate=30/1 ! videoconvert ! video/x-raw,format=BGR ! avenc_ljpeg ! filesink location=losslessgr16.mjpg

This does not:
gst-launch-1.0 -vvv filesrc location=source.g16 ! videoparse width=640 height=480 format=27 framerate=30/1 ! video/x-raw,format=GRAY16_LE,width=640,height=480,framerate=30/1 ! videoconvert ! video/x-raw,format=I420 ! avenc_ljpeg ! filesink location=losslessgr16.mjpg
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
/GstPipeline:pipeline0/GstVideoParse:videoparse0.GstPad:src: caps = "video/x-raw\,\ format\=\(string\)GRAY16_LE\,\ width\=\(int\)640\,\ height\=\(int\)480\,\ interlace-mode\=\(string\)progressive\,\ pixel-aspect-ratio\=\(fraction\)1/1\,\ colorimetry\=\(string\)1:4:0:0\,\ framerate\=\(fraction\)30/1"
/GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = "video/x-raw\,\ format\=\(string\)GRAY16_LE\,\ width\=\(int\)640\,\ height\=\(int\)480\,\ interlace-mode\=\(string\)progressive\,\ pixel-aspect-ratio\=\(fraction\)1/1\,\ colorimetry\=\(string\)1:4:0:0\,\ framerate\=\(fraction\)30/1"
/GstPipeline:pipeline0/GstVideoConvert:videoconvert0.GstPad:src: caps = "video/x-raw\,\ width\=\(int\)640\,\ height\=\(int\)480\,\ interlace-mode\=\(string\)progressive\,\ pixel-aspect-ratio\=\(fraction\)1/1\,\ framerate\=\(fraction\)30/1\,\ format\=\(string\)I420"
/GstPipeline:pipeline0/GstCapsFilter:capsfilter1.GstPad:src: caps = "video/x-raw\,\ width\=\(int\)640\,\ height\=\(int\)480\,\ interlace-mode\=\(string\)progressive\,\ pixel-aspect-ratio\=\(fraction\)1/1\,\ framerate\=\(fraction\)30/1\,\ format\=\(string\)I420"
/GstPipeline:pipeline0/GstCapsFilter:capsfilter1.GstPad:sink: caps = "video/x-raw\,\ width\=\(int\)640\,\ height\=\(int\)480\,\ interlace-mode\=\(string\)progressive\,\ pixel-aspect-ratio\=\(fraction\)1/1\,\ framerate\=\(fraction\)30/1\,\ format\=\(string\)I420"
/GstPipeline:pipeline0/GstVideoConvert:videoconvert0.GstPad:sink: caps = "video/x-raw\,\ format\=\(string\)GRAY16_LE\,\ width\=\(int\)640\,\ height\=\(int\)480\,\ interlace-mode\=\(string\)progressive\,\ pixel-aspect-ratio\=\(fraction\)1/1\,\ colorimetry\=\(string\)1:4:0:0\,\ framerate\=\(fraction\)30/1"
/GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:sink: caps = "video/x-raw\,\ format\=\(string\)GRAY16_LE\,\ width\=\(int\)640\,\ height\=\(int\)480\,\ interlace-mode\=\(string\)progressive\,\ pixel-aspect-ratio\=\(fraction\)1/1\,\ colorimetry\=\(string\)1:4:0:0\,\ framerate\=\(fraction\)30/1"
ERROR: from element /GstPipeline:pipeline0/GstVideoParse:videoparse0: Internal data stream error.
Additional debug info:
gstrawparse.c(487): gst_raw_parse_loop (): /GstPipeline:pipeline0/GstVideoParse:videoparse0:
stream stopped, reason not-negotiated
ERROR: pipeline doesn't want to preroll.
Setting pipeline to NULL ...
/GstPipeline:pipeline0/GstCapsFilter:capsfilter1.GstPad:src: caps = "NULL"
/GstPipeline:pipeline0/GstCapsFilter:capsfilter1.GstPad:sink: caps = "NULL"
/GstPipeline:pipeline0/GstVideoConvert:videoconvert0.GstPad:src: caps = "NULL"
/GstPipeline:pipeline0/GstVideoConvert:videoconvert0.GstPad:sink: caps = "NULL"
/GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = "NULL"
/GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:sink: caps = "NULL"
/GstPipeline:pipeline0/GstVideoParse:videoparse0.GstPad:src: caps = "NULL"
Freeing pipeline ...

Is this a bug in avenc_ljpeg, or did I not constrain the caps correctly?

From: gstreamer-devel [[hidden email]] on behalf of Ryan Talbot [[hidden email]]
Sent: Friday, February 3, 2017 11:12 AM
To: [hidden email]
Subject: Lossless end-to-end 16-bit grayscale compression?

This sender failed our fraud detection checks and may not be who they appear to be. Learn about spoofing Feedback
Hi list,

I'm trying to losslessy compress the output of the disparity plugin.  Its source caps say it outputs RGB, but the algorithm itself is supposed to generate 16-bit grayscale.  After a lot of headache, I finally found a combo of avenc_ljpeg and avdec_mjpeg that would work to encode and then decode the RGB stream and get the exact same data on both ends.  Now, I would like to do the same for a 16-bit grayscale stream of images, but am having little luck.  avenc_mjpeg does support GRAY16_BE/LE, but I don't know how to make it lossless.

Does such a solution exist, or do we need to roll our own/modify a codec?

Thanks,
Ryan Talbot

_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

RE: Lossless end-to-end 16-bit grayscale compression?

nh4cl
In reply to this post by Ryan Talbot
Hi Ryan, Thanks for your posts.
Could you please explain what you meant by "The conversion from GRAY16_LE->I420 seems to be lossless"? The GRAY16 is just one plane with each pixel being 16-bit, whereas I420 is Luma followed by two sub-sampled Chroma planes with 8-bit per component (12-bit per pixel). You should be loosing the lower 8-bit of your GRAY16_LE content in this conversion.