From 73d0c7516f36c7af7852e38a75628b66cdda4287 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Fri, 11 Nov 2011 17:46:41 +0000 Subject: [PATCH] opus: port to 0.11 --- ext/opus/gstopusdec.c | 211 ++++++++++++++++++++++++++++++-------------------- ext/opus/gstopusdec.h | 2 + ext/opus/gstopusenc.c | 152 ++++++++++++++++-------------------- 3 files changed, 193 insertions(+), 172 deletions(-) diff --git a/ext/opus/gstopusdec.c b/ext/opus/gstopusdec.c index 35f501a..199731e 100644 --- a/ext/opus/gstopusdec.c +++ b/ext/opus/gstopusdec.c @@ -54,11 +54,10 @@ static GstStaticPadTemplate opus_dec_src_factory = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-raw-int, " + GST_STATIC_CAPS ("audio/x-raw, " + "format = (string) { S16LE }, " "rate = (int) { 8000, 12000, 16000, 24000, 48000 }, " - "channels = (int) [ 1, 2 ], " - "endianness = (int) BYTE_ORDER, " - "signed = (boolean) true, " "width = (int) 16, " "depth = (int) 16") + "channels = (int) [ 1, 2 ] ") ); static GstStaticPadTemplate opus_dec_sink_factory = @@ -68,7 +67,7 @@ GST_STATIC_PAD_TEMPLATE ("sink", GST_STATIC_CAPS ("audio/x-opus") ); -GST_BOILERPLATE (GstOpusDec, gst_opus_dec, GstElement, GST_TYPE_ELEMENT); +G_DEFINE_TYPE (GstOpusDec, gst_opus_dec, GST_TYPE_ELEMENT); static gboolean opus_dec_sink_event (GstPad * pad, GstEvent * event); static GstFlowReturn opus_dec_chain (GstPad * pad, GstBuffer * buf); @@ -79,8 +78,6 @@ static GstStateChangeReturn opus_dec_change_state (GstElement * element, static gboolean opus_dec_src_event (GstPad * pad, GstEvent * event); static gboolean opus_dec_src_query (GstPad * pad, GstQuery * query); static gboolean opus_dec_sink_query (GstPad * pad, GstQuery * query); -static const GstQueryType *opus_get_src_query_types (GstPad * pad); -static const GstQueryType *opus_get_sink_query_types (GstPad * pad); static gboolean opus_dec_convert (GstPad * pad, GstFormat src_format, gint64 src_value, GstFormat * dest_format, gint64 * dest_value); @@ -95,9 +92,11 @@ static GstFlowReturn opus_dec_chain_parse_comments (GstOpusDec * dec, #endif static void -gst_opus_dec_base_init (gpointer g_class) +gst_opus_dec_class_init (GstOpusDecClass * klass) { - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + GstElementClass *element_class; + + element_class = (GstElementClass *) klass; gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&opus_dec_src_factory)); @@ -107,16 +106,8 @@ gst_opus_dec_base_init (gpointer g_class) "Codec/Decoder/Audio", "decode opus streams to audio", "Sebastian Dröge "); -} - -static void -gst_opus_dec_class_init (GstOpusDecClass * klass) -{ - GstElementClass *gstelement_class; - - gstelement_class = (GstElementClass *) klass; - gstelement_class->change_state = GST_DEBUG_FUNCPTR (opus_dec_change_state); + element_class->change_state = GST_DEBUG_FUNCPTR (opus_dec_change_state); GST_DEBUG_CATEGORY_INIT (opusdec_debug, "opusdec", 0, "opus decoding element"); @@ -154,27 +145,21 @@ gst_opus_dec_reset (GstOpusDec * dec) } static void -gst_opus_dec_init (GstOpusDec * dec, GstOpusDecClass * g_class) +gst_opus_dec_init (GstOpusDec * dec) { dec->sinkpad = gst_pad_new_from_static_template (&opus_dec_sink_factory, "sink"); gst_pad_set_chain_function (dec->sinkpad, GST_DEBUG_FUNCPTR (opus_dec_chain)); gst_pad_set_event_function (dec->sinkpad, GST_DEBUG_FUNCPTR (opus_dec_sink_event)); - gst_pad_set_query_type_function (dec->sinkpad, - GST_DEBUG_FUNCPTR (opus_get_sink_query_types)); gst_pad_set_query_function (dec->sinkpad, GST_DEBUG_FUNCPTR (opus_dec_sink_query)); - gst_pad_set_setcaps_function (dec->sinkpad, - GST_DEBUG_FUNCPTR (opus_dec_sink_setcaps)); gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad); dec->srcpad = gst_pad_new_from_static_template (&opus_dec_src_factory, "src"); gst_pad_use_fixed_caps (dec->srcpad); gst_pad_set_event_function (dec->srcpad, GST_DEBUG_FUNCPTR (opus_dec_src_event)); - gst_pad_set_query_type_function (dec->srcpad, - GST_DEBUG_FUNCPTR (opus_get_src_query_types)); gst_pad_set_query_function (dec->srcpad, GST_DEBUG_FUNCPTR (opus_dec_src_query)); gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad); @@ -185,6 +170,52 @@ gst_opus_dec_init (GstOpusDec * dec, GstOpusDecClass * g_class) gst_opus_dec_reset (dec); } +static GstFlowReturn +gst_opus_dec_negotiate_pool (GstOpusDec * dec, GstCaps * caps, gsize bytes) +{ + GstQuery *query; + GstBufferPool *pool = NULL; + guint size, min, max, prefix, alignment; + GstStructure *config; + + /* find a pool for the negotiated caps now */ + query = gst_query_new_allocation (caps, TRUE); + + if (gst_pad_peer_query (dec->srcpad, query)) { + GST_DEBUG_OBJECT (dec, "got downstream ALLOCATION hints"); + /* we got configuration from our peer, parse them */ + gst_query_parse_allocation_params (query, &size, &min, &max, &prefix, + &alignment, &pool); + size = MAX (size, bytes); + } else { + GST_DEBUG_OBJECT (dec, "didn't get downstream ALLOCATION hints"); + size = bytes; + min = max = 0; + prefix = 0; + alignment = 0; + } + + if (pool == NULL) { + /* we did not get a pool, make one ourselves then */ + pool = gst_buffer_pool_new (); + } + + if (dec->pool) + gst_object_unref (dec->pool); + dec->pool = pool; + + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_set (config, caps, size, min, max, prefix, alignment); + + gst_buffer_pool_set_config (pool, config); + /* and activate */ + gst_buffer_pool_set_active (pool, TRUE); + + gst_query_unref (query); + + return GST_FLOW_OK; +} + static gboolean opus_dec_sink_setcaps (GstPad * pad, GstCaps * caps) { @@ -367,17 +398,6 @@ cleanup: return res; } -static const GstQueryType * -opus_get_sink_query_types (GstPad * pad) -{ - static const GstQueryType opus_dec_sink_query_types[] = { - GST_QUERY_CONVERT, - 0 - }; - - return opus_dec_sink_query_types; -} - static gboolean opus_dec_sink_query (GstPad * pad, GstQuery * query) { @@ -408,18 +428,6 @@ opus_dec_sink_query (GstPad * pad, GstQuery * query) return res; } -static const GstQueryType * -opus_get_src_query_types (GstPad * pad) -{ - static const GstQueryType opus_dec_src_query_types[] = { - GST_QUERY_POSITION, - GST_QUERY_DURATION, - 0 - }; - - return opus_dec_src_query_types; -} - static gboolean opus_dec_src_query (GstPad * pad, GstQuery * query) { @@ -446,7 +454,7 @@ opus_dec_src_query (GstPad * pad, GstQuery * query) } if ((res = opus_dec_convert (dec->srcpad, GST_FORMAT_TIME, - segment.last_stop, &format, &cur))) { + segment.position, &format, &cur))) { gst_query_set_position (query, format, cur); } break; @@ -456,7 +464,7 @@ opus_dec_src_query (GstPad * pad, GstQuery * query) gint64 dur; /* get duration from demuxer */ - if (!gst_pad_query_peer_duration (dec->sinkpad, &format, &dur)) + if (!gst_pad_query_peer_duration (dec->sinkpad, format, &dur)) break; gst_query_parse_duration (query, &format, NULL); @@ -540,48 +548,57 @@ opus_dec_sink_event (GstPad * pad, GstEvent * event) GST_LOG_OBJECT (dec, "handling %s event", GST_EVENT_TYPE_NAME (event)); switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_NEWSEGMENT:{ - GstFormat format; - gdouble rate, arate; - gint64 start, stop, time; - gboolean update; + case GST_EVENT_SEGMENT:{ + const GstSegment *segment = NULL; - gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, - &start, &stop, &time); + gst_event_parse_segment (event, &segment); - if (format != GST_FORMAT_TIME) + if (segment->format != GST_FORMAT_TIME) goto newseg_wrong_format; - if (rate <= 0.0) + if (segment->rate <= 0.0) goto newseg_wrong_rate; - if (update) { +#if 0 + /* TODO: update is gone */ + if (segment->update) { /* time progressed without data, see if we can fill the gap with * some concealment data */ - if (dec->segment.last_stop < start) { + if (dec->segment.position < segment->start) { GstClockTime duration; - duration = start - dec->segment.last_stop; - opus_dec_chain_parse_data (dec, NULL, dec->segment.last_stop, + duration = segment->start - dec->segment.position; + opus_dec_chain_parse_data (dec, NULL, dec->segment.position, duration); } } +#endif /* now configure the values */ - gst_segment_set_newsegment_full (&dec->segment, update, - rate, arate, GST_FORMAT_TIME, start, stop, time); + gst_segment_copy_into (segment, &dec->segment); dec->granulepos = -1; GST_DEBUG_OBJECT (dec, "segment now: cur = %" GST_TIME_FORMAT " [%" GST_TIME_FORMAT " - %" GST_TIME_FORMAT "]", - GST_TIME_ARGS (dec->segment.last_stop), + GST_TIME_ARGS (dec->segment.position), GST_TIME_ARGS (dec->segment.start), GST_TIME_ARGS (dec->segment.stop)); ret = gst_pad_push_event (dec->srcpad, event); break; } + + case GST_EVENT_CAPS: + { + GstCaps *caps; + + gst_event_parse_caps (event, &caps); + ret = opus_dec_sink_setcaps (pad, caps); + gst_event_unref (event); + break; + } + default: ret = gst_pad_event_default (pad, event); break; @@ -629,12 +646,10 @@ opus_dec_chain_parse_header (GstOpusDec * dec, GstBuffer * buf) GST_SECOND, dec->sample_rate); /* set caps */ - caps = gst_caps_new_simple ("audio/x-raw-int", + caps = gst_caps_new_simple ("audio/x-raw", + "format", G_TYPE_STRING, "S16LE", "rate", G_TYPE_INT, dec->sample_rate, - "channels", G_TYPE_INT, dec->n_channels, - "signed", G_TYPE_BOOLEAN, TRUE, - "endianness", G_TYPE_INT, G_BYTE_ORDER, - "width", G_TYPE_INT, 16, "depth", G_TYPE_INT, 16, NULL); + "channels", G_TYPE_INT, dec->n_channels, NULL); GST_DEBUG_OBJECT (dec, "rate=%d channels=%d frame-size=%d", dec->sample_rate, dec->n_channels, dec->frame_size); @@ -718,14 +733,14 @@ opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buf, GstClockTime timestamp, GstClockTime duration) { GstFlowReturn res = GST_FLOW_OK; - gint size; + gsize size, out_size; guint8 *data; GstBuffer *outbuf; gint16 *out_data; int n, err; if (timestamp != -1) { - dec->segment.last_stop = timestamp; + dec->segment.position = timestamp; dec->granulepos = -1; } @@ -737,12 +752,10 @@ opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buf, goto creation_failed; /* set caps */ - caps = gst_caps_new_simple ("audio/x-raw-int", + caps = gst_caps_new_simple ("audio/x-raw", + "format", G_TYPE_STRING, "S16LE", "rate", G_TYPE_INT, dec->sample_rate, - "channels", G_TYPE_INT, dec->n_channels, - "signed", G_TYPE_BOOLEAN, TRUE, - "endianness", G_TYPE_INT, G_BYTE_ORDER, - "width", G_TYPE_INT, 16, "depth", G_TYPE_INT, 16, NULL); + "channels", G_TYPE_INT, dec->n_channels, NULL); GST_DEBUG_OBJECT (dec, "rate=%d channels=%d frame-size=%d", dec->sample_rate, dec->n_channels, dec->frame_size); @@ -750,12 +763,19 @@ opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buf, if (!gst_pad_set_caps (dec->srcpad, caps)) GST_ERROR ("nego failure"); + /* negotiate a bufferpool */ + if ((res = + gst_opus_dec_negotiate_pool (dec, caps, + dec->frame_size * dec->n_channels * 2)) != GST_FLOW_OK) { + gst_caps_unref (caps); + goto no_bufferpool; + } + gst_caps_unref (caps); } if (buf) { - data = GST_BUFFER_DATA (buf); - size = GST_BUFFER_SIZE (buf); + data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ); GST_DEBUG_OBJECT (dec, "received buffer of size %u", size); @@ -772,21 +792,27 @@ opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buf, 48000)); GST_DEBUG ("channels %d", opus_packet_get_nb_channels (data)); - res = gst_pad_alloc_buffer_and_set_caps (dec->srcpad, - GST_BUFFER_OFFSET_NONE, dec->frame_samples * dec->n_channels * 2, - GST_PAD_CAPS (dec->srcpad), &outbuf); + if (gst_pad_check_reconfigure (dec->srcpad)) { + GstCaps *caps = gst_pad_get_current_caps (dec->srcpad); + gst_opus_dec_negotiate_pool (dec, caps, + dec->frame_samples * dec->n_channels * 2); + gst_caps_unref (caps); + } + res = gst_buffer_pool_acquire_buffer (dec->pool, &outbuf, NULL); if (res != GST_FLOW_OK) { GST_DEBUG_OBJECT (dec, "buf alloc flow: %s", gst_flow_get_name (res)); return res; } - out_data = (gint16 *) GST_BUFFER_DATA (outbuf); + out_data = (gint16 *) gst_buffer_map (outbuf, &out_size, NULL, GST_MAP_WRITE); GST_LOG_OBJECT (dec, "decoding frame"); n = opus_decode (dec->state, data, size, out_data, dec->frame_samples, 0); + gst_buffer_unmap (buf, data, size); if (n < 0) { + gst_buffer_unmap (outbuf, out_data, out_size); GST_ELEMENT_ERROR (dec, STREAM, DECODE, ("Decoding error: %d", n), (NULL)); return GST_FLOW_ERROR; } @@ -806,7 +832,7 @@ opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buf, dec->discont = 0; } - dec->segment.last_stop += dec->frame_duration; + dec->segment.position += dec->frame_duration; GST_LOG_OBJECT (dec, "pushing buffer with ts=%" GST_TIME_FORMAT ", dur=%" GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)), @@ -814,6 +840,8 @@ opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buf, res = gst_pad_push (dec->srcpad, outbuf); + gst_buffer_unmap (outbuf, out_data, out_size); + if (res != GST_FLOW_OK) GST_DEBUG_OBJECT (dec, "flow: %s", gst_flow_get_name (res)); @@ -822,6 +850,10 @@ opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buf, creation_failed: GST_ERROR_OBJECT (dec, "Failed to create Opus decoder: %d", err); return GST_FLOW_ERROR; + +no_bufferpool: + GST_ERROR_OBJECT (dec, "Failed to negotiate buffer pool: %d", res); + return GST_FLOW_ERROR; } static GstFlowReturn @@ -866,7 +898,9 @@ opus_dec_change_state (GstElement * element, GstStateChange transition) break; } - ret = parent_class->change_state (element, transition); + ret = + GST_ELEMENT_CLASS (gst_opus_dec_parent_class)->change_state (element, + transition); if (ret != GST_STATE_CHANGE_SUCCESS) return ret; @@ -875,6 +909,11 @@ opus_dec_change_state (GstElement * element, GstStateChange transition) break; case GST_STATE_CHANGE_PAUSED_TO_READY: gst_opus_dec_reset (dec); + if (dec->pool) { + gst_buffer_pool_set_active (dec->pool, FALSE); + gst_object_unref (dec->pool); + dec->pool = NULL; + } break; case GST_STATE_CHANGE_READY_TO_NULL: break; diff --git a/ext/opus/gstopusdec.h b/ext/opus/gstopusdec.h index 886a907..57db884 100644 --- a/ext/opus/gstopusdec.h +++ b/ext/opus/gstopusdec.h @@ -64,6 +64,8 @@ struct _GstOpusDec { int sample_rate; int n_channels; + + GstBufferPool *pool; }; struct _GstOpusDecClass { diff --git a/ext/opus/gstopusenc.c b/ext/opus/gstopusenc.c index 8d40cdf..484a84b 100644 --- a/ext/opus/gstopusenc.c +++ b/ext/opus/gstopusenc.c @@ -82,11 +82,10 @@ gst_opus_enc_bandwidth_get_type (void) static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-raw-int, " + GST_STATIC_CAPS ("audio/x-raw, " + "format = (string) { S16LE }, " "rate = (int) { 8000, 12000, 16000, 24000, 48000 }, " - "channels = (int) [ 1, 2 ], " - "endianness = (int) BYTE_ORDER, " - "signed = (boolean) TRUE, " "width = (int) 16, " "depth = (int) 16") + "channels = (int) [ 1, 2 ] ") ); static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", @@ -138,31 +137,19 @@ static GstStateChangeReturn gst_opus_enc_change_state (GstElement * element, static GstFlowReturn gst_opus_enc_encode (GstOpusEnc * enc, gboolean flush); -static void -gst_opus_enc_setup_interfaces (GType opusenc_type) -{ - static const GInterfaceInfo tag_setter_info = { NULL, NULL, NULL }; - const GInterfaceInfo preset_interface_info = { - NULL, /* interface_init */ - NULL, /* interface_finalize */ - NULL /* interface_data */ - }; - - g_type_add_interface_static (opusenc_type, GST_TYPE_TAG_SETTER, - &tag_setter_info); - g_type_add_interface_static (opusenc_type, GST_TYPE_PRESET, - &preset_interface_info); - - GST_DEBUG_CATEGORY_INIT (opusenc_debug, "opusenc", 0, "Opus encoder"); -} - -GST_BOILERPLATE_FULL (GstOpusEnc, gst_opus_enc, GstElement, GST_TYPE_ELEMENT, - gst_opus_enc_setup_interfaces); +#define gst_opus_enc_parent_class parent_class +G_DEFINE_TYPE_WITH_CODE (GstOpusEnc, gst_opus_enc, GST_TYPE_ELEMENT, + G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL); + G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL)); static void -gst_opus_enc_base_init (gpointer g_class) +gst_opus_enc_class_init (GstOpusEncClass * klass) { - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + GObjectClass *gobject_class; + GstElementClass *element_class; + + gobject_class = (GObjectClass *) klass; + element_class = (GstElementClass *) klass; gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&src_factory)); @@ -172,16 +159,6 @@ gst_opus_enc_base_init (gpointer g_class) "Codec/Encoder/Audio", "Encodes audio in Opus format", "Sebastian Dröge "); -} - -static void -gst_opus_enc_class_init (GstOpusEncClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; gobject_class->set_property = gst_opus_enc_set_property; gobject_class->get_property = gst_opus_enc_get_property; @@ -230,8 +207,9 @@ gst_opus_enc_class_init (GstOpusEncClass * klass) gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_opus_enc_finalize); - gstelement_class->change_state = - GST_DEBUG_FUNCPTR (gst_opus_enc_change_state); + element_class->change_state = GST_DEBUG_FUNCPTR (gst_opus_enc_change_state); + + GST_DEBUG_CATEGORY_INIT (opusenc_debug, "opusenc", 0, "Opus encoder"); } static void @@ -305,13 +283,13 @@ gst_opus_enc_sink_setcaps (GstPad * pad, GstCaps * caps) static GstCaps * -gst_opus_enc_sink_getcaps (GstPad * pad) +gst_opus_enc_sink_getcaps (GstPad * pad, GstCaps * filter) { GstCaps *caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); GstCaps *peercaps = NULL; GstOpusEnc *enc = GST_OPUS_ENC (gst_pad_get_parent_element (pad)); - peercaps = gst_pad_peer_get_caps (enc->srcpad); + peercaps = gst_pad_peer_get_caps (enc->srcpad, NULL); if (peercaps) { if (!gst_caps_is_empty (peercaps) && !gst_caps_is_any (peercaps)) { @@ -332,6 +310,13 @@ gst_opus_enc_sink_getcaps (GstPad * pad) gst_object_unref (enc); + if (filter) { + GstCaps *new_caps = + gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (caps); + caps = new_caps; + } + return caps; } @@ -449,20 +434,6 @@ gst_opus_enc_get_latency (GstOpusEnc * enc) enc->sample_rate); } -static const GstQueryType * -gst_opus_enc_get_query_types (GstPad * pad) -{ - static const GstQueryType gst_opus_enc_src_query_types[] = { - GST_QUERY_POSITION, - GST_QUERY_DURATION, - GST_QUERY_CONVERT, - GST_QUERY_LATENCY, - 0 - }; - - return gst_opus_enc_src_query_types; -} - static gboolean gst_opus_enc_src_query (GstPad * pad, GstQuery * query) { @@ -478,17 +449,17 @@ gst_opus_enc_src_query (GstPad * pad, GstQuery * query) gint64 pos, val; gst_query_parse_position (query, &req_fmt, NULL); - if ((res = gst_pad_query_peer_position (enc->sinkpad, &req_fmt, &val))) { + if ((res = gst_pad_query_peer_position (enc->sinkpad, req_fmt, &val))) { gst_query_set_position (query, req_fmt, val); break; } fmt = GST_FORMAT_TIME; - if (!(res = gst_pad_query_peer_position (enc->sinkpad, &fmt, &pos))) + if (!(res = gst_pad_query_peer_position (enc->sinkpad, fmt, &pos))) break; if ((res = - gst_pad_query_peer_convert (enc->sinkpad, fmt, pos, &req_fmt, + gst_pad_query_peer_convert (enc->sinkpad, fmt, pos, req_fmt, &val))) gst_query_set_position (query, req_fmt, val); @@ -500,17 +471,17 @@ gst_opus_enc_src_query (GstPad * pad, GstQuery * query) gint64 dur, val; gst_query_parse_duration (query, &req_fmt, NULL); - if ((res = gst_pad_query_peer_duration (enc->sinkpad, &req_fmt, &val))) { + if ((res = gst_pad_query_peer_duration (enc->sinkpad, req_fmt, &val))) { gst_query_set_duration (query, req_fmt, val); break; } fmt = GST_FORMAT_TIME; - if (!(res = gst_pad_query_peer_duration (enc->sinkpad, &fmt, &dur))) + if (!(res = gst_pad_query_peer_duration (enc->sinkpad, fmt, &dur))) break; if ((res = - gst_pad_query_peer_convert (enc->sinkpad, fmt, dur, &req_fmt, + gst_pad_query_peer_convert (enc->sinkpad, fmt, dur, req_fmt, &val))) { gst_query_set_duration (query, req_fmt, val); } @@ -589,7 +560,7 @@ error: } static void -gst_opus_enc_init (GstOpusEnc * enc, GstOpusEncClass * klass) +gst_opus_enc_init (GstOpusEnc * enc) { enc->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink"); gst_element_add_pad (GST_ELEMENT (enc), enc->sinkpad); @@ -597,8 +568,6 @@ gst_opus_enc_init (GstOpusEnc * enc, GstOpusEncClass * klass) GST_DEBUG_FUNCPTR (gst_opus_enc_sinkevent)); gst_pad_set_chain_function (enc->sinkpad, GST_DEBUG_FUNCPTR (gst_opus_enc_chain)); - gst_pad_set_setcaps_function (enc->sinkpad, - GST_DEBUG_FUNCPTR (gst_opus_enc_sink_setcaps)); gst_pad_set_getcaps_function (enc->sinkpad, GST_DEBUG_FUNCPTR (gst_opus_enc_sink_getcaps)); gst_pad_set_query_function (enc->sinkpad, @@ -607,8 +576,6 @@ gst_opus_enc_init (GstOpusEnc * enc, GstOpusEncClass * klass) enc->srcpad = gst_pad_new_from_static_template (&src_factory, "src"); gst_pad_set_query_function (enc->srcpad, GST_DEBUG_FUNCPTR (gst_opus_enc_src_query)); - gst_pad_set_query_type_function (enc->srcpad, - GST_DEBUG_FUNCPTR (gst_opus_enc_get_query_types)); gst_element_add_pad (GST_ELEMENT (enc), enc->srcpad); enc->n_channels = -1; @@ -708,9 +675,9 @@ encoder_creation_failed: static GstFlowReturn gst_opus_enc_push_buffer (GstOpusEnc * enc, GstBuffer * buffer) { - guint size; + gsize size; - size = GST_BUFFER_SIZE (buffer); + size = gst_buffer_get_size (buffer); enc->bytes_out += size; @@ -785,6 +752,16 @@ gst_opus_enc_sinkevent (GstPad * pad, GstEvent * event) res = gst_pad_event_default (pad, event); break; } + case GST_EVENT_CAPS: + { + GstCaps *caps; + + gst_event_parse_caps (event, &caps); + res = gst_opus_enc_sink_setcaps (pad, caps); + gst_event_unref (event); + break; + } + default: res = gst_pad_event_default (pad, event); break; @@ -810,21 +787,20 @@ gst_opus_enc_encode (GstOpusEnc * enc, gboolean flush) guint diff = bytes - gst_adapter_available (enc->adapter) % bytes; GstBuffer *buf = gst_buffer_new_and_alloc (diff); - memset (GST_BUFFER_DATA (buf), 0, diff); + gst_buffer_memset (buf, 0, 0, diff); gst_adapter_push (enc->adapter, buf); } while (gst_adapter_available (enc->adapter) >= bytes) { gint16 *data; - gint outsize; + gint encoded_size; + unsigned char *out_data; + gsize out_size; GstBuffer *outbuf; - ret = gst_pad_alloc_buffer_and_set_caps (enc->srcpad, - GST_BUFFER_OFFSET_NONE, bytes_per_packet, GST_PAD_CAPS (enc->srcpad), - &outbuf); - - if (GST_FLOW_OK != ret) + outbuf = gst_buffer_new_and_alloc (bytes_per_packet); + if (!outbuf) goto done; data = (gint16 *) gst_adapter_take (enc->adapter, bytes); @@ -833,18 +809,20 @@ gst_opus_enc_encode (GstOpusEnc * enc, gboolean flush) GST_DEBUG_OBJECT (enc, "encoding %d samples (%d bytes)", enc->frame_samples, bytes); - outsize = opus_encode (enc->state, data, enc->frame_samples, - GST_BUFFER_DATA (outbuf), bytes_per_packet); + out_data = gst_buffer_map (outbuf, &out_size, NULL, GST_MAP_WRITE); + encoded_size = opus_encode (enc->state, data, enc->frame_samples, + out_data, bytes_per_packet); + gst_buffer_unmap (outbuf, out_data, out_size); g_free (data); - if (outsize < 0) { - GST_ERROR_OBJECT (enc, "Encoding failed: %d", outsize); + if (encoded_size < 0) { + GST_ERROR_OBJECT (enc, "Encoding failed: %d", encoded_size); ret = GST_FLOW_ERROR; goto done; - } else if (outsize != bytes_per_packet) { + } else if (encoded_size != bytes_per_packet) { GST_WARNING_OBJECT (enc, - "Encoded size %d is different from %d bytes per packet", outsize, + "Encoded size %d is different from %d bytes per packet", encoded_size, bytes_per_packet); ret = GST_FLOW_ERROR; goto done; @@ -888,7 +866,8 @@ gst_opus_enc_chain (GstPad * pad, GstBuffer * buf) if (!enc->header_sent) { GstCaps *caps; - caps = gst_pad_get_caps (enc->srcpad); + caps = gst_pad_get_caps (enc->srcpad, NULL); + caps = gst_caps_copy (caps); gst_caps_set_simple (caps, "rate", G_TYPE_INT, enc->sample_rate, "channels", G_TYPE_INT, enc->n_channels, @@ -899,11 +878,13 @@ gst_opus_enc_chain (GstPad * pad, GstBuffer * buf) GST_LOG_OBJECT (enc, "rate=%d channels=%d frame-size=%d", enc->sample_rate, enc->n_channels, enc->frame_size); gst_pad_set_caps (enc->srcpad, caps); + gst_caps_unref (caps); enc->header_sent = TRUE; } - GST_DEBUG_OBJECT (enc, "received buffer of %u bytes", GST_BUFFER_SIZE (buf)); + GST_DEBUG_OBJECT (enc, "received buffer of %u bytes", + gst_buffer_get_size (buf)); /* Save the timestamp of the first buffer. This will be later * used as offset for all following buffers */ @@ -931,13 +912,12 @@ gst_opus_enc_chain (GstPad * pad, GstBuffer * buf) diff_bytes = GST_CLOCK_TIME_TO_FRAMES (diff, enc->sample_rate) * enc->n_channels * 2; - if (diff_bytes >= GST_BUFFER_SIZE (buf)) { + if (diff_bytes >= gst_buffer_get_size (buf)) { gst_buffer_unref (buf); return GST_FLOW_OK; } - buf = gst_buffer_make_metadata_writable (buf); - GST_BUFFER_DATA (buf) += diff_bytes; - GST_BUFFER_SIZE (buf) -= diff_bytes; + buf = gst_buffer_make_writable (buf); + gst_buffer_resize (buf, diff_bytes, gst_buffer_get_size (buf) - diff_bytes); GST_BUFFER_TIMESTAMP (buf) += diff; if (GST_BUFFER_DURATION_IS_VALID (buf)) -- 2.7.4