Merge branch 'master' into 0.11

This commit is contained in:
Wim Taymans 2011-10-04 13:29:21 +02:00
commit 6bd65058c4
2 changed files with 76 additions and 123 deletions

View file

@ -55,7 +55,7 @@ GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("audio/x-raw-int, "
"rate = (int) [ 32000, 64000 ], "
"rate = (int) { 8000, 12000, 16000, 24000, 48000 }, "
"channels = (int) [ 1, 2 ], "
"endianness = (int) BYTE_ORDER, "
"signed = (boolean) true, " "width = (int) 16, " "depth = (int) 16")
@ -193,6 +193,8 @@ opus_dec_sink_setcaps (GstPad * pad, GstCaps * caps)
GstStructure *s;
const GValue *streamheader;
GST_DEBUG_OBJECT (pad, "Setting sink caps to %" GST_PTR_FORMAT, caps);
s = gst_caps_get_structure (caps, 0);
if ((streamheader = gst_structure_get_value (s, "streamheader")) &&
G_VALUE_HOLDS (streamheader, GST_TYPE_ARRAY) &&
@ -237,6 +239,47 @@ opus_dec_sink_setcaps (GstPad * pad, GstCaps * caps)
}
}
if (!gst_structure_get_int (s, "frame-size", &dec->frame_size)) {
GST_WARNING_OBJECT (dec, "Frame size not included in caps");
}
if (!gst_structure_get_int (s, "channels", &dec->n_channels)) {
GST_WARNING_OBJECT (dec, "Number of channels not included in caps");
}
if (!gst_structure_get_int (s, "rate", &dec->sample_rate)) {
GST_WARNING_OBJECT (dec, "Sample rate not included in caps");
}
switch (dec->frame_size) {
case 2:
dec->frame_samples = dec->sample_rate / 400;
break;
case 5:
dec->frame_samples = dec->sample_rate / 200;
break;
case 10:
dec->frame_samples = dec->sample_rate / 100;
break;
case 20:
dec->frame_samples = dec->sample_rate / 50;
break;
case 40:
dec->frame_samples = dec->sample_rate / 25;
break;
case 60:
dec->frame_samples = 3 * dec->sample_rate / 50;
break;
default:
GST_WARNING_OBJECT (dec, "Unsupported frame size: %d", dec->frame_size);
break;
}
dec->frame_duration = gst_util_uint64_scale_int (dec->frame_samples,
GST_SECOND, dec->sample_rate);
GST_INFO_OBJECT (dec,
"Got frame size %d, %d channels, %d Hz, giving %d samples per frame, frame duration %"
GST_TIME_FORMAT, dec->frame_size, dec->n_channels, dec->sample_rate,
dec->frame_samples, GST_TIME_ARGS (dec->frame_duration));
done:
gst_object_unref (dec);
return ret;
@ -566,7 +609,7 @@ static GstFlowReturn
opus_dec_chain_parse_header (GstOpusDec * dec, GstBuffer * buf)
{
GstCaps *caps;
//gint error = OPUS_OK;
int err;
#if 0
dec->samples_per_frame = opus_packet_get_samples_per_frame (
@ -578,42 +621,10 @@ opus_dec_chain_parse_header (GstOpusDec * dec, GstBuffer * buf)
goto invalid_header;
#endif
#if 0
#ifdef HAVE_OPUS_0_7
dec->mode =
opus_mode_create (dec->sample_rate, dec->header.frame_size, &error);
#else
dec->mode =
opus_mode_create (dec->sample_rate, dec->header.nb_channels,
dec->header.frame_size, &error);
#endif
if (!dec->mode)
goto mode_init_failed;
/* initialize the decoder */
#ifdef HAVE_OPUS_0_11
dec->state =
opus_decoder_create_custom (dec->mode, dec->header.nb_channels, &error);
#else
#ifdef HAVE_OPUS_0_7
dec->state = opus_decoder_create (dec->mode, dec->header.nb_channels, &error);
#else
dec->state = opus_decoder_create (dec->mode);
#endif
#endif
#endif
dec->state = opus_decoder_create (dec->sample_rate, dec->n_channels);
if (!dec->state)
dec->state = opus_decoder_create (dec->sample_rate, dec->n_channels, &err);
if (!dec->state || err != OPUS_OK)
goto init_failed;
#if 0
#ifdef HAVE_OPUS_0_8
dec->frame_size = dec->header.frame_size;
#else
opus_mode_info (dec->mode, OPUS_GET_FRAME_SIZE, &dec->frame_size);
#endif
#endif
dec->frame_duration = gst_util_uint64_scale_int (dec->frame_size,
GST_SECOND, dec->sample_rate);
@ -711,7 +722,7 @@ opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buf,
guint8 *data;
GstBuffer *outbuf;
gint16 *out_data;
int n;
int n, err;
if (timestamp != -1) {
dec->segment.last_stop = timestamp;
@ -721,7 +732,9 @@ opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buf,
if (dec->state == NULL) {
GstCaps *caps;
dec->state = opus_decoder_create (dec->sample_rate, dec->n_channels);
dec->state = opus_decoder_create (dec->sample_rate, dec->n_channels, &err);
if (!dec->state || err != OPUS_OK)
goto creation_failed;
/* set caps */
caps = gst_caps_new_simple ("audio/x-raw-int",
@ -772,7 +785,7 @@ opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buf,
GST_LOG_OBJECT (dec, "decoding frame");
n = opus_decode (dec->state, data, size, out_data, dec->frame_samples, TRUE);
n = opus_decode (dec->state, data, size, out_data, dec->frame_samples, 0);
if (n < 0) {
GST_ELEMENT_ERROR (dec, STREAM, DECODE, ("Decoding error: %d", n), (NULL));
return GST_FLOW_ERROR;
@ -805,6 +818,10 @@ opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buf,
GST_DEBUG_OBJECT (dec, "flow: %s", gst_flow_get_name (res));
return res;
creation_failed:
GST_ERROR_OBJECT (dec, "Failed to create Opus decoder: %d", err);
return GST_FLOW_ERROR;
}
static GstFlowReturn
@ -814,6 +831,10 @@ opus_dec_chain (GstPad * pad, GstBuffer * buf)
GstOpusDec *dec;
dec = GST_OPUS_DEC (gst_pad_get_parent (pad));
GST_LOG_OBJECT (pad,
"Got buffer ts %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT,
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
if (GST_BUFFER_IS_DISCONT (buf)) {
dec->discont = TRUE;

View file

@ -63,7 +63,7 @@ gst_opus_enc_bandwidth_get_type (void)
{OPUS_BANDWIDTH_WIDEBAND, "Wide band", "wideband"},
{OPUS_BANDWIDTH_SUPERWIDEBAND, "Super wide band", "superwideband"},
{OPUS_BANDWIDTH_FULLBAND, "Full band", "fullband"},
{OPUS_BANDWIDTH_AUTO, "Auto", "auto"},
{OPUS_AUTO, "Auto", "auto"},
{0, NULL, NULL}
};
static volatile GType id = 0;
@ -286,12 +286,13 @@ gst_opus_enc_sink_setcaps (GstPad * pad, GstCaps * caps)
enc->frame_samples = enc->sample_rate / 50;
break;
case 40:
enc->frame_samples = enc->sample_rate / 20;
enc->frame_samples = enc->sample_rate / 25;
break;
case 60:
enc->frame_samples = 3 * enc->sample_rate / 50;
break;
default:
GST_WARNING_OBJECT (enc, "Unsupported frame size: %d", enc->frame_size);
return FALSE;
break;
}
@ -664,62 +665,24 @@ gst_opus_enc_create_metadata_buffer (GstOpusEnc * enc)
static gboolean
gst_opus_enc_setup (GstOpusEnc * enc)
{
//gint error = OPUS_OK;
int error = OPUS_OK;
enc->setup = FALSE;
#if 0
#ifdef HAVE_OPUS_0_7
enc->mode = opus_mode_create (enc->rate, enc->frame_size, &error);
#else
enc->mode =
opus_mode_create (enc->rate, enc->n_channels, enc->frame_size, &error);
#endif
if (!enc->mode)
goto mode_initialization_failed;
#ifdef HAVE_OPUS_0_11
opus_header_init (&enc->header, enc->mode, enc->frame_size, enc->n_channels);
#else
#ifdef HAVE_OPUS_0_7
opus_header_init (&enc->header, enc->mode, enc->n_channels);
#else
opus_header_init (&enc->header, enc->mode);
#endif
#endif
enc->header.nb_channels = enc->n_channels;
#ifdef HAVE_OPUS_0_8
enc->frame_size = enc->header.frame_size;
#else
opus_mode_info (enc->mode, OPUS_GET_FRAME_SIZE, &enc->frame_size);
#endif
#endif
#if 0
#ifdef HAVE_OPUS_0_11
enc->state = opus_encoder_create_custom (enc->mode, enc->n_channels, &error);
#else
#ifdef HAVE_OPUS_0_7
enc->state = opus_encoder_create (enc->mode, enc->n_channels, &error);
#else
enc->state = opus_encoder_create (enc->mode);
#endif
#endif
#endif
enc->state = opus_encoder_create (enc->sample_rate, enc->n_channels,
enc->audio_or_voip ? OPUS_APPLICATION_AUDIO : OPUS_APPLICATION_VOIP);
if (!enc->state)
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_FLAG (!enc->cbr), 0);
opus_encoder_ctl (enc->state, OPUS_SET_VBR (!enc->cbr), 0);
opus_encoder_ctl (enc->state, OPUS_SET_VBR_CONSTRAINT (enc->constrained_vbr),
0);
opus_encoder_ctl (enc->state, OPUS_SET_COMPLEXITY (enc->complexity), 0);
opus_encoder_ctl (enc->state, OPUS_SET_INBAND_FEC_FLAG (enc->inband_fec), 0);
opus_encoder_ctl (enc->state, OPUS_SET_DTX_FLAG (enc->dtx), 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_SET_PACKET_LOSS_PERC (enc->packet_loss_percentage), 0);
@ -879,6 +842,12 @@ gst_opus_enc_encode (GstOpusEnc * enc, gboolean flush)
GST_ERROR_OBJECT (enc, "Encoding failed: %d", outsize);
ret = GST_FLOW_ERROR;
goto done;
} else if (outsize != bytes_per_packet) {
GST_WARNING_OBJECT (enc,
"Encoded size %d is different from %d bytes per packet", outsize,
bytes_per_packet);
ret = GST_FLOW_ERROR;
goto done;
}
GST_BUFFER_TIMESTAMP (outbuf) = enc->start_ts +
@ -916,29 +885,10 @@ gst_opus_enc_chain (GstPad * pad, GstBuffer * buf)
if (!enc->setup)
goto not_setup;
#if 0
if (!enc->header_sent) {
/* Opus streams begin with two headers; the initial header (with
most of the codec setup parameters) which is mandated by the Ogg
bitstream spec. The second header holds any comment fields.
We merely need to make the headers, then pass them to libopus
one at a time; libopus handles the additional Ogg bitstream
constraints */
GstBuffer *buf1, *buf2;
GstCaps *caps;
guchar data[100];
/* create header buffer */
opus_header_to_packet (&enc->header, data, 100);
buf1 = gst_opus_enc_buffer_from_data (enc, data, 100, 0);
/* create comment buffer */
buf2 = gst_opus_enc_create_metadata_buffer (enc);
/* mark and put on caps */
caps = gst_pad_get_caps (enc->srcpad);
caps = gst_opus_enc_set_header_on_caps (caps, buf1, buf2);
gst_caps_set_simple (caps,
"rate", G_TYPE_INT, enc->sample_rate,
"channels", G_TYPE_INT, enc->n_channels,
@ -950,26 +900,8 @@ gst_opus_enc_chain (GstPad * pad, GstBuffer * buf)
enc->sample_rate, enc->n_channels, enc->frame_size);
gst_pad_set_caps (enc->srcpad, caps);
gst_buffer_set_caps (buf1, caps);
gst_buffer_set_caps (buf2, caps);
gst_caps_unref (caps);
/* push out buffers */
ret = gst_opus_enc_push_buffer (enc, buf1);
if (ret != GST_FLOW_OK) {
gst_buffer_unref (buf2);
goto done;
}
ret = gst_opus_enc_push_buffer (enc, buf2);
if (ret != GST_FLOW_OK)
goto done;
enc->header_sent = TRUE;
}
#endif
GST_DEBUG_OBJECT (enc, "received buffer of %u bytes", GST_BUFFER_SIZE (buf));