static GstBusSyncReply gst_uri_downloader_bus_handler (GstBus * bus, GstMessage * message, gpointer data) { GstUriDownloader *downloader = (GstUriDownloader *) (data); if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR || GST_MESSAGE_TYPE (message) == GST_MESSAGE_WARNING) { GError *err = NULL; gchar *dbg_info = NULL; gst_message_parse_error (message, &err, &dbg_info); GST_WARNING_OBJECT (downloader, "Received error: %s from %s, the download will be cancelled", GST_OBJECT_NAME (message->src), err->message); GST_DEBUG ("Debugging info: %s\n", (dbg_info) ? dbg_info : "none"); g_error_free (err); g_free (dbg_info); /* remove the sync handler to avoid duplicated messages */ gst_bus_set_sync_handler (downloader->priv->bus, NULL, NULL); gst_uri_downloader_cancel (downloader); } gst_message_unref (message); return GST_BUS_DROP; }
static void gst_uri_downloader_dispose (GObject * object) { GstUriDownloader *downloader = GST_URI_DOWNLOADER (object); gst_uri_downloader_cancel (downloader); g_mutex_lock (&downloader->download_lock); if (downloader->urisrc != NULL) { gst_element_set_state (downloader->urisrc, GST_STATE_NULL); gst_object_unref (downloader->urisrc); downloader->urisrc = NULL; } g_mutex_unlock (&downloader->download_lock); if (downloader->bus != NULL) { gst_object_unref (downloader->bus); downloader->bus = NULL; } if (downloader->pad) { gst_object_unref (downloader->pad); downloader->pad = NULL; } G_OBJECT_CLASS (parent_class)->dispose (object); }
static void gst_hls_demux_stop (GstHLSDemux * demux) { gst_uri_downloader_cancel (demux->downloader); if (GST_TASK_STATE (demux->updates_task) != GST_TASK_STOPPED) { demux->stop_stream_task = TRUE; gst_task_stop (demux->updates_task); GST_TASK_SIGNAL (demux->updates_task); } if (GST_TASK_STATE (demux->stream_task) != GST_TASK_STOPPED) gst_task_stop (demux->stream_task); }
static gboolean gst_hls_demux_src_event (GstPad * pad, GstObject * parent, GstEvent * event) { GstHLSDemux *demux; demux = GST_HLS_DEMUX (parent); switch (event->type) { case GST_EVENT_SEEK: { gdouble rate; GstFormat format; GstSeekFlags flags; GstSeekType start_type, stop_type; gint64 start, stop; GList *walk; GstClockTime position, current_pos, target_pos; gint current_sequence; GstM3U8MediaFile *file; GST_INFO_OBJECT (demux, "Received GST_EVENT_SEEK"); if (gst_m3u8_client_is_live (demux->client)) { GST_WARNING_OBJECT (demux, "Received seek event for live stream"); return FALSE; } gst_event_parse_seek (event, &rate, &format, &flags, &start_type, &start, &stop_type, &stop); if (format != GST_FORMAT_TIME) return FALSE; GST_DEBUG_OBJECT (demux, "seek event, rate: %f start: %" GST_TIME_FORMAT " stop: %" GST_TIME_FORMAT, rate, GST_TIME_ARGS (start), GST_TIME_ARGS (stop)); GST_M3U8_CLIENT_LOCK (demux->client); file = GST_M3U8_MEDIA_FILE (demux->client->current->files->data); current_sequence = file->sequence; current_pos = 0; target_pos = (GstClockTime) start; for (walk = demux->client->current->files; walk; walk = walk->next) { file = walk->data; current_sequence = file->sequence; if (current_pos <= target_pos && target_pos < current_pos + file->duration) { break; } current_pos += file->duration; } GST_M3U8_CLIENT_UNLOCK (demux->client); if (walk == NULL) { GST_WARNING_OBJECT (demux, "Could not find seeked fragment"); return FALSE; } if (flags & GST_SEEK_FLAG_FLUSH) { GST_DEBUG_OBJECT (demux, "sending flush start"); gst_pad_push_event (demux->srcpad, gst_event_new_flush_start ()); } demux->cancelled = TRUE; gst_task_pause (demux->stream_task); gst_uri_downloader_cancel (demux->downloader); gst_task_stop (demux->updates_task); gst_task_pause (demux->stream_task); /* wait for streaming to finish */ g_rec_mutex_lock (&demux->stream_lock); demux->need_cache = TRUE; while (!g_queue_is_empty (demux->queue)) { GstFragment *fragment = g_queue_pop_head (demux->queue); g_object_unref (fragment); } g_queue_clear (demux->queue); GST_M3U8_CLIENT_LOCK (demux->client); GST_DEBUG_OBJECT (demux, "seeking to sequence %d", current_sequence); demux->client->sequence = current_sequence; gst_m3u8_client_get_current_position (demux->client, &position); demux->position_shift = start - position; demux->need_segment = TRUE; GST_M3U8_CLIENT_UNLOCK (demux->client); if (flags & GST_SEEK_FLAG_FLUSH) { GST_DEBUG_OBJECT (demux, "sending flush stop"); gst_pad_push_event (demux->srcpad, gst_event_new_flush_stop (TRUE)); } demux->cancelled = FALSE; gst_task_start (demux->stream_task); g_rec_mutex_unlock (&demux->stream_lock); return TRUE; } default: break; } return gst_pad_event_default (pad, parent, event); }