summaryrefslogtreecommitdiff
path: root/gst/jpegformat/gstjpegparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst/jpegformat/gstjpegparse.c')
-rw-r--r--gst/jpegformat/gstjpegparse.c140
1 files changed, 76 insertions, 64 deletions
diff --git a/gst/jpegformat/gstjpegparse.c b/gst/jpegformat/gstjpegparse.c
index 1d4eaf9a2..fd977dc79 100644
--- a/gst/jpegformat/gstjpegparse.c
+++ b/gst/jpegformat/gstjpegparse.c
@@ -59,7 +59,7 @@ GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("image/jpeg, "
- "format = (fourcc) { I420, Y41B, UYVY, YV12 }, "
+ "format = (string) { I420, Y41B, UYVY, YV12 }, "
"width = (int) [ 0, MAX ],"
"height = (int) [ 0, MAX ], "
"interlaced = (boolean) { true, false }, "
@@ -99,8 +99,8 @@ struct _GstJpegParsePrivate
/* TRUE if the image is interlaced */
gboolean interlaced;
- /* fourcc color space */
- guint32 fourcc;
+ /* format color space */
+ const gchar *format;
/* TRUE if the src caps sets a specific framerate */
gboolean has_fps;
@@ -124,31 +124,12 @@ static void gst_jpeg_parse_dispose (GObject * object);
static GstFlowReturn gst_jpeg_parse_chain (GstPad * pad, GstBuffer * buffer);
static gboolean gst_jpeg_parse_sink_setcaps (GstPad * pad, GstCaps * caps);
static gboolean gst_jpeg_parse_sink_event (GstPad * pad, GstEvent * event);
-static GstCaps *gst_jpeg_parse_src_getcaps (GstPad * pad);
+static GstCaps *gst_jpeg_parse_src_getcaps (GstPad * pad, GstCaps * filter);
static GstStateChangeReturn gst_jpeg_parse_change_state (GstElement * element,
GstStateChange transition);
-#define _do_init(bla) \
- GST_DEBUG_CATEGORY_INIT (jpeg_parse_debug, "jpegparse", 0, "JPEG parser");
-
-GST_BOILERPLATE_FULL (GstJpegParse, gst_jpeg_parse, GstElement,
- GST_TYPE_ELEMENT, _do_init);
-
-static void
-gst_jpeg_parse_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_add_static_pad_template (element_class,
- &gst_jpeg_parse_src_pad_template);
- gst_element_class_add_static_pad_template (element_class,
- &gst_jpeg_parse_sink_pad_template);
- gst_element_class_set_details_simple (element_class,
- "JPEG stream parser",
- "Video/Parser",
- "Parse JPEG images into single-frame buffers",
- "Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>");
-}
+#define gst_jpeg_parse_parent_class parent_class
+G_DEFINE_TYPE (GstJpegParse, gst_jpeg_parse, GST_TYPE_ELEMENT);
static void
gst_jpeg_parse_class_init (GstJpegParseClass * klass)
@@ -164,10 +145,23 @@ gst_jpeg_parse_class_init (GstJpegParseClass * klass)
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_jpeg_parse_change_state);
+
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&gst_jpeg_parse_src_pad_template));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&gst_jpeg_parse_sink_pad_template));
+
+ gst_element_class_set_details_simple (gstelement_class,
+ "JPEG stream parser",
+ "Video/Parser",
+ "Parse JPEG images into single-frame buffers",
+ "Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>");
+
+ GST_DEBUG_CATEGORY_INIT (jpeg_parse_debug, "jpegparse", 0, "JPEG parser");
}
static void
-gst_jpeg_parse_init (GstJpegParse * parse, GstJpegParseClass * g_class)
+gst_jpeg_parse_init (GstJpegParse * parse)
{
GstPad *sinkpad;
@@ -181,8 +175,6 @@ gst_jpeg_parse_init (GstJpegParse * parse, GstJpegParseClass * g_class)
GST_DEBUG_FUNCPTR (gst_jpeg_parse_chain));
gst_pad_set_event_function (sinkpad,
GST_DEBUG_FUNCPTR (gst_jpeg_parse_sink_event));
- gst_pad_set_setcaps_function (sinkpad,
- GST_DEBUG_FUNCPTR (gst_jpeg_parse_sink_setcaps));
gst_element_add_pad (GST_ELEMENT (parse), sinkpad);
parse->priv->srcpad =
@@ -234,12 +226,11 @@ gst_jpeg_parse_sink_setcaps (GstPad * pad, GstCaps * caps)
}
static GstCaps *
-gst_jpeg_parse_src_getcaps (GstPad * pad)
+gst_jpeg_parse_src_getcaps (GstPad * pad, GstCaps * filter)
{
GstCaps *result;
- if ((result = GST_PAD_CAPS (pad))) {
- result = gst_caps_ref (result);
+ if ((result = gst_pad_get_current_caps (pad))) {
GST_DEBUG_OBJECT (pad, "using pad caps %" GST_PTR_FORMAT, result);
} else {
result = gst_caps_ref (GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (pad)));
@@ -487,21 +478,21 @@ gst_jpeg_parse_sof (GstJpegParse * parse, GstByteReader * reader)
}
if (numcomps == 1) {
- /* gray image - no fourcc */
- parse->priv->fourcc = 0;
+ /* gray image - no format */
+ parse->priv->format = "";
} else if (numcomps == 3) {
temp = (blockWidth[0] * blockHeight[0]) / (blockWidth[1] * blockHeight[1]);
if (temp == 4 && blockHeight[0] == 2)
- parse->priv->fourcc = GST_MAKE_FOURCC ('I', '4', '2', '0');
+ parse->priv->format = "I420";
else if (temp == 4 && blockHeight[0] == 4)
- parse->priv->fourcc = GST_MAKE_FOURCC ('Y', '4', '1', 'B');
+ parse->priv->format = "Y41B";
else if (temp == 2)
- parse->priv->fourcc = GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y');
+ parse->priv->format = "UYVY";
else if (temp == 1)
- parse->priv->fourcc = GST_MAKE_FOURCC ('Y', 'V', '1', '2');
+ parse->priv->format = "YV12";
else
- parse->priv->fourcc = 0;
+ parse->priv->format = "";
} else {
return FALSE;
}
@@ -517,7 +508,8 @@ gst_jpeg_parse_remove_marker (GstJpegParse * parse,
{
guint16 size = 0;
guint pos = gst_byte_reader_get_pos (reader);
- guint8 *data = GST_BUFFER_DATA (buffer);
+ guint8 *data;
+ gsize bsize;
if (!gst_byte_reader_peek_uint16_be (reader, &size))
return FALSE;
@@ -526,9 +518,9 @@ gst_jpeg_parse_remove_marker (GstJpegParse * parse,
GST_LOG_OBJECT (parse, "unhandled marker %x removing %u bytes", marker, size);
- memmove (&data[pos], &data[pos + size],
- GST_BUFFER_SIZE (buffer) - (pos + size));
- GST_BUFFER_SIZE (buffer) -= size;
+ data = gst_buffer_map (buffer, &bsize, NULL, GST_MAP_READWRITE);
+ memmove (&data[pos], &data[pos + size], bsize - (pos + size));
+ gst_buffer_unmap (buffer, data, bsize - size);
if (!gst_byte_reader_set_pos (reader, pos - size))
return FALSE;
@@ -579,14 +571,12 @@ get_tag_list (GstJpegParse * parse)
static inline void
extract_and_queue_tags (GstJpegParse * parse, guint size, guint8 * data,
- GstTagList * (*tag_func) (const GstBuffer * buff))
+ GstTagList * (*tag_func) (GstBuffer * buff))
{
GstTagList *tags;
GstBuffer *buf;
- buf = gst_buffer_new ();
- GST_BUFFER_DATA (buf) = data;
- GST_BUFFER_SIZE (buf) = size;
+ buf = gst_buffer_new_wrapped_full (data, NULL, 0, size);
tags = tag_func (buf);
gst_buffer_unref (buf);
@@ -702,9 +692,14 @@ gst_jpeg_parse_com (GstJpegParse * parse, GstByteReader * reader)
static gboolean
gst_jpeg_parse_read_header (GstJpegParse * parse, GstBuffer * buffer)
{
- GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (buffer);
+ GstByteReader reader;
guint8 marker = 0;
gboolean foundSOF = FALSE;
+ guint8 *data;
+ gsize size;
+
+ data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+ gst_byte_reader_init (&reader, data, size);
if (!gst_byte_reader_peek_uint8 (&reader, &marker))
goto error;
@@ -720,7 +715,7 @@ gst_jpeg_parse_read_header (GstJpegParse * parse, GstBuffer * buffer)
switch (marker) {
case SOS: /* start of scan (begins compressed data) */
- return foundSOF;
+ goto done;
case SOI:
break;
@@ -751,12 +746,12 @@ gst_jpeg_parse_read_header (GstJpegParse * parse, GstBuffer * buffer)
parse->priv->interlaced = TRUE;
/* fall through */
case SOF0:
- foundSOF = TRUE;
/* parse Start Of Frame */
if (!gst_jpeg_parse_sof (parse, &reader))
goto error;
- return TRUE;
+ foundSOF = TRUE;
+ goto done;
default:
if (marker == JPG || (marker >= JPG0 && marker <= JPG13)) {
@@ -766,25 +761,35 @@ gst_jpeg_parse_read_header (GstJpegParse * parse, GstBuffer * buffer)
} else if (marker >= APP0 && marker <= APP15) {
if (!gst_jpeg_parse_skip_marker (parse, &reader, marker))
goto error;
- } else {
- GST_WARNING_OBJECT (parse, "unhandled marker %x, leaving", marker);
- /* Not SOF or SOI. Must not be a JPEG file (or file pointer
- * is placed wrong). In either case, it's an error. */
- return FALSE;
- }
+ } else
+ goto unhandled;
}
if (!gst_byte_reader_peek_uint8 (&reader, &marker))
goto error;
}
+done:
+ gst_buffer_unmap (buffer, data, size);
return foundSOF;
+ /* ERRORS */
error:
- GST_WARNING_OBJECT (parse,
- "Error parsing image header (need more than %u bytes available)",
- gst_byte_reader_get_remaining (&reader));
- return FALSE;
+ {
+ GST_WARNING_OBJECT (parse,
+ "Error parsing image header (need more than %u bytes available)",
+ gst_byte_reader_get_remaining (&reader));
+ gst_buffer_unmap (buffer, data, size);
+ return FALSE;
+ }
+unhandled:
+ {
+ GST_WARNING_OBJECT (parse, "unhandled marker %x, leaving", marker);
+ /* Not SOF or SOI. Must not be a JPEG file (or file pointer
+ * is placed wrong). In either case, it's an error. */
+ gst_buffer_unmap (buffer, data, size);
+ return FALSE;
+ }
}
static gboolean
@@ -801,7 +806,7 @@ gst_jpeg_parse_set_new_caps (GstJpegParse * parse, gboolean header_ok)
if (header_ok == TRUE) {
gst_caps_set_simple (caps,
- "format", GST_TYPE_FOURCC, parse->priv->fourcc,
+ "format", G_TYPE_STRING, parse->priv->format,
"interlaced", G_TYPE_BOOLEAN, parse->priv->interlaced,
"width", G_TYPE_INT, parse->priv->width,
"height", G_TYPE_INT, parse->priv->height, NULL);
@@ -896,8 +901,6 @@ gst_jpeg_parse_push_buffer (GstJpegParse * parse, guint len)
GST_BUFFER_DURATION (outbuf) = parse->priv->duration;
- gst_buffer_set_caps (outbuf, GST_PAD_CAPS (parse->priv->srcpad));
-
GST_LOG_OBJECT (parse, "pushing buffer (ts=%" GST_TIME_FORMAT ", len=%u)",
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)), len);
@@ -957,6 +960,15 @@ gst_jpeg_parse_sink_event (GstPad * pad, GstEvent * event)
GST_DEBUG_OBJECT (parse, "event : %s", GST_EVENT_TYPE_NAME (event));
switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_CAPS:
+ {
+ GstCaps *caps;
+
+ gst_event_parse_caps (event, &caps);
+ res = gst_jpeg_parse_sink_setcaps (pad, caps);
+ gst_event_unref (event);
+ break;
+ }
case GST_EVENT_FLUSH_STOP:
parse->priv->next_ts = GST_CLOCK_TIME_NONE;
parse->priv->last_offset = 0;
@@ -972,7 +984,7 @@ gst_jpeg_parse_sink_event (GstPad * pad, GstEvent * event)
res = gst_pad_push_event (parse->priv->srcpad, event);
break;
}
- case GST_EVENT_NEWSEGMENT:
+ case GST_EVENT_SEGMENT:
/* Discard any data in the adapter. There should have been an EOS before
* to flush it. */
gst_adapter_clear (parse->priv->adapter);