mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 01:00: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_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",
|
||||
GST_PAD_SINK,
|
||||
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_element_class_add_pad_template (gstelement_class,
|
||||
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_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);
|
||||
if (active_stream == NULL)
|
||||
continue;
|
||||
/* TODO: support 'application' mimeType */
|
||||
if (active_stream->mimeType == GST_STREAM_APPLICATION)
|
||||
continue;
|
||||
|
||||
srcpad = gst_dash_demux_create_pad (demux, active_stream);
|
||||
if (srcpad == NULL)
|
||||
continue;
|
||||
|
||||
caps = gst_dash_demux_get_input_caps (demux, active_stream);
|
||||
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++);
|
||||
tmpl = gst_static_pad_template_get (&gst_dash_demux_videosrc_template);
|
||||
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:
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
|
@ -814,7 +831,6 @@ gst_dash_demux_get_video_input_caps (GstDashDemux * demux,
|
|||
GstActiveStream * stream)
|
||||
{
|
||||
guint width = 0, height = 0;
|
||||
const gchar *mimeType = NULL;
|
||||
GstCaps *caps = 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);
|
||||
height = gst_mpd_client_get_video_stream_height (stream);
|
||||
}
|
||||
mimeType = gst_mpd_client_get_stream_mimeType (stream);
|
||||
if (mimeType == NULL)
|
||||
caps = gst_mpd_client_get_stream_caps (stream);
|
||||
if (caps == NULL)
|
||||
return NULL;
|
||||
|
||||
caps = gst_caps_from_string (mimeType);
|
||||
if (width > 0 && height > 0) {
|
||||
gst_caps_set_simple (caps, "width", G_TYPE_INT, width, "height",
|
||||
G_TYPE_INT, height, NULL);
|
||||
|
@ -843,7 +858,6 @@ gst_dash_demux_get_audio_input_caps (GstDashDemux * demux,
|
|||
GstActiveStream * stream)
|
||||
{
|
||||
guint rate = 0, channels = 0;
|
||||
const gchar *mimeType;
|
||||
GstCaps *caps = 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);
|
||||
rate = gst_mpd_client_get_audio_stream_rate (stream);
|
||||
}
|
||||
mimeType = gst_mpd_client_get_stream_mimeType (stream);
|
||||
if (mimeType == NULL)
|
||||
caps = gst_mpd_client_get_stream_caps (stream);
|
||||
if (caps == NULL)
|
||||
return NULL;
|
||||
|
||||
caps = gst_caps_from_string (mimeType);
|
||||
if (rate > 0) {
|
||||
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,
|
||||
GstActiveStream * stream)
|
||||
{
|
||||
const gchar *mimeType;
|
||||
GstCaps *caps = NULL;
|
||||
|
||||
if (stream == NULL)
|
||||
return NULL;
|
||||
|
||||
mimeType = gst_mpd_client_get_stream_mimeType (stream);
|
||||
if (mimeType == NULL)
|
||||
caps = gst_mpd_client_get_stream_caps (stream);
|
||||
if (caps == NULL)
|
||||
return NULL;
|
||||
|
||||
caps = gst_caps_from_string (mimeType);
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
|
|
|
@ -99,6 +99,7 @@ struct _GstDashDemux
|
|||
|
||||
gint n_audio_streams;
|
||||
gint n_video_streams;
|
||||
gint n_subtitle_streams;
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 *
|
||||
gst_mpdparser_mimetype_to_caps (const gchar * mimeType)
|
||||
{
|
||||
|
@ -5271,10 +5292,11 @@ gst_mpdparser_mimetype_to_caps (const gchar * mimeType)
|
|||
return mimeType;
|
||||
}
|
||||
|
||||
const gchar *
|
||||
gst_mpd_client_get_stream_mimeType (GstActiveStream * stream)
|
||||
GstCaps *
|
||||
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
|
||||
|| stream->cur_representation == NULL)
|
||||
|
@ -5285,7 +5307,16 @@ gst_mpd_client_get_stream_mimeType (GstActiveStream * stream)
|
|||
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
|
||||
|
|
|
@ -569,6 +569,7 @@ gboolean gst_mpdparser_get_chunk_by_index (GstMpdClient *client, guint indexStre
|
|||
/* Active stream */
|
||||
guint gst_mpdparser_get_nb_active_stream (GstMpdClient *client);
|
||||
GstActiveStream *gst_mpdparser_get_active_stream_by_index (GstMpdClient *client, guint stream_idx);
|
||||
gboolean gst_mpd_client_active_stream_contains_subtitles (GstActiveStream * stream);
|
||||
|
||||
/* AdaptationSet */
|
||||
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);
|
||||
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) */
|
||||
const gchar *gst_mpd_client_get_stream_mimeType (GstActiveStream * stream);
|
||||
/* Get audio/video stream parameters (caps, width, height, rate, number of channels) */
|
||||
GstCaps * gst_mpd_client_get_stream_caps (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_height (GstActiveStream * stream);
|
||||
|
|
Loading…
Reference in a new issue