opusenc: Put lookahead/pre-skip into the OpusHead header

https://bugzilla.gnome.org/show_bug.cgi?id=757153
This commit is contained in:
Sebastian Dröge 2015-10-30 20:47:20 +02:00
parent e75a9edff1
commit c7d785a512
4 changed files with 22 additions and 16 deletions

View file

@ -722,6 +722,7 @@ gst_opus_enc_setup (GstOpusEnc * enc)
int error = OPUS_OK; int error = OPUS_OK;
GstCaps *caps; GstCaps *caps;
gboolean ret; gboolean ret;
gint32 lookahead;
#ifndef GST_DISABLE_GST_DEBUG #ifndef GST_DISABLE_GST_DEBUG
GST_DEBUG_OBJECT (enc, GST_DEBUG_OBJECT (enc,
@ -759,10 +760,16 @@ gst_opus_enc_setup (GstOpusEnc * enc)
opus_multistream_encoder_ctl (enc->state, opus_multistream_encoder_ctl (enc->state,
OPUS_SET_PACKET_LOSS_PERC (enc->packet_loss_percentage), 0); OPUS_SET_PACKET_LOSS_PERC (enc->packet_loss_percentage), 0);
GST_LOG_OBJECT (enc, "we have frame size %d", enc->frame_size); opus_multistream_encoder_ctl (enc->state, OPUS_GET_LOOKAHEAD (&lookahead), 0);
gst_opus_header_create_caps (&caps, NULL, enc->n_channels, GST_LOG_OBJECT (enc, "we have frame size %d, lookahead %d", enc->frame_size,
enc->n_stereo_streams, enc->sample_rate, enc->channel_mapping_family, lookahead);
/* lookahead is samples, the Opus header wants it in 48kHz samples */
lookahead = lookahead * 48000 / enc->sample_rate;
gst_opus_header_create_caps (&caps, NULL, lookahead, enc->sample_rate,
enc->n_channels, enc->n_stereo_streams, enc->channel_mapping_family,
enc->decoding_channel_mapping, enc->decoding_channel_mapping,
gst_tag_setter_get_tag_list (GST_TAG_SETTER (enc))); gst_tag_setter_get_tag_list (GST_TAG_SETTER (enc)));

View file

@ -27,16 +27,15 @@
#include "gstopusheader.h" #include "gstopusheader.h"
static GstBuffer * static GstBuffer *
gst_opus_enc_create_id_buffer (gint nchannels, gint n_stereo_streams, gst_opus_enc_create_id_buffer (guint16 pre_skip, guint sample_rate,
gint sample_rate, guint8 channel_mapping_family, guint8 nchannels, guint8 n_stereo_streams, guint8 channel_mapping_family,
const guint8 * channel_mapping) const guint8 * channel_mapping)
{ {
GstBuffer *buffer; GstBuffer *buffer;
GstByteWriter bw; GstByteWriter bw;
gboolean hdl = TRUE; gboolean hdl = TRUE;
g_return_val_if_fail (nchannels > 0 && nchannels < 256, NULL); g_return_val_if_fail (nchannels > 0, NULL);
g_return_val_if_fail (n_stereo_streams >= 0, NULL);
g_return_val_if_fail (n_stereo_streams <= nchannels - n_stereo_streams, NULL); g_return_val_if_fail (n_stereo_streams <= nchannels - n_stereo_streams, NULL);
gst_byte_writer_init (&bw); gst_byte_writer_init (&bw);
@ -45,7 +44,7 @@ gst_opus_enc_create_id_buffer (gint nchannels, gint n_stereo_streams,
hdl &= gst_byte_writer_put_data (&bw, (const guint8 *) "OpusHead", 8); hdl &= gst_byte_writer_put_data (&bw, (const guint8 *) "OpusHead", 8);
hdl &= gst_byte_writer_put_uint8 (&bw, 0x01); /* version number */ hdl &= gst_byte_writer_put_uint8 (&bw, 0x01); /* version number */
hdl &= gst_byte_writer_put_uint8 (&bw, nchannels); hdl &= gst_byte_writer_put_uint8 (&bw, nchannels);
hdl &= gst_byte_writer_put_uint16_le (&bw, 0); /* pre-skip */ hdl &= gst_byte_writer_put_uint16_le (&bw, pre_skip);
hdl &= gst_byte_writer_put_uint32_le (&bw, sample_rate); hdl &= gst_byte_writer_put_uint32_le (&bw, sample_rate);
hdl &= gst_byte_writer_put_uint16_le (&bw, 0); /* output gain */ hdl &= gst_byte_writer_put_uint16_le (&bw, 0); /* output gain */
hdl &= gst_byte_writer_put_uint8 (&bw, channel_mapping_family); hdl &= gst_byte_writer_put_uint8 (&bw, channel_mapping_family);
@ -211,8 +210,9 @@ gst_opus_header_create_caps_from_headers (GstCaps ** caps, GSList ** headers,
} }
void void
gst_opus_header_create_caps (GstCaps ** caps, GSList ** headers, gint nchannels, gst_opus_header_create_caps (GstCaps ** caps, GSList ** headers,
gint n_stereo_streams, gint sample_rate, guint8 channel_mapping_family, guint16 pre_skip, guint sample_rate, guint8 nchannels,
guint8 n_stereo_streams, guint8 channel_mapping_family,
const guint8 * channel_mapping, const GstTagList * tags) const guint8 * channel_mapping, const GstTagList * tags)
{ {
GstBuffer *buf1, *buf2; GstBuffer *buf1, *buf2;
@ -220,7 +220,6 @@ gst_opus_header_create_caps (GstCaps ** caps, GSList ** headers, gint nchannels,
g_return_if_fail (caps); g_return_if_fail (caps);
g_return_if_fail (!headers || !*headers); g_return_if_fail (!headers || !*headers);
g_return_if_fail (nchannels > 0); g_return_if_fail (nchannels > 0);
g_return_if_fail (sample_rate >= 0); /* 0 -> unset */
g_return_if_fail (channel_mapping_family == 0 || channel_mapping); g_return_if_fail (channel_mapping_family == 0 || channel_mapping);
/* Opus streams in Ogg begin with two headers; the initial header (with /* Opus streams in Ogg begin with two headers; the initial header (with
@ -229,8 +228,8 @@ gst_opus_header_create_caps (GstCaps ** caps, GSList ** headers, gint nchannels,
/* create header buffers */ /* create header buffers */
buf1 = buf1 =
gst_opus_enc_create_id_buffer (nchannels, n_stereo_streams, sample_rate, gst_opus_enc_create_id_buffer (pre_skip, sample_rate, nchannels,
channel_mapping_family, channel_mapping); n_stereo_streams, channel_mapping_family, channel_mapping);
buf2 = gst_opus_enc_create_metadata_buffer (tags); buf2 = gst_opus_enc_create_metadata_buffer (tags);
gst_opus_header_create_caps_from_headers (caps, headers, buf1, buf2); gst_opus_header_create_caps_from_headers (caps, headers, buf1, buf2);

View file

@ -29,7 +29,7 @@ G_BEGIN_DECLS
extern void gst_opus_header_create_caps_from_headers (GstCaps **caps, GSList **headers, extern void gst_opus_header_create_caps_from_headers (GstCaps **caps, GSList **headers,
GstBuffer *id_header, GstBuffer *comment_header); GstBuffer *id_header, GstBuffer *comment_header);
extern void gst_opus_header_create_caps (GstCaps **caps, GSList **headers, extern void gst_opus_header_create_caps (GstCaps **caps, GSList **headers,
gint nchannels, gint n_stereo_streams, gint sample_rate, guint16 pre_skip, guint sample_rate32, guint8 nchannels, guint8 n_stereo_streams,
guint8 channel_mapping_family, const guint8 *channel_mapping, guint8 channel_mapping_family, const guint8 *channel_mapping,
const GstTagList *tags); const GstTagList *tags);
extern gboolean gst_opus_header_is_header (GstBuffer * buf, extern gboolean gst_opus_header_is_header (GstBuffer * buf,

View file

@ -359,8 +359,8 @@ gst_opus_parse_parse_frame (GstBaseParse * base, GstBaseParseFrame * frame)
channel_mapping_family = 0; channel_mapping_family = 0;
channel_mapping[0] = 0; channel_mapping[0] = 0;
channel_mapping[1] = 1; channel_mapping[1] = 1;
gst_opus_header_create_caps (&caps, &parse->headers, channels, 1, 48000, gst_opus_header_create_caps (&caps, &parse->headers, 0, 48000, channels,
channel_mapping_family, channel_mapping, NULL); 1, channel_mapping_family, channel_mapping, NULL);
} }
gst_buffer_replace (&parse->id_header, NULL); gst_buffer_replace (&parse->id_header, NULL);