mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-10 17:35:59 +00:00
playback: Add gstplaybackutils.{h,c} to deploy the common subroutines
Bring some of the helper functions in gstplaybin2.c to new files gstplaybackutils.{h,c} which can be utilized by other files in gst/playback too. https://bugzilla.gnome.org/show_bug.cgi?id=687182
This commit is contained in:
parent
51c3ef05cd
commit
16378a7de3
4 changed files with 173 additions and 101 deletions
|
@ -13,7 +13,8 @@ libgstplayback_la_SOURCES = \
|
|||
gstplaysinkvideoconvert.c \
|
||||
gstplaysinkaudioconvert.c \
|
||||
gstplaysinkconvertbin.c \
|
||||
gststreamsynchronizer.c
|
||||
gststreamsynchronizer.c \
|
||||
gstplaybackutils.c
|
||||
|
||||
nodist_libgstplayback_la_SOURCES = $(built_sources)
|
||||
libgstplayback_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(csp_cflags)
|
||||
|
@ -34,7 +35,8 @@ noinst_HEADERS = \
|
|||
gstplaysinkvideoconvert.h \
|
||||
gstplaysinkaudioconvert.h \
|
||||
gstplaysinkconvertbin.h \
|
||||
gststreamsynchronizer.h
|
||||
gststreamsynchronizer.h \
|
||||
gstplaybackutils.h
|
||||
|
||||
BUILT_SOURCES = $(built_headers) $(built_sources)
|
||||
|
||||
|
|
129
gst/playback/gstplaybackutils.c
Normal file
129
gst/playback/gstplaybackutils.c
Normal file
|
@ -0,0 +1,129 @@
|
|||
/* Copyright (C) <2014> Intel Corporation
|
||||
* Copyright (C) <2014> Sreerenj Balachandran <sreerenj.balachandran@intel.com>
|
||||
*
|
||||
* Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include "gstplaybackutils.h"
|
||||
|
||||
static GstStaticCaps raw_audio_caps = GST_STATIC_CAPS ("audio/x-raw(ANY)");
|
||||
static GstStaticCaps raw_video_caps = GST_STATIC_CAPS ("video/x-raw(ANY)");
|
||||
|
||||
/* unref the caps after usage */
|
||||
static GstCaps *
|
||||
get_template_caps (GstElementFactory * factory, GstPadDirection direction)
|
||||
{
|
||||
const GList *templates;
|
||||
GstStaticPadTemplate *templ = NULL;
|
||||
GList *walk;
|
||||
|
||||
templates = gst_element_factory_get_static_pad_templates (factory);
|
||||
for (walk = (GList *) templates; walk; walk = g_list_next (walk)) {
|
||||
templ = walk->data;
|
||||
if (templ->direction == direction)
|
||||
break;
|
||||
}
|
||||
if (templ)
|
||||
return gst_static_caps_get (&templ->static_caps);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_included (GList * list, GstCapsFeatures * cf)
|
||||
{
|
||||
for (; list; list = list->next) {
|
||||
if (gst_caps_features_is_equal ((GstCapsFeatures *) list->data, cf))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* compute the number of common caps features */
|
||||
guint
|
||||
gst_playback_utils_get_n_common_capsfeatures (GstElementFactory * fact1,
|
||||
GstElementFactory * fact2, GstPlayFlags flags, gboolean isaudioelement)
|
||||
{
|
||||
GstCaps *fact1_tmpl_caps, *fact2_tmpl_caps;
|
||||
GstCapsFeatures *fact1_features, *fact2_features;
|
||||
GstStructure *fact1_struct, *fact2_struct;
|
||||
GList *cf_list = NULL;
|
||||
guint fact1_caps_size, fact2_caps_size;
|
||||
guint i, j, n_common_cf = 0;
|
||||
GstCaps *raw_caps =
|
||||
(isaudioelement) ? gst_static_caps_get (&raw_audio_caps) :
|
||||
gst_static_caps_get (&raw_video_caps);
|
||||
GstStructure *raw_struct = gst_caps_get_structure (raw_caps, 0);
|
||||
gboolean native_raw =
|
||||
(isaudioelement ? ! !(flags & GST_PLAY_FLAG_NATIVE_AUDIO) : ! !(flags &
|
||||
GST_PLAY_FLAG_NATIVE_VIDEO));
|
||||
|
||||
fact1_tmpl_caps = get_template_caps (fact1, GST_PAD_SRC);
|
||||
fact2_tmpl_caps = get_template_caps (fact2, GST_PAD_SINK);
|
||||
if (!fact1_tmpl_caps || !fact2_tmpl_caps) {
|
||||
GST_ERROR ("Failed to get template caps from decoder or sink");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fact1_caps_size = gst_caps_get_size (fact1_tmpl_caps);
|
||||
fact2_caps_size = gst_caps_get_size (fact2_tmpl_caps);
|
||||
|
||||
for (i = 0; i < fact1_caps_size; i++) {
|
||||
fact1_features =
|
||||
gst_caps_get_features ((const GstCaps *) fact1_tmpl_caps, i);
|
||||
fact1_struct =
|
||||
gst_caps_get_structure ((const GstCaps *) fact1_tmpl_caps, i);
|
||||
for (j = 0; j < fact2_caps_size; j++) {
|
||||
|
||||
fact2_features =
|
||||
gst_caps_get_features ((const GstCaps *) fact2_tmpl_caps, j);
|
||||
fact2_struct =
|
||||
gst_caps_get_structure ((const GstCaps *) fact2_tmpl_caps, j);
|
||||
|
||||
/* A common caps feature is given if the caps features are equal
|
||||
* and the structures can intersect. If the NATIVE_AUDIO/NATIVE_VIDEO
|
||||
* flags are not set we also allow if both structures are raw caps with
|
||||
* system memory caps features, because in that case we have converters in
|
||||
* place.
|
||||
*/
|
||||
if (gst_caps_features_is_equal (fact1_features, fact2_features) &&
|
||||
(gst_structure_can_intersect (fact1_struct, fact2_struct) ||
|
||||
(!native_raw
|
||||
&& gst_caps_features_is_equal (fact1_features,
|
||||
GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)
|
||||
&& gst_structure_can_intersect (raw_struct, fact1_struct)
|
||||
&& gst_structure_can_intersect (raw_struct, fact2_struct)))
|
||||
&& !is_included (cf_list, fact2_features)) {
|
||||
cf_list = g_list_prepend (cf_list, fact2_features);
|
||||
n_common_cf++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cf_list)
|
||||
g_list_free (cf_list);
|
||||
|
||||
gst_caps_unref (fact1_tmpl_caps);
|
||||
gst_caps_unref (fact2_tmpl_caps);
|
||||
|
||||
return n_common_cf;
|
||||
}
|
37
gst/playback/gstplaybackutils.h
Normal file
37
gst/playback/gstplaybackutils.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* Copyright (C) <2014> Intel Corporation
|
||||
* Copyright (C) <2014> Sreerenj Balachandran <sreerenj.balachandran@intel.com>
|
||||
*
|
||||
* Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_PLAYBACK_UTILS_H__
|
||||
#define __GST_PLAYBACK_UTILS_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include "gstplay-enum.h"
|
||||
|
||||
guint
|
||||
gst_playback_utils_get_n_common_capsfeatures (GstElementFactory * fact1,
|
||||
GstElementFactory * fact2,
|
||||
GstPlayFlags flags,
|
||||
gboolean isaudioelement);
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_PLAYBACK_UTILS_H__ */
|
|
@ -237,6 +237,7 @@
|
|||
#include "gstplayback.h"
|
||||
#include "gstplaysink.h"
|
||||
#include "gstsubtitleoverlay.h"
|
||||
#include "gstplaybackutils.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (gst_play_bin_debug);
|
||||
#define GST_CAT_DEFAULT gst_play_bin_debug
|
||||
|
@ -3811,103 +3812,6 @@ avelement_compare (gconstpointer p1, gconstpointer p2)
|
|||
return strcmp (GST_OBJECT_NAME (fd1), GST_OBJECT_NAME (fd2));
|
||||
}
|
||||
|
||||
/* unref the caps after usage */
|
||||
static GstCaps *
|
||||
get_template_caps (GstElementFactory * factory, GstPadDirection direction)
|
||||
{
|
||||
const GList *templates;
|
||||
GstStaticPadTemplate *templ = NULL;
|
||||
GList *walk;
|
||||
|
||||
templates = gst_element_factory_get_static_pad_templates (factory);
|
||||
for (walk = (GList *) templates; walk; walk = g_list_next (walk)) {
|
||||
templ = walk->data;
|
||||
if (templ->direction == direction)
|
||||
break;
|
||||
}
|
||||
if (templ)
|
||||
return gst_static_caps_get (&templ->static_caps);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_included (GList * list, GstCapsFeatures * cf)
|
||||
{
|
||||
for (; list; list = list->next) {
|
||||
if (gst_caps_features_is_equal ((GstCapsFeatures *) list->data, cf))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* compute the number of common caps features */
|
||||
static guint
|
||||
get_n_common_capsfeatures (GstPlayBin * playbin, GstElementFactory * dec,
|
||||
GstElementFactory * sink, gboolean isaudioelement)
|
||||
{
|
||||
GstCaps *d_tmpl_caps, *s_tmpl_caps;
|
||||
GstCapsFeatures *d_features, *s_features;
|
||||
GstStructure *d_struct, *s_struct;
|
||||
GList *cf_list = NULL;
|
||||
guint d_caps_size, s_caps_size;
|
||||
guint i, j, n_common_cf = 0;
|
||||
GstCaps *raw_caps =
|
||||
(isaudioelement) ? gst_static_caps_get (&raw_audio_caps) :
|
||||
gst_static_caps_get (&raw_video_caps);
|
||||
GstStructure *raw_struct = gst_caps_get_structure (raw_caps, 0);
|
||||
GstPlayFlags flags = gst_play_bin_get_flags (playbin);
|
||||
gboolean native_raw =
|
||||
(isaudioelement ? ! !(flags & GST_PLAY_FLAG_NATIVE_AUDIO) : ! !(flags &
|
||||
GST_PLAY_FLAG_NATIVE_VIDEO));
|
||||
|
||||
d_tmpl_caps = get_template_caps (dec, GST_PAD_SRC);
|
||||
s_tmpl_caps = get_template_caps (sink, GST_PAD_SINK);
|
||||
|
||||
if (!d_tmpl_caps || !s_tmpl_caps) {
|
||||
GST_ERROR ("Failed to get template caps from decoder or sink");
|
||||
return 0;
|
||||
}
|
||||
|
||||
d_caps_size = gst_caps_get_size (d_tmpl_caps);
|
||||
s_caps_size = gst_caps_get_size (s_tmpl_caps);
|
||||
|
||||
for (i = 0; i < d_caps_size; i++) {
|
||||
d_features = gst_caps_get_features ((const GstCaps *) d_tmpl_caps, i);
|
||||
d_struct = gst_caps_get_structure ((const GstCaps *) d_tmpl_caps, i);
|
||||
for (j = 0; j < s_caps_size; j++) {
|
||||
|
||||
s_features = gst_caps_get_features ((const GstCaps *) s_tmpl_caps, j);
|
||||
s_struct = gst_caps_get_structure ((const GstCaps *) s_tmpl_caps, j);
|
||||
|
||||
/* A common caps feature is given if the caps features are equal
|
||||
* and the structures can intersect. If the NATIVE_AUDIO/NATIVE_VIDEO
|
||||
* flags are not set we also allow if both structures are raw caps with
|
||||
* system memory caps features, because in that case we have converters in
|
||||
* place.
|
||||
*/
|
||||
if (gst_caps_features_is_equal (d_features, s_features) &&
|
||||
(gst_structure_can_intersect (d_struct, s_struct) ||
|
||||
(!native_raw
|
||||
&& gst_caps_features_is_equal (d_features,
|
||||
GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)
|
||||
&& gst_structure_can_intersect (raw_struct, d_struct)
|
||||
&& gst_structure_can_intersect (raw_struct, s_struct)))
|
||||
&& !is_included (cf_list, s_features)) {
|
||||
cf_list = g_list_prepend (cf_list, s_features);
|
||||
n_common_cf++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cf_list)
|
||||
g_list_free (cf_list);
|
||||
|
||||
gst_caps_unref (d_tmpl_caps);
|
||||
gst_caps_unref (s_tmpl_caps);
|
||||
|
||||
return n_common_cf;
|
||||
}
|
||||
|
||||
static GSequence *
|
||||
avelements_create (GstPlayBin * playbin, gboolean isaudioelement)
|
||||
{
|
||||
|
@ -3951,8 +3855,8 @@ avelements_create (GstPlayBin * playbin, gboolean isaudioelement)
|
|||
s_factory = (GstElementFactory *) sl->data;
|
||||
|
||||
n_common_cf =
|
||||
get_n_common_capsfeatures (playbin, d_factory, s_factory,
|
||||
isaudioelement);
|
||||
gst_playback_utils_get_n_common_capsfeatures (d_factory, s_factory,
|
||||
gst_play_bin_get_flags (playbin), isaudioelement);
|
||||
if (n_common_cf < 1)
|
||||
continue;
|
||||
|
||||
|
|
Loading…
Reference in a new issue