[asterisk-commits] dvossel: branch dvossel/opus_codec_ftw r330105 - in /team/dvossel/opus_codec_...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Jul 28 16:02:58 CDT 2011
Author: dvossel
Date: Thu Jul 28 16:02:54 2011
New Revision: 330105
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=330105
Log:
Adds support for more opus options
Modified:
team/dvossel/opus_codec_ftw/codecs/codec_opus.c
team/dvossel/opus_codec_ftw/include/asterisk/opus.h
team/dvossel/opus_codec_ftw/main/frame.c
team/dvossel/opus_codec_ftw/res/res_format_attr_opus.c
team/dvossel/opus_codec_ftw/res/res_rtp_asterisk.c
Modified: team/dvossel/opus_codec_ftw/codecs/codec_opus.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/opus_codec_ftw/codecs/codec_opus.c?view=diff&rev=330105&r1=330104&r2=330105
==============================================================================
--- team/dvossel/opus_codec_ftw/codecs/codec_opus.c (original)
+++ team/dvossel/opus_codec_ftw/codecs/codec_opus.c Thu Jul 28 16:02:54 2011
@@ -73,7 +73,6 @@
unsigned int frame_size;
/* OPUS output sample rate */
unsigned int sample_rate;
-
/*! Number of current valid out frame buffers */
unsigned int frame_offsets_num;
/*! The current number of bytes stored in the frame offsets. */
@@ -84,12 +83,17 @@
unsigned int len;
} frame_offsets[MAX_ENC_RETURN_FRAMES];
};
+
struct opus_decoder_pvt {
int init;
OpusDecoder *dec;
SpeexResamplerState *resamp;
+
+ /* frame size of incoming OPUS frames to decode */
unsigned int frame_size;
+ /* SLIN output buffer */
int16_t slin_buf[OUTBUF_SIZE];
+ /* Number of slin samples in output buffer */
unsigned slin_samples;
};
@@ -99,10 +103,26 @@
int slin_rate = ast_format_rate(slin_src);
int opus_rate = slin_rate;
int error = 0;
+ int time_period = 0;
+ int cbr = 0;
+ int dtx = 0;
+ int fec = 0;
+ int enc_mode = OPUS_ATTR_VAL_MODE_VOICE;
+ int max_bitrate = 0;
if (pvt->explicit_dst.id) {
opus_rate = ast_format_rate(&pvt->explicit_dst);
- }
+ ast_format_get_value(&pvt->explicit_dst, OPUS_ATTR_KEY_PTIME, &time_period);
+ ast_format_get_value(&pvt->explicit_dst, OPUS_ATTR_KEY_MODE, &enc_mode);
+ ast_format_get_value(&pvt->explicit_dst, OPUS_ATTR_KEY_CBR, &cbr);
+ ast_format_get_value(&pvt->explicit_dst, OPUS_ATTR_KEY_FEC, &fec);
+ ast_format_get_value(&pvt->explicit_dst, OPUS_ATTR_KEY_DTX, &dtx);
+ ast_format_get_value(&pvt->explicit_dst, OPUS_ATTR_KEY_MAX_BITRATE, &max_bitrate);
+ }
+
+ time_period = time_period ? time_period : DEFAULT_TIME_PERIOD;
+ enc_mode = enc_mode == OPUS_ATTR_VAL_MODE_VOICE ? OPUS_APPLICATION_VOIP : OPUS_APPLICATION_AUDIO;
+
if (slin_rate != opus_rate) {
if (!(enc->resamp = speex_resampler_init(1, slin_rate, opus_rate, 5, &error))) {
@@ -110,13 +130,26 @@
}
}
- if (!(enc->enc = opus_encoder_create(slin_rate, 1, OPUS_APPLICATION_VOIP))) {
+ if (!(enc->enc = opus_encoder_create(slin_rate, 1, enc_mode))) {
ast_log(LOG_WARNING, "Failed to create OPUS encoder\n");
speex_resampler_destroy(enc->resamp);
return -1;
}
- enc->frame_size = opus_rate / (1000 / DEFAULT_TIME_PERIOD);
+ if (max_bitrate) {
+ opus_encoder_ctl(enc->enc, OPUS_SET_BITRATE(max_bitrate));
+ }
+ if (fec) {
+ opus_encoder_ctl(enc->enc, OPUS_SET_INBAND_FEC_FLAG(fec));
+ }
+ if (dtx) {
+ opus_encoder_ctl(enc->enc, OPUS_SET_DTX_FLAG(dtx));
+ }
+ if (cbr) {
+ opus_encoder_ctl(enc->enc, OPUS_SET_VBR_CONSTRAINT(cbr));
+ }
+
+ enc->frame_size = opus_rate / (1000 / time_period);
enc->sample_rate = opus_rate;
pvt->samples = 0;
@@ -276,7 +309,7 @@
pvt->samples = 0;
memset(enc->frame_offsets, 0, sizeof(enc->frame_offsets));
enc->frame_offsets_num = 0;
- enc->frame_offsets_numbytes = OUTBUF_SIZE;\
+ enc->frame_offsets_numbytes = OUTBUF_SIZE;
return frame;
}
@@ -286,12 +319,15 @@
{
struct opus_decoder_pvt *dec = pvt->pvt;
int error;
+ int fec = 0;
if (!dec->init) {
opus_dec_set(pvt, &f->subclass.format);
}
- error = opus_decode(dec->dec, f->data.ptr, f->datalen, dec->slin_buf, dec->frame_size, 0);
+ ast_format_get_value(&f->subclass.format, OPUS_ATTR_KEY_FEC, &fec);
+
+ error = opus_decode(dec->dec, f->data.ptr, f->datalen, dec->slin_buf, dec->frame_size, fec);
if (error <= 0) {
ast_log(LOG_WARNING, "error decoding OPUS, error code %d\n", error);
return -1;
Modified: team/dvossel/opus_codec_ftw/include/asterisk/opus.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/opus_codec_ftw/include/asterisk/opus.h?view=diff&rev=330105&r1=330104&r2=330105
==============================================================================
--- team/dvossel/opus_codec_ftw/include/asterisk/opus.h (original)
+++ team/dvossel/opus_codec_ftw/include/asterisk/opus.h Thu Jul 28 16:02:54 2011
@@ -27,14 +27,23 @@
/*! OPUS format attribute key value pairs, all are accessible through ast_format_get_value()*/
enum opus_attr_keys {
- OPUS_ATTR_KEY_SAMP_RATE, /*!< value is opus_attr_vals enum */
+ OPUS_ATTR_KEY_SAMP_RATE, /*!< value is in opus_attr_vals enum */
OPUS_ATTR_KEY_DTX, /*!< value is an int, 1 dtx is enabled, 0 dtx not enabled. */
OPUS_ATTR_KEY_FEC, /*!< value is an int, 1 encode with FEC, 0 do not use FEC. */
OPUS_ATTR_KEY_CBR, /*!< value is an int, 1 encode with constant bit rate, 0 do not encode with constant bit rate. */
OPUS_ATTR_KEY_MAX_BITRATE, /*!< value is an int */
+ OPUS_ATTR_KEY_PTIME, /*!< value is in opus_attr_vals enum */
+ OPUS_ATTR_KEY_MODE, /*!< AUDIO or VOICE mode */
};
enum opus_attr_vals {
+ OPUS_ATTR_VAL_MODE_VOICE = 0,
+ OPUS_ATTR_VAL_MODE_AUDIO = 1,
+ OPUS_ATTR_VAL_PTIME_5 = 5, /* 5ms per frame */
+ OPUS_ATTR_VAL_PTIME_10 = 10, /* 10ms per frame */
+ OPUS_ATTR_VAL_PTIME_20 = 20, /* 20ms per frame */
+ OPUS_ATTR_VAL_PTIME_40 = 40, /* 40ms per frame */
+ OPUS_ATTR_VAL_PTIME_60 = 60, /* 40ms per frame */
OPUS_ATTR_VAL_SAMP_8KHZ = 8000,
OPUS_ATTR_VAL_SAMP_12KHZ = 12000,
OPUS_ATTR_VAL_SAMP_16KHZ = 16000,
Modified: team/dvossel/opus_codec_ftw/main/frame.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/opus_codec_ftw/main/frame.c?view=diff&rev=330105&r1=330104&r2=330105
==============================================================================
--- team/dvossel/opus_codec_ftw/main/frame.c (original)
+++ team/dvossel/opus_codec_ftw/main/frame.c Thu Jul 28 16:02:54 2011
@@ -1012,10 +1012,18 @@
return 160;
}
case AST_FORMAT_CELT:
- case AST_FORMAT_OPUS:
/* TODO The assumes 20ms delivery right now, which is incorrect */
samples = ast_format_rate(&f->subclass.format) / 50;
break;
+ case AST_FORMAT_OPUS:
+ {
+ int period = 0;
+
+ ast_format_get_value(&f->subclass.format, OPUS_ATTR_KEY_PTIME, &period);
+ period = period ? period : 20;
+ samples = ast_format_rate(&f->subclass.format) / (1000 / period);
+ break;
+ }
default:
ast_log(LOG_WARNING, "Unable to calculate samples for format %s\n", ast_getformatname(&f->subclass.format));
}
Modified: team/dvossel/opus_codec_ftw/res/res_format_attr_opus.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/opus_codec_ftw/res/res_format_attr_opus.c?view=diff&rev=330105&r1=330104&r2=330105
==============================================================================
--- team/dvossel/opus_codec_ftw/res/res_format_attr_opus.c (original)
+++ team/dvossel/opus_codec_ftw/res/res_format_attr_opus.c Thu Jul 28 16:02:54 2011
@@ -41,6 +41,8 @@
unsigned int dtx;
unsigned int fec;
unsigned int cbr;
+ unsigned int ptime;
+ unsigned int mode;
};
static enum ast_format_cmp_res opus_cmp(const struct ast_format_attr *fattr1, const struct ast_format_attr *fattr2)
@@ -75,6 +77,10 @@
case OPUS_ATTR_KEY_CBR:
*val = attr->cbr;
break;
+ case OPUS_ATTR_KEY_PTIME:
+ *val = attr->ptime;
+ case OPUS_ATTR_KEY_MODE:
+ *val = attr->mode;
default:
return -1;
ast_log(LOG_WARNING, "unknown attribute type %d\n", key);
@@ -117,6 +123,16 @@
return -1;
}
break;
+ case OPUS_ATTR_KEY_PTIME:
+ if (attr->ptime != (va_arg(ap, int))) {
+ return -1;
+ }
+ break;
+ case OPUS_ATTR_KEY_MODE:
+ if (attr->mode != (va_arg(ap, int))) {
+ return -1;
+ }
+ break;
default:
return -1;
ast_log(LOG_WARNING, "unknown attribute type %d\n", key);
@@ -149,6 +165,10 @@
/* If CBR is requested, use it */
attr_res->cbr = attr1->cbr || attr2->cbr ? 1 : 0;
+
+ attr_res->ptime = MIN(attr1->ptime, attr2->ptime);
+
+ attr_res->mode = MIN(attr1->mode, attr2->mode);
return joint;
}
@@ -177,6 +197,12 @@
break;
case OPUS_ATTR_KEY_CBR:
attr->cbr = (va_arg(ap, int));
+ break;
+ case OPUS_ATTR_KEY_PTIME:
+ attr->ptime = (va_arg(ap, int));
+ break;
+ case OPUS_ATTR_KEY_MODE:
+ attr->mode = (va_arg(ap, int));
break;
default:
ast_log(LOG_WARNING, "unknown attribute type %d\n", key);
Modified: team/dvossel/opus_codec_ftw/res/res_rtp_asterisk.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/opus_codec_ftw/res/res_rtp_asterisk.c?view=diff&rev=330105&r1=330104&r2=330105
==============================================================================
--- team/dvossel/opus_codec_ftw/res/res_rtp_asterisk.c (original)
+++ team/dvossel/opus_codec_ftw/res/res_rtp_asterisk.c Thu Jul 28 16:02:54 2011
@@ -381,7 +381,17 @@
static int rtp_get_rate(struct ast_format *format)
{
- return (format->id == AST_FORMAT_G722) ? 8000 : ast_format_rate(format);
+ /* Sometimes RFCs are weird, and the actual rate of a format
+ * isn't want we use for the RTP timestamp. This is a place
+ * for those exceptions. */
+ switch (format->id) {
+ case AST_FORMAT_G722:
+ return 8000;
+ case AST_FORMAT_OPUS:
+ return 48000;
+ default:
+ return ast_format_rate(format);
+ }
}
static unsigned int ast_rtcp_calc_interval(struct ast_rtp *rtp)
More information about the asterisk-commits
mailing list