From: Edward Hervey Date: Fri, 25 Nov 2011 11:48:58 +0000 (+0100) Subject: Merge remote-tracking branch 'origin/master' into 0.11 X-Git-Tag: 1.10.4~478^2~115 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a8024bb6989d524d11c8020ac67a60e63bee46ff;p=platform%2Fupstream%2Fgst-plugins-base.git Merge remote-tracking branch 'origin/master' into 0.11 Conflicts: ext/faac/gstfaac.c ext/opus/gstopusdec.c ext/opus/gstopusenc.c gst/audiovisualizers/gstspacescope.c gst/colorspace/colorspace.c --- a8024bb6989d524d11c8020ac67a60e63bee46ff diff --cc ext/opus/gstopusdec.c index 4e1a3a4,5828397..3a63349 --- a/ext/opus/gstopusdec.c +++ b/ext/opus/gstopusdec.c @@@ -53,10 -55,11 +55,10 @@@ static GstStaticPadTemplate opus_dec_sr GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-raw-int, " - "rate = (int) { 48000, 24000, 16000, 12000, 8000 }, " - "channels = (int) [ 1, 8 ], " - "endianness = (int) BYTE_ORDER, " - "signed = (boolean) true, " "width = (int) 16, " "depth = (int) 16") + GST_STATIC_CAPS ("audio/x-raw, " - "format = (string) { S16LE }, " ++ "format = (string) { " GST_AUDIO_NE (S16) " }, " + "rate = (int) { 8000, 12000, 16000, 24000, 48000 }, " - "channels = (int) [ 1, 2 ] ") ++ "channels = (int) [ 1, 8 ] ") ); static GstStaticPadTemplate opus_dec_sink_factory = @@@ -66,8 -69,21 +68,21 @@@ GST_STATIC_PAD_TEMPLATE ("sink" GST_STATIC_CAPS ("audio/x-opus") ); +G_DEFINE_TYPE (GstOpusDec, gst_opus_dec, GST_TYPE_AUDIO_DECODER); + + #define DB_TO_LINEAR(x) pow (10., (x) / 20.) + + #define DEFAULT_USE_INBAND_FEC FALSE + #define DEFAULT_APPLY_GAIN TRUE + + enum + { + PROP_0, + PROP_USE_INBAND_FEC, + PROP_APPLY_GAIN + }; + -GST_BOILERPLATE (GstOpusDec, gst_opus_dec, GstAudioDecoder, - GST_TYPE_AUDIO_DECODER); + static GstFlowReturn gst_opus_dec_parse_header (GstOpusDec * dec, GstBuffer * buf); static gboolean gst_opus_dec_start (GstAudioDecoder * dec); @@@ -76,29 -92,55 +91,48 @@@ static GstFlowReturn gst_opus_dec_handl GstBuffer * buffer); static gboolean gst_opus_dec_set_format (GstAudioDecoder * bdec, GstCaps * caps); + static void gst_opus_dec_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + static void gst_opus_dec_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); + static void -gst_opus_dec_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&opus_dec_src_factory)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&opus_dec_sink_factory)); - gst_element_class_set_details_simple (element_class, "Opus audio decoder", - "Codec/Decoder/Audio", - "decode opus streams to audio", - "Sebastian Dröge "); -} - -static void gst_opus_dec_class_init (GstOpusDecClass * klass) { + GObjectClass *gobject_class; GstAudioDecoderClass *adclass; - GstElementClass *gstelement_class; + GstElementClass *element_class; + gobject_class = (GObjectClass *) klass; adclass = (GstAudioDecoderClass *) klass; - gstelement_class = (GstElementClass *) klass; + element_class = (GstElementClass *) klass; + gobject_class->set_property = gst_opus_dec_set_property; + gobject_class->get_property = gst_opus_dec_get_property; + adclass->start = GST_DEBUG_FUNCPTR (gst_opus_dec_start); adclass->stop = GST_DEBUG_FUNCPTR (gst_opus_dec_stop); adclass->handle_frame = GST_DEBUG_FUNCPTR (gst_opus_dec_handle_frame); adclass->set_format = GST_DEBUG_FUNCPTR (gst_opus_dec_set_format); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&opus_dec_src_factory)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&opus_dec_sink_factory)); + gst_element_class_set_details_simple (element_class, "Opus audio decoder", + "Codec/Decoder/Audio", + "decode opus streams to audio", + "Sebastian Dröge "); + g_object_class_install_property (gobject_class, PROP_USE_INBAND_FEC, + g_param_spec_boolean ("use-inband-fec", "Use in-band FEC", + "Use forward error correction if available", DEFAULT_USE_INBAND_FEC, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_APPLY_GAIN, + g_param_spec_boolean ("apply-gain", "Apply gain", + "Apply gain if any is specified in the header", DEFAULT_APPLY_GAIN, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); GST_DEBUG_CATEGORY_INIT (opusdec_debug, "opusdec", 0, "opus decoding element"); @@@ -154,13 -218,92 +210,97 @@@ gst_opus_dec_get_r128_volume (gint16 r1 static GstFlowReturn gst_opus_dec_parse_header (GstOpusDec * dec, GstBuffer * buf) { - g_return_val_if_fail (gst_opus_header_is_header (buf, "OpusHead", 8), - GST_FLOW_ERROR); - g_return_val_if_fail (GST_BUFFER_SIZE (buf) >= 19, GST_FLOW_ERROR); - const guint8 *data = GST_BUFFER_DATA (buf); ++ const guint8 *data; + GstCaps *caps; + GstStructure *s; + const GstAudioChannelPosition *pos = NULL; + + g_return_val_if_fail (gst_opus_header_is_id_header (buf), GST_FLOW_ERROR); ++ ++ data = gst_buffer_map (buf, NULL, NULL, GST_MAP_READ); ++ + g_return_val_if_fail (dec->n_channels != data[9], GST_FLOW_ERROR); - dec->pre_skip = GST_READ_UINT16_LE (GST_BUFFER_DATA (buf) + 10); - GST_INFO_OBJECT (dec, "Found pre-skip of %u samples", dec->pre_skip); + dec->n_channels = data[9]; + dec->pre_skip = GST_READ_UINT16_LE (data + 10); + dec->r128_gain = GST_READ_UINT16_LE (data + 14); + dec->r128_gain_volume = gst_opus_dec_get_r128_volume (dec->r128_gain); + GST_INFO_OBJECT (dec, + "Found pre-skip of %u samples, R128 gain %d (volume %f)", + dec->pre_skip, dec->r128_gain, dec->r128_gain_volume); + + dec->channel_mapping_family = data[18]; + if (dec->channel_mapping_family == 0) { + /* implicit mapping */ + GST_INFO_OBJECT (dec, "Channel mapping family 0, implicit mapping"); + dec->n_streams = dec->n_stereo_streams = 1; + dec->channel_mapping[0] = 0; + dec->channel_mapping[1] = 1; + } else { + dec->n_streams = data[19]; + dec->n_stereo_streams = data[20]; + memcpy (dec->channel_mapping, data + 21, dec->n_channels); + + if (dec->channel_mapping_family == 1) { + GST_INFO_OBJECT (dec, "Channel mapping family 1, Vorbis mapping"); + switch (dec->n_channels) { + case 1: + case 2: + /* nothing */ + break; + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + pos = gst_opus_channel_positions[dec->n_channels - 1]; + break; + default:{ + gint i; + GstAudioChannelPosition *posn = + g_new (GstAudioChannelPosition, dec->n_channels); + + GST_ELEMENT_WARNING (GST_ELEMENT (dec), STREAM, DECODE, + (NULL), ("Using NONE channel layout for more than 8 channels")); + + for (i = 0; i < dec->n_channels; i++) + posn[i] = GST_AUDIO_CHANNEL_POSITION_NONE; + + pos = posn; + } + } + } else { + GST_INFO_OBJECT (dec, "Channel mapping family %d", + dec->channel_mapping_family); + } + } + + /* negotiate width with downstream */ + caps = gst_pad_get_allowed_caps (GST_AUDIO_DECODER_SRC_PAD (dec)); + s = gst_caps_get_structure (caps, 0); + gst_structure_fixate_field_nearest_int (s, "rate", 48000); + gst_structure_get_int (s, "rate", &dec->sample_rate); + gst_structure_fixate_field_nearest_int (s, "channels", dec->n_channels); + gst_structure_get_int (s, "channels", &dec->n_channels); + + GST_INFO_OBJECT (dec, "Negotiated %d channels, %d Hz", dec->n_channels, + dec->sample_rate); + + if (pos) { + gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos); + } + + if (dec->n_channels > 8) { + g_free ((GstAudioChannelPosition *) pos); + } + + GST_INFO_OBJECT (dec, "Setting src caps to %" GST_PTR_FORMAT, caps); + gst_pad_set_caps (GST_AUDIO_DECODER_SRC_PAD (dec), caps); + gst_caps_unref (caps); + ++ gst_buffer_unmap (buf, (guint8 *) data, -1); + return GST_FLOW_OK; } @@@ -171,53 -314,11 +311,11 @@@ gst_opus_dec_parse_comments (GstOpusDe return GST_FLOW_OK; } - static void - gst_opus_dec_setup_from_peer_caps (GstOpusDec * dec) - { - GstPad *srcpad, *peer; - GstStructure *s; - GstCaps *caps; - const GstCaps *template_caps; - const GstCaps *peer_caps; - - srcpad = GST_AUDIO_DECODER_SRC_PAD (dec); - peer = gst_pad_get_peer (srcpad); - - if (peer) { - template_caps = gst_pad_get_pad_template_caps (srcpad); - peer_caps = gst_pad_get_caps (peer); - GST_DEBUG_OBJECT (dec, "Peer caps: %" GST_PTR_FORMAT, peer_caps); - caps = gst_caps_intersect (template_caps, peer_caps); - gst_pad_fixate_caps (peer, caps); - GST_DEBUG_OBJECT (dec, "Fixated caps: %" GST_PTR_FORMAT, caps); - - s = gst_caps_get_structure (caps, 0); - if (!gst_structure_get_int (s, "channels", &dec->n_channels)) { - dec->n_channels = 2; - GST_WARNING_OBJECT (dec, "Failed to get channels, using default %d", - dec->n_channels); - } else { - GST_DEBUG_OBJECT (dec, "Got channels %d", dec->n_channels); - } - if (!gst_structure_get_int (s, "rate", &dec->sample_rate)) { - dec->sample_rate = 48000; - GST_WARNING_OBJECT (dec, "Failed to get rate, using default %d", - dec->sample_rate); - } else { - GST_DEBUG_OBJECT (dec, "Got sample rate %d", dec->sample_rate); - } - - gst_audio_decoder_set_outcaps (GST_AUDIO_DECODER (dec), caps); - } else { - GST_WARNING_OBJECT (dec, "Failed to get src pad peer"); - } - } - static GstFlowReturn - opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buf) + opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buffer) { GstFlowReturn res = GST_FLOW_OK; - gint size; + gsize size, out_size; guint8 *data; GstBuffer *outbuf; gint16 *out_data; @@@ -235,66 -337,107 +334,110 @@@ goto creation_failed; } + if (buffer) { + GST_DEBUG_OBJECT (dec, "Received buffer of size %u", - GST_BUFFER_SIZE (buffer)); ++ gst_buffer_get_size (buffer)); + } else { + GST_DEBUG_OBJECT (dec, "Received missing buffer"); + } + + /* if using in-band FEC, we introdude one extra frame's delay as we need + to potentially wait for next buffer to decode a missing buffer */ + if (dec->use_inband_fec && !dec->primed) { + GST_DEBUG_OBJECT (dec, "First buffer received in FEC mode, early out"); + goto done; + } + + /* That's the buffer we'll be sending to the opus decoder. */ + buf = dec->use_inband_fec && dec->last_buffer ? dec->last_buffer : buffer; + 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); + GST_DEBUG_OBJECT (dec, "Using buffer of size %u", size); } else { /* concealment data, pass NULL as the bits parameters */ - GST_DEBUG_OBJECT (dec, "creating concealment data"); + GST_DEBUG_OBJECT (dec, "Using NULL buffer"); data = NULL; size = 0; } - if (data) { - samples = - opus_packet_get_samples_per_frame (data, - dec->sample_rate) * opus_packet_get_nb_frames (data, size); - packet_size = samples * dec->n_channels * 2; - GST_DEBUG_OBJECT (dec, "bandwidth %d", opus_packet_get_bandwidth (data)); - GST_DEBUG_OBJECT (dec, "samples %d", samples); - } else { - /* use maximum size (120 ms) as we do now know in advance how many samples - will be returned */ - samples = 120 * dec->sample_rate / 1000; - } - + /* use maximum size (120 ms) as the number of returned samples is + not constant over the stream. */ + samples = 120 * dec->sample_rate / 1000; packet_size = samples * dec->n_channels * 2; + - res = gst_pad_alloc_buffer_and_set_caps (GST_AUDIO_DECODER_SRC_PAD (dec), - GST_BUFFER_OFFSET_NONE, packet_size, - GST_PAD_CAPS (GST_AUDIO_DECODER_SRC_PAD (dec)), &outbuf); - - if (res != GST_FLOW_OK) { - GST_DEBUG_OBJECT (dec, "buf alloc flow: %s", gst_flow_get_name (res)); - return res; + outbuf = gst_buffer_new_and_alloc (packet_size); + if (!outbuf) { + goto buffer_failed; } - out_data = (gint16 *) GST_BUFFER_DATA (outbuf); + out_data = (gint16 *) gst_buffer_map (outbuf, &out_size, NULL, GST_MAP_WRITE); - n = opus_decode (dec->state, data, size, out_data, samples, 0); + if (dec->use_inband_fec) { + if (dec->last_buffer) { + /* normal delayed decode */ + n = opus_multistream_decode (dec->state, data, size, out_data, samples, + 0); + } else { + /* FEC reconstruction decode */ + n = opus_multistream_decode (dec->state, data, size, out_data, samples, + 1); + } + } else { + /* normal decode */ + n = opus_multistream_decode (dec->state, data, size, out_data, samples, 0); + } + gst_buffer_unmap (buf, data, size); + gst_buffer_unmap (outbuf, out_data, out_size); + if (n < 0) { GST_ELEMENT_ERROR (dec, STREAM, DECODE, ("Decoding error: %d", n), (NULL)); return GST_FLOW_ERROR; } GST_DEBUG_OBJECT (dec, "decoded %d samples", n); -- GST_BUFFER_SIZE (outbuf) = n * 2 * dec->n_channels; ++ gst_buffer_set_size (outbuf, n * 2 * dec->n_channels); /* Skip any samples that need skipping */ if (dec->pre_skip > 0) { guint scaled_pre_skip = dec->pre_skip * dec->sample_rate / 48000; guint skip = scaled_pre_skip > n ? n : scaled_pre_skip; guint scaled_skip = skip * 48000 / dec->sample_rate; -- GST_BUFFER_SIZE (outbuf) -= skip * 2 * dec->n_channels; -- GST_BUFFER_DATA (outbuf) += skip * 2 * dec->n_channels; ++ ++ gst_buffer_resize (outbuf, skip * 2 * dec->n_channels, -1); dec->pre_skip -= scaled_skip; GST_INFO_OBJECT (dec, "Skipping %u samples (%u at 48000 Hz, %u left to skip)", skip, scaled_skip, dec->pre_skip); -- if (GST_BUFFER_SIZE (outbuf) == 0) { ++ if (gst_buffer_get_size (outbuf) == 0) { gst_buffer_unref (outbuf); outbuf = NULL; } } + /* Apply gain */ + /* Would be better off leaving this to a volume element, as this is + a naive conversion that does too many int/float conversions. + However, we don't have control over the pipeline... + So make it optional if the user program wants to use a volume, + but do it by default so the correct volume goes out by default */ + if (dec->apply_gain && outbuf && dec->r128_gain) { - unsigned int i, nsamples = GST_BUFFER_SIZE (outbuf) / 2; ++ gsize rsize; ++ unsigned int i, nsamples; + double volume = dec->r128_gain_volume; - gint16 *samples = (gint16 *) GST_BUFFER_DATA (outbuf); ++ gint16 *samples = ++ (gint16 *) gst_buffer_map (outbuf, &rsize, NULL, GST_MAP_READWRITE); ++ + GST_DEBUG_OBJECT (dec, "Applying gain: volume %f", volume); ++ nsamples = rsize / 2; + for (i = 0; i < nsamples; ++i) { + int sample = (int) (samples[i] * volume + 0.5); + samples[i] = sample < -32768 ? -32768 : sample > 32767 ? 32767 : sample; + } ++ gst_buffer_unmap (outbuf, samples, rsize); + } + res = gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (dec), outbuf, 1); if (res != GST_FLOW_OK) diff --cc ext/opus/gstopusenc.c index 9dec51e,6dad531..b7e282c --- a/ext/opus/gstopusenc.c +++ b/ext/opus/gstopusenc.c @@@ -177,13 -178,41 +178,10 @@@ static gint64 gst_opus_enc_get_latency static GstFlowReturn gst_opus_enc_encode (GstOpusEnc * enc, GstBuffer * buffer); - static GstFlowReturn gst_opus_enc_encode (GstOpusEnc * enc, GstBuffer * buf); - static gint64 gst_opus_enc_get_latency (GstOpusEnc * enc); -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, GstAudioEncoder, - GST_TYPE_AUDIO_ENCODER, gst_opus_enc_setup_interfaces); - -static void -gst_opus_enc_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); -- - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_factory)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_factory)); - gst_element_class_set_details_simple (element_class, "Opus audio encoder", - "Codec/Encoder/Audio", - "Encodes audio in Opus format", - "Sebastian Dröge "); -} +#define gst_opus_enc_parent_class parent_class +G_DEFINE_TYPE_WITH_CODE (GstOpusEnc, gst_opus_enc, GST_TYPE_AUDIO_ENCODER, + G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL); + G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL)); static void gst_opus_enc_class_init (GstOpusEncClass * klass) @@@ -199,15 -228,6 +197,15 @@@ gobject_class->set_property = gst_opus_enc_set_property; gobject_class->get_property = gst_opus_enc_get_property; - gst_element_class_add_pad_template (element_class, ++ gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&src_factory)); - gst_element_class_add_pad_template (element_class, ++ gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&sink_factory)); - gst_element_class_set_details_simple (element_class, "Opus audio encoder", ++ gst_element_class_set_details_simple (gstelement_class, "Opus audio encoder", + "Codec/Encoder/Audio", + "Encodes audio in Opus format", + "Sebastian Dröge "); + base_class->start = GST_DEBUG_FUNCPTR (gst_opus_enc_start); base_class->stop = GST_DEBUG_FUNCPTR (gst_opus_enc_stop); base_class->set_format = GST_DEBUG_FUNCPTR (gst_opus_enc_set_format); @@@ -290,7 -308,7 +288,7 @@@ gst_opus_enc_finalize (GObject * object } static void --gst_opus_enc_init (GstOpusEnc * enc, GstOpusEncClass * klass) ++gst_opus_enc_init (GstOpusEnc * enc) { GstAudioEncoder *benc = GST_AUDIO_ENCODER (enc); @@@ -324,7 -342,7 +322,7 @@@ gst_opus_enc_start (GstAudioEncoder * b GstOpusEnc *enc = GST_OPUS_ENC (benc); GST_DEBUG_OBJECT (enc, "start"); -- enc->tags = gst_tag_list_new (); ++ enc->tags = gst_tag_list_new_empty (); enc->header_sent = FALSE; return TRUE; @@@ -501,9 -596,9 +577,9 @@@ gst_opus_enc_sink_event (GstAudioEncode static GstFlowReturn gst_opus_enc_encode (GstOpusEnc * enc, GstBuffer * buf) { -- guint8 *bdata, *data, *mdata = NULL; ++ guint8 *bdata = NULL, *data, *mdata = NULL; gsize bsize, size; - gsize bytes; + gsize bytes = enc->frame_samples * enc->n_channels * 2; gint ret = GST_FLOW_OK; g_mutex_lock (enc->property_lock); @@@ -529,38 -624,40 +605,39 @@@ goto done; } - while (size) { - gint outsize; + gint encoded_size; + unsigned char *out_data; + gsize out_size; GstBuffer *outbuf; - outbuf = gst_buffer_new_and_alloc (enc->max_payload_size); - ret = gst_pad_alloc_buffer_and_set_caps (GST_AUDIO_ENCODER_SRC_PAD (enc), - GST_BUFFER_OFFSET_NONE, enc->max_payload_size * enc->n_channels, - GST_PAD_CAPS (GST_AUDIO_ENCODER_SRC_PAD (enc)), &outbuf); - - if (GST_FLOW_OK != ret) ++ outbuf = gst_buffer_new_and_alloc (enc->max_payload_size * enc->n_channels); + if (!outbuf) goto done; GST_DEBUG_OBJECT (enc, "encoding %d samples (%d bytes)", - enc->frame_samples); + enc->frame_samples, (int) bytes); - outsize = + out_data = gst_buffer_map (outbuf, &out_size, NULL, GST_MAP_WRITE); + encoded_size = - opus_encode (enc->state, (const gint16 *) data, enc->frame_samples, - out_data, enc->max_payload_size); + opus_multistream_encode (enc->state, (const gint16 *) data, - enc->frame_samples, GST_BUFFER_DATA (outbuf), - enc->max_payload_size * enc->n_channels); ++ enc->frame_samples, out_data, enc->max_payload_size * enc->n_channels); + gst_buffer_unmap (outbuf, out_data, out_size); - 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 > enc->max_payload_size) { + } else if (encoded_size > enc->max_payload_size) { GST_WARNING_OBJECT (enc, "Encoded size %d is higher than max payload size (%d bytes)", -- outsize, enc->max_payload_size); ++ out_size, enc->max_payload_size); ret = GST_FLOW_ERROR; goto done; } - GST_DEBUG_OBJECT (enc, "Output packet is %u bytes", outsize); -- GST_BUFFER_SIZE (outbuf) = outsize; ++ GST_DEBUG_OBJECT (enc, "Output packet is %u bytes", encoded_size); ++ gst_buffer_set_size (outbuf, encoded_size); ret = gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (enc), outbuf, @@@ -613,7 -709,7 +691,7 @@@ gst_opus_enc_handle_frame (GstAudioEnco } GST_DEBUG_OBJECT (enc, "received buffer %p of %u bytes", buf, -- buf ? GST_BUFFER_SIZE (buf) : 0); ++ buf ? gst_buffer_get_size (buf) : 0); ret = gst_opus_enc_encode (enc, buf); diff --cc ext/opus/gstopusheader.c index 3551055,1aa3b0d..4f95363 --- a/ext/opus/gstopusheader.c +++ b/ext/opus/gstopusheader.c @@@ -62,7 -68,7 +68,7 @@@ gst_opus_enc_create_metadata_buffer (co if (tags == NULL) { /* FIXME: better fix chain of callers to not write metadata at all, * if there is none */ -- empty_tags = gst_tag_list_new (); ++ empty_tags = gst_tag_list_new_empty (); tags = empty_tags; } comments = @@@ -165,6 -185,46 +185,58 @@@ gst_opus_header_create_caps (GstCaps * gboolean gst_opus_header_is_header (GstBuffer * buf, const char *magic, guint magic_size) { -- return (GST_BUFFER_SIZE (buf) >= magic_size -- && !memcmp (magic, GST_BUFFER_DATA (buf), magic_size)); ++ return (gst_buffer_get_size (buf) >= magic_size ++ && !gst_buffer_memcmp (buf, 0, magic, magic_size)); + } + + gboolean + gst_opus_header_is_id_header (GstBuffer * buf) + { - gsize size = GST_BUFFER_SIZE (buf); - const guint8 *data = GST_BUFFER_DATA (buf); ++ gsize size = gst_buffer_get_size (buf); ++ guint8 *data = NULL; + guint8 channels, channel_mapping_family, n_streams, n_stereo_streams; ++ gboolean ret = FALSE; + + if (size < 19) - return FALSE; ++ goto beach; + if (!gst_opus_header_is_header (buf, "OpusHead", 8)) - return FALSE; ++ goto beach; ++ ++ data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ); ++ + channels = data[9]; ++ + if (channels == 0) - return FALSE; ++ goto beach; ++ + channel_mapping_family = data[18]; ++ + if (channel_mapping_family == 0) { + if (channels > 2) - return FALSE; ++ goto beach; + } else { + channels = data[9]; + if (size < 21 + channels) - return FALSE; ++ goto beach; + n_streams = data[19]; + n_stereo_streams = data[20]; + if (n_streams == 0) - return FALSE; ++ goto beach; + if (n_stereo_streams > n_streams) - return FALSE; ++ goto beach; + if (n_streams + n_stereo_streams > 255) - return FALSE; ++ goto beach; + } - return TRUE; ++ ret = TRUE; ++ ++beach: ++ if (data) ++ gst_buffer_unmap (buf, data, size); ++ return ret; + } + + gboolean + gst_opus_header_is_comment_header (GstBuffer * buf) + { + return gst_opus_header_is_header (buf, "OpusTags", 8); }