mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 18:05:37 +00:00
dashdemux: create src pads for subtitle streams.
Create src pads for Representations that contain timed-text subtitles, both when the subtitles are encapsulated in ISO BMFF (i.e., the Representation has mimeType "application/mp4") and when they are unencapsulated (i.e., the Representation has mimeType "application/ttml+xml"). https://bugzilla.gnome.org/show_bug.cgi?id=747774
This commit is contained in:
parent
bed2c6820f
commit
69f86e51b2
4 changed files with 65 additions and 22 deletions
|
@ -167,6 +167,12 @@ GST_STATIC_PAD_TEMPLATE ("audio_%02u",
|
||||||
GST_PAD_SOMETIMES,
|
GST_PAD_SOMETIMES,
|
||||||
GST_STATIC_CAPS_ANY);
|
GST_STATIC_CAPS_ANY);
|
||||||
|
|
||||||
|
static GstStaticPadTemplate gst_dash_demux_subtitlesrc_template =
|
||||||
|
GST_STATIC_PAD_TEMPLATE ("subtitle_%02u",
|
||||||
|
GST_PAD_SRC,
|
||||||
|
GST_PAD_SOMETIMES,
|
||||||
|
GST_STATIC_CAPS_ANY);
|
||||||
|
|
||||||
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
|
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
GST_PAD_SINK,
|
GST_PAD_SINK,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
|
@ -377,6 +383,8 @@ gst_dash_demux_class_init (GstDashDemuxClass * klass)
|
||||||
gst_static_pad_template_get (&gst_dash_demux_audiosrc_template));
|
gst_static_pad_template_get (&gst_dash_demux_audiosrc_template));
|
||||||
gst_element_class_add_pad_template (gstelement_class,
|
gst_element_class_add_pad_template (gstelement_class,
|
||||||
gst_static_pad_template_get (&gst_dash_demux_videosrc_template));
|
gst_static_pad_template_get (&gst_dash_demux_videosrc_template));
|
||||||
|
gst_element_class_add_pad_template (gstelement_class,
|
||||||
|
gst_static_pad_template_get (&gst_dash_demux_subtitlesrc_template));
|
||||||
|
|
||||||
gst_element_class_add_pad_template (gstelement_class,
|
gst_element_class_add_pad_template (gstelement_class,
|
||||||
gst_static_pad_template_get (&sinktemplate));
|
gst_static_pad_template_get (&sinktemplate));
|
||||||
|
@ -535,11 +543,11 @@ gst_dash_demux_setup_all_streams (GstDashDemux * demux)
|
||||||
active_stream = gst_mpdparser_get_active_stream_by_index (demux->client, i);
|
active_stream = gst_mpdparser_get_active_stream_by_index (demux->client, i);
|
||||||
if (active_stream == NULL)
|
if (active_stream == NULL)
|
||||||
continue;
|
continue;
|
||||||
/* TODO: support 'application' mimeType */
|
|
||||||
if (active_stream->mimeType == GST_STREAM_APPLICATION)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
srcpad = gst_dash_demux_create_pad (demux, active_stream);
|
srcpad = gst_dash_demux_create_pad (demux, active_stream);
|
||||||
|
if (srcpad == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
caps = gst_dash_demux_get_input_caps (demux, active_stream);
|
caps = gst_dash_demux_get_input_caps (demux, active_stream);
|
||||||
GST_LOG_OBJECT (demux, "Creating stream %d %" GST_PTR_FORMAT, i, caps);
|
GST_LOG_OBJECT (demux, "Creating stream %d %" GST_PTR_FORMAT, i, caps);
|
||||||
|
|
||||||
|
@ -771,6 +779,15 @@ gst_dash_demux_create_pad (GstDashDemux * demux, GstActiveStream * stream)
|
||||||
name = g_strdup_printf ("video_%02u", demux->n_video_streams++);
|
name = g_strdup_printf ("video_%02u", demux->n_video_streams++);
|
||||||
tmpl = gst_static_pad_template_get (&gst_dash_demux_videosrc_template);
|
tmpl = gst_static_pad_template_get (&gst_dash_demux_videosrc_template);
|
||||||
break;
|
break;
|
||||||
|
case GST_STREAM_APPLICATION:
|
||||||
|
if (gst_mpd_client_active_stream_contains_subtitles (stream)) {
|
||||||
|
name = g_strdup_printf ("subtitle_%02u", demux->n_subtitle_streams++);
|
||||||
|
tmpl =
|
||||||
|
gst_static_pad_template_get (&gst_dash_demux_subtitlesrc_template);
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -814,7 +831,6 @@ gst_dash_demux_get_video_input_caps (GstDashDemux * demux,
|
||||||
GstActiveStream * stream)
|
GstActiveStream * stream)
|
||||||
{
|
{
|
||||||
guint width = 0, height = 0;
|
guint width = 0, height = 0;
|
||||||
const gchar *mimeType = NULL;
|
|
||||||
GstCaps *caps = NULL;
|
GstCaps *caps = NULL;
|
||||||
|
|
||||||
if (stream == NULL)
|
if (stream == NULL)
|
||||||
|
@ -825,11 +841,10 @@ gst_dash_demux_get_video_input_caps (GstDashDemux * demux,
|
||||||
width = gst_mpd_client_get_video_stream_width (stream);
|
width = gst_mpd_client_get_video_stream_width (stream);
|
||||||
height = gst_mpd_client_get_video_stream_height (stream);
|
height = gst_mpd_client_get_video_stream_height (stream);
|
||||||
}
|
}
|
||||||
mimeType = gst_mpd_client_get_stream_mimeType (stream);
|
caps = gst_mpd_client_get_stream_caps (stream);
|
||||||
if (mimeType == NULL)
|
if (caps == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
caps = gst_caps_from_string (mimeType);
|
|
||||||
if (width > 0 && height > 0) {
|
if (width > 0 && height > 0) {
|
||||||
gst_caps_set_simple (caps, "width", G_TYPE_INT, width, "height",
|
gst_caps_set_simple (caps, "width", G_TYPE_INT, width, "height",
|
||||||
G_TYPE_INT, height, NULL);
|
G_TYPE_INT, height, NULL);
|
||||||
|
@ -843,7 +858,6 @@ gst_dash_demux_get_audio_input_caps (GstDashDemux * demux,
|
||||||
GstActiveStream * stream)
|
GstActiveStream * stream)
|
||||||
{
|
{
|
||||||
guint rate = 0, channels = 0;
|
guint rate = 0, channels = 0;
|
||||||
const gchar *mimeType;
|
|
||||||
GstCaps *caps = NULL;
|
GstCaps *caps = NULL;
|
||||||
|
|
||||||
if (stream == NULL)
|
if (stream == NULL)
|
||||||
|
@ -854,11 +868,10 @@ gst_dash_demux_get_audio_input_caps (GstDashDemux * demux,
|
||||||
channels = gst_mpd_client_get_audio_stream_num_channels (stream);
|
channels = gst_mpd_client_get_audio_stream_num_channels (stream);
|
||||||
rate = gst_mpd_client_get_audio_stream_rate (stream);
|
rate = gst_mpd_client_get_audio_stream_rate (stream);
|
||||||
}
|
}
|
||||||
mimeType = gst_mpd_client_get_stream_mimeType (stream);
|
caps = gst_mpd_client_get_stream_caps (stream);
|
||||||
if (mimeType == NULL)
|
if (caps == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
caps = gst_caps_from_string (mimeType);
|
|
||||||
if (rate > 0) {
|
if (rate > 0) {
|
||||||
gst_caps_set_simple (caps, "rate", G_TYPE_INT, rate, NULL);
|
gst_caps_set_simple (caps, "rate", G_TYPE_INT, rate, NULL);
|
||||||
}
|
}
|
||||||
|
@ -873,18 +886,15 @@ static GstCaps *
|
||||||
gst_dash_demux_get_application_input_caps (GstDashDemux * demux,
|
gst_dash_demux_get_application_input_caps (GstDashDemux * demux,
|
||||||
GstActiveStream * stream)
|
GstActiveStream * stream)
|
||||||
{
|
{
|
||||||
const gchar *mimeType;
|
|
||||||
GstCaps *caps = NULL;
|
GstCaps *caps = NULL;
|
||||||
|
|
||||||
if (stream == NULL)
|
if (stream == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
mimeType = gst_mpd_client_get_stream_mimeType (stream);
|
caps = gst_mpd_client_get_stream_caps (stream);
|
||||||
if (mimeType == NULL)
|
if (caps == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
caps = gst_caps_from_string (mimeType);
|
|
||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,7 @@ struct _GstDashDemux
|
||||||
|
|
||||||
gint n_audio_streams;
|
gint n_audio_streams;
|
||||||
gint n_video_streams;
|
gint n_video_streams;
|
||||||
|
gint n_subtitle_streams;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstDashDemuxClass
|
struct _GstDashDemuxClass
|
||||||
|
|
|
@ -5256,6 +5256,27 @@ gst_mpdparser_get_active_stream_by_index (GstMpdClient * client,
|
||||||
return g_list_nth_data (client->active_streams, stream_idx);
|
return g_list_nth_data (client->active_streams, stream_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_mpd_client_active_stream_contains_subtitles (GstActiveStream * stream)
|
||||||
|
{
|
||||||
|
const gchar *mimeType;
|
||||||
|
const gchar *adapt_set_codecs;
|
||||||
|
const gchar *rep_codecs;
|
||||||
|
|
||||||
|
mimeType = stream->cur_representation->RepresentationBase->mimeType;
|
||||||
|
if (!mimeType)
|
||||||
|
mimeType = stream->cur_adapt_set->RepresentationBase->mimeType;
|
||||||
|
|
||||||
|
if (g_strcmp0 (mimeType, "application/ttml+xml") == 0)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
adapt_set_codecs = stream->cur_adapt_set->RepresentationBase->codecs;
|
||||||
|
rep_codecs = stream->cur_representation->RepresentationBase->codecs;
|
||||||
|
|
||||||
|
return (adapt_set_codecs && g_str_has_prefix (adapt_set_codecs, "stpp"))
|
||||||
|
|| (rep_codecs && g_str_has_prefix (rep_codecs, "stpp"));
|
||||||
|
}
|
||||||
|
|
||||||
static const gchar *
|
static const gchar *
|
||||||
gst_mpdparser_mimetype_to_caps (const gchar * mimeType)
|
gst_mpdparser_mimetype_to_caps (const gchar * mimeType)
|
||||||
{
|
{
|
||||||
|
@ -5271,10 +5292,11 @@ gst_mpdparser_mimetype_to_caps (const gchar * mimeType)
|
||||||
return mimeType;
|
return mimeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
const gchar *
|
GstCaps *
|
||||||
gst_mpd_client_get_stream_mimeType (GstActiveStream * stream)
|
gst_mpd_client_get_stream_caps (GstActiveStream * stream)
|
||||||
{
|
{
|
||||||
const gchar *mimeType;
|
const gchar *mimeType, *caps_string;
|
||||||
|
GstCaps *ret = NULL;
|
||||||
|
|
||||||
if (stream == NULL || stream->cur_adapt_set == NULL
|
if (stream == NULL || stream->cur_adapt_set == NULL
|
||||||
|| stream->cur_representation == NULL)
|
|| stream->cur_representation == NULL)
|
||||||
|
@ -5285,7 +5307,16 @@ gst_mpd_client_get_stream_mimeType (GstActiveStream * stream)
|
||||||
mimeType = stream->cur_adapt_set->RepresentationBase->mimeType;
|
mimeType = stream->cur_adapt_set->RepresentationBase->mimeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
return gst_mpdparser_mimetype_to_caps (mimeType);
|
caps_string = gst_mpdparser_mimetype_to_caps (mimeType);
|
||||||
|
|
||||||
|
if ((g_strcmp0 (caps_string, "application/mp4") == 0)
|
||||||
|
&& gst_mpd_client_active_stream_contains_subtitles (stream))
|
||||||
|
caps_string = "video/quicktime";
|
||||||
|
|
||||||
|
if (caps_string)
|
||||||
|
ret = gst_caps_from_string (caps_string);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
|
|
@ -569,6 +569,7 @@ gboolean gst_mpdparser_get_chunk_by_index (GstMpdClient *client, guint indexStre
|
||||||
/* Active stream */
|
/* Active stream */
|
||||||
guint gst_mpdparser_get_nb_active_stream (GstMpdClient *client);
|
guint gst_mpdparser_get_nb_active_stream (GstMpdClient *client);
|
||||||
GstActiveStream *gst_mpdparser_get_active_stream_by_index (GstMpdClient *client, guint stream_idx);
|
GstActiveStream *gst_mpdparser_get_active_stream_by_index (GstMpdClient *client, guint stream_idx);
|
||||||
|
gboolean gst_mpd_client_active_stream_contains_subtitles (GstActiveStream * stream);
|
||||||
|
|
||||||
/* AdaptationSet */
|
/* AdaptationSet */
|
||||||
guint gst_mpdparser_get_nb_adaptationSet (GstMpdClient *client);
|
guint gst_mpdparser_get_nb_adaptationSet (GstMpdClient *client);
|
||||||
|
@ -580,8 +581,8 @@ GstFlowReturn gst_mpd_client_advance_segment (GstMpdClient * client, GstActiveSt
|
||||||
void gst_mpd_client_seek_to_first_segment (GstMpdClient * client);
|
void gst_mpd_client_seek_to_first_segment (GstMpdClient * client);
|
||||||
GstDateTime *gst_mpd_client_get_next_segment_availability_end_time (GstMpdClient * client, GstActiveStream * stream);
|
GstDateTime *gst_mpd_client_get_next_segment_availability_end_time (GstMpdClient * client, GstActiveStream * stream);
|
||||||
|
|
||||||
/* Get audio/video stream parameters (mimeType, width, height, rate, number of channels) */
|
/* Get audio/video stream parameters (caps, width, height, rate, number of channels) */
|
||||||
const gchar *gst_mpd_client_get_stream_mimeType (GstActiveStream * stream);
|
GstCaps * gst_mpd_client_get_stream_caps (GstActiveStream * stream);
|
||||||
gboolean gst_mpd_client_get_bitstream_switching_flag (GstActiveStream * stream);
|
gboolean gst_mpd_client_get_bitstream_switching_flag (GstActiveStream * stream);
|
||||||
guint gst_mpd_client_get_video_stream_width (GstActiveStream * stream);
|
guint gst_mpd_client_get_video_stream_width (GstActiveStream * stream);
|
||||||
guint gst_mpd_client_get_video_stream_height (GstActiveStream * stream);
|
guint gst_mpd_client_get_video_stream_height (GstActiveStream * stream);
|
||||||
|
|
Loading…
Reference in a new issue