diff options
author | Thiago Santos <thiagossantos@gmail.com> | 2017-10-13 08:55:10 -0700 |
---|---|---|
committer | Thiago Santos <thiagossantos@gmail.com> | 2017-10-13 08:55:10 -0700 |
commit | bdf194cc1790010c579362acb0b90fe7ffc07bb1 (patch) | |
tree | 993c847c3f38de3b2c7889378dcd61dd1cfeca6e | |
parent | 9ecbe8cd9fe493b846fa7234a3f816f9fe4ed3ce (diff) |
-rw-r--r-- | ext/hls/gsthlsdemux.c | 37 | ||||
-rw-r--r-- | gst-libs/gst/adaptivedemux/gstadaptivedemux.c | 76 | ||||
-rw-r--r-- | gst-libs/gst/adaptivedemux/gstadaptivedemux.h | 10 |
3 files changed, 84 insertions, 39 deletions
diff --git a/ext/hls/gsthlsdemux.c b/ext/hls/gsthlsdemux.c index 2992c3662..ba14bbdf7 100644 --- a/ext/hls/gsthlsdemux.c +++ b/ext/hls/gsthlsdemux.c @@ -493,6 +493,7 @@ create_stream_for_playlist (GstAdaptiveDemux * demux, GstM3U8 * playlist, return; } + GST_ERROR ("CREATE STREAM FOR PLAYLIST"); stream = gst_adaptive_demux_stream_new (demux, gst_hls_demux_create_pad (hlsdemux)); @@ -519,6 +520,8 @@ gst_hls_demux_setup_streams (GstAdaptiveDemux * demux) return FALSE; } + GST_ERROR ("SETUP SETUP SETUP SETUP SETUP ####################"); + gst_hls_demux_clear_all_pending_data (hlsdemux); /* 1 output for the main playlist */ @@ -573,11 +576,22 @@ gst_hls_demux_set_current_variant (GstHLSDemux * hlsdemux, hlsdemux->current_variant->m3u8->sequence_position; variant->m3u8->sequence = hlsdemux->current_variant->m3u8->sequence; - GST_DEBUG_OBJECT (hlsdemux, + GST_ERROR_OBJECT (hlsdemux, "Switching Variant. Copying over sequence %" G_GINT64_FORMAT " and sequence_pos %" GST_TIME_FORMAT, variant->m3u8->sequence, GST_TIME_ARGS (variant->m3u8->sequence_position)); + { + GstM3U8MediaFile *file; + GList *iter; + GST_ERROR ("FILES: %p", variant->m3u8->files); + for (iter = variant->m3u8->files; iter; iter = g_list_next (iter)) { + file = iter->data; + GST_ERROR ("FILE: %" GST_TIME_FORMAT " %s %" G_GINT64_FORMAT, + GST_TIME_ARGS (file->duration), file->uri, file->sequence); + } + } + for (i = 0; i < GST_HLS_N_MEDIA_TYPES; ++i) { GList *mlist = hlsdemux->current_variant->media[i]; @@ -586,6 +600,8 @@ gst_hls_demux_set_current_variant (GstHLSDemux * hlsdemux, GstHLSMedia *new_media = gst_hls_variant_find_matching_media (variant, old_media); + GST_ERROR ("NEW MEDIA: %p", new_media); + if (new_media) { new_media->playlist->sequence = old_media->playlist->sequence; new_media->playlist->sequence_position = @@ -609,7 +625,7 @@ gst_hls_demux_process_manifest (GstAdaptiveDemux * demux, GstBuffer * buf) GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux); gchar *playlist = NULL; - GST_INFO_OBJECT (demux, "Initial playlist location: %s (base uri: %s)", + GST_ERROR_OBJECT (demux, "Initial playlist location: %s (base uri: %s)", demux->manifest_uri, demux->manifest_base_uri); playlist = gst_hls_src_buf_to_utf8_playlist (buf); @@ -650,6 +666,7 @@ gst_hls_demux_process_manifest (GstAdaptiveDemux * demux, GstBuffer * buf) if (!hlsdemux->master->is_simple) { GError *err = NULL; + GST_ERROR ("UPDATING PLAYLIST"); if (!gst_hls_demux_update_playlist (hlsdemux, FALSE, &err)) { GST_ELEMENT_ERROR_FROM_ERROR (demux, "Could not fetch media playlist", err); @@ -1085,7 +1102,7 @@ gst_hls_demux_update_fragment_info (GstAdaptiveDemuxStream * stream) file = gst_m3u8_get_next_fragment (m3u8, forward, &sequence_pos, &discont); if (file == NULL) { - GST_INFO_OBJECT (hlsdemux, "This playlist doesn't contain more fragments"); + GST_ERROR_OBJECT (hlsdemux, "This playlist doesn't contain more fragments"); return GST_FLOW_EOS; } @@ -1108,7 +1125,7 @@ gst_hls_demux_update_fragment_info (GstAdaptiveDemuxStream * stream) g_free (stream->fragment.uri); stream->fragment.uri = g_strdup (file->uri); - GST_DEBUG_OBJECT (hlsdemux, "Stream %p URI now %s", stream, file->uri); + GST_ERROR_OBJECT (hlsdemux, "Stream %p URI now %s", stream, file->uri); stream->fragment.range_start = file->offset; if (file->size != -1) @@ -1150,8 +1167,10 @@ gst_hls_demux_select_bitrate (GstAdaptiveDemuxStream * stream, guint64 bitrate) gst_hls_demux_change_playlist (hlsdemux, bitrate / MAX (1.0, ABS (demux->segment.rate)), &changed); - if (changed) + if (changed) { + GST_ERROR ("SELECT BITRATE %" G_GUINT64_FORMAT, (guint64) bitrate); gst_hls_demux_setup_streams (GST_ADAPTIVE_DEMUX_CAST (hlsdemux)); + } return changed; } @@ -1391,7 +1410,7 @@ retry: return FALSE; } g_clear_error (err); - GST_INFO_OBJECT (demux, + GST_ERROR_OBJECT (demux, "Updating playlist %s failed, attempt to refresh variant playlist %s", uri, main_uri); download = @@ -1404,6 +1423,7 @@ retry: buf = gst_fragment_get_buffer (download); playlist = gst_hls_src_buf_to_utf8_playlist (buf); + GST_ERROR ("PLAYLIST:\n%s\n", playlist); gst_buffer_unref (buf); if (playlist == NULL) { @@ -1456,6 +1476,8 @@ retry: gst_buffer_unref (buf); g_object_unref (download); + GST_ERROR ("PLAYLIST:\n%s\n", playlist); + if (playlist == NULL) { GST_WARNING_OBJECT (demux, "Couldn't validate playlist encoding"); g_set_error (err, GST_STREAM_ERROR, GST_STREAM_ERROR_WRONG_TYPE, @@ -1566,13 +1588,14 @@ retry: target_pos = MAX (target_pos, m3u8->sequence_position); } - GST_LOG_OBJECT (demux, "Looking for sequence position %" + GST_ERROR_OBJECT (demux, "Looking for sequence position %" GST_TIME_FORMAT " in updated playlist", GST_TIME_ARGS (target_pos)); current_pos = 0; for (walk = m3u8->files; walk; walk = walk->next) { GstM3U8MediaFile *file = walk->data; + GST_ERROR ("CURRENT POS: %" GST_TIME_FORMAT, GST_TIME_ARGS (current_pos)); sequence = file->sequence; if (current_pos <= target_pos && target_pos < current_pos + file->duration) { diff --git a/gst-libs/gst/adaptivedemux/gstadaptivedemux.c b/gst-libs/gst/adaptivedemux/gstadaptivedemux.c index 5e8a9ff4c..e2eb2cd94 100644 --- a/gst-libs/gst/adaptivedemux/gstadaptivedemux.c +++ b/gst-libs/gst/adaptivedemux/gstadaptivedemux.c @@ -108,11 +108,12 @@ threads that use only the manifest_lock and not the api_lock. These threads run one of the following functions: gst_adaptive_demux_stream_download_loop, gst_adaptive_demux_updates_loop, _src_chain, _src_event. In order to guarantee that all operations during an API call are not impacted by other writes, the -above mentioned functions must check a cancelled flag every time they reacquire -the manifest_lock. If the flag is set, they must exit immediately, without -performing any changes on the shared data. In this way, an API call (eg seek -request) can set the cancel flag before releasing the manifest_lock and be sure -that the demux object and its streams are not changed by anybody else. +above mentioned functions must check a possible cancel reason every time +they reacquire the manifest_lock. If the flag is set, they must exit +immediately, without performing any changes on the shared data. +In this way, an API call (eg seek request) can set the cancel flag before +releasing the manifest_lock and be sure that the demux object and its streams +are not changed by anybody else. */ #ifdef HAVE_CONFIG_H @@ -710,6 +711,7 @@ gst_adaptive_demux_sink_event (GstPad * pad, GstObject * parent, } if (demux->next_streams) { + GST_ERROR ("NEXT STREAMS EVENT"); gst_adaptive_demux_prepare_streams (demux, gst_adaptive_demux_is_live (demux)); gst_adaptive_demux_start_tasks (demux, TRUE); @@ -1240,11 +1242,11 @@ gst_adaptive_demux_expose_streams (GstAdaptiveDemux * demux) GST_MANIFEST_UNLOCK (demux); - GST_DEBUG_OBJECT (pad, "Pushing EOS"); + GST_ERROR_OBJECT (pad, "Pushing EOS"); gst_pad_push_event (pad, gst_event_ref (eos)); gst_pad_set_active (pad, FALSE); - GST_LOG_OBJECT (pad, "Removing stream"); + GST_ERROR_OBJECT (pad, "Removing stream"); gst_element_remove_pad (GST_ELEMENT (demux), pad); GST_MANIFEST_LOCK (demux); @@ -1262,10 +1264,11 @@ gst_adaptive_demux_expose_streams (GstAdaptiveDemux * demux) * Even if it doesn't do that, we will change its state later in * gst_adaptive_demux_stop_tasks. */ - GST_LOG_OBJECT (stream, "Marking stream as cancelled"); + GST_ERROR_OBJECT (stream, "Marking stream as cancelled"); gst_task_stop (stream->download_task); g_mutex_lock (&stream->fragment_download_lock); - stream->cancelled = TRUE; + GST_ERROR ("CANCELLING EXPOSING STREAMS"); + stream->cancelled = GST_ADAPTIVE_DEMUX_CANCEL_SWITCH; g_cond_signal (&stream->fragment_download_cond); g_mutex_unlock (&stream->fragment_download_lock); } @@ -1368,7 +1371,7 @@ gst_adaptive_demux_stream_free (GstAdaptiveDemuxStream * stream) gst_task_stop (stream->download_task); g_mutex_lock (&stream->fragment_download_lock); - stream->cancelled = TRUE; + stream->cancelled = GST_ADAPTIVE_DEMUX_CANCEL_STOP; g_cond_signal (&stream->fragment_download_cond); g_mutex_unlock (&stream->fragment_download_lock); } @@ -2009,7 +2012,7 @@ gst_adaptive_demux_start_tasks (GstAdaptiveDemux * demux, if (!start_preroll_streams) { g_mutex_lock (&stream->fragment_download_lock); - stream->cancelled = FALSE; + stream->cancelled = GST_ADAPTIVE_DEMUX_NO_CANCEL; g_mutex_unlock (&stream->fragment_download_lock); } @@ -2076,7 +2079,7 @@ gst_adaptive_demux_stop_tasks (GstAdaptiveDemux * demux, gboolean stop_updates) GstAdaptiveDemuxStream *stream = iter->data; g_mutex_lock (&stream->fragment_download_lock); - stream->cancelled = TRUE; + stream->cancelled = GST_ADAPTIVE_DEMUX_CANCEL_STOP; gst_task_stop (stream->download_task); g_cond_signal (&stream->fragment_download_cond); g_mutex_unlock (&stream->fragment_download_lock); @@ -2293,7 +2296,7 @@ gst_adaptive_demux_handle_preroll (GstAdaptiveDemux * demux, if (demux->priv->preroll_pending == 0) { /* That was the last one, time to release all streams * and expose them */ - GST_DEBUG_OBJECT (demux, "All streams prerolled. exposing"); + GST_ERROR_OBJECT (demux, "All streams prerolled. exposing"); gst_adaptive_demux_expose_streams (demux); g_cond_broadcast (&demux->priv->preroll_cond); } @@ -2374,6 +2377,7 @@ gst_adaptive_demux_stream_push_buffer (GstAdaptiveDemuxStream * stream, } if (stream->do_block) { + GST_ERROR ("DO BLOCK"); g_mutex_lock (&demux->priv->preroll_lock); @@ -2828,7 +2832,7 @@ gst_adaptive_demux_stream_wait_manifest_update (GstAdaptiveDemux * demux, * us to download in the playlist or the playlist * became non-live */ while (TRUE) { - GST_DEBUG_OBJECT (demux, "No fragment left but live playlist, wait a bit"); + GST_ERROR_OBJECT (demux, "No fragment left but live playlist, wait a bit"); /* get the manifest_update_lock while still holding the manifest_lock. * This will prevent other threads to signal the condition (they will need @@ -2859,20 +2863,22 @@ gst_adaptive_demux_stream_wait_manifest_update (GstAdaptiveDemux * demux, /* Got a new fragment or not live anymore? */ if (gst_adaptive_demux_stream_update_fragment_info (demux, stream) == GST_FLOW_OK) { - GST_DEBUG_OBJECT (demux, "new fragment available, " + GST_ERROR_OBJECT (demux, "new fragment available, " "not waiting for manifest update"); ret = TRUE; break; } if (!gst_adaptive_demux_is_live (demux)) { - GST_DEBUG_OBJECT (demux, "Not live anymore, " + GST_ERROR_OBJECT (demux, "Not live anymore, " "not waiting for manifest update"); ret = FALSE; break; } + + GST_ERROR ("NOTHING HAPPENS, FEIJOADA"); } - GST_DEBUG_OBJECT (demux, "Retrying now"); + GST_ERROR_OBJECT (demux, "Retrying now %d", ret); return ret; } @@ -3322,7 +3328,7 @@ gst_adaptive_demux_stream_download_fragment (GstAdaptiveDemuxStream * stream) stream->last_ret = GST_FLOW_OK; stream->first_fragment_buffer = TRUE; - GST_DEBUG_OBJECT (stream->pad, "Downloading %s%s%s", + GST_ERROR_OBJECT (stream->pad, "Downloading %s%s%s", stream->fragment.uri ? "FRAGMENT " : "", stream->fragment.header_uri ? "HEADER " : "", stream->fragment.index_uri ? "INDEX" : ""); @@ -3778,6 +3784,10 @@ gst_adaptive_demux_stream_download_loop (GstAdaptiveDemuxStream * stream) goto end; } gst_task_stop (stream->download_task); + if (stream->cancelled == GST_ADAPTIVE_DEMUX_CANCEL_SWITCH) { + GST_ERROR ("GOTO END"); + goto end; + } } else { gst_task_stop (stream->download_task); if (gst_adaptive_demux_combine_flows (demux) == GST_FLOW_EOS) { @@ -3971,7 +3981,7 @@ gst_adaptive_demux_updates_loop (GstAdaptiveDemux * demux) GstFlowReturn ret = GST_FLOW_OK; /* Wait here until we should do the next update or we're cancelled */ - GST_DEBUG_OBJECT (demux, "Wait for next playlist update"); + GST_ERROR_OBJECT (demux, "Wait for next playlist update"); GST_MANIFEST_UNLOCK (demux); @@ -3980,9 +3990,11 @@ gst_adaptive_demux_updates_loop (GstAdaptiveDemux * demux) g_mutex_unlock (&demux->priv->updates_timed_lock); goto quit; } + GST_ERROR ("WAIT UNTIL %" G_GUINT64_FORMAT " - %" G_GINT64_FORMAT, + (guint64) next_update, klass->get_manifest_update_interval (demux)); gst_adaptive_demux_wait_until (demux->realtime_clock, - &demux->priv->updates_timed_cond, - &demux->priv->updates_timed_lock, next_update); + &demux->priv->updates_timed_cond, &demux->priv->updates_timed_lock, + next_update); g_mutex_unlock (&demux->priv->updates_timed_lock); g_mutex_lock (&demux->priv->updates_timed_lock); @@ -3994,10 +4006,12 @@ gst_adaptive_demux_updates_loop (GstAdaptiveDemux * demux) GST_MANIFEST_LOCK (demux); - GST_DEBUG_OBJECT (demux, "Updating playlist"); + GST_ERROR_OBJECT (demux, "Updating playlist"); ret = gst_adaptive_demux_update_manifest (demux); + GST_ERROR_OBJECT (demux, "Update result: %d %s", ret, + gst_flow_get_name (ret)); if (ret == GST_FLOW_EOS) { } else if (ret != GST_FLOW_OK) { /* update_failed_count is used only here, no need to protect it */ @@ -4016,7 +4030,7 @@ gst_adaptive_demux_updates_loop (GstAdaptiveDemux * demux) goto end; } } else { - GST_DEBUG_OBJECT (demux, "Updated playlist successfully"); + GST_ERROR_OBJECT (demux, "Updated playlist successfully"); demux->priv->update_failed_count = 0; next_update = gst_adaptive_demux_get_monotonic_time (demux) + @@ -4201,6 +4215,7 @@ gst_adaptive_demux_stream_advance_fragment_unlocked (GstAdaptiveDemux * demux, GST_TIME_AS_USECONDS (gst_adaptive_demux_get_monotonic_time (demux)); if (ret == GST_FLOW_OK) { + GST_ERROR ("ADVANCE FRAGMENT SELECT BITRATE"); if (gst_adaptive_demux_stream_select_bitrate (demux, stream, gst_adaptive_demux_stream_update_current_bitrate (demux, stream))) { stream->need_header = TRUE; @@ -4221,14 +4236,13 @@ gst_adaptive_demux_stream_advance_fragment_unlocked (GstAdaptiveDemux * demux, GstAdaptiveDemuxStream *other = iter->data; if (other != stream) { g_mutex_lock (&other->fragment_download_lock); - can_expose &= (other->cancelled == TRUE - || other->download_finished == TRUE); + can_expose &= (other->cancelled || other->download_finished == TRUE); g_mutex_unlock (&other->fragment_download_lock); } } if (can_expose) { - GST_DEBUG_OBJECT (demux, "Subclass wants new pads " + GST_ERROR_OBJECT (demux, "Subclass wants new pads " "to do bitrate switching"); gst_adaptive_demux_prepare_streams (demux, FALSE); gst_adaptive_demux_start_tasks (demux, TRUE); @@ -4269,19 +4283,19 @@ gst_adaptive_demux_stream_update_fragment_info (GstAdaptiveDemux * demux, stream->fragment.bitrate = 0; stream->fragment.finished = FALSE; - GST_LOG_OBJECT (stream->pad, "position %" GST_TIME_FORMAT, + GST_ERROR_OBJECT (stream->pad, "position %" GST_TIME_FORMAT, GST_TIME_ARGS (stream->segment.position)); ret = klass->stream_update_fragment_info (stream); - GST_LOG_OBJECT (stream->pad, "ret:%s uri:%s", gst_flow_get_name (ret), + GST_ERROR_OBJECT (stream->pad, "ret:%s uri:%s", gst_flow_get_name (ret), stream->fragment.uri); if (ret == GST_FLOW_OK) { - GST_LOG_OBJECT (stream->pad, + GST_ERROR_OBJECT (stream->pad, "timestamp %" GST_TIME_FORMAT " duration:%" GST_TIME_FORMAT, GST_TIME_ARGS (stream->fragment.timestamp), GST_TIME_ARGS (stream->fragment.duration)); - GST_LOG_OBJECT (stream->pad, + GST_ERROR_OBJECT (stream->pad, "range start:%" G_GUINT64_FORMAT " end:%" G_GUINT64_FORMAT, stream->fragment.range_start, stream->fragment.range_end); } @@ -4422,7 +4436,7 @@ gst_adaptive_demux_advance_period (GstAdaptiveDemux * demux) g_return_if_fail (klass->advance_period != NULL); - GST_DEBUG_OBJECT (demux, "Advancing to next period"); + GST_ERROR_OBJECT (demux, "Advancing to next period"); klass->advance_period (demux); gst_adaptive_demux_prepare_streams (demux, FALSE); gst_adaptive_demux_start_tasks (demux, TRUE); diff --git a/gst-libs/gst/adaptivedemux/gstadaptivedemux.h b/gst-libs/gst/adaptivedemux/gstadaptivedemux.h index d59314c9b..47198054a 100644 --- a/gst-libs/gst/adaptivedemux/gstadaptivedemux.h +++ b/gst-libs/gst/adaptivedemux/gstadaptivedemux.h @@ -121,6 +121,14 @@ struct _GstAdaptiveDemuxStreamFragment gboolean finished; }; +typedef enum +{ + GST_ADAPTIVE_DEMUX_NO_CANCEL = 0, + GST_ADAPTIVE_DEMUX_CANCEL_SWITCH, + GST_ADAPTIVE_DEMUX_CANCEL_STOP, + GST_ADAPTIVE_DEMUX_CANCEL_ERROR +} GstAdaptiveDemuxCancelReason; + struct _GstAdaptiveDemuxStream { GstPad *pad; @@ -160,7 +168,7 @@ struct _GstAdaptiveDemuxStream GMutex fragment_download_lock; GCond fragment_download_cond; gboolean download_finished; /* protected by fragment_download_lock */ - gboolean cancelled; /* protected by fragment_download_lock */ + GstAdaptiveDemuxCancelReason cancelled; /* protected by fragment_download_lock */ gboolean src_at_ready; /* protected by fragment_download_lock */ gboolean starting_fragment; gboolean first_fragment_buffer; |