mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-26 02:00:33 +00:00
encodebin: Select muxer further
Sort muxers based on their caps and ranking before iterating to find one that fits the profile. Sorting is done by putting the elements that have a pad template that can produce the exact caps that is on the profile. For example: when asking for "video/quicktime, variant=iso", muxers that have this exact caps on their pad templates will be put first on the list than ones that have only "video/quicktime". https://bugzilla.gnome.org/show_bug.cgi?id=651496
This commit is contained in:
parent
de4fc848fa
commit
2768ed75e0
1 changed files with 78 additions and 7 deletions
|
@ -1479,17 +1479,59 @@ cleanup:
|
|||
}
|
||||
|
||||
static gboolean
|
||||
_factory_can_sink_caps (GstElementFactory * factory, const GstCaps * caps)
|
||||
_gst_caps_match_foreach (GQuark field_id, const GValue * value, gpointer data)
|
||||
{
|
||||
GstStructure *structure = data;
|
||||
const GValue *other_value = gst_structure_id_get_value (structure, field_id);
|
||||
|
||||
if (G_UNLIKELY (other_value == NULL))
|
||||
return FALSE;
|
||||
if (gst_value_compare (value, other_value) == GST_VALUE_EQUAL) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* checks that there is at least one structure on caps_a that has
|
||||
* all its fields exactly the same as one structure on caps_b
|
||||
*/
|
||||
static gboolean
|
||||
_gst_caps_match (const GstCaps * caps_a, const GstCaps * caps_b)
|
||||
{
|
||||
gint i, j;
|
||||
gboolean res = FALSE;
|
||||
|
||||
for (i = 0; i < gst_caps_get_size (caps_a); i++) {
|
||||
GstStructure *structure_a = gst_caps_get_structure (caps_a, i);
|
||||
for (j = 0; j < gst_caps_get_size (caps_b); j++) {
|
||||
GstStructure *structure_b = gst_caps_get_structure (caps_b, j);
|
||||
|
||||
res = gst_structure_foreach (structure_a, _gst_caps_match_foreach,
|
||||
structure_b);
|
||||
if (res)
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
end:
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_factory_can_handle_caps (GstElementFactory * factory, const GstCaps * caps,
|
||||
GstPadDirection dir, gboolean exact)
|
||||
{
|
||||
GList *templates = factory->staticpadtemplates;
|
||||
|
||||
while (templates) {
|
||||
GstStaticPadTemplate *template = (GstStaticPadTemplate *) templates->data;
|
||||
|
||||
if (template->direction == GST_PAD_SINK) {
|
||||
if (template->direction == dir) {
|
||||
GstCaps *tmp = gst_static_caps_get (&template->static_caps);
|
||||
|
||||
if (gst_caps_can_intersect (tmp, caps)) {
|
||||
if ((exact && _gst_caps_match (caps, tmp)) ||
|
||||
(!exact && gst_caps_can_intersect (tmp, caps))) {
|
||||
gst_caps_unref (tmp);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1540,6 +1582,31 @@ beach:
|
|||
return formatter;
|
||||
}
|
||||
|
||||
static gint
|
||||
compare_elements (gconstpointer a, gconstpointer b, gpointer udata)
|
||||
{
|
||||
GstCaps *caps = udata;
|
||||
GstElementFactory *fac_a = (GstElementFactory *) a;
|
||||
GstElementFactory *fac_b = (GstElementFactory *) b;
|
||||
|
||||
/* FIXME not quite sure this is the best algorithm to order the elements
|
||||
* Some caps similarity comparison algorithm would fit better than going
|
||||
* boolean (equals/not equals).
|
||||
*/
|
||||
gboolean equals_a = _factory_can_handle_caps (fac_a, caps, GST_PAD_SRC, TRUE);
|
||||
gboolean equals_b = _factory_can_handle_caps (fac_b, caps, GST_PAD_SRC, TRUE);
|
||||
|
||||
if (equals_a == equals_b) {
|
||||
return gst_plugin_feature_get_rank ((GstPluginFeature *) fac_b) -
|
||||
gst_plugin_feature_get_rank ((GstPluginFeature *) fac_a);
|
||||
} else if (equals_a) {
|
||||
return -1;
|
||||
} else if (equals_b) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline GstElement *
|
||||
_get_muxer (GstEncodeBin * ebin)
|
||||
{
|
||||
|
@ -1562,6 +1629,10 @@ _get_muxer (GstEncodeBin * ebin)
|
|||
gst_element_factory_list_filter (ebin->formatters, format, GST_PAD_SRC,
|
||||
TRUE);
|
||||
|
||||
muxers = g_list_sort_with_data (muxers, compare_elements, (gpointer) format);
|
||||
formatters =
|
||||
g_list_sort_with_data (formatters, compare_elements, (gpointer) format);
|
||||
|
||||
muxers = g_list_concat (muxers, formatters);
|
||||
|
||||
if (muxers == NULL)
|
||||
|
@ -1582,10 +1653,10 @@ _get_muxer (GstEncodeBin * ebin)
|
|||
for (tmp = profiles; tmp; tmp = tmp->next) {
|
||||
GstEncodingProfile *sprof = (GstEncodingProfile *) tmp->data;
|
||||
|
||||
if (!_factory_can_sink_caps (muxerfact,
|
||||
gst_encoding_profile_get_format (sprof))) {
|
||||
GST_DEBUG ("Skipping muxer because it can't sink caps %" GST_PTR_FORMAT,
|
||||
gst_encoding_profile_get_format (sprof));
|
||||
if (!_factory_can_handle_caps (muxerfact,
|
||||
gst_encoding_profile_get_format (sprof), GST_PAD_SINK, FALSE)) {
|
||||
GST_DEBUG ("Skipping muxer because it can't sink caps %"
|
||||
GST_PTR_FORMAT, gst_encoding_profile_get_format (sprof));
|
||||
cansinkstreams = FALSE;
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue