mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
opus: switch to multistream API
It's very similar to the basic API, and is a superset ot it, which will allow encoding and decoding more than 2 channels.
This commit is contained in:
parent
e4ae3e89fa
commit
670c365400
4 changed files with 49 additions and 24 deletions
|
@ -150,7 +150,7 @@ gst_opus_dec_reset (GstOpusDec * dec)
|
|||
{
|
||||
dec->packetno = 0;
|
||||
if (dec->state) {
|
||||
opus_decoder_destroy (dec->state);
|
||||
opus_multistream_decoder_destroy (dec->state);
|
||||
dec->state = NULL;
|
||||
}
|
||||
|
||||
|
@ -228,6 +228,16 @@ gst_opus_dec_parse_header (GstOpusDec * dec, GstBuffer * buf)
|
|||
"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 = GST_BUFFER_DATA (buf)[18];
|
||||
if (dec->channel_mapping_family != 0) {
|
||||
GST_ELEMENT_ERROR (dec, STREAM, DECODE,
|
||||
("Decoding error: unsupported channel nmapping family %d",
|
||||
dec->channel_mapping_family), (NULL));
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
dec->channel_mapping[0] = 0;
|
||||
dec->channel_mapping[1] = 1;
|
||||
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
|
@ -298,7 +308,8 @@ opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buffer)
|
|||
|
||||
GST_DEBUG_OBJECT (dec, "Creating decoder with %d channels, %d Hz",
|
||||
dec->n_channels, dec->sample_rate);
|
||||
dec->state = opus_decoder_create (dec->sample_rate, dec->n_channels, &err);
|
||||
dec->state = opus_multistream_decoder_create (dec->sample_rate,
|
||||
dec->n_channels, 1, 1, dec->channel_mapping, &err);
|
||||
if (!dec->state || err != OPUS_OK)
|
||||
goto creation_failed;
|
||||
}
|
||||
|
@ -350,14 +361,16 @@ opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buffer)
|
|||
if (dec->use_inband_fec) {
|
||||
if (dec->last_buffer) {
|
||||
/* normal delayed decode */
|
||||
n = opus_decode (dec->state, data, size, out_data, samples, 0);
|
||||
n = opus_multistream_decode (dec->state, data, size, out_data, samples,
|
||||
0);
|
||||
} else {
|
||||
/* FEC reconstruction decode */
|
||||
n = opus_decode (dec->state, data, size, out_data, samples, 1);
|
||||
n = opus_multistream_decode (dec->state, data, size, out_data, samples,
|
||||
1);
|
||||
}
|
||||
} else {
|
||||
/* normal decode */
|
||||
n = opus_decode (dec->state, data, size, out_data, samples, 0);
|
||||
n = opus_multistream_decode (dec->state, data, size, out_data, samples, 0);
|
||||
}
|
||||
|
||||
if (n < 0) {
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/audio/gstaudiodecoder.h>
|
||||
#include <opus/opus.h>
|
||||
#include <opus/opus_multistream.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
@ -44,7 +44,7 @@ typedef struct _GstOpusDecClass GstOpusDecClass;
|
|||
struct _GstOpusDec {
|
||||
GstAudioDecoder element;
|
||||
|
||||
OpusDecoder *state;
|
||||
OpusMSDecoder *state;
|
||||
|
||||
guint64 packetno;
|
||||
|
||||
|
@ -55,6 +55,8 @@ struct _GstOpusDec {
|
|||
int n_channels;
|
||||
guint32 pre_skip;
|
||||
gint16 r128_gain;
|
||||
guint8 channel_mapping_family;
|
||||
guint8 channel_mapping[256];
|
||||
|
||||
gboolean apply_gain;
|
||||
double r128_gain_volume;
|
||||
|
|
|
@ -355,7 +355,7 @@ gst_opus_enc_stop (GstAudioEncoder * benc)
|
|||
GST_DEBUG_OBJECT (enc, "stop");
|
||||
enc->header_sent = FALSE;
|
||||
if (enc->state) {
|
||||
opus_encoder_destroy (enc->state);
|
||||
opus_multistream_encoder_destroy (enc->state);
|
||||
enc->state = NULL;
|
||||
}
|
||||
gst_tag_list_free (enc->tags);
|
||||
|
@ -435,7 +435,7 @@ gst_opus_enc_set_format (GstAudioEncoder * benc, GstAudioInfo * info)
|
|||
|
||||
/* handle reconfigure */
|
||||
if (enc->state) {
|
||||
opus_encoder_destroy (enc->state);
|
||||
opus_multistream_encoder_destroy (enc->state);
|
||||
enc->state = NULL;
|
||||
}
|
||||
if (!gst_opus_enc_setup (enc))
|
||||
|
@ -455,24 +455,34 @@ static gboolean
|
|||
gst_opus_enc_setup (GstOpusEnc * enc)
|
||||
{
|
||||
int error = OPUS_OK;
|
||||
unsigned char mapping[256];
|
||||
int n;
|
||||
|
||||
GST_DEBUG_OBJECT (enc, "setup");
|
||||
|
||||
enc->state = opus_encoder_create (enc->sample_rate, enc->n_channels,
|
||||
for (n = 0; n < enc->n_channels; ++n)
|
||||
mapping[n] = n;
|
||||
|
||||
enc->state =
|
||||
opus_multistream_encoder_create (enc->sample_rate, enc->n_channels,
|
||||
(enc->n_channels + 1) / 2, enc->n_channels / 2, mapping,
|
||||
enc->audio_or_voip ? OPUS_APPLICATION_AUDIO : OPUS_APPLICATION_VOIP,
|
||||
&error);
|
||||
if (!enc->state || error != OPUS_OK)
|
||||
goto encoder_creation_failed;
|
||||
|
||||
opus_encoder_ctl (enc->state, OPUS_SET_BITRATE (enc->bitrate), 0);
|
||||
opus_encoder_ctl (enc->state, OPUS_SET_BANDWIDTH (enc->bandwidth), 0);
|
||||
opus_encoder_ctl (enc->state, OPUS_SET_VBR (!enc->cbr), 0);
|
||||
opus_encoder_ctl (enc->state, OPUS_SET_VBR_CONSTRAINT (enc->constrained_vbr),
|
||||
opus_multistream_encoder_ctl (enc->state, OPUS_SET_BITRATE (enc->bitrate), 0);
|
||||
opus_multistream_encoder_ctl (enc->state, OPUS_SET_BANDWIDTH (enc->bandwidth),
|
||||
0);
|
||||
opus_encoder_ctl (enc->state, OPUS_SET_COMPLEXITY (enc->complexity), 0);
|
||||
opus_encoder_ctl (enc->state, OPUS_SET_INBAND_FEC (enc->inband_fec), 0);
|
||||
opus_encoder_ctl (enc->state, OPUS_SET_DTX (enc->dtx), 0);
|
||||
opus_encoder_ctl (enc->state,
|
||||
opus_multistream_encoder_ctl (enc->state, OPUS_SET_VBR (!enc->cbr), 0);
|
||||
opus_multistream_encoder_ctl (enc->state,
|
||||
OPUS_SET_VBR_CONSTRAINT (enc->constrained_vbr), 0);
|
||||
opus_multistream_encoder_ctl (enc->state,
|
||||
OPUS_SET_COMPLEXITY (enc->complexity), 0);
|
||||
opus_multistream_encoder_ctl (enc->state,
|
||||
OPUS_SET_INBAND_FEC (enc->inband_fec), 0);
|
||||
opus_multistream_encoder_ctl (enc->state, OPUS_SET_DTX (enc->dtx), 0);
|
||||
opus_multistream_encoder_ctl (enc->state,
|
||||
OPUS_SET_PACKET_LOSS_PERC (enc->packet_loss_percentage), 0);
|
||||
|
||||
GST_LOG_OBJECT (enc, "we have frame size %d", enc->frame_size);
|
||||
|
@ -557,8 +567,8 @@ gst_opus_enc_encode (GstOpusEnc * enc, GstBuffer * buf)
|
|||
enc->frame_samples);
|
||||
|
||||
outsize =
|
||||
opus_encode (enc->state, (const gint16 *) data, enc->frame_samples,
|
||||
GST_BUFFER_DATA (outbuf), enc->max_payload_size);
|
||||
opus_multistream_encode (enc->state, (const gint16 *) data,
|
||||
enc->frame_samples, GST_BUFFER_DATA (outbuf), enc->max_payload_size);
|
||||
|
||||
if (outsize < 0) {
|
||||
GST_ERROR_OBJECT (enc, "Encoding failed: %d", outsize);
|
||||
|
@ -694,7 +704,7 @@ gst_opus_enc_set_property (GObject * object, guint prop_id,
|
|||
g_mutex_lock (enc->property_lock); \
|
||||
enc->prop = g_value_get_##type (value); \
|
||||
if (enc->state) { \
|
||||
opus_encoder_ctl (enc->state, OPUS_SET_##ctl (enc->prop)); \
|
||||
opus_multistream_encoder_ctl (enc->state, OPUS_SET_##ctl (enc->prop)); \
|
||||
} \
|
||||
g_mutex_unlock (enc->property_lock); \
|
||||
} while(0)
|
||||
|
@ -720,7 +730,7 @@ gst_opus_enc_set_property (GObject * object, guint prop_id,
|
|||
/* this one has an opposite meaning to the opus ctl... */
|
||||
g_mutex_lock (enc->property_lock);
|
||||
enc->cbr = g_value_get_boolean (value);
|
||||
opus_encoder_ctl (enc->state, OPUS_SET_VBR (!enc->cbr));
|
||||
opus_multistream_encoder_ctl (enc->state, OPUS_SET_VBR (!enc->cbr));
|
||||
g_mutex_unlock (enc->property_lock);
|
||||
break;
|
||||
case PROP_CONSTRAINED_VBR:
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include <gst/gst.h>
|
||||
#include <gst/audio/gstaudioencoder.h>
|
||||
|
||||
#include <opus/opus.h>
|
||||
#include <opus/opus_multistream.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
@ -50,7 +50,7 @@ typedef struct _GstOpusEncClass GstOpusEncClass;
|
|||
struct _GstOpusEnc {
|
||||
GstAudioEncoder element;
|
||||
|
||||
OpusEncoder *state;
|
||||
OpusMSEncoder *state;
|
||||
|
||||
/* Locks those properties which may be changed at play time */
|
||||
GMutex *property_lock;
|
||||
|
|
Loading…
Reference in a new issue