mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
flvdemux: Refactor metadata tag handling
The FLV header cannot be trusted to indicate video or audio presence, as the comments already mention. Don't delay pushing tags waiting for streams that might never appear. Tags are now pushed immediately after they change: - After parsing an onMetaData script object - After negotiating caps on a pad https://bugzilla.gnome.org/show_bug.cgi?id=768440
This commit is contained in:
parent
a85dbfc246
commit
ee44e60f7b
2 changed files with 51 additions and 56 deletions
|
@ -114,6 +114,8 @@ static gboolean gst_flv_demux_src_event (GstPad * pad, GstObject * parent,
|
|||
|
||||
static GstIndex *gst_flv_demux_get_index (GstElement * element);
|
||||
|
||||
static void gst_flv_demux_push_tags (GstFlvDemux * demux);
|
||||
|
||||
static void
|
||||
gst_flv_demux_parse_and_add_index_entry (GstFlvDemux * demux, GstClockTime ts,
|
||||
guint64 pos, gboolean keyframe)
|
||||
|
@ -561,6 +563,18 @@ error:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_flv_demux_clear_tags (GstFlvDemux * demux)
|
||||
{
|
||||
GST_DEBUG_OBJECT (demux, "clearing taglist");
|
||||
|
||||
if (demux->taglist) {
|
||||
gst_tag_list_unref (demux->taglist);
|
||||
}
|
||||
demux->taglist = gst_tag_list_new_empty ();
|
||||
gst_tag_list_set_scope (demux->taglist, GST_TAG_SCOPE_GLOBAL);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_flv_demux_parse_tag_script (GstFlvDemux * demux, GstBuffer * buffer)
|
||||
{
|
||||
|
@ -594,6 +608,8 @@ gst_flv_demux_parse_tag_script (GstFlvDemux * demux, GstBuffer * buffer)
|
|||
gboolean end_marker = FALSE;
|
||||
GST_DEBUG_OBJECT (demux, "we have a metadata script object");
|
||||
|
||||
gst_flv_demux_clear_tags (demux);
|
||||
|
||||
if (!gst_byte_reader_get_uint8 (&reader, &type)) {
|
||||
g_free (function_name);
|
||||
goto cleanup;
|
||||
|
@ -636,7 +652,7 @@ gst_flv_demux_parse_tag_script (GstFlvDemux * demux, GstBuffer * buffer)
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
demux->push_tags = TRUE;
|
||||
gst_flv_demux_push_tags (demux);
|
||||
}
|
||||
|
||||
g_free (function_name);
|
||||
|
@ -689,7 +705,6 @@ gst_flv_demux_audio_negotiate (GstFlvDemux * demux, guint32 codec_tag,
|
|||
guint32 rate, guint32 channels, guint32 width)
|
||||
{
|
||||
GstCaps *caps = NULL, *old_caps;
|
||||
gchar *codec_name = NULL;
|
||||
gboolean ret = FALSE;
|
||||
guint adjusted_rate = rate;
|
||||
GstEvent *event;
|
||||
|
@ -871,18 +886,10 @@ done:
|
|||
demux->width = width;
|
||||
|
||||
if (caps) {
|
||||
codec_name = gst_pb_utils_get_codec_description (caps);
|
||||
|
||||
if (codec_name) {
|
||||
if (demux->taglist == NULL)
|
||||
demux->taglist = gst_tag_list_new_empty ();
|
||||
gst_tag_list_add (demux->taglist, GST_TAG_MERGE_REPLACE,
|
||||
GST_TAG_AUDIO_CODEC, codec_name, NULL);
|
||||
g_free (codec_name);
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (demux->audio_pad, "successfully negotiated caps %"
|
||||
GST_PTR_FORMAT, caps);
|
||||
|
||||
gst_flv_demux_push_tags (demux);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (demux->audio_pad, "delayed setting caps");
|
||||
}
|
||||
|
@ -914,27 +921,37 @@ gst_flv_demux_push_src_event (GstFlvDemux * demux, GstEvent * event)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_flv_demux_add_codec_tag (GstFlvDemux * demux, const gchar * tag,
|
||||
GstPad * pad)
|
||||
{
|
||||
if (pad) {
|
||||
GstCaps *caps = gst_pad_get_current_caps (pad);
|
||||
|
||||
if (caps) {
|
||||
gchar *codec_name = gst_pb_utils_get_codec_description (caps);
|
||||
|
||||
if (codec_name) {
|
||||
gst_tag_list_add (demux->taglist, GST_TAG_MERGE_REPLACE,
|
||||
tag, codec_name, NULL);
|
||||
g_free (codec_name);
|
||||
}
|
||||
|
||||
gst_caps_unref (caps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_flv_demux_push_tags (GstFlvDemux * demux)
|
||||
{
|
||||
if (demux->has_audio && !demux->audio_pad) {
|
||||
GST_DEBUG_OBJECT (demux,
|
||||
"Waiting for audio stream pad to come up before we can push tags");
|
||||
return;
|
||||
}
|
||||
if (demux->has_video && !demux->video_pad) {
|
||||
GST_DEBUG_OBJECT (demux,
|
||||
"Waiting for video stream pad to come up before we can push tags");
|
||||
return;
|
||||
}
|
||||
if (demux->taglist) {
|
||||
GST_DEBUG_OBJECT (demux, "pushing tags out %" GST_PTR_FORMAT,
|
||||
demux->taglist);
|
||||
gst_tag_list_set_scope (demux->taglist, GST_TAG_SCOPE_GLOBAL);
|
||||
gst_flv_demux_push_src_event (demux, gst_event_new_tag (demux->taglist));
|
||||
demux->taglist = gst_tag_list_new_empty ();
|
||||
demux->push_tags = FALSE;
|
||||
}
|
||||
gst_flv_demux_add_codec_tag (demux, GST_TAG_AUDIO_CODEC, demux->audio_pad);
|
||||
gst_flv_demux_add_codec_tag (demux, GST_TAG_VIDEO_CODEC, demux->video_pad);
|
||||
|
||||
GST_DEBUG_OBJECT (demux, "pushing %" GST_PTR_FORMAT, demux->taglist);
|
||||
|
||||
gst_flv_demux_push_src_event (demux,
|
||||
gst_event_new_tag (gst_tag_list_copy (demux->taglist)));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -1137,7 +1154,6 @@ gst_flv_demux_parse_tag_audio (GstFlvDemux * demux, GstBuffer * buffer)
|
|||
GST_DEBUG_OBJECT (demux, "emitting no more pads");
|
||||
gst_element_no_more_pads (GST_ELEMENT (demux));
|
||||
demux->no_more_pads = TRUE;
|
||||
demux->push_tags = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1156,10 +1172,6 @@ gst_flv_demux_parse_tag_audio (GstFlvDemux * demux, GstBuffer * buffer)
|
|||
}
|
||||
}
|
||||
|
||||
/* Push taglist if present */
|
||||
if (G_UNLIKELY (demux->push_tags))
|
||||
gst_flv_demux_push_tags (demux);
|
||||
|
||||
/* Check if we have anything to push */
|
||||
if (demux->tag_data_size <= codec_data) {
|
||||
GST_LOG_OBJECT (demux, "Nothing left in this tag, returning");
|
||||
|
@ -1241,7 +1253,6 @@ gst_flv_demux_parse_tag_audio (GstFlvDemux * demux, GstBuffer * buffer)
|
|||
" after 6 seconds of audio");
|
||||
gst_element_no_more_pads (GST_ELEMENT_CAST (demux));
|
||||
demux->no_more_pads = TRUE;
|
||||
demux->push_tags = TRUE;
|
||||
}
|
||||
|
||||
/* Push downstream */
|
||||
|
@ -1273,7 +1284,6 @@ gst_flv_demux_video_negotiate (GstFlvDemux * demux, guint32 codec_tag)
|
|||
{
|
||||
gboolean ret = FALSE;
|
||||
GstCaps *caps = NULL, *old_caps;
|
||||
gchar *codec_name = NULL;
|
||||
GstEvent *event;
|
||||
gchar *stream_id;
|
||||
|
||||
|
@ -1378,18 +1388,10 @@ done:
|
|||
demux->video_codec_tag = codec_tag;
|
||||
|
||||
if (caps) {
|
||||
codec_name = gst_pb_utils_get_codec_description (caps);
|
||||
|
||||
if (codec_name) {
|
||||
if (demux->taglist == NULL)
|
||||
demux->taglist = gst_tag_list_new_empty ();
|
||||
gst_tag_list_add (demux->taglist, GST_TAG_MERGE_REPLACE,
|
||||
GST_TAG_VIDEO_CODEC, codec_name, NULL);
|
||||
g_free (codec_name);
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (demux->video_pad, "successfully negotiated caps %"
|
||||
GST_PTR_FORMAT, caps);
|
||||
|
||||
gst_flv_demux_push_tags (demux);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (demux->video_pad, "delayed setting caps");
|
||||
}
|
||||
|
@ -1568,7 +1570,6 @@ gst_flv_demux_parse_tag_video (GstFlvDemux * demux, GstBuffer * buffer)
|
|||
GST_DEBUG_OBJECT (demux, "emitting no more pads");
|
||||
gst_element_no_more_pads (GST_ELEMENT (demux));
|
||||
demux->no_more_pads = TRUE;
|
||||
demux->push_tags = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1587,10 +1588,6 @@ gst_flv_demux_parse_tag_video (GstFlvDemux * demux, GstBuffer * buffer)
|
|||
demux->got_par = FALSE;
|
||||
}
|
||||
|
||||
/* Push taglist if present */
|
||||
if (G_UNLIKELY (demux->push_tags))
|
||||
gst_flv_demux_push_tags (demux);
|
||||
|
||||
/* Check if we have anything to push */
|
||||
if (demux->tag_data_size <= codec_data) {
|
||||
GST_LOG_OBJECT (demux, "Nothing left in this tag, returning");
|
||||
|
@ -1677,7 +1674,6 @@ gst_flv_demux_parse_tag_video (GstFlvDemux * demux, GstBuffer * buffer)
|
|||
" after 6 seconds of video");
|
||||
gst_element_no_more_pads (GST_ELEMENT_CAST (demux));
|
||||
demux->no_more_pads = TRUE;
|
||||
demux->push_tags = TRUE;
|
||||
}
|
||||
|
||||
/* Push downstream */
|
||||
|
@ -1925,7 +1921,6 @@ gst_flv_demux_cleanup (GstFlvDemux * demux)
|
|||
|
||||
demux->has_audio = FALSE;
|
||||
demux->has_video = FALSE;
|
||||
demux->push_tags = FALSE;
|
||||
demux->got_par = FALSE;
|
||||
|
||||
demux->indexed = FALSE;
|
||||
|
@ -1997,6 +1992,8 @@ gst_flv_demux_cleanup (GstFlvDemux * demux)
|
|||
g_array_free (demux->filepositions, TRUE);
|
||||
demux->filepositions = NULL;
|
||||
}
|
||||
|
||||
gst_flv_demux_clear_tags (demux);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3588,7 +3585,6 @@ gst_flv_demux_init (GstFlvDemux * demux)
|
|||
gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);
|
||||
|
||||
demux->adapter = gst_adapter_new ();
|
||||
demux->taglist = gst_tag_list_new_empty ();
|
||||
demux->flowcombiner = gst_flow_combiner_new ();
|
||||
gst_segment_init (&demux->segment, GST_FORMAT_TIME);
|
||||
|
||||
|
|
|
@ -126,7 +126,6 @@ struct _GstFlvDemux
|
|||
gboolean need_header;
|
||||
gboolean has_audio;
|
||||
gboolean has_video;
|
||||
gboolean push_tags;
|
||||
gboolean strict;
|
||||
gboolean flushing;
|
||||
|
||||
|
|
Loading…
Reference in a new issue