encoding: Support more topologies in profile_from_discoverer()

Previous implementation was only working when the stream was inside a
container, this refactoring allows using virtually any stream as input.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/766>
This commit is contained in:
Thibault Saunier 2020-07-24 08:33:23 -04:00 committed by GStreamer Merge Bot
parent c2b9be5c94
commit 718122a9bf

View file

@ -1954,11 +1954,11 @@ gst_encoding_profile_deserialize_valfunc (GValue * value, const gchar * s)
return FALSE; return FALSE;
} }
static gboolean static GstEncodingProfile *
add_stream_to_profile (GstEncodingContainerProfile * profile, create_stream_profile_recurse (GstEncodingProfile * toplevel,
GstDiscovererStreamInfo * sinfo) GstDiscovererStreamInfo * sinfo)
{ {
GstEncodingProfile *sprofile = NULL; GstEncodingProfile *profile = NULL;
GstStructure *s; GstStructure *s;
GstCaps *caps; GstCaps *caps;
@ -1984,42 +1984,72 @@ add_stream_to_profile (GstEncodingContainerProfile * profile,
GST_LOG ("Stream: %" GST_PTR_FORMAT, caps); GST_LOG ("Stream: %" GST_PTR_FORMAT, caps);
if (GST_IS_DISCOVERER_AUDIO_INFO (sinfo)) { if (GST_IS_DISCOVERER_AUDIO_INFO (sinfo)) {
sprofile = profile =
(GstEncodingProfile *) gst_encoding_audio_profile_new (caps, NULL, (GstEncodingProfile *) gst_encoding_audio_profile_new (caps, NULL,
NULL, 0); NULL, 0);
} else if (GST_IS_DISCOVERER_VIDEO_INFO (sinfo)) { } else if (GST_IS_DISCOVERER_VIDEO_INFO (sinfo)) {
sprofile = profile =
(GstEncodingProfile *) gst_encoding_video_profile_new (caps, NULL, (GstEncodingProfile *) gst_encoding_video_profile_new (caps, NULL,
NULL, 0); NULL, 0);
} else if (GST_IS_DISCOVERER_CONTAINER_INFO (sinfo)) { } else if (GST_IS_DISCOVERER_CONTAINER_INFO (sinfo)) {
GList *streams, *stream; GList *streams, *stream;
guint n_streams = 0;
streams = streams =
gst_discoverer_container_info_get_streams (GST_DISCOVERER_CONTAINER_INFO gst_discoverer_container_info_get_streams (GST_DISCOVERER_CONTAINER_INFO
(sinfo)); (sinfo));
for (stream = streams; stream; stream = stream->next) {
if (add_stream_to_profile (profile,
(GstDiscovererStreamInfo *) stream->data))
n_streams++;
}
gst_discoverer_stream_info_list_free (streams);
gst_caps_unref (caps);
return n_streams != 0; if (!toplevel || !GST_IS_ENCODING_CONTAINER_PROFILE (toplevel)) {
GstEncodingProfile *prev_toplevel = toplevel;
toplevel = (GstEncodingProfile *)
gst_encoding_container_profile_new ("auto-generated",
"Automatically generated from GstDiscovererInfo", caps, NULL);
if (prev_toplevel)
gst_encoding_container_profile_add_profile
(GST_ENCODING_CONTAINER_PROFILE (toplevel), prev_toplevel);
}
for (stream = streams; stream; stream = stream->next)
create_stream_profile_recurse (toplevel,
(GstDiscovererStreamInfo *) stream->data);
gst_discoverer_stream_info_list_free (streams);
} else { } else {
GST_WARNING ("Ignoring stream of type '%s'", GST_FIXME ("Ignoring stream of type '%s'",
g_type_name (G_OBJECT_TYPE (sinfo))); g_type_name (G_OBJECT_TYPE (sinfo)));
/* subtitles or other ? ignore for now */ /* subtitles or other ? ignore for now */
} }
if (sprofile)
gst_encoding_container_profile_add_profile (profile, sprofile);
else
GST_ERROR ("Failed to create stream profile from caps %" GST_PTR_FORMAT,
caps);
gst_caps_unref (caps); gst_caps_unref (caps);
return sprofile != NULL; if (profile) {
const gchar *stream_id = gst_discoverer_stream_info_get_stream_id (sinfo);
if (stream_id) {
const gchar *subid = strchr (stream_id, '/');
gst_encoding_profile_set_name (profile, subid ? subid : stream_id);
}
if (GST_IS_ENCODING_CONTAINER_PROFILE (toplevel))
gst_encoding_container_profile_add_profile ((GstEncodingContainerProfile
*)
toplevel, profile);
}
if (!toplevel && profile)
toplevel = profile;
sinfo = gst_discoverer_stream_info_get_next (sinfo);
if (sinfo)
return create_stream_profile_recurse (toplevel, sinfo);
return toplevel;
}
static gint
_compare_profile_names (const GstEncodingProfile * a,
const GstEncodingProfile * b)
{
return g_strcmp0 (a->name, b->name);
} }
/** /**
@ -2035,11 +2065,8 @@ add_stream_to_profile (GstEncodingContainerProfile * profile,
GstEncodingProfile * GstEncodingProfile *
gst_encoding_profile_from_discoverer (GstDiscovererInfo * info) gst_encoding_profile_from_discoverer (GstDiscovererInfo * info)
{ {
GstEncodingContainerProfile *profile; GstEncodingProfile *profile;
GstDiscovererStreamInfo *sinfo; GstDiscovererStreamInfo *sinfo;
GList *streams, *stream;
GstCaps *caps = NULL;
guint n_streams = 0;
if (!info || gst_discoverer_info_get_result (info) != GST_DISCOVERER_OK) if (!info || gst_discoverer_info_get_result (info) != GST_DISCOVERER_OK)
return NULL; return NULL;
@ -2048,32 +2075,19 @@ gst_encoding_profile_from_discoverer (GstDiscovererInfo * info)
if (!sinfo) if (!sinfo)
return NULL; return NULL;
caps = gst_discoverer_stream_info_get_caps (sinfo); profile = create_stream_profile_recurse (NULL, sinfo);
GST_LOG ("Container: %" GST_PTR_FORMAT, caps); if (GST_IS_ENCODING_CONTAINER_PROFILE (profile)) {
profile = if (!gst_encoding_container_profile_get_profiles
gst_encoding_container_profile_new ("auto-generated", (GST_ENCODING_CONTAINER_PROFILE (profile))) {
"Automatically generated from GstDiscovererInfo", caps, NULL); GST_ERROR ("Failed to add any streams");
gst_caps_unref (caps); g_object_unref (profile);
if (!profile) { return NULL;
GST_ERROR ("Failed to create container profile from caps %" GST_PTR_FORMAT, }
caps); /* Sort by stream ID */
return NULL; GST_ENCODING_CONTAINER_PROFILE (profile)->encodingprofiles =
} g_list_sort (GST_ENCODING_CONTAINER_PROFILE (profile)->encodingprofiles,
(GCompareFunc) _compare_profile_names);
streams =
gst_discoverer_container_info_get_streams (GST_DISCOVERER_CONTAINER_INFO
(sinfo));
for (stream = streams; stream; stream = stream->next) {
if (add_stream_to_profile (profile,
(GstDiscovererStreamInfo *) stream->data))
n_streams++;
}
gst_discoverer_stream_info_list_free (streams);
if (n_streams == 0) {
GST_ERROR ("Failed to add any streams");
g_object_unref (profile);
return NULL;
} }
return (GstEncodingProfile *) profile; return (GstEncodingProfile *) profile;