|
Packit Service |
4387a0 |
/* Copyright (C) <2014> Intel Corporation
|
|
Packit Service |
4387a0 |
* Copyright (C) <2014> Sreerenj Balachandran <sreerenj.balachandran@intel.com>
|
|
Packit Service |
4387a0 |
*
|
|
Packit Service |
4387a0 |
* Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
|
|
Packit Service |
4387a0 |
*
|
|
Packit Service |
4387a0 |
* This library is free software; you can redistribute it and/or
|
|
Packit Service |
4387a0 |
* modify it under the terms of the GNU Library General Public
|
|
Packit Service |
4387a0 |
* License as published by the Free Software Foundation; either
|
|
Packit Service |
4387a0 |
* version 2 of the License, or (at your option) any later version.
|
|
Packit Service |
4387a0 |
*
|
|
Packit Service |
4387a0 |
* This library is distributed in the hope that it will be useful,
|
|
Packit Service |
4387a0 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
4387a0 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
4387a0 |
* Library General Public License for more details.
|
|
Packit Service |
4387a0 |
*
|
|
Packit Service |
4387a0 |
* You should have received a copy of the GNU Library General Public
|
|
Packit Service |
4387a0 |
* License along with this library; if not, write to the
|
|
Packit Service |
4387a0 |
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
Packit Service |
4387a0 |
* Boston, MA 02110-1301, USA.
|
|
Packit Service |
4387a0 |
*/
|
|
Packit Service |
4387a0 |
|
|
Packit Service |
4387a0 |
#ifdef HAVE_CONFIG_H
|
|
Packit Service |
4387a0 |
#include "config.h"
|
|
Packit Service |
4387a0 |
#endif
|
|
Packit Service |
4387a0 |
|
|
Packit Service |
4387a0 |
#include <gst/gst.h>
|
|
Packit Service |
4387a0 |
#include "gstplaybackutils.h"
|
|
Packit Service |
4387a0 |
|
|
Packit Service |
4387a0 |
static GstStaticCaps raw_audio_caps = GST_STATIC_CAPS ("audio/x-raw(ANY)");
|
|
Packit Service |
4387a0 |
static GstStaticCaps raw_video_caps = GST_STATIC_CAPS ("video/x-raw(ANY)");
|
|
Packit Service |
4387a0 |
|
|
Packit Service |
4387a0 |
/* unref the caps after usage */
|
|
Packit Service |
4387a0 |
static GstCaps *
|
|
Packit Service |
4387a0 |
get_template_caps (GstElementFactory * factory, GstPadDirection direction)
|
|
Packit Service |
4387a0 |
{
|
|
Packit Service |
4387a0 |
const GList *templates;
|
|
Packit Service |
4387a0 |
GstStaticPadTemplate *templ = NULL;
|
|
Packit Service |
4387a0 |
GList *walk;
|
|
Packit Service |
4387a0 |
|
|
Packit Service |
4387a0 |
templates = gst_element_factory_get_static_pad_templates (factory);
|
|
Packit Service |
4387a0 |
for (walk = (GList *) templates; walk; walk = g_list_next (walk)) {
|
|
Packit Service |
4387a0 |
templ = walk->data;
|
|
Packit Service |
4387a0 |
if (templ->direction == direction)
|
|
Packit Service |
4387a0 |
break;
|
|
Packit Service |
4387a0 |
}
|
|
Packit Service |
4387a0 |
if (templ)
|
|
Packit Service |
4387a0 |
return gst_static_caps_get (&templ->static_caps);
|
|
Packit Service |
4387a0 |
else
|
|
Packit Service |
4387a0 |
return NULL;
|
|
Packit Service |
4387a0 |
}
|
|
Packit Service |
4387a0 |
|
|
Packit Service |
4387a0 |
static gboolean
|
|
Packit Service |
4387a0 |
is_included (GList * list, GstCapsFeatures * cf)
|
|
Packit Service |
4387a0 |
{
|
|
Packit Service |
4387a0 |
for (; list; list = list->next) {
|
|
Packit Service |
4387a0 |
if (gst_caps_features_is_equal ((GstCapsFeatures *) list->data, cf))
|
|
Packit Service |
4387a0 |
return TRUE;
|
|
Packit Service |
4387a0 |
}
|
|
Packit Service |
4387a0 |
return FALSE;
|
|
Packit Service |
4387a0 |
}
|
|
Packit Service |
4387a0 |
|
|
Packit Service |
4387a0 |
/* compute the number of common caps features */
|
|
Packit Service |
4387a0 |
guint
|
|
Packit Service |
4387a0 |
gst_playback_utils_get_n_common_capsfeatures (GstElementFactory * fact1,
|
|
Packit Service |
4387a0 |
GstElementFactory * fact2, GstPlayFlags flags, gboolean isaudioelement)
|
|
Packit Service |
4387a0 |
{
|
|
Packit Service |
4387a0 |
GstCaps *fact1_tmpl_caps, *fact2_tmpl_caps;
|
|
Packit Service |
4387a0 |
GstCapsFeatures *fact1_features, *fact2_features;
|
|
Packit Service |
4387a0 |
GstStructure *fact1_struct, *fact2_struct;
|
|
Packit Service |
4387a0 |
GList *cf_list = NULL;
|
|
Packit Service |
4387a0 |
guint fact1_caps_size, fact2_caps_size;
|
|
Packit Service |
4387a0 |
guint i, j, n_common_cf = 0;
|
|
Packit Service |
4387a0 |
GstCaps *raw_caps =
|
|
Packit Service |
4387a0 |
(isaudioelement) ? gst_static_caps_get (&raw_audio_caps) :
|
|
Packit Service |
4387a0 |
gst_static_caps_get (&raw_video_caps);
|
|
Packit Service |
4387a0 |
GstStructure *raw_struct = gst_caps_get_structure (raw_caps, 0);
|
|
Packit Service |
4387a0 |
gboolean native_raw =
|
|
Packit Service |
4387a0 |
(isaudioelement ? ! !(flags & GST_PLAY_FLAG_NATIVE_AUDIO) : ! !(flags &
|
|
Packit Service |
4387a0 |
GST_PLAY_FLAG_NATIVE_VIDEO));
|
|
Packit Service |
4387a0 |
|
|
Packit Service |
4387a0 |
fact1_tmpl_caps = get_template_caps (fact1, GST_PAD_SRC);
|
|
Packit Service |
4387a0 |
fact2_tmpl_caps = get_template_caps (fact2, GST_PAD_SINK);
|
|
Packit Service |
4387a0 |
if (!fact1_tmpl_caps || !fact2_tmpl_caps) {
|
|
Packit Service |
4387a0 |
GST_ERROR ("Failed to get template caps from decoder or sink");
|
|
Packit Service |
4387a0 |
if (fact1_tmpl_caps)
|
|
Packit Service |
4387a0 |
gst_caps_unref (fact1_tmpl_caps);
|
|
Packit Service |
4387a0 |
else if (fact2_tmpl_caps)
|
|
Packit Service |
4387a0 |
gst_caps_unref (fact2_tmpl_caps);
|
|
Packit Service |
4387a0 |
return 0;
|
|
Packit Service |
4387a0 |
}
|
|
Packit Service |
4387a0 |
|
|
Packit Service |
4387a0 |
fact1_caps_size = gst_caps_get_size (fact1_tmpl_caps);
|
|
Packit Service |
4387a0 |
fact2_caps_size = gst_caps_get_size (fact2_tmpl_caps);
|
|
Packit Service |
4387a0 |
|
|
Packit Service |
4387a0 |
for (i = 0; i < fact1_caps_size; i++) {
|
|
Packit Service |
4387a0 |
fact1_features =
|
|
Packit Service |
4387a0 |
gst_caps_get_features ((const GstCaps *) fact1_tmpl_caps, i);
|
|
Packit Service |
4387a0 |
if (gst_caps_features_is_any (fact1_features))
|
|
Packit Service |
4387a0 |
continue;
|
|
Packit Service |
4387a0 |
fact1_struct =
|
|
Packit Service |
4387a0 |
gst_caps_get_structure ((const GstCaps *) fact1_tmpl_caps, i);
|
|
Packit Service |
4387a0 |
for (j = 0; j < fact2_caps_size; j++) {
|
|
Packit Service |
4387a0 |
|
|
Packit Service |
4387a0 |
fact2_features =
|
|
Packit Service |
4387a0 |
gst_caps_get_features ((const GstCaps *) fact2_tmpl_caps, j);
|
|
Packit Service |
4387a0 |
if (gst_caps_features_is_any (fact2_features))
|
|
Packit Service |
4387a0 |
continue;
|
|
Packit Service |
4387a0 |
fact2_struct =
|
|
Packit Service |
4387a0 |
gst_caps_get_structure ((const GstCaps *) fact2_tmpl_caps, j);
|
|
Packit Service |
4387a0 |
|
|
Packit Service |
4387a0 |
/* A common caps feature is given if the caps features are equal
|
|
Packit Service |
4387a0 |
* and the structures can intersect. If the NATIVE_AUDIO/NATIVE_VIDEO
|
|
Packit Service |
4387a0 |
* flags are not set we also allow if both structures are raw caps with
|
|
Packit Service |
4387a0 |
* system memory caps features, because in that case we have converters in
|
|
Packit Service |
4387a0 |
* place.
|
|
Packit Service |
4387a0 |
*/
|
|
Packit Service |
4387a0 |
if (gst_caps_features_is_equal (fact1_features, fact2_features) &&
|
|
Packit Service |
4387a0 |
(gst_structure_can_intersect (fact1_struct, fact2_struct) ||
|
|
Packit Service |
4387a0 |
(!native_raw
|
|
Packit Service |
4387a0 |
&& gst_caps_features_is_equal (fact1_features,
|
|
Packit Service |
4387a0 |
GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)
|
|
Packit Service |
4387a0 |
&& gst_structure_can_intersect (raw_struct, fact1_struct)
|
|
Packit Service |
4387a0 |
&& gst_structure_can_intersect (raw_struct, fact2_struct)))
|
|
Packit Service |
4387a0 |
&& !is_included (cf_list, fact2_features)) {
|
|
Packit Service |
4387a0 |
cf_list = g_list_prepend (cf_list, fact2_features);
|
|
Packit Service |
4387a0 |
n_common_cf++;
|
|
Packit Service |
4387a0 |
}
|
|
Packit Service |
4387a0 |
}
|
|
Packit Service |
4387a0 |
}
|
|
Packit Service |
4387a0 |
if (cf_list)
|
|
Packit Service |
4387a0 |
g_list_free (cf_list);
|
|
Packit Service |
4387a0 |
|
|
Packit Service |
4387a0 |
gst_caps_unref (fact1_tmpl_caps);
|
|
Packit Service |
4387a0 |
gst_caps_unref (fact2_tmpl_caps);
|
|
Packit Service |
4387a0 |
|
|
Packit Service |
4387a0 |
return n_common_cf;
|
|
Packit Service |
4387a0 |
}
|
|
Packit Service |
4387a0 |
|
|
Packit Service |
4387a0 |
gint
|
|
Packit Service |
4387a0 |
gst_playback_utils_compare_factories_func (gconstpointer p1, gconstpointer p2)
|
|
Packit Service |
4387a0 |
{
|
|
Packit Service |
4387a0 |
GstPluginFeature *f1, *f2;
|
|
Packit Service |
4387a0 |
gboolean is_parser1, is_parser2;
|
|
Packit Service |
4387a0 |
|
|
Packit Service |
4387a0 |
f1 = (GstPluginFeature *) p1;
|
|
Packit Service |
4387a0 |
f2 = (GstPluginFeature *) p2;
|
|
Packit Service |
4387a0 |
|
|
Packit Service |
4387a0 |
is_parser1 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f1),
|
|
Packit Service |
4387a0 |
GST_ELEMENT_FACTORY_TYPE_PARSER);
|
|
Packit Service |
4387a0 |
is_parser2 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f2),
|
|
Packit Service |
4387a0 |
GST_ELEMENT_FACTORY_TYPE_PARSER);
|
|
Packit Service |
4387a0 |
|
|
Packit Service |
4387a0 |
|
|
Packit Service |
4387a0 |
/* We want all parsers first as we always want to plug parsers
|
|
Packit Service |
4387a0 |
* before decoders */
|
|
Packit Service |
4387a0 |
if (is_parser1 && !is_parser2)
|
|
Packit Service |
4387a0 |
return -1;
|
|
Packit Service |
4387a0 |
else if (!is_parser1 && is_parser2)
|
|
Packit Service |
4387a0 |
return 1;
|
|
Packit Service |
4387a0 |
|
|
Packit Service |
4387a0 |
/* And if it's a both a parser we first sort by rank
|
|
Packit Service |
4387a0 |
* and then by factory name */
|
|
Packit Service |
4387a0 |
return gst_plugin_feature_rank_compare_func (p1, p2);
|
|
Packit Service |
4387a0 |
}
|