static gboolean gst_jpeg_parse_sink_event (GstPad * pad, GstEvent * event) { GstJpegParse *parse; gboolean res = TRUE; parse = GST_JPEG_PARSE (gst_pad_get_parent (pad)); GST_DEBUG_OBJECT (parse, "event : %s", GST_EVENT_TYPE_NAME (event)); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_FLUSH_STOP: parse->priv->next_ts = GST_CLOCK_TIME_NONE; parse->priv->duration = GST_CLOCK_TIME_NONE; parse->priv->last_offset = 0; parse->priv->last_entropy_len = 0; parse->priv->last_resync = FALSE; gst_adapter_clear (parse->priv->adapter); break; case GST_EVENT_EOS:{ /* Push the remaining data, even though it's incomplete */ guint available = gst_adapter_available (parse->priv->adapter); if (available > 0) gst_jpeg_parse_push_buffer (parse, available); res = gst_pad_push_event (parse->priv->srcpad, event); break; } case GST_EVENT_NEWSEGMENT: /* Discard any data in the adapter. There should have been an EOS before * to flush it. */ gst_adapter_clear (parse->priv->adapter); res = gst_pad_push_event (parse->priv->srcpad, event); parse->priv->new_segment = TRUE; break; case GST_EVENT_TAG:{ if (!parse->priv->new_segment) res = gst_pad_event_default (pad, event); else { GstTagList *taglist = NULL; gst_event_parse_tag (event, &taglist); /* Hold on to the tags till the srcpad caps are definitely set */ gst_tag_list_insert (get_tag_list (parse), taglist, GST_TAG_MERGE_REPLACE); GST_DEBUG ("collected tags: %" GST_PTR_FORMAT, parse->priv->tags); gst_event_unref (event); } break; } default: res = gst_pad_event_default (pad, event); break; } gst_object_unref (parse); return res; }
static GstStateChangeReturn gst_jpeg_parse_change_state (GstElement * element, GstStateChange transition) { GstStateChangeReturn ret; GstJpegParse *parse; parse = GST_JPEG_PARSE (element); switch (transition) { case GST_STATE_CHANGE_READY_TO_PAUSED: parse->priv->has_fps = FALSE; parse->priv->interlaced = FALSE; parse->priv->width = parse->priv->height = 0; parse->priv->framerate_numerator = 0; parse->priv->framerate_denominator = 1; parse->priv->caps_framerate_numerator = parse->priv->caps_framerate_denominator = 0; parse->priv->caps_width = parse->priv->caps_height = -1; parse->priv->new_segment = FALSE; parse->priv->next_ts = GST_CLOCK_TIME_NONE; parse->priv->duration = GST_CLOCK_TIME_NONE; parse->priv->last_offset = 0; parse->priv->last_entropy_len = 0; parse->priv->last_resync = FALSE; parse->priv->tags = NULL; default: break; } ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); if (ret != GST_STATE_CHANGE_SUCCESS) return ret; switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: gst_adapter_clear (parse->priv->adapter); if (parse->priv->tags) { gst_tag_list_free (parse->priv->tags); parse->priv->tags = NULL; } break; default: break; } return ret; }
static void gst_jpeg_parse_dispose (GObject * object) { GstJpegParse *parse = GST_JPEG_PARSE (object); if (parse->priv->adapter != NULL) { gst_adapter_clear (parse->priv->adapter); gst_object_unref (parse->priv->adapter); parse->priv->adapter = NULL; } G_OBJECT_CLASS (parent_class)->dispose (object); }
static gboolean gst_jpeg_parse_sink_setcaps (GstPad * pad, GstCaps * caps) { GstJpegParse *parse = GST_JPEG_PARSE (GST_OBJECT_PARENT (pad)); GstStructure *s = gst_caps_get_structure (caps, 0); const GValue *framerate; if ((framerate = gst_structure_get_value (s, "framerate")) != NULL) { if (GST_VALUE_HOLDS_FRACTION (framerate)) { parse->priv->framerate_numerator = gst_value_get_fraction_numerator (framerate); parse->priv->framerate_denominator = gst_value_get_fraction_denominator (framerate); parse->priv->has_fps = TRUE; GST_DEBUG_OBJECT (parse, "got framerate of %d/%d", parse->priv->framerate_numerator, parse->priv->framerate_denominator); } } return TRUE; }
static GstFlowReturn gst_jpeg_parse_chain (GstPad * pad, GstBuffer * buf) { GstJpegParse *parse; gint len; GstClockTime timestamp, duration; GstFlowReturn ret = GST_FLOW_OK; parse = GST_JPEG_PARSE (GST_PAD_PARENT (pad)); timestamp = GST_BUFFER_TIMESTAMP (buf); duration = GST_BUFFER_DURATION (buf); gst_adapter_push (parse->priv->adapter, buf); while (ret == GST_FLOW_OK && gst_jpeg_parse_skip_to_jpeg_header (parse)) { if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (parse->priv->next_ts))) parse->priv->next_ts = timestamp; if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (duration))) parse->priv->duration = duration; /* check if we already have a EOI */ len = gst_jpeg_parse_get_image_length (parse); if (len == 0) { return GST_FLOW_OK; } else if (len < 0) { gst_adapter_flush (parse->priv->adapter, -len); continue; } GST_LOG_OBJECT (parse, "parsed image of size %d", len); /* now we have enough in the adapter to process a full jpeg image */ ret = gst_jpeg_parse_push_buffer (parse, len); } GST_DEBUG_OBJECT (parse, "No further start marker found."); return ret; }