I am trying to display a live h.264 RTSP stream. I use playbin2 as follows:
gst-launch -v playbin2 uri=rtsp://192.168.20.30
It seems to launch and detect the stream and parse it but then it keeps spitting out:
..
Discont detected from 0:00:00.500000000 to 1:20:05.153366000
Discont detected from 0:00:00.500000000 to 1:20:05.177366000
Discont detected from 0:00:00.500000000 to 1:20:05.201366000
Discont detected from 0:00:00.500000000 to 1:20:05.225366000
Discont detected from 0:00:00.500000000 to 1:20:05.249366000
Discont detected from 0:00:00.500000000 to 1:20:05.273366000
Discont detected from 0:00:00.500000000 to 1:20:05.297366000
Discont detected from 0:00:00.500000000 to 1:20:05.321366000
Discont detected from 0:00:00.500000000 to 1:20:05.345366000
...
This goes on forever and nothing is displayed.
解決済! 解決策の投稿を見る。
JianLi Sep 23, 2013 11:03 PM (in response to Karina Valencia Aguilar)
I think it's ts rtsp streaming, as this log is coming from aiurdemux, for normal rtsp streaming, aiurdemux should not be used, please confirm.
Please try below patch, we have fixed this.
diff --git a/fsl_mm_linux/Multimedia/src/parser/aiur/src/aiurdemux.c b/fsl_mm_linux/Multimedia/src/parser/aiur/src/aiurdemux.c
index cccda71..9a0f6b8 100755
--- a/fsl_mm_linux/Multimedia/src/parser/aiur/src/aiurdemux.c
+++ b/fsl_mm_linux/Multimedia/src/parser/aiur/src/aiurdemux.c
@@ -305,6 +305,7 @@ enum
PROP_STREAM_MASK,
PROP_PROGRAM_MASK,
PROP_INTERLEAVE_QUEUE_SIZE,
+ PROP_STREAMING_LATENCY,
};
@@ -363,6 +364,11 @@ static GstsutilsOptionEntry g_aiurdemux_option_table[] = {
G_TYPE_UINT,
G_STRUCT_OFFSET (AiurDemuxOption, interleave_queue_size),
"10240000", "0", G_MAXUINT_STR},
+ {PROP_STREAMING_LATENCY, "streaming_latency", "latency for streaming",
+ "set the latency in ms seconds for streaming mode",
+ G_TYPE_UINT,
+ G_STRUCT_OFFSET (AiurDemuxOption, streaming_latency),
+ "400", "0", G_MAXUINT_STR},
{-1, NULL, NULL, NULL, 0, 0, NULL} /* terminator */
};
@@ -378,7 +384,7 @@ static AiurDemuxConfigEntry aiur_config_table[] = {
{"aiur_index_dir", TYPE_STRING, G_STRUCT_OFFSET (AiurDemuxConfig, index_file_prefix), NULL}, /* default $HOME/.aiur */
{"aiur_retimestamp_delay_ms", TYPE_INT, G_STRUCT_OFFSET (AiurDemuxConfig, retimestamp_delay_ms), "500"}, /* 500ms */
- {"aiur_retimestamp_threashold_ms", TYPE_INT, G_STRUCT_OFFSET (AiurDemuxConfig, retimestamp_threashold_ms), "2000"}, /* 2 second */
+ {"aiur_retimestamp_threashold_ms", TYPE_INT, G_STRUCT_OFFSET (AiurDemuxConfig, retimestamp_threashold_ms), "0"}, /* disable retime stamp for streaming*/
{"aiur_cache_stream_preserve_size", TYPE_INT,
G_STRUCT_OFFSET (AiurDemuxConfig,
@@ -402,6 +408,7 @@ static AiurDemuxConfigEntry aiur_config_table[] = {
{"aiur_drop_prerollsample", TYPE_BOOLEAN, G_STRUCT_OFFSET (AiurDemuxConfig,
drop_sample),
"true"},
+ {"aiur_autoDelay", TYPE_BOOLEAN, G_STRUCT_OFFSET (AiurDemuxConfig,autoDelay),"true"},
{NULL} /* terminator */
};
@@ -2043,6 +2050,8 @@ gst_aiurdemux_change_state (GstElement * element, GstStateChange transition)
case GST_STATE_CHANGE_READY_TO_PAUSED:
MM_INIT_DBG_MEM ("aiurdemux");
demux->discont_check_track = -1;
+ demux->clock_offset = GST_CLOCK_TIME_NONE;
+ demux->start_time = GST_CLOCK_TIME_NONE;
demux->tag_list = gst_tag_list_new ();
break;
default:
@@ -2428,6 +2437,43 @@ aiurdemux_make_discont (GstAiurDemux * demux, GstClockTime ts)
}
static void
+aiurdemux_check_start_offset (GstAiurDemux * demux, AiurDemuxStream * stream)
+{
+ if(!demux->config.autoDelay)
+ return;
+ //clock of pipeline has started when first buffer arrives, so adjust the buffer timestamp
+ if(demux->clock_offset == GST_CLOCK_TIME_NONE){
+ GstClockTime base_time,now;
+ GstClock *clock = NULL;
+ GstClockTimeDiff offset = 0;
+ base_time = GST_ELEMENT_CAST (demux)->base_time;
+ clock = GST_ELEMENT_CLOCK (demux);
+ if(clock != NULL){
+ now = gst_clock_get_time (clock);
+ offset = now - base_time;
+ if(offset > 0)
+ demux->clock_offset = offset;
+ }
+ GST_LOG_OBJECT (demux,"basetime=%"GST_TIME_FORMAT,GST_TIME_ARGS (base_time));
+ GST_LOG_OBJECT (demux,"now=%"GST_TIME_FORMAT,GST_TIME_ARGS (now));
+ GST_LOG_OBJECT (demux,"clock_offset=%"GST_TIME_FORMAT,GST_TIME_ARGS (demux->clock_offset));
+ }
+ if(stream->last_stop == 0 && (GST_CLOCK_TIME_IS_VALID (demux->clock_offset))){
+ stream->last_stop = demux->clock_offset;
+ GST_LOG_OBJECT (demux,"last_stop =%"GST_TIME_FORMAT,GST_TIME_ARGS (stream->last_stop));
+ }
+ if(demux->start_time == GST_CLOCK_TIME_NONE){
+ demux->start_time = stream->sample_stat.start;
+ GST_LOG_OBJECT (demux,"start_time=%"GST_TIME_FORMAT,GST_TIME_ARGS (demux->start_time));
+ }
+ if((GST_CLOCK_TIME_IS_VALID (demux->clock_offset))
+ && (GST_CLOCK_TIME_IS_VALID (demux->start_time))
+ && (GST_CLOCK_TIME_IS_VALID (stream->sample_stat.start))){
+ stream->sample_stat.start = stream->sample_stat.start - demux->start_time + demux->clock_offset + (GST_MSECOND * demux->option.streaming_latency);
+ GST_LOG_OBJECT (demux,"***start=%"GST_TIME_FORMAT,GST_TIME_ARGS (stream->sample_stat.start));
+ }
+}
+static void
aiurdemux_check_discont (GstAiurDemux * demux, AiurDemuxStream * stream)
{
if ((demux->clip_info.auto_retimestamp)
@@ -4125,6 +4171,9 @@ aiurdemux_loop_state_movie (GstAiurDemux * demux)
}
if ((stream) && (stream->buffer)) {
+ GST_LOG_OBJECT (demux, "CHECK track_idx=%d,usStartTime=%lld,sampleFlags=%x",track_idx,stream->sample_stat.start,stream->sample_stat.flag);
+ if(demux->clip_info.live)
+ aiurdemux_check_start_offset(demux, stream);
aiurdemux_check_discont (demux, stream);
aiurdemux_adjust_timestamp (demux, stream, stream->buffer);
if (stream->new_segment) {
diff --git a/fsl_mm_linux/Multimedia/src/parser/aiur/src/aiurdemux.h b/fsl_mm_linux/Multimedia/src/parser/aiur/src/aiurdemux.h
index d75b65d..d314868 100755
--- a/fsl_mm_linux/Multimedia/src/parser/aiur/src/aiurdemux.h
+++ b/fsl_mm_linux/Multimedia/src/parser/aiur/src/aiurdemux.h
@@ -82,6 +82,7 @@ typedef struct _AiurDemuxOption
guint program_mask;
gint program_number;
guint interleave_queue_size;
+ guint streaming_latency;
} AiurDemuxOption;
typedef struct
@@ -152,6 +153,7 @@ typedef struct
gint num_of_samples;
gboolean drop_sample;
+ gboolean autoDelay;
} AiurDemuxConfig;
struct _GstAiurDemux
@@ -192,12 +194,13 @@ struct _GstAiurDemux
AiurDemuxPlayMode play_mode;
- GstClockTime start_time;
gint32 discont_check_track;
guint32 new_segment_mask;
guint32 valid_mask;
gboolean check_discont;
GstClockTime base_offset;
+ GstClockTime clock_offset;//clock running time when first buffer arrives
+ GstClockTime start_time;//first buffer timestamp
guint interleave_queue_size;
--
1.7.9.5
I have the same issue.
It seems aiurdemux print this message. and I replace aiurdemux with mepgtsdemux, problem solved. but the software demux 's performance was not satisfied.
the log is as
gstbasesink.c(2866): gst_base_sink_is_too_late (): /GstPipeline:pipeline0/MFW_GST_V4LSINK_INFO_T:mfw_gst_v4lsink_info_t0:
There may be a timestamping problem, or this computer is too slow.
what should I do to fix this "Discont detected from" issue. .
gst-launch-0.10 udpsrc port=4444 buffer-size="5000" caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,
encoding-name=(string)H264" ! .recv_rtp_sink_0 gstrtpbin ! rtpmp2tdepay ! mpegtsdemux name=demux demux. ! queue max-si
ze-buffers=8000 max-size-time=0 ! vpudec ! mfw_v4lsink demux. ! queue max-size-buffers=8000 max-size-time=0 ! beepdec
! audioconvert ! 'audio/x-raw-int, channels=2'! alsasink
I use VLC as a RTP server.
JianLi Sep 23, 2013 11:03 PM (in response to Karina Valencia Aguilar)
I think it's ts rtsp streaming, as this log is coming from aiurdemux, for normal rtsp streaming, aiurdemux should not be used, please confirm.
Please try below patch, we have fixed this.
diff --git a/fsl_mm_linux/Multimedia/src/parser/aiur/src/aiurdemux.c b/fsl_mm_linux/Multimedia/src/parser/aiur/src/aiurdemux.c
index cccda71..9a0f6b8 100755
--- a/fsl_mm_linux/Multimedia/src/parser/aiur/src/aiurdemux.c
+++ b/fsl_mm_linux/Multimedia/src/parser/aiur/src/aiurdemux.c
@@ -305,6 +305,7 @@ enum
PROP_STREAM_MASK,
PROP_PROGRAM_MASK,
PROP_INTERLEAVE_QUEUE_SIZE,
+ PROP_STREAMING_LATENCY,
};
@@ -363,6 +364,11 @@ static GstsutilsOptionEntry g_aiurdemux_option_table[] = {
G_TYPE_UINT,
G_STRUCT_OFFSET (AiurDemuxOption, interleave_queue_size),
"10240000", "0", G_MAXUINT_STR},
+ {PROP_STREAMING_LATENCY, "streaming_latency", "latency for streaming",
+ "set the latency in ms seconds for streaming mode",
+ G_TYPE_UINT,
+ G_STRUCT_OFFSET (AiurDemuxOption, streaming_latency),
+ "400", "0", G_MAXUINT_STR},
{-1, NULL, NULL, NULL, 0, 0, NULL} /* terminator */
};
@@ -378,7 +384,7 @@ static AiurDemuxConfigEntry aiur_config_table[] = {
{"aiur_index_dir", TYPE_STRING, G_STRUCT_OFFSET (AiurDemuxConfig, index_file_prefix), NULL}, /* default $HOME/.aiur */
{"aiur_retimestamp_delay_ms", TYPE_INT, G_STRUCT_OFFSET (AiurDemuxConfig, retimestamp_delay_ms), "500"}, /* 500ms */
- {"aiur_retimestamp_threashold_ms", TYPE_INT, G_STRUCT_OFFSET (AiurDemuxConfig, retimestamp_threashold_ms), "2000"}, /* 2 second */
+ {"aiur_retimestamp_threashold_ms", TYPE_INT, G_STRUCT_OFFSET (AiurDemuxConfig, retimestamp_threashold_ms), "0"}, /* disable retime stamp for streaming*/
{"aiur_cache_stream_preserve_size", TYPE_INT,
G_STRUCT_OFFSET (AiurDemuxConfig,
@@ -402,6 +408,7 @@ static AiurDemuxConfigEntry aiur_config_table[] = {
{"aiur_drop_prerollsample", TYPE_BOOLEAN, G_STRUCT_OFFSET (AiurDemuxConfig,
drop_sample),
"true"},
+ {"aiur_autoDelay", TYPE_BOOLEAN, G_STRUCT_OFFSET (AiurDemuxConfig,autoDelay),"true"},
{NULL} /* terminator */
};
@@ -2043,6 +2050,8 @@ gst_aiurdemux_change_state (GstElement * element, GstStateChange transition)
case GST_STATE_CHANGE_READY_TO_PAUSED:
MM_INIT_DBG_MEM ("aiurdemux");
demux->discont_check_track = -1;
+ demux->clock_offset = GST_CLOCK_TIME_NONE;
+ demux->start_time = GST_CLOCK_TIME_NONE;
demux->tag_list = gst_tag_list_new ();
break;
default:
@@ -2428,6 +2437,43 @@ aiurdemux_make_discont (GstAiurDemux * demux, GstClockTime ts)
}
static void
+aiurdemux_check_start_offset (GstAiurDemux * demux, AiurDemuxStream * stream)
+{
+ if(!demux->config.autoDelay)
+ return;
+ //clock of pipeline has started when first buffer arrives, so adjust the buffer timestamp
+ if(demux->clock_offset == GST_CLOCK_TIME_NONE){
+ GstClockTime base_time,now;
+ GstClock *clock = NULL;
+ GstClockTimeDiff offset = 0;
+ base_time = GST_ELEMENT_CAST (demux)->base_time;
+ clock = GST_ELEMENT_CLOCK (demux);
+ if(clock != NULL){
+ now = gst_clock_get_time (clock);
+ offset = now - base_time;
+ if(offset > 0)
+ demux->clock_offset = offset;
+ }
+ GST_LOG_OBJECT (demux,"basetime=%"GST_TIME_FORMAT,GST_TIME_ARGS (base_time));
+ GST_LOG_OBJECT (demux,"now=%"GST_TIME_FORMAT,GST_TIME_ARGS (now));
+ GST_LOG_OBJECT (demux,"clock_offset=%"GST_TIME_FORMAT,GST_TIME_ARGS (demux->clock_offset));
+ }
+ if(stream->last_stop == 0 && (GST_CLOCK_TIME_IS_VALID (demux->clock_offset))){
+ stream->last_stop = demux->clock_offset;
+ GST_LOG_OBJECT (demux,"last_stop =%"GST_TIME_FORMAT,GST_TIME_ARGS (stream->last_stop));
+ }
+ if(demux->start_time == GST_CLOCK_TIME_NONE){
+ demux->start_time = stream->sample_stat.start;
+ GST_LOG_OBJECT (demux,"start_time=%"GST_TIME_FORMAT,GST_TIME_ARGS (demux->start_time));
+ }
+ if((GST_CLOCK_TIME_IS_VALID (demux->clock_offset))
+ && (GST_CLOCK_TIME_IS_VALID (demux->start_time))
+ && (GST_CLOCK_TIME_IS_VALID (stream->sample_stat.start))){
+ stream->sample_stat.start = stream->sample_stat.start - demux->start_time + demux->clock_offset + (GST_MSECOND * demux->option.streaming_latency);
+ GST_LOG_OBJECT (demux,"***start=%"GST_TIME_FORMAT,GST_TIME_ARGS (stream->sample_stat.start));
+ }
+}
+static void
aiurdemux_check_discont (GstAiurDemux * demux, AiurDemuxStream * stream)
{
if ((demux->clip_info.auto_retimestamp)
@@ -4125,6 +4171,9 @@ aiurdemux_loop_state_movie (GstAiurDemux * demux)
}
if ((stream) && (stream->buffer)) {
+ GST_LOG_OBJECT (demux, "CHECK track_idx=%d,usStartTime=%lld,sampleFlags=%x",track_idx,stream->sample_stat.start,stream->sample_stat.flag);
+ if(demux->clip_info.live)
+ aiurdemux_check_start_offset(demux, stream);
aiurdemux_check_discont (demux, stream);
aiurdemux_adjust_timestamp (demux, stream, stream->buffer);
if (stream->new_segment) {
diff --git a/fsl_mm_linux/Multimedia/src/parser/aiur/src/aiurdemux.h b/fsl_mm_linux/Multimedia/src/parser/aiur/src/aiurdemux.h
index d75b65d..d314868 100755
--- a/fsl_mm_linux/Multimedia/src/parser/aiur/src/aiurdemux.h
+++ b/fsl_mm_linux/Multimedia/src/parser/aiur/src/aiurdemux.h
@@ -82,6 +82,7 @@ typedef struct _AiurDemuxOption
guint program_mask;
gint program_number;
guint interleave_queue_size;
+ guint streaming_latency;
} AiurDemuxOption;
typedef struct
@@ -152,6 +153,7 @@ typedef struct
gint num_of_samples;
gboolean drop_sample;
+ gboolean autoDelay;
} AiurDemuxConfig;
struct _GstAiurDemux
@@ -192,12 +194,13 @@ struct _GstAiurDemux
AiurDemuxPlayMode play_mode;
- GstClockTime start_time;
gint32 discont_check_track;
guint32 new_segment_mask;
guint32 valid_mask;
gboolean check_discont;
GstClockTime base_offset;
+ GstClockTime clock_offset;//clock running time when first buffer arrives
+ GstClockTime start_time;//first buffer timestamp
guint interleave_queue_size;
--
1.7.9.5