From: Aaron Boxer Date: Mon, 12 Jun 2017 13:47:49 +0000 (-0400) Subject: jpeg2000parse: allow parsing when current caps are null X-Git-Tag: 1.19.3~507^2~5088 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2cffa1579a1adeded10a9036876d729bbf6a32d1;p=platform%2Fupstream%2Fgstreamer.git jpeg2000parse: allow parsing when current caps are null In this case, we assume that the format is jpc, and we infer the color space from the number of components. This allows the parser to process a jpc disk file coming from a filesrc element. https://bugzilla.gnome.org/show_bug.cgi?id=783291 --- diff --git a/gst/videoparsers/gstjpeg2000parse.c b/gst/videoparsers/gstjpeg2000parse.c index f20aea0..36da1f6 100644 --- a/gst/videoparsers/gstjpeg2000parse.c +++ b/gst/videoparsers/gstjpeg2000parse.c @@ -108,13 +108,7 @@ static GstStaticPadTemplate srctemplate = static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS ("image/x-jpc," - GST_JPEG2000_SAMPLING_LIST ";" - "image/x-jpc, " - GST_JPEG2000_COLORSPACE_LIST ";" - "image/x-j2c," - GST_JPEG2000_SAMPLING_LIST ";" - "image/x-j2c, " GST_JPEG2000_COLORSPACE_LIST) + GST_STATIC_CAPS ("image/x-jpc;image/x-j2c") ); #define parent_class gst_jpeg2000_parse_parent_class @@ -250,17 +244,12 @@ gst_jpeg2000_parse_negotiate (GstJPEG2000Parse * parse, GstCaps * in_caps) } } - /* FIXME We could fail the negotiation immediatly if caps are empty */ if (caps && !gst_caps_is_empty (caps)) { /* fixate to avoid ambiguity with lists when parsing */ caps = gst_caps_fixate (caps); codec_format = format_from_media_type (gst_caps_get_structure (caps, 0)); } - /* default */ - if (codec_format == GST_JPEG2000_PARSE_NO_CODEC) - codec_format = GST_JPEG2000_PARSE_J2C; - GST_DEBUG_OBJECT (parse, "selected codec format %d", codec_format); parse->codec_format = codec_format; @@ -296,7 +285,6 @@ gst_jpeg2000_parse_handle_frame (GstBaseParse * parse, guint eoc_offset = 0; GstCaps *current_caps = NULL; GstStructure *current_caps_struct = NULL; - const gchar *colorspace_string = NULL; GstJPEG2000Colorspace colorspace = GST_JPEG2000_COLORSPACE_NONE; guint x0, y0, x1, y1; guint width = 0, height = 0; @@ -319,27 +307,45 @@ gst_jpeg2000_parse_handle_frame (GstBaseParse * parse, GstCaps *src_caps = NULL; guint frame_size = 0; gboolean is_j2c; + gboolean parsed_j2c_4cc = FALSE; if (!gst_buffer_map (frame->buffer, &map, GST_MAP_READ)) { GST_ERROR_OBJECT (jpeg2000parse, "Unable to map buffer"); return GST_FLOW_ERROR; } + gst_byte_reader_init (&reader, map.data, map.size); + /* try to get from caps */ if (jpeg2000parse->codec_format == GST_JPEG2000_PARSE_NO_CODEC) gst_jpeg2000_parse_negotiate (jpeg2000parse, NULL); - is_j2c = jpeg2000parse->codec_format == GST_JPEG2000_PARSE_J2C; + /* if we can't get from caps, then try to parse */ + if (jpeg2000parse->codec_format == GST_JPEG2000_PARSE_NO_CODEC) { + /* check for "jp2c" */ + j2c_box_id_offset = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff, + GST_MAKE_FOURCC ('j', 'p', '2', 'c'), 0, + gst_byte_reader_get_remaining (&reader)); + parsed_j2c_4cc = TRUE; + is_j2c = j2c_box_id_offset != -1; + /* since we only support j2c and jpc at the moment, we can deduce the codec format */ + jpeg2000parse->codec_format = + is_j2c ? GST_JPEG2000_PARSE_J2C : GST_JPEG2000_PARSE_JPC; - gst_byte_reader_init (&reader, map.data, map.size); - num_prefix_bytes = GST_JPEG2000_MARKER_SIZE; + } else { + is_j2c = jpeg2000parse->codec_format == GST_JPEG2000_PARSE_J2C; + } + num_prefix_bytes = GST_JPEG2000_MARKER_SIZE; if (is_j2c) { num_prefix_bytes += GST_JPEG2000_JP2_SIZE_OF_BOX_LEN + GST_JPEG2000_JP2_SIZE_OF_BOX_ID; - /* check for "jp2c" */ - j2c_box_id_offset = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff, - GST_MAKE_FOURCC ('j', 'p', '2', 'c'), 0, - gst_byte_reader_get_remaining (&reader)); + /* check for "jp2c" (may have already parsed j2c_box_id_offset if caps are empty) */ + if (!parsed_j2c_4cc) { + j2c_box_id_offset = + gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff, + GST_MAKE_FOURCC ('j', 'p', '2', 'c'), 0, + gst_byte_reader_get_remaining (&reader)); + } if (j2c_box_id_offset == -1) { GST_ELEMENT_ERROR (jpeg2000parse, STREAM, DECODE, NULL, @@ -480,28 +486,46 @@ gst_jpeg2000_parse_handle_frame (GstBaseParse * parse, } current_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (parse)); - if (!current_caps) { - GST_ERROR_OBJECT (jpeg2000parse, "Unable to get current caps"); - ret = GST_FLOW_NOT_NEGOTIATED; - goto beach; - } + if (current_caps) { + const gchar *colorspace_string = NULL; + current_caps_struct = gst_caps_get_structure (current_caps, 0); + if (!current_caps_struct) { + GST_ERROR_OBJECT (jpeg2000parse, + "Unable to get structure of current caps struct"); + ret = GST_FLOW_NOT_NEGOTIATED; + goto beach; + } - current_caps_struct = gst_caps_get_structure (current_caps, 0); - if (!current_caps_struct) { - GST_ERROR_OBJECT (jpeg2000parse, - "Unable to get structure of current caps struct"); - ret = GST_FLOW_NOT_NEGOTIATED; - goto beach; - } + colorspace_string = gst_structure_get_string + (current_caps_struct, "colorspace"); + if (colorspace_string) + colorspace = gst_jpeg2000_colorspace_from_string (colorspace_string); + sink_sampling_string = gst_structure_get_string + (current_caps_struct, "sampling"); + if (sink_sampling_string) + sink_sampling = gst_jpeg2000_sampling_from_string (sink_sampling_string); - colorspace_string = gst_structure_get_string - (current_caps_struct, "colorspace"); - if (colorspace_string) - colorspace = gst_jpeg2000_colorspace_from_string (colorspace_string); - sink_sampling_string = gst_structure_get_string - (current_caps_struct, "sampling"); - if (sink_sampling_string) - sink_sampling = gst_jpeg2000_sampling_from_string (sink_sampling_string); + } else { + /* guess color space based on number of components */ + if (numcomps == 0 || numcomps > 4) { + GST_ERROR_OBJECT (jpeg2000parse, + "Unable to guess color space from number of components %d", numcomps); + ret = GST_FLOW_NOT_NEGOTIATED; + goto beach; + } + colorspace = + (numcomps >= + 3) ? GST_JPEG2000_COLORSPACE_RGB : GST_JPEG2000_COLORSPACE_GRAY; + if (numcomps == 4) { + GST_WARNING_OBJECT (jpeg2000parse, "No caps available: assuming RGBA"); + } else if (numcomps == 3) { + GST_WARNING_OBJECT (jpeg2000parse, "No caps available: assuming RGB"); + } else if (numcomps == 2) { + GST_WARNING_OBJECT (jpeg2000parse, + "No caps available: assuming grayscale with alpha"); + } + + } for (compno = 0; compno < numcomps; ++compno) { @@ -651,13 +675,15 @@ gst_jpeg2000_parse_handle_frame (GstBaseParse * parse, } } - if (gst_structure_get_fraction (current_caps_struct, "framerate", &fr_num, + if (current_caps_struct && + gst_structure_get_fraction (current_caps_struct, "framerate", &fr_num, &fr_denom)) { gst_caps_set_simple (src_caps, "framerate", GST_TYPE_FRACTION, fr_num, fr_denom, NULL); } else { GST_WARNING_OBJECT (jpeg2000parse, "No framerate set"); } + if (!gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (parse), src_caps)) { GST_ERROR_OBJECT (jpeg2000parse, "Unable to set source caps"); ret = GST_FLOW_NOT_NEGOTIATED; @@ -690,6 +716,8 @@ gst_jpeg2000_parse_handle_frame (GstBaseParse * parse, frame_size, eoc_frame_size); } frame_size = eoc_frame_size; + } else { + goto beach; } /* clean up and finish frame */