[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