encodebin: Add flags to disable conversion elements

Add a flags property and two flags to allow one to disable the
conversion elements within encodebin. Doing so insists that the
uncompressed input to encodebin for the appropriate stream type is
sufficient to meet the caps requirements of the encoders, muxers and
encodebin target.

This is mostly beneficial to bypass slow caps negotiations in the
conversion elements.
This commit is contained in:
Robert Swain 2011-06-29 13:12:49 +02:00
parent 96d2120c2b
commit 7ad1ba6fba

View file

@ -118,6 +118,15 @@
#define fast_pad_link(a,b) gst_pad_link_full((a),(b),GST_PAD_LINK_CHECK_NOTHING) #define fast_pad_link(a,b) gst_pad_link_full((a),(b),GST_PAD_LINK_CHECK_NOTHING)
#define fast_element_link(a,b) gst_element_link_pads_full((a),"src",(b),"sink",GST_PAD_LINK_CHECK_NOTHING) #define fast_element_link(a,b) gst_element_link_pads_full((a),"src",(b),"sink",GST_PAD_LINK_CHECK_NOTHING)
typedef enum
{
GST_ENC_FLAG_NATIVE_AUDIO = (1 << 0),
GST_ENC_FLAG_NATIVE_VIDEO = (1 << 1)
} GstEncFlags;
#define GST_TYPE_ENC_FLAGS (gst_enc_flags_get_type())
GType gst_enc_flags_get_type (void);
/* generic templates */ /* generic templates */
static GstStaticPadTemplate muxer_src_template = static GstStaticPadTemplate muxer_src_template =
GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
@ -180,6 +189,8 @@ struct _GstEncodeBin
guint64 tolerance; guint64 tolerance;
gboolean avoid_reencoding; gboolean avoid_reencoding;
GstEncFlags flags;
}; };
struct _GstEncodeBinClass struct _GstEncodeBinClass
@ -216,6 +227,7 @@ struct _StreamGroup
#define DEFAULT_QUEUE_TIME_MAX GST_SECOND #define DEFAULT_QUEUE_TIME_MAX GST_SECOND
#define DEFAULT_AUDIO_JITTER_TOLERANCE 20 * GST_MSECOND #define DEFAULT_AUDIO_JITTER_TOLERANCE 20 * GST_MSECOND
#define DEFAULT_AVOID_REENCODING FALSE #define DEFAULT_AVOID_REENCODING FALSE
#define DEFAULT_FLAGS 0
#define DEFAULT_RAW_CAPS \ #define DEFAULT_RAW_CAPS \
"video/x-raw-yuv; " \ "video/x-raw-yuv; " \
@ -238,6 +250,7 @@ enum
PROP_QUEUE_TIME_MAX, PROP_QUEUE_TIME_MAX,
PROP_AUDIO_JITTER_TOLERANCE, PROP_AUDIO_JITTER_TOLERANCE,
PROP_AVOID_REENCODING, PROP_AVOID_REENCODING,
PROP_FLAGS,
PROP_LAST PROP_LAST
}; };
@ -248,6 +261,31 @@ enum
LAST_SIGNAL LAST_SIGNAL
}; };
#define C_FLAGS(v) ((guint) v)
GType
gst_enc_flags_get_type (void)
{
static const GFlagsValue values[] = {
{C_FLAGS (GST_ENC_FLAG_NATIVE_AUDIO), "Only use native audio formats",
"native-audio"},
{C_FLAGS (GST_ENC_FLAG_NATIVE_VIDEO), "Only use native video formats",
"native-video"},
{0, NULL, NULL}
};
static volatile GType id = 0;
if (g_once_init_enter ((gsize *) & id)) {
GType _id;
_id = g_flags_register_static ("GstEncFlags", values);
g_once_init_leave ((gsize *) & id, _id);
}
return id;
}
static guint gst_encode_bin_signals[LAST_SIGNAL] = { 0 }; static guint gst_encode_bin_signals[LAST_SIGNAL] = { 0 };
static GstStaticCaps default_raw_caps = GST_STATIC_CAPS (DEFAULT_RAW_CAPS); static GstStaticCaps default_raw_caps = GST_STATIC_CAPS (DEFAULT_RAW_CAPS);
@ -339,6 +377,16 @@ gst_encode_bin_class_init (GstEncodeBinClass * klass)
DEFAULT_AVOID_REENCODING, DEFAULT_AVOID_REENCODING,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GstEncodeBin:flags
*
* Control the behaviour of encodebin.
*/
g_object_class_install_property (gobject_klass, PROP_FLAGS,
g_param_spec_flags ("flags", "Flags", "Flags to control behaviour",
GST_TYPE_ENC_FLAGS, DEFAULT_FLAGS,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/* Signals */ /* Signals */
/** /**
* GstEncodeBin::request-pad * GstEncodeBin::request-pad
@ -447,6 +495,7 @@ gst_encode_bin_init (GstEncodeBin * encode_bin)
encode_bin->queue_time_max = DEFAULT_QUEUE_TIME_MAX; encode_bin->queue_time_max = DEFAULT_QUEUE_TIME_MAX;
encode_bin->tolerance = DEFAULT_AUDIO_JITTER_TOLERANCE; encode_bin->tolerance = DEFAULT_AUDIO_JITTER_TOLERANCE;
encode_bin->avoid_reencoding = DEFAULT_AVOID_REENCODING; encode_bin->avoid_reencoding = DEFAULT_AVOID_REENCODING;
encode_bin->flags = DEFAULT_FLAGS;
tmpl = gst_static_pad_template_get (&muxer_src_template); tmpl = gst_static_pad_template_get (&muxer_src_template);
encode_bin->srcpad = gst_ghost_pad_new_no_target_from_template ("src", tmpl); encode_bin->srcpad = gst_ghost_pad_new_no_target_from_template ("src", tmpl);
@ -480,6 +529,9 @@ gst_encode_bin_set_property (GObject * object, guint prop_id,
case PROP_AVOID_REENCODING: case PROP_AVOID_REENCODING:
ebin->avoid_reencoding = g_value_get_boolean (value); ebin->avoid_reencoding = g_value_get_boolean (value);
break; break;
case PROP_FLAGS:
ebin->flags = g_value_get_flags (value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -511,6 +563,9 @@ gst_encode_bin_get_property (GObject * object, guint prop_id,
case PROP_AVOID_REENCODING: case PROP_AVOID_REENCODING:
g_value_set_boolean (value, ebin->avoid_reencoding); g_value_set_boolean (value, ebin->avoid_reencoding);
break; break;
case PROP_FLAGS:
g_value_set_flags (value, ebin->flags);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -1206,10 +1261,12 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof,
/* 3.2. restriction elements */ /* 3.2. restriction elements */
/* FIXME : Once we have properties for specific converters, use those */ /* FIXME : Once we have properties for specific converters, use those */
if (GST_IS_ENCODING_VIDEO_PROFILE (sprof)) { if (GST_IS_ENCODING_VIDEO_PROFILE (sprof)) {
const gboolean native_video = ! !(ebin->flags & GST_ENC_FLAG_NATIVE_VIDEO);
GstElement *cspace, *scale, *vrate, *cspace2; GstElement *cspace, *scale, *vrate, *cspace2;
GST_LOG ("Adding conversion elements for video stream"); GST_LOG ("Adding conversion elements for video stream");
if (!native_video) {
cspace = gst_element_factory_make ("ffmpegcolorspace", NULL); cspace = gst_element_factory_make ("ffmpegcolorspace", NULL);
scale = gst_element_factory_make ("videoscale", NULL); scale = gst_element_factory_make ("videoscale", NULL);
if (!scale) { if (!scale) {
@ -1237,6 +1294,7 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof,
if (!fast_element_link (cspace, scale) || if (!fast_element_link (cspace, scale) ||
!fast_element_link (scale, cspace2)) !fast_element_link (scale, cspace2))
goto converter_link_failure; goto converter_link_failure;
}
if (!gst_encoding_video_profile_get_variableframerate if (!gst_encoding_video_profile_get_variableframerate
(GST_ENCODING_VIDEO_PROFILE (sprof))) { (GST_ENCODING_VIDEO_PROFILE (sprof))) {
@ -1249,15 +1307,23 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof,
gst_bin_add ((GstBin *) ebin, vrate); gst_bin_add ((GstBin *) ebin, vrate);
tosync = g_list_prepend (tosync, vrate); tosync = g_list_prepend (tosync, vrate);
sgroup->converters = g_list_prepend (sgroup->converters, vrate); sgroup->converters = g_list_prepend (sgroup->converters, vrate);
if (!fast_element_link (cspace2, vrate) ||
!fast_element_link (vrate, last)) if ((!native_video && !fast_element_link (cspace2, vrate))
goto converter_link_failure; || !fast_element_link (vrate, last))
} else if (!fast_element_link (cspace2, last))
goto converter_link_failure; goto converter_link_failure;
if (!native_video)
last = cspace; last = cspace;
else
last = vrate;
} else if (!native_video) {
if (!fast_element_link (cspace2, last))
goto converter_link_failure;
last = cspace;
}
} else if (GST_IS_ENCODING_AUDIO_PROFILE (sprof)) { } else if (GST_IS_ENCODING_AUDIO_PROFILE (sprof)
&& !(ebin->flags & GST_ENC_FLAG_NATIVE_AUDIO)) {
GstElement *aconv, *ares, *arate, *aconv2; GstElement *aconv, *ares, *arate, *aconv2;
GST_LOG ("Adding conversion elements for audio stream"); GST_LOG ("Adding conversion elements for audio stream");