From 426b2db2cba849ab4f64a6ba91047380ff338837 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 1 Dec 2008 15:48:13 +0000 Subject: [PATCH] ext/jp2k/: Add image/x-jpc caps name for real, raw JPEG2000 codestream data. Original commit message from CVS: * ext/jp2k/gstjasperdec.c: (gst_jasper_dec_sink_setcaps): * ext/jp2k/gstjasperenc.c: (gst_jasper_enc_reset), (gst_jasper_enc_set_src_caps), (gst_jasper_enc_init_encoder), (gst_jasper_enc_sink_setcaps), (gst_jasper_enc_get_data): * ext/jp2k/gstjasperenc.h: Add image/x-jpc caps name for real, raw JPEG2000 codestream data. In 0.11 we should merge image/x-j2c and image/x-jpc and simply drop the non-standard boxing in the jasper elements and handle it in qtmux/qtdemux. image/x-jpc will be used by mxfdemux later. Also add support for JP2 output in jp2kenc. --- ChangeLog | 15 ++++++++ ext/jp2k/gstjasperdec.c | 15 ++++++-- ext/jp2k/gstjasperenc.c | 91 ++++++++++++++++++++++++++++++++++++++++++------- ext/jp2k/gstjasperenc.h | 7 ++++ 4 files changed, 113 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2929aa7..cd153a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,20 @@ 2008-12-01 Sebastian Dröge + * ext/jp2k/gstjasperdec.c: (gst_jasper_dec_sink_setcaps): + * ext/jp2k/gstjasperenc.c: (gst_jasper_enc_reset), + (gst_jasper_enc_set_src_caps), (gst_jasper_enc_init_encoder), + (gst_jasper_enc_sink_setcaps), (gst_jasper_enc_get_data): + * ext/jp2k/gstjasperenc.h: + Add image/x-jpc caps name for real, raw JPEG2000 codestream data. + In 0.11 we should merge image/x-j2c and image/x-jpc and simply drop + the non-standard boxing in the jasper elements and handle it in + qtmux/qtdemux. + image/x-jpc will be used by mxfdemux later. + + Also add support for JP2 output in jp2kenc. + +2008-12-01 Sebastian Dröge + * gst/mxf/mxfaes-bwf.c: (mxf_bwf_create_caps): * gst/mxf/mxfalaw.c: (mxf_alaw_create_caps): * gst/mxf/mxfdemux.c: diff --git a/ext/jp2k/gstjasperdec.c b/ext/jp2k/gstjasperdec.c index fb0b10a..9b334de 100644 --- a/ext/jp2k/gstjasperdec.c +++ b/ext/jp2k/gstjasperdec.c @@ -48,12 +48,19 @@ enum ARG_0, }; +/* FIXME 0.11: Use a single caps name for jpeg2000 codestreams + * and drop the "boxed" variant + */ + static GstStaticPadTemplate gst_jasper_dec_sink_template = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS ("image/x-j2c, " "framerate = " GST_VIDEO_FPS_RANGE ", " + "fields = (int) 1; " + "image/x-jpc, " + "framerate = " GST_VIDEO_FPS_RANGE ", " "fields = (int) 1; " "image/jp2") ); @@ -181,7 +188,7 @@ gst_jasper_dec_sink_setcaps (GstPad * pad, GstCaps * caps) dec->codec_data = NULL; } - if (!strcmp (mimetype, "image/x-j2c")) { + if (!strcmp (mimetype, "image/x-j2c") || !strcmp (mimetype, "image/x-jpc")) { const GValue *codec_data; gint fields; @@ -207,7 +214,11 @@ gst_jasper_dec_sink_setcaps (GstPad * pad, GstCaps * caps) dec->fmt = jas_image_strtofmt ("jpc"); /* strip the j2c box stuff it is embedded in */ - dec->strip = 8; + if (!strcmp (mimetype, "image/x-jpc")) + dec->strip = 0; + else + dec->strip = 8; + codec_data = gst_structure_get_value (s, "codec_data"); if (codec_data) { dec->codec_data = gst_value_get_buffer (codec_data); diff --git a/ext/jp2k/gstjasperenc.c b/ext/jp2k/gstjasperenc.c index b0bbf22..095bc8f 100644 --- a/ext/jp2k/gstjasperenc.c +++ b/ext/jp2k/gstjasperenc.c @@ -59,11 +59,14 @@ static GstStaticPadTemplate gst_jasper_enc_sink_template = ); static GstStaticPadTemplate gst_jasper_enc_src_template = -GST_STATIC_PAD_TEMPLATE ("src", + GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS ("image/x-j2c, " - "framerate = " GST_VIDEO_FPS_RANGE ", " "fields = (int) 1") + "framerate = " GST_VIDEO_FPS_RANGE ", " "fields = (int) 1; " + "image/x-jpc, " + "framerate = " GST_VIDEO_FPS_RANGE ", " "fields = (int) 1; " + "image/jp2") ); static void gst_jasper_enc_base_init (gpointer g_class); @@ -155,6 +158,7 @@ gst_jasper_enc_reset (GstJasperEnc * enc) jas_image_destroy (enc->image); enc->image = NULL; enc->fmt = -1; + enc->mode = GST_JP2ENC_MODE_J2C; enc->clrspc = JAS_CLRSPC_UNKNOWN; enc->format = GST_VIDEO_FORMAT_UNKNOWN; } @@ -165,6 +169,29 @@ gst_jasper_enc_set_src_caps (GstJasperEnc * enc) GstCaps *caps; guint32 fourcc; gboolean ret; + GstCaps *peercaps; + + peercaps = gst_pad_peer_get_caps (enc->srcpad); + if (peercaps) { + guint i, n; + + n = gst_caps_get_size (peercaps); + for (i = 0; i < n; i++) { + GstStructure *s = gst_caps_get_structure (peercaps, i); + const gchar *name = gst_structure_get_name (s); + + if (!strcmp (name, "image/x-j2c")) { + enc->mode = GST_JP2ENC_MODE_J2C; + break; + } else if (!strcmp (name, "image/x-jpc")) { + enc->mode = GST_JP2ENC_MODE_JPC; + break; + } else if (!strcmp (name, "image/jp2")) { + enc->mode = GST_JP2ENC_MODE_JP2; + break; + } + } + } /* enumerated colourspace */ if (gst_video_format_is_rgb (enc->format)) { @@ -173,9 +200,26 @@ gst_jasper_enc_set_src_caps (GstJasperEnc * enc) fourcc = GST_MAKE_FOURCC ('s', 'Y', 'U', 'V'); } - caps = gst_caps_new_simple ("image/x-j2c", "width", G_TYPE_INT, enc->width, - "height", G_TYPE_INT, enc->height, "fourcc", GST_TYPE_FOURCC, fourcc, - NULL); + switch (enc->mode) { + case GST_JP2ENC_MODE_J2C: + caps = + gst_caps_new_simple ("image/x-j2c", "width", G_TYPE_INT, enc->width, + "height", G_TYPE_INT, enc->height, "fourcc", GST_TYPE_FOURCC, fourcc, + NULL); + break; + case GST_JP2ENC_MODE_JPC: + caps = + gst_caps_new_simple ("image/x-jpc", "width", G_TYPE_INT, enc->width, + "height", G_TYPE_INT, enc->height, "fourcc", GST_TYPE_FOURCC, fourcc, + NULL); + break; + case GST_JP2ENC_MODE_JP2: + caps = gst_caps_new_simple ("image/jp2", "width", G_TYPE_INT, enc->width, + "height", G_TYPE_INT, enc->height, "fourcc", GST_TYPE_FOURCC, fourcc, + NULL); + break; + } + if (enc->fps_den > 0) gst_caps_set_simple (caps, @@ -197,7 +241,15 @@ gst_jasper_enc_init_encoder (GstJasperEnc * enc) jas_image_cmptparm_t param[GST_JASPER_ENC_MAX_COMPONENT]; gint i; - enc->fmt = jas_image_strtofmt ("jpc"); + switch (enc->mode) { + case GST_JP2ENC_MODE_J2C: + case GST_JP2ENC_MODE_JPC: + enc->fmt = jas_image_strtofmt ("jpc"); + break; + case GST_JP2ENC_MODE_JP2: + enc->fmt = jas_image_strtofmt ("jp2"); + break; + } if (gst_video_format_is_rgb (enc->format)) enc->clrspc = JAS_CLRSPC_SRGB; @@ -282,10 +334,12 @@ gst_jasper_enc_sink_setcaps (GstPad * pad, GstCaps * caps) enc->inc[i] = gst_video_format_get_pixel_stride (format, i); } + if (!gst_jasper_enc_set_src_caps (enc)) + goto setcaps_failed; if (!gst_jasper_enc_init_encoder (enc)) goto setup_failed; - return gst_jasper_enc_set_src_caps (enc); + return TRUE; /* ERRORS */ setup_failed: @@ -293,6 +347,12 @@ setup_failed: GST_ELEMENT_ERROR (enc, LIBRARY, SETTINGS, (NULL), (NULL)); return FALSE; } +setcaps_failed: + { + GST_WARNING_OBJECT (enc, "Setting src caps failed"); + GST_ELEMENT_ERROR (enc, LIBRARY, SETTINGS, (NULL), (NULL)); + return FALSE; + } refuse_caps: { GST_WARNING_OBJECT (enc, "refused caps %" GST_PTR_FORMAT, caps); @@ -307,12 +367,14 @@ gst_jasper_enc_get_data (GstJasperEnc * enc, guint8 * data, GstBuffer ** outbuf) GstFlowReturn ret = GST_FLOW_OK; jas_stream_t *stream = NULL; gint i; - guint size; + guint size, boxsize; g_return_val_if_fail (outbuf != NULL, GST_FLOW_ERROR); *outbuf = NULL; + boxsize = (enc->mode == GST_JP2ENC_MODE_J2C) ? 8 : 0; + if (!(stream = jas_stream_memopen (NULL, 0))) goto fail_stream; @@ -356,7 +418,8 @@ gst_jasper_enc_get_data (GstJasperEnc * enc, guint8 * data, GstBuffer ** outbuf) size = jas_stream_length (stream); ret = gst_pad_alloc_buffer_and_set_caps (enc->srcpad, - GST_BUFFER_OFFSET_NONE, size + 8, GST_PAD_CAPS (enc->srcpad), outbuf); + GST_BUFFER_OFFSET_NONE, size + boxsize, GST_PAD_CAPS (enc->srcpad), + outbuf); if (ret != GST_FLOW_OK) goto no_buffer; @@ -364,12 +427,14 @@ gst_jasper_enc_get_data (GstJasperEnc * enc, guint8 * data, GstBuffer ** outbuf) data = GST_BUFFER_DATA (*outbuf); if (jas_stream_flush (stream) || jas_stream_rewind (stream) < 0 || - jas_stream_read (stream, data + 8, size) < size) + jas_stream_read (stream, data + boxsize, size) < size) goto fail_image_out; - /* write atom prefix */ - GST_WRITE_UINT32_BE (data, size + 8); - GST_WRITE_UINT32_LE (data + 4, GST_MAKE_FOURCC ('j', 'p', '2', 'c')); + if (boxsize) { + /* write atom prefix */ + GST_WRITE_UINT32_BE (data, size + 8); + GST_WRITE_UINT32_LE (data + 4, GST_MAKE_FOURCC ('j', 'p', '2', 'c')); + } done: if (stream) diff --git a/ext/jp2k/gstjasperenc.h b/ext/jp2k/gstjasperenc.h index 93090cd..7cfd2ff 100644 --- a/ext/jp2k/gstjasperenc.h +++ b/ext/jp2k/gstjasperenc.h @@ -42,6 +42,12 @@ G_BEGIN_DECLS typedef struct _GstJasperEnc GstJasperEnc; typedef struct _GstJasperEncClass GstJasperEncClass; +enum { + GST_JP2ENC_MODE_J2C = 0, + GST_JP2ENC_MODE_JPC, + GST_JP2ENC_MODE_JP2 +}; + #define GST_JASPER_ENC_MAX_COMPONENT 4 struct _GstJasperEnc @@ -55,6 +61,7 @@ struct _GstJasperEnc /* jasper image fmt */ gint fmt; + gint mode; jas_clrspc_t clrspc; /* stream/image properties */ -- 2.7.4