mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
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
This commit is contained in:
parent
eebc4c0022
commit
2cffa1579a
1 changed files with 70 additions and 42 deletions
|
@ -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;
|
||||
|
||||
gst_byte_reader_init (&reader, map.data, map.size);
|
||||
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;
|
||||
/* 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;
|
||||
|
||||
} 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" (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,12 +486,8 @@ 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,
|
||||
|
@ -503,6 +505,28 @@ gst_jpeg2000_parse_handle_frame (GstBaseParse * parse,
|
|||
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) {
|
||||
|
||||
/* skip Ssiz (precision and signed/unsigned bit ) */
|
||||
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue