[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