gstrtpj2k: set sampling field required by RFC

This field is now required in the sink caps.

https://bugzilla.gnome.org/show_bug.cgi?id=766236
This commit is contained in:
Aaron Boxer 2016-05-13 15:08:24 -04:00 committed by Sebastian Dröge
parent 4e23d206b9
commit b4a4fa19a1
3 changed files with 116 additions and 24 deletions

View file

@ -22,6 +22,59 @@
#define __GST_RTP_J2K_COMMON_H__ #define __GST_RTP_J2K_COMMON_H__
/* Sampling values from RFC 5371 for JPEG 2000 over RTP : https://datatracker.ietf.org/doc/rfc5371/C
RGB: standard Red, Green, Blue color space.
BGR: standard Blue, Green, Red color space.
RGBA: standard Red, Green, Blue, Alpha color space.
BGRA: standard Blue, Green, Red, Alpha color space.
YCbCr-4:4:4: standard YCbCr color space; no subsampling.
YCbCr-4:2:2: standard YCbCr color space; Cb and Cr are subsampled horizontally by 1/2.
YCbCr-4:2:0: standard YCbCr color space; Cb and Cr are subsampled horizontally and vertically by 1/2.
YCbCr-4:1:1: standard YCbCr color space; Cb and Cr are subsampled vertically by 1/4.
GRAYSCALE: basically, a single component image of just multilevels of grey.
*/
#define GST_RTP_J2K_RGB "RGB"
#define GST_RTP_J2K_BGR "BGR"
#define GST_RTP_J2K_RGBA "RGBA"
#define GST_RTP_J2K_BGRA "BGRA"
#define GST_RTP_J2K_YBRA "YCbCrA"
#define GST_RTP_J2K_YBR444 "YCbCr-4:4:4"
#define GST_RTP_J2K_YBR422 "YCbCr-4:2:2"
#define GST_RTP_J2K_YBR420 "YCbCr-4:2:0"
#define GST_RTP_J2K_YBR410 "YCbCr-4:1:0"
#define GST_RTP_J2K_GRAYSCALE "GRAYSCALE"
#define GST_RTP_J2K_SAMPLING_LIST "sampling = (string) {\"RGB\", \"BGR\", \"RGBA\", \"BGRA\", \"YCbCrA\", \"YCbCr-4:4:4\", \"YCbCr-4:2:2\", \"YCbCr-4:2:0\", \"YCbCr-4:1:1\", \"GRAYSCALE\"}"
typedef enum
{
GST_RTP_SAMPLING_NONE,
GST_RTP_SAMPLING_RGB,
GST_RTP_SAMPLING_BGR,
GST_RTP_SAMPLING_RGBA,
GST_RTP_SAMPLING_BGRA,
GST_RTP_SAMPLING_YBRA,
GST_RTP_SAMPLING_YBR444,
GST_RTP_SAMPLING_YBR422,
GST_RTP_SAMPLING_YBR420,
GST_RTP_SAMPLING_YBR410,
GST_RTP_SAMPLING_GRAYSCALE
} GstRtpSampling;
/* /*
* GstRtpJ2KMarker: * GstRtpJ2KMarker:
* @GST_J2K_MARKER: Prefix for JPEG 2000 marker * @GST_J2K_MARKER: Prefix for JPEG 2000 marker
@ -29,7 +82,7 @@
* @GST_J2K_MARKER_SOT: Start of tile * @GST_J2K_MARKER_SOT: Start of tile
* @GST_J2K_MARKER_EOC: End of Codestream * @GST_J2K_MARKER_EOC: End of Codestream
* *
* Identifers for markers in JPEG 2000 codestreams * Identifiers for markers in JPEG 2000 code streams
*/ */
typedef enum typedef enum
{ {

View file

@ -47,16 +47,22 @@ static GstStaticPadTemplate gst_rtp_j2k_depay_src_template =
GST_STATIC_PAD_TEMPLATE ("src", GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS ("image/x-jpc") GST_STATIC_CAPS ("image/x-jpc, "
"colorspace = (string) { sRGB, sYUV, GRAY }")
); );
static GstStaticPadTemplate gst_rtp_j2k_depay_sink_template = static GstStaticPadTemplate gst_rtp_j2k_depay_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink", GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS ("application/x-rtp, " GST_STATIC_CAPS ("application/x-rtp, "
"media = (string) \"video\", " "media = (string) \"video\", " "clock-rate = (int) 90000, "
"clock-rate = (int) 90000, " "encoding-name = (string) \"JPEG2000\"") GST_RTP_J2K_SAMPLING_LIST ","
"encoding-name = (string) \"JPEG2000\";"
"application/x-rtp, "
"media = (string) \"video\", " "clock-rate = (int) 90000, "
"colorspace = (string) { sRGB, sYUV, GRAY }, "
"encoding-name = (string) \"JPEG2000\";")
); );
enum enum
@ -177,10 +183,12 @@ gst_rtp_j2k_depay_finalize (GObject * object)
static gboolean static gboolean
gst_rtp_j2k_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps) gst_rtp_j2k_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
{ {
GstStructure *structure; GstStructure *structure = NULL;
gint clock_rate; gint clock_rate;
GstCaps *outcaps; GstCaps *outcaps = NULL;
gboolean res; gboolean res = FALSE;
const gchar *colorspace = NULL;
const gchar *sampling = NULL;
structure = gst_caps_get_structure (caps, 0); structure = gst_caps_get_structure (caps, 0);
@ -188,10 +196,35 @@ gst_rtp_j2k_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
clock_rate = 90000; clock_rate = 90000;
depayload->clock_rate = clock_rate; depayload->clock_rate = clock_rate;
outcaps = sampling = gst_structure_get_string (structure, "sampling");
gst_caps_new_simple ("image/x-jpc", "framerate", GST_TYPE_FRACTION, 0, 1, if (sampling) {
"fields", G_TYPE_INT, 1, "colorspace", G_TYPE_STRING, "sYUV", NULL); if (!strcmp (sampling, GST_RTP_J2K_RGB) ||
!strcmp (sampling, GST_RTP_J2K_RGBA) ||
!strcmp (sampling, GST_RTP_J2K_BGR) ||
!strcmp (sampling, GST_RTP_J2K_BGRA))
colorspace = "sRGB";
else if (!strcmp (sampling, GST_RTP_J2K_GRAYSCALE))
colorspace = "GRAY";
else
colorspace = "sYUV";
} else {
GST_ELEMENT_WARNING (depayload, STREAM, DEMUX, NULL,
("Non-compliant stream: sampling field missing. Frames my appear incorrect"));
colorspace = gst_structure_get_string (structure, "colorspace");
if (!strcmp (colorspace, "GRAY")) {
sampling = GST_RTP_J2K_GRAYSCALE;
}
}
outcaps = gst_caps_new_simple ("image/x-jpc",
"framerate", GST_TYPE_FRACTION, 0, 1,
"fields", G_TYPE_INT, 1, "colorspace", G_TYPE_STRING, colorspace, NULL);
if (sampling)
gst_caps_set_simple (outcaps, "sampling", G_TYPE_STRING, sampling, NULL);
res = gst_pad_set_caps (depayload->srcpad, outcaps); res = gst_pad_set_caps (depayload->srcpad, outcaps);
gst_caps_unref (outcaps); gst_caps_unref (outcaps);
return res; return res;

View file

@ -48,9 +48,10 @@ static GstStaticPadTemplate gst_rtp_j2k_pay_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink", GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS ("image/x-jpc") GST_STATIC_CAPS ("image/x-jpc, " GST_RTP_J2K_SAMPLING_LIST)
); );
static GstStaticPadTemplate gst_rtp_j2k_pay_src_template = static GstStaticPadTemplate gst_rtp_j2k_pay_src_template =
GST_STATIC_PAD_TEMPLATE ("src", GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
@ -59,7 +60,7 @@ GST_STATIC_PAD_TEMPLATE ("src",
" media = (string) \"video\", " " media = (string) \"video\", "
" payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", " " payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
" clock-rate = (int) 90000, " " clock-rate = (int) 90000, "
" encoding-name = (string) \"JPEG2000\"") GST_RTP_J2K_SAMPLING_LIST "," " encoding-name = (string) \"JPEG2000\"")
); );
GST_DEBUG_CATEGORY_STATIC (rtpj2kpay_debug); GST_DEBUG_CATEGORY_STATIC (rtpj2kpay_debug);
@ -137,24 +138,29 @@ static gboolean
gst_rtp_j2k_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps) gst_rtp_j2k_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps)
{ {
GstStructure *caps_structure = gst_caps_get_structure (caps, 0); GstStructure *caps_structure = gst_caps_get_structure (caps, 0);
GstRtpJ2KPay *pay;
gint width = 0, height = 0;
gboolean res; gboolean res;
gint width = 0, height = 0;
const gchar *sampling = NULL;
pay = GST_RTP_J2K_PAY (basepayload); gboolean has_width = gst_structure_get_int (caps_structure, "width", &width);
gboolean has_height =
gst_structure_get_int (caps_structure, "height", &height);
/* these properties are not mandatory, we can get them from the stream */
if (gst_structure_get_int (caps_structure, "height", &height)) { /* sampling is a required field */
pay->height = height; sampling = gst_structure_get_string (caps_structure, "sampling");
}
if (gst_structure_get_int (caps_structure, "width", &width)) {
pay->width = width;
}
gst_rtp_base_payload_set_options (basepayload, "video", TRUE, "JPEG2000", gst_rtp_base_payload_set_options (basepayload, "video", TRUE, "JPEG2000",
90000); 90000);
res = gst_rtp_base_payload_set_outcaps (basepayload, NULL);
if (has_width && has_height)
res = gst_rtp_base_payload_set_outcaps (basepayload,
"sampling", G_TYPE_STRING, sampling, "width", G_TYPE_INT, width,
"height", G_TYPE_INT, height, NULL);
else
res =
gst_rtp_base_payload_set_outcaps (basepayload, "sampling",
G_TYPE_STRING, sampling, NULL);
return res; return res;
} }