static gboolean gst_hls_demux_get_next_fragment (GstHLSDemux * demux) { GstBuffer *buf; guint avail; const gchar *next_fragment_uri; GstClockTime duration; GstClockTime timestamp; gboolean discont; if (!gst_m3u8_client_get_next_fragment (demux->client, &discont, &next_fragment_uri, &duration, ×tamp)) { GST_INFO_OBJECT (demux, "This playlist doesn't contain more fragments"); demux->end_of_playlist = TRUE; gst_task_start (demux->task); return FALSE; } GST_INFO_OBJECT (demux, "Fetching next fragment %s", next_fragment_uri); if (!gst_hls_demux_fetch_location (demux, next_fragment_uri)) { /* FIXME: The gst_m3u8_get_next_fragment increments the sequence number but another thread might call get_next_fragment and this decrement will not redownload the failed fragment, but might duplicate the download of a succeeded fragment */ g_atomic_int_add (&demux->client->sequence, -1); return FALSE; } avail = gst_adapter_available (demux->download); buf = gst_adapter_take_buffer (demux->download, avail); GST_BUFFER_DURATION (buf) = duration; GST_BUFFER_TIMESTAMP (buf) = timestamp; /* We actually need to do this every time we switch bitrate */ if (G_UNLIKELY (demux->do_typefind)) { GstCaps *caps = gst_type_find_helper_for_buffer (NULL, buf, NULL); if (!demux->input_caps || !gst_caps_is_equal (caps, demux->input_caps)) { gst_caps_replace (&demux->input_caps, caps); /* gst_pad_set_caps (demux->srcpad, demux->input_caps); */ GST_INFO_OBJECT (demux, "Input source caps: %" GST_PTR_FORMAT, demux->input_caps); demux->do_typefind = FALSE; } else gst_caps_unref (caps); } gst_buffer_set_caps (buf, demux->input_caps); if (discont) { GST_DEBUG_OBJECT (demux, "Marking fragment as discontinuous"); GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT); } g_queue_push_tail (demux->queue, buf); gst_task_start (demux->task); gst_adapter_clear (demux->download); return TRUE; }
static gboolean gst_hls_demux_get_next_fragment (GstHLSDemux * demux, gboolean retry) { GstBuffer *buf; guint avail; const gchar *next_fragment_uri; GstClockTime duration; gboolean discont; if (!gst_m3u8_client_get_next_fragment (demux->client, &discont, &next_fragment_uri, &duration)) { GST_INFO_OBJECT (demux, "This playlist doesn't contain more fragments"); demux->end_of_playlist = TRUE; GST_TASK_SIGNAL (demux->task); return FALSE; } GST_INFO_OBJECT (demux, "Fetching next fragment %s", next_fragment_uri); if (!gst_hls_demux_fetch_location (demux, next_fragment_uri)) return FALSE; avail = gst_adapter_available (demux->download); buf = gst_adapter_take_buffer (demux->download, avail); GST_BUFFER_DURATION (buf) = duration; if (G_UNLIKELY (demux->input_caps == NULL)) { demux->input_caps = gst_type_find_helper_for_buffer (NULL, buf, NULL); if (demux->input_caps) { gst_pad_set_caps (demux->srcpad, demux->input_caps); GST_INFO_OBJECT (demux, "Input source caps: %" GST_PTR_FORMAT, demux->input_caps); } } if (discont) { GST_DEBUG_OBJECT (demux, "Marking fragment as discontinuous"); GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT); } g_queue_push_tail (demux->queue, buf); GST_TASK_SIGNAL (demux->task); gst_adapter_clear (demux->download); return TRUE; }
static gboolean gst_hls_demux_update_playlist (GstHLSDemux * demux, gboolean retry) { const guint8 *data; gchar *playlist; guint avail; GST_INFO_OBJECT (demux, "Updating the playlist %s", demux->client->current->uri); if (!gst_hls_demux_fetch_location (demux, demux->client->current->uri)) return FALSE; avail = gst_adapter_available (demux->download); data = gst_adapter_peek (demux->download, avail); playlist = gst_hls_src_buf_to_utf8_playlist ((gchar *) data, avail); gst_adapter_clear (demux->download); if (playlist == NULL) { GST_WARNING_OBJECT (demux, "Couldn't not validate playlist encoding"); return FALSE; } gst_m3u8_client_update (demux->client, playlist); return TRUE; }