[asterisk-commits] file: branch group/media_formats r406132 - in /team/group/media_formats: incl...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jan 21 15:43:01 CST 2014


Author: file
Date: Tue Jan 21 15:42:59 2014
New Revision: 406132

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=406132
Log:
Add callbacks for getting samples/length and remove interpolation callback, it's not needed.

Modified:
    team/group/media_formats/include/asterisk/codec.h
    team/group/media_formats/main/codec_builtin.c

Modified: team/group/media_formats/include/asterisk/codec.h
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats/include/asterisk/codec.h?view=diff&rev=406132&r1=406131&r2=406132
==============================================================================
--- team/group/media_formats/include/asterisk/codec.h (original)
+++ team/group/media_formats/include/asterisk/codec.h Tue Jan 21 15:42:59 2014
@@ -60,8 +60,6 @@
 	int (*get_samples)(struct ast_frame *frame);
 	/*! \brief Callback function for getting the length of media based on number of samples */
 	int (*get_length)(unsigned int samples);
-	/*! \brief Callback function for getting the duration in ms of an interpolation frame */
-	int (*get_interpolation_length)(void);
 	/*! \brief Whether the media can be smoothed or not */
 	unsigned int smooth:1;
 };

Modified: team/group/media_formats/main/codec_builtin.c
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats/main/codec_builtin.c?view=diff&rev=406132&r1=406131&r2=406132
==============================================================================
--- team/group/media_formats/main/codec_builtin.c (original)
+++ team/group/media_formats/main/codec_builtin.c Tue Jan 21 15:42:59 2014
@@ -33,6 +33,60 @@
 
 #include "asterisk/logger.h"
 #include "asterisk/codec.h"
+#include "asterisk/frame.h"
+
+enum frame_type {
+	TYPE_HIGH,     /* 0x0 */
+	TYPE_LOW,      /* 0x1 */
+	TYPE_SILENCE,  /* 0x2 */
+	TYPE_DONTSEND  /* 0x3 */
+};
+
+#define TYPE_MASK 0x3
+
+static int g723_len(unsigned char buf)
+{
+	enum frame_type type = buf & TYPE_MASK;
+
+	switch(type) {
+	case TYPE_DONTSEND:
+		return 0;
+		break;
+	case TYPE_SILENCE:
+		return 4;
+		break;
+	case TYPE_HIGH:
+		return 24;
+		break;
+	case TYPE_LOW:
+		return 20;
+		break;
+	default:
+		ast_log(LOG_WARNING, "Badly encoded frame (%d)\n", type);
+	}
+	return -1;
+}
+
+static int g723_samples(struct ast_frame *frame)
+{
+	unsigned char *buf = frame->data.ptr;
+	int pos = 0, samples = 0, res;
+
+	while(pos < frame->datalen) {
+		res = g723_len(buf[pos]);
+		if (res <= 0)
+			break;
+		samples += 240;
+		pos += res;
+	}
+
+	return samples;
+}
+
+static int g723_length(unsigned int samples)
+{
+	return (samples / 240) * 20;
+}
 
 static struct ast_codec g723 = {
 	.name = "g723",
@@ -43,7 +97,19 @@
 	.maximum_ms = 300,
 	.increment_ms = 30,
 	.default_ms = 30,
-};
+	.get_samples = g723_samples,
+	.get_length = g723_length,
+};
+
+static int ulaw_samples(struct ast_frame *frame)
+{
+	return frame->datalen;
+}
+
+static int ulaw_length(unsigned int samples)
+{
+	return samples;
+}
 
 static struct ast_codec ulaw = {
 	.name = "ulaw",
@@ -54,6 +120,8 @@
 	.maximum_ms = 150,
 	.increment_ms = 10,
 	.default_ms = 20,
+	.get_samples = ulaw_samples,
+	.get_length = ulaw_length,
 };
 
 static struct ast_codec alaw = {
@@ -65,7 +133,19 @@
 	.maximum_ms = 150,
 	.increment_ms = 10,
 	.default_ms = 20,
-};
+	.get_samples = ulaw_samples,
+	.get_length = ulaw_length,
+};
+
+static int gsm_samples(struct ast_frame *frame)
+{
+	return 160 * (frame->datalen / 33);
+}
+
+static int gsm_length(unsigned int samples)
+{
+	return (samples / 160) * 33;
+}
 
 static struct ast_codec gsm = {
 	.name = "gsm",
@@ -76,7 +156,19 @@
 	.maximum_ms = 300,
 	.increment_ms = 20,
 	.default_ms = 20,
-};
+	.get_samples = gsm_samples,
+	.get_length = gsm_length,
+};
+
+static int g726_samples(struct ast_frame *frame)
+{
+	return frame->datalen * 2;
+}
+
+static int g726_length(unsigned int samples)
+{
+	return samples / 2;
+}
 
 static struct ast_codec g726rfc3551 = {
 	.name = "g726",
@@ -87,6 +179,8 @@
 	.maximum_ms = 300,
 	.increment_ms = 10,
 	.default_ms = 20,
+	.get_samples = g726_samples,
+	.get_length = g726_length,
 };
 
 static struct ast_codec g726aal2 = {
@@ -98,6 +192,8 @@
 	.maximum_ms = 300,
 	.increment_ms = 10,
 	.default_ms = 20,
+	.get_samples = g726_samples,
+	.get_length = g726_length,
 };
 
 static struct ast_codec adpcm = {
@@ -109,7 +205,19 @@
 	.maximum_ms = 300,
 	.increment_ms = 10,
 	.default_ms = 20,
-};
+	.get_samples = g726_samples,
+	.get_length = g726_length,
+};
+
+static int slin_samples(struct ast_frame *frame)
+{
+	return frame->datalen / 2;
+}
+
+static int slin_length(unsigned int samples)
+{
+	return samples * 2;
+}
 
 static struct ast_codec slin8 = {
 	.name = "slin",
@@ -120,6 +228,8 @@
 	.maximum_ms = 70,
 	.increment_ms = 10,
 	.default_ms = 20,
+	.get_samples = slin_samples,
+	.get_length = slin_length,
 };
 
 static struct ast_codec slin12 = {
@@ -131,6 +241,8 @@
 	.maximum_ms = 70,
 	.increment_ms = 10,
 	.default_ms = 20,
+	.get_samples = slin_samples,
+	.get_length = slin_length,
 };
 
 static struct ast_codec slin16 = {
@@ -142,6 +254,8 @@
 	.maximum_ms = 70,
 	.increment_ms = 10,
 	.default_ms = 20,
+	.get_samples = slin_samples,
+	.get_length = slin_length,
 };
 
 static struct ast_codec slin24 = {
@@ -153,6 +267,8 @@
 	.maximum_ms = 70,
 	.increment_ms = 10,
 	.default_ms = 20,
+	.get_samples = slin_samples,
+	.get_length = slin_length,
 };
 
 static struct ast_codec slin32 = {
@@ -164,6 +280,8 @@
 	.maximum_ms = 70,
 	.increment_ms = 10,
 	.default_ms = 20,
+	.get_samples = slin_samples,
+	.get_length = slin_length,
 };
 
 static struct ast_codec slin44 = {
@@ -175,6 +293,8 @@
 	.maximum_ms = 70,
 	.increment_ms = 10,
 	.default_ms = 20,
+	.get_samples = slin_samples,
+	.get_length = slin_length,
 };
 
 static struct ast_codec slin48 = {
@@ -186,6 +306,8 @@
 	.maximum_ms = 70,
 	.increment_ms = 10,
 	.default_ms = 20,
+	.get_samples = slin_samples,
+	.get_length = slin_length,
 };
 
 static struct ast_codec slin96 = {
@@ -197,6 +319,8 @@
 	.maximum_ms = 70,
 	.increment_ms = 10,
 	.default_ms = 20,
+	.get_samples = slin_samples,
+	.get_length = slin_length,
 };
 
 static struct ast_codec slin192 = {
@@ -208,7 +332,19 @@
 	.maximum_ms = 70,
 	.increment_ms = 10,
 	.default_ms = 20,
-};
+	.get_samples = slin_samples,
+	.get_length = slin_length,
+};
+
+static int lpc10_samples(struct ast_frame *frame)
+{
+	int samples = 22 * 8;
+
+	/* assumes that the RTP packet contains one LPC10 frame */
+	samples += (((char *)(frame->data.ptr))[7] & 0x1) * 8;
+
+	return samples;
+}
 
 static struct ast_codec lpc10 = {
 	.name = "lpc10",
@@ -219,7 +355,18 @@
 	.maximum_ms = 20,
 	.increment_ms = 20,
 	.default_ms = 20,
-};
+	.get_samples = lpc10_samples,
+};
+
+static int g729_samples(struct ast_frame *frame)
+{
+	return frame->datalen * 8;
+}
+
+static int g729_length(unsigned int samples)
+{
+	return samples / 8;
+}
 
 static struct ast_codec g729a = {
 	.name = "g729",
@@ -230,7 +377,123 @@
 	.maximum_ms = 230,
 	.increment_ms = 10,
 	.default_ms = 20,
-};
+	.get_samples = g729_samples,
+	.get_length = g729_length,
+};
+
+static unsigned char get_n_bits_at(unsigned char *data, int n, int bit)
+{
+	int byte = bit / 8;       /* byte containing first bit */
+	int rem = 8 - (bit % 8);  /* remaining bits in first byte */
+	unsigned char ret = 0;
+
+	if (n <= 0 || n > 8)
+		return 0;
+
+	if (rem < n) {
+		ret = (data[byte] << (n - rem));
+		ret |= (data[byte + 1] >> (8 - n + rem));
+	} else {
+		ret = (data[byte] >> (rem - n));
+	}
+
+	return (ret & (0xff >> (8 - n)));
+}
+
+static int speex_get_wb_sz_at(unsigned char *data, int len, int bit)
+{
+	static const int SpeexWBSubModeSz[] = {
+		4, 36, 112, 192,
+		352, 0, 0, 0 };
+	int off = bit;
+	unsigned char c;
+
+	/* skip up to two wideband frames */
+	if (((len * 8 - off) >= 5) &&
+		get_n_bits_at(data, 1, off)) {
+		c = get_n_bits_at(data, 3, off + 1);
+		off += SpeexWBSubModeSz[c];
+
+		if (((len * 8 - off) >= 5) &&
+			get_n_bits_at(data, 1, off)) {
+			c = get_n_bits_at(data, 3, off + 1);
+			off += SpeexWBSubModeSz[c];
+
+			if (((len * 8 - off) >= 5) &&
+				get_n_bits_at(data, 1, off)) {
+				ast_log(LOG_WARNING, "Encountered corrupt speex frame; too many wideband frames in a row.\n");
+				return -1;
+			}
+		}
+
+	}
+	return off - bit;
+}
+
+static int speex_samples(unsigned char *data, int len)
+{
+	static const int SpeexSubModeSz[] = {
+		5, 43, 119, 160,
+		220, 300, 364, 492,
+		79, 0, 0, 0,
+		0, 0, 0, 0 };
+	static const int SpeexInBandSz[] = {
+		1, 1, 4, 4,
+		4, 4, 4, 4,
+		8, 8, 16, 16,
+		32, 32, 64, 64 };
+	int bit = 0;
+	int cnt = 0;
+	int off;
+	unsigned char c;
+
+	while ((len * 8 - bit) >= 5) {
+		/* skip wideband frames */
+		off = speex_get_wb_sz_at(data, len, bit);
+		if (off < 0)  {
+			ast_log(LOG_WARNING, "Had error while reading wideband frames for speex samples\n");
+			break;
+		}
+		bit += off;
+
+		if ((len * 8 - bit) < 5)
+			break;
+
+		/* get control bits */
+		c = get_n_bits_at(data, 5, bit);
+		bit += 5;
+
+		if (c == 15) {
+			/* terminator */
+			break;
+		} else if (c == 14) {
+			/* in-band signal; next 4 bits contain signal id */
+			c = get_n_bits_at(data, 4, bit);
+			bit += 4;
+			bit += SpeexInBandSz[c];
+		} else if (c == 13) {
+			/* user in-band; next 4 bits contain msg len */
+			c = get_n_bits_at(data, 4, bit);
+			bit += 4;
+			/* after which it's 5-bit signal id + c bytes of data */
+			bit += 5 + c * 8;
+		} else if (c > 8) {
+			/* unknown */
+			ast_log(LOG_WARNING, "Unknown speex control frame %d\n", c);
+			break;
+		} else {
+			/* skip number bits for submode (less the 5 control bits) */
+			bit += SpeexSubModeSz[c] - 5;
+			cnt += 160; /* new frame */
+		}
+	}
+	return cnt;
+}
+
+static int speex8_samples(struct ast_frame *frame)
+{
+	return speex_samples(frame->data.ptr, frame->datalen);
+}
 
 static struct ast_codec speex8 = {
 	.name = "speex",
@@ -241,7 +504,13 @@
 	.maximum_ms = 60,
 	.increment_ms = 10,
 	.default_ms = 20,
-};
+	.get_samples = speex8_samples,
+};
+
+static int speex16_samples(struct ast_frame *frame)
+{
+	return 2 * speex_samples(frame->data.ptr, frame->datalen);
+}
 
 static struct ast_codec speex16 = {
 	.name = "speex",
@@ -252,7 +521,13 @@
 	.maximum_ms = 60,
 	.increment_ms = 10,
 	.default_ms = 20,
-};
+	.get_samples = speex16_samples,
+};
+
+static int speex32_samples(struct ast_frame *frame)
+{
+	return 4 * speex_samples(frame->data.ptr, frame->datalen);
+}
 
 static struct ast_codec speex32 = {
 	.name = "speex",
@@ -263,7 +538,13 @@
 	.maximum_ms = 60,
 	.increment_ms = 10,
 	.default_ms = 20,
-};
+	.get_samples = speex32_samples,
+};
+
+static int ilbc_samples(struct ast_frame *frame)
+{
+	return 240 * (frame->datalen / 50);
+}
 
 static struct ast_codec ilbc = {
 	.name = "ilbc",
@@ -274,6 +555,7 @@
 	.maximum_ms = 30,
 	.increment_ms = 30,
 	.default_ms = 30,
+	.get_samples = ilbc_samples,
 };
 
 static struct ast_codec g722 = {
@@ -285,7 +567,19 @@
 	.maximum_ms = 150,
 	.increment_ms = 10,
 	.default_ms = 20,
-};
+	.get_samples = g726_samples,
+	.get_length = g726_length,
+};
+
+static int siren7_samples(struct ast_frame *frame)
+{
+	return frame->datalen * (16000 / 4000);
+}
+
+static int siren7_length(unsigned int samples)
+{
+	return samples / (16000 / 4000);
+}
 
 static struct ast_codec siren7 = {
 	.name = "siren7",
@@ -296,7 +590,19 @@
 	.maximum_ms = 80,
 	.increment_ms = 20,
 	.default_ms = 20,
-};
+	.get_samples = siren7_samples,
+	.get_length = siren7_length,
+};
+
+static int siren14_samples(struct ast_frame *frame)
+{
+	return (int) frame->datalen * ((float) 32000 / 6000);
+}
+
+static int siren14_length(unsigned int samples)
+{
+	return (int) samples / ((float) 32000 / 6000);;
+}
 
 static struct ast_codec siren14 = {
 	.name = "siren14",
@@ -307,6 +613,8 @@
 	.maximum_ms = 80,
 	.increment_ms = 20,
 	.default_ms = 20,
+	.get_samples = siren14_samples,
+	.get_length = siren14_length,
 };
 
 static struct ast_codec testlaw = {
@@ -318,7 +626,19 @@
 	.maximum_ms = 150,
 	.increment_ms = 10,
 	.default_ms = 20,
-};
+	.get_samples = ulaw_samples,
+	.get_length = ulaw_length,
+};
+
+static int g719_samples(struct ast_frame *frame)
+{
+	return (int) frame->datalen * ((float) 48000 / 8000);
+}
+
+static int g719_length(unsigned int samples)
+{
+	return (int) samples / ((float) 48000 / 8000);
+}
 
 static struct ast_codec g719 = {
 	.name = "g719",
@@ -329,6 +649,8 @@
 	.maximum_ms = 80,
 	.increment_ms = 20,
 	.default_ms = 20,
+	.get_samples = g719_samples,
+	.get_length = g719_length,
 };
 
 static struct ast_codec opus = {




More information about the asterisk-commits mailing list