From ea065d86126a0b38c2de4dfd1a4bdd70646535fe Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Mon, 10 Sep 2018 15:20:17 +0900 Subject: [PATCH] hlsdemux/mpegtsdemux : Check the pcr_pid in PMT at every ts fragment problems : video is not playing smoothly after seek. cause : During hls streaming, there is a stream where pmt version does not change but pcr_pid changes when fragment is changed. When converting the time stamp, the problem is caused using the wrong pcr. Change-Id: I6c11cfeb01b7a1e85fa2cca98316a204c178f3f5 --- ext/hls/gsthlsdemux.c | 34 ++++++++++++++++++++++++++++------ gst/mpegtsdemux/mpegtsbase.c | 26 ++++++++++++++++++++++++++ gst/mpegtsdemux/mpegtspacketizer.c | 25 +++++++++++-------------- gst/mpegtsdemux/mpegtspacketizer.h | 1 + 4 files changed, 66 insertions(+), 20 deletions(-) mode change 100644 => 100755 ext/hls/gsthlsdemux.c diff --git a/ext/hls/gsthlsdemux.c b/ext/hls/gsthlsdemux.c old mode 100644 new mode 100755 index e21bf34..cd50c78 --- a/ext/hls/gsthlsdemux.c +++ b/ext/hls/gsthlsdemux.c @@ -115,6 +115,10 @@ static gboolean gst_hls_demux_get_live_seek_range (GstAdaptiveDemux * demux, static GstM3U8 *gst_hls_demux_stream_get_m3u8 (GstHLSDemuxStream * hls_stream); static void gst_hls_demux_set_current_variant (GstHLSDemux * hlsdemux, GstHLSVariantStream * variant); +#ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING +static void gst_hls_demux_push_fragment_finished_event (GstAdaptiveDemux * demux, + GstAdaptiveDemuxStream * stream); +#endif #define gst_hls_demux_parent_class parent_class G_DEFINE_TYPE (GstHLSDemux, gst_hls_demux, GST_TYPE_ADAPTIVE_DEMUX); @@ -517,8 +521,8 @@ gst_adaptive_demux_find_stream (GstAdaptiveDemux * demux, gboolean is_primary_pl ((type == GST_HLS_MEDIA_TYPE_VIDEO) && (g_strrstr(caps_str, "video")))) find_stream = TRUE; - g_free (caps_str); - gst_caps_unref(caps); + g_free (caps_str); + gst_caps_unref(caps); if (find_stream) return stream; @@ -1025,6 +1029,9 @@ gst_hls_demux_finish_fragment (GstAdaptiveDemux * demux, if (hls_stream->current_key) gst_hls_demux_stream_decrypt_end (hls_stream); +#ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING + gst_hls_demux_push_fragment_finished_event (demux, stream); +#endif if (stream->last_ret == GST_FLOW_OK) { if (hls_stream->pending_decrypted_buffer) { if (hls_stream->current_key) { @@ -1214,14 +1221,15 @@ gst_hls_demux_update_fragment_info (GstAdaptiveDemuxStream * stream) /* set up our source for download */ #ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING - hlsdemux_stream->current_pts = sequence_pos; -#endif + stream->fragment.timestamp = hlsdemux_stream->current_pts = sequence_pos; +#else if (hlsdemux_stream->reset_pts || discont || stream->demux->segment.rate < 0.0) { stream->fragment.timestamp = sequence_pos; } else { stream->fragment.timestamp = GST_CLOCK_TIME_NONE; } +#endif g_free (hlsdemux_stream->current_key); hlsdemux_stream->current_key = g_strdup (file->key); @@ -1273,10 +1281,8 @@ gst_hls_demux_select_bitrate (GstAdaptiveDemuxStream * stream, guint64 bitrate) gst_hls_demux_change_playlist (hlsdemux, bitrate / MAX (1.0, ABS (demux->segment.rate)), &changed); -#ifndef TIZEN_FEATURE_AVOID_PAD_SWITCHING if (changed) gst_hls_demux_setup_streams (GST_ADAPTIVE_DEMUX_CAST (hlsdemux)); -#endif return changed; } @@ -1998,3 +2004,19 @@ gst_hls_demux_get_live_seek_range (GstAdaptiveDemux * demux, gint64 * start, return ret; } + +#ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING +static void +gst_hls_demux_push_fragment_finished_event (GstAdaptiveDemux * demux, + GstAdaptiveDemuxStream * stream) +{ + GstPad *pad = stream->pad; + GstEvent *event; + + event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, + gst_structure_new_empty ("fragment_finished")); + + GST_DEBUG_OBJECT(demux, "push fragment_finished event"); + gst_pad_push_event (pad, event); +} +#endif diff --git a/gst/mpegtsdemux/mpegtsbase.c b/gst/mpegtsdemux/mpegtsbase.c index 2625b7d..1189bcf 100644 --- a/gst/mpegtsdemux/mpegtsbase.c +++ b/gst/mpegtsdemux/mpegtsbase.c @@ -794,6 +794,9 @@ mpegts_base_is_same_program (MpegTSBase * base, MpegTSBaseProgram * oldprogram, guint i, nbstreams; MpegTSBaseStream *oldstream; gboolean sawpcrpid = FALSE; +#ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING + gboolean pcrpid_changed = FALSE; +#endif if (oldprogram->pmt_pid != new_pmt_pid) { GST_DEBUG ("Different pmt_pid (new:0x%04x, old:0x%04x)", new_pmt_pid, @@ -804,7 +807,11 @@ mpegts_base_is_same_program (MpegTSBase * base, MpegTSBaseProgram * oldprogram, if (oldprogram->pcr_pid != new_pmt->pcr_pid) { GST_DEBUG ("Different pcr_pid (new:0x%04x, old:0x%04x)", new_pmt->pcr_pid, oldprogram->pcr_pid); +#ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING + pcrpid_changed = TRUE; +#else return FALSE; +#endif } /* Check the streams */ @@ -837,6 +844,13 @@ mpegts_base_is_same_program (MpegTSBase * base, MpegTSBaseProgram * oldprogram, return FALSE; } +#ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING + if (pcrpid_changed) { + GST_DEBUG ("only pcr_pid is changed"); + oldprogram->pcr_pid = new_pmt->pcr_pid; + return TRUE; + } +#endif GST_DEBUG ("Programs are equal"); return TRUE; } @@ -1446,6 +1460,18 @@ mpegts_base_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) gst_segment_init (&base->segment, GST_FORMAT_UNDEFINED); base->seen_pat = FALSE; break; +#ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING + case GST_EVENT_CUSTOM_DOWNSTREAM: + structure = gst_event_get_structure(event); + if (gst_structure_has_name (structure, "fragment_finished")) { + GST_DEBUG_OBJECT (base, "Got fragment_finished event"); + if (!base->packetizer->need_pmt_update) { + base->packetizer->need_pmt_update = TRUE; + GST_DEBUG_OBJECT (base, "Set need_pmt_update"); + } + } + break; +#endif default: res = GST_MPEGTS_BASE_GET_CLASS (base)->push_event (base, event); } diff --git a/gst/mpegtsdemux/mpegtspacketizer.c b/gst/mpegtsdemux/mpegtspacketizer.c index 593cb23..9f47054 100644 --- a/gst/mpegtsdemux/mpegtspacketizer.c +++ b/gst/mpegtsdemux/mpegtspacketizer.c @@ -271,6 +271,7 @@ mpegts_packetizer_init (MpegTSPacketizer2 * packetizer) packetizer->last_in_time = GST_CLOCK_TIME_NONE; #ifdef TIZEN_FEATURE_TSDEMUX_MODIFICATION packetizer->is_live_stream = FALSE; + packetizer->need_pmt_update = FALSE; #endif packetizer->pcr_discont_threshold = GST_SECOND; } @@ -396,26 +397,12 @@ mpegts_packetizer_parse_adaptation_field_control (MpegTSPacketizer2 * GST_TIME_ARGS (PCRTIME_TO_GSTTIME (packet->pcr)), packet->offset); PACKETIZER_GROUP_LOCK (packetizer); -#ifdef TIZEN_FEATURE_TSDEMUX_MODIFICATION - if (packetizer->calculate_skew - && GST_CLOCK_TIME_IS_VALID (packetizer->last_in_time)) { - pcrtable = get_pcr_table (packetizer, packet->pid); - if (((!GST_CLOCK_TIME_IS_VALID (pcrtable->base_time)) - || (!GST_CLOCK_TIME_IS_VALID (pcrtable->base_pcrtime))) - || (packetizer->is_live_stream)) { - calculate_skew (packetizer, pcrtable, packet->pcr, - packetizer->last_in_time); - } else - GST_DEBUG (" **** skew calculation not done **** !!!"); - } -#else if (packetizer->calculate_skew && GST_CLOCK_TIME_IS_VALID (packetizer->last_in_time)) { pcrtable = get_pcr_table (packetizer, packet->pid); calculate_skew (packetizer, pcrtable, packet->pcr, packetizer->last_in_time); } -#endif if (packetizer->calculate_offset) { if (!pcrtable) pcrtable = get_pcr_table (packetizer, packet->pid); @@ -1186,6 +1173,13 @@ section_start: * * same last_section_number * * same section_number was seen */ +#ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING + if (table_id == 0x02 && packetizer->need_pmt_update) { + GST_DEBUG ("Didn't check the seen_section_before"); + packetizer->need_pmt_update = FALSE; + goto skip; + } +#endif if (seen_section_before (stream, table_id, subtable_extension, version_number, section_number, last_section_number)) { GST_DEBUG @@ -1198,6 +1192,9 @@ section_start: goto out; goto section_start; } +#ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING +skip: +#endif if (G_UNLIKELY (section_number > last_section_number)) { GST_WARNING ("PID 0x%04x corrupted packet (section_number:%d > last_section_number:%d)", diff --git a/gst/mpegtsdemux/mpegtspacketizer.h b/gst/mpegtsdemux/mpegtspacketizer.h index e4f85e2..c59e7bc 100644 --- a/gst/mpegtsdemux/mpegtspacketizer.h +++ b/gst/mpegtsdemux/mpegtspacketizer.h @@ -280,6 +280,7 @@ struct _MpegTSPacketizer2 { #ifdef TIZEN_FEATURE_TSDEMUX_MODIFICATION gboolean is_live_stream; + gboolean need_pmt_update; #endif /* offset to observations table */ -- 2.7.4