mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 18:51:11 +00:00
opusenc: add upstream negotiation for multistream ability
This will help elements that cannot deal with multistream, such as the RTP payloader. The caps now do not include a "streams" field anymore, but a "multistream" boolean, since we have no real use for knowing the exact amount of streams. https://bugzilla.gnome.org/show_bug.cgi?id=665078
This commit is contained in:
parent
3a978f5a69
commit
3f47a43f2a
2 changed files with 69 additions and 4 deletions
|
@ -126,7 +126,7 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
|
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
GST_PAD_SRC,
|
GST_PAD_SRC,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS ("audio/x-opus, streams = (int) [1, 255 ]")
|
GST_STATIC_CAPS ("audio/x-opus")
|
||||||
);
|
);
|
||||||
|
|
||||||
#define DEFAULT_AUDIO TRUE
|
#define DEFAULT_AUDIO TRUE
|
||||||
|
@ -161,6 +161,7 @@ static void gst_opus_enc_finalize (GObject * object);
|
||||||
|
|
||||||
static gboolean gst_opus_enc_sink_event (GstAudioEncoder * benc,
|
static gboolean gst_opus_enc_sink_event (GstAudioEncoder * benc,
|
||||||
GstEvent * event);
|
GstEvent * event);
|
||||||
|
static GstCaps *gst_opus_enc_sink_getcaps (GstAudioEncoder * benc);
|
||||||
static gboolean gst_opus_enc_setup (GstOpusEnc * enc);
|
static gboolean gst_opus_enc_setup (GstOpusEnc * enc);
|
||||||
|
|
||||||
static void gst_opus_enc_get_property (GObject * object, guint prop_id,
|
static void gst_opus_enc_get_property (GObject * object, guint prop_id,
|
||||||
|
@ -229,6 +230,7 @@ gst_opus_enc_class_init (GstOpusEncClass * klass)
|
||||||
base_class->set_format = GST_DEBUG_FUNCPTR (gst_opus_enc_set_format);
|
base_class->set_format = GST_DEBUG_FUNCPTR (gst_opus_enc_set_format);
|
||||||
base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_opus_enc_handle_frame);
|
base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_opus_enc_handle_frame);
|
||||||
base_class->event = GST_DEBUG_FUNCPTR (gst_opus_enc_sink_event);
|
base_class->event = GST_DEBUG_FUNCPTR (gst_opus_enc_sink_event);
|
||||||
|
base_class->getcaps = GST_DEBUG_FUNCPTR (gst_opus_enc_sink_getcaps);
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class, PROP_AUDIO,
|
g_object_class_install_property (gobject_class, PROP_AUDIO,
|
||||||
g_param_spec_boolean ("audio", "Audio or voice",
|
g_param_spec_boolean ("audio", "Audio or voice",
|
||||||
|
@ -721,6 +723,68 @@ gst_opus_enc_sink_event (GstAudioEncoder * benc, GstEvent * event)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstCaps *
|
||||||
|
gst_opus_enc_sink_getcaps (GstAudioEncoder * benc)
|
||||||
|
{
|
||||||
|
GstOpusEnc *enc;
|
||||||
|
GstCaps *caps;
|
||||||
|
GstCaps *peercaps = NULL;
|
||||||
|
GstCaps *intersect = NULL;
|
||||||
|
guint i;
|
||||||
|
gboolean allow_multistream;
|
||||||
|
|
||||||
|
enc = GST_OPUS_ENC (benc);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (enc, "sink getcaps");
|
||||||
|
|
||||||
|
peercaps = gst_pad_peer_get_caps (GST_AUDIO_ENCODER_SRC_PAD (benc));
|
||||||
|
if (!peercaps) {
|
||||||
|
GST_DEBUG_OBJECT (benc, "No peercaps, returning template sink caps");
|
||||||
|
return
|
||||||
|
gst_caps_copy (gst_pad_get_pad_template_caps
|
||||||
|
(GST_AUDIO_ENCODER_SINK_PAD (benc)));
|
||||||
|
}
|
||||||
|
|
||||||
|
intersect = gst_caps_intersect (peercaps,
|
||||||
|
gst_pad_get_pad_template_caps (GST_AUDIO_ENCODER_SRC_PAD (benc)));
|
||||||
|
gst_caps_unref (peercaps);
|
||||||
|
|
||||||
|
if (gst_caps_is_empty (intersect))
|
||||||
|
return intersect;
|
||||||
|
|
||||||
|
allow_multistream = FALSE;
|
||||||
|
for (i = 0; i < gst_caps_get_size (intersect); i++) {
|
||||||
|
GstStructure *s = gst_caps_get_structure (intersect, i);
|
||||||
|
gboolean multistream;
|
||||||
|
if (gst_structure_get_boolean (s, "multistream", &multistream)) {
|
||||||
|
if (multistream) {
|
||||||
|
allow_multistream = TRUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
allow_multistream = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_caps_unref (intersect);
|
||||||
|
|
||||||
|
caps =
|
||||||
|
gst_caps_copy (gst_pad_get_pad_template_caps (GST_AUDIO_ENCODER_SINK_PAD
|
||||||
|
(benc)));
|
||||||
|
if (!allow_multistream) {
|
||||||
|
GValue range = { 0 };
|
||||||
|
g_value_init (&range, GST_TYPE_INT_RANGE);
|
||||||
|
gst_value_set_int_range (&range, 1, 2);
|
||||||
|
for (i = 0; i < gst_caps_get_size (caps); i++) {
|
||||||
|
GstStructure *s = gst_caps_get_structure (caps, i);
|
||||||
|
gst_structure_set_value (s, "channels", &range);
|
||||||
|
}
|
||||||
|
g_value_unset (&range);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (enc, "Returning caps: %" GST_PTR_FORMAT, caps);
|
||||||
|
return caps;
|
||||||
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_opus_enc_encode (GstOpusEnc * enc, GstBuffer * buf)
|
gst_opus_enc_encode (GstOpusEnc * enc, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
|
|
|
@ -151,6 +151,7 @@ gst_opus_header_create_caps_from_headers (GstCaps ** caps, GSList ** headers,
|
||||||
GstBuffer * buf1, GstBuffer * buf2)
|
GstBuffer * buf1, GstBuffer * buf2)
|
||||||
{
|
{
|
||||||
int n_streams, family;
|
int n_streams, family;
|
||||||
|
gboolean multistream;
|
||||||
|
|
||||||
g_return_if_fail (caps);
|
g_return_if_fail (caps);
|
||||||
g_return_if_fail (headers && !*headers);
|
g_return_if_fail (headers && !*headers);
|
||||||
|
@ -167,9 +168,9 @@ gst_opus_header_create_caps_from_headers (GstCaps ** caps, GSList ** headers,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mark and put on caps */
|
/* mark and put on caps */
|
||||||
*caps =
|
multistream = n_streams > 1;
|
||||||
gst_caps_new_simple ("audio/x-opus", "streams", G_TYPE_INT, n_streams,
|
*caps = gst_caps_new_simple ("audio/x-opus",
|
||||||
NULL);
|
"multistream", G_TYPE_BOOLEAN, multistream, NULL);
|
||||||
*caps = _gst_caps_set_buffer_array (*caps, "streamheader", buf1, buf2, NULL);
|
*caps = _gst_caps_set_buffer_array (*caps, "streamheader", buf1, buf2, NULL);
|
||||||
|
|
||||||
*headers = g_slist_prepend (*headers, buf2);
|
*headers = g_slist_prepend (*headers, buf2);
|
||||||
|
|
Loading…
Reference in a new issue