[asterisk-commits] tilghman: branch tilghman/codec_bits2 r136749 - in /team/tilghman/codec_bits2...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Aug 7 21:29:48 CDT 2008


Author: tilghman
Date: Thu Aug  7 21:29:48 2008
New Revision: 136749

URL: http://svn.digium.com/view/asterisk?view=rev&rev=136749
Log:
Committing work, so it's not lost

Modified:
    team/tilghman/codec_bits2/include/asterisk/abstract_jb.h
    team/tilghman/codec_bits2/include/asterisk/frame.h
    team/tilghman/codec_bits2/include/asterisk/image.h
    team/tilghman/codec_bits2/include/asterisk/slinfactory.h
    team/tilghman/codec_bits2/include/asterisk/translate.h
    team/tilghman/codec_bits2/main/frame.c
    team/tilghman/codec_bits2/main/slinfactory.c
    team/tilghman/codec_bits2/main/translate.c

Modified: team/tilghman/codec_bits2/include/asterisk/abstract_jb.h
URL: http://svn.digium.com/view/asterisk/team/tilghman/codec_bits2/include/asterisk/abstract_jb.h?view=diff&rev=136749&r1=136748&r2=136749
==============================================================================
--- team/tilghman/codec_bits2/include/asterisk/abstract_jb.h (original)
+++ team/tilghman/codec_bits2/include/asterisk/abstract_jb.h Thu Aug  7 21:29:48 2008
@@ -31,6 +31,7 @@
 #define _ABSTRACT_JB_H_
 
 #include <sys/time.h>
+#include "asterisk/frame_defs.h"
 
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
@@ -97,6 +98,8 @@
 	FILE *logfile;
 	/*! \brief Jitterbuffer internal state flags. */
 	unsigned int flags;
+	/*! \brief Extended codec for the last voice frame in */
+	struct ast_extended_codec last_eformat;
 };
 
 

Modified: team/tilghman/codec_bits2/include/asterisk/frame.h
URL: http://svn.digium.com/view/asterisk/team/tilghman/codec_bits2/include/asterisk/frame.h?view=diff&rev=136749&r1=136748&r2=136749
==============================================================================
--- team/tilghman/codec_bits2/include/asterisk/frame.h (original)
+++ team/tilghman/codec_bits2/include/asterisk/frame.h Thu Aug  7 21:29:48 2008
@@ -33,10 +33,16 @@
 
 #include "asterisk/endian.h"
 #include "asterisk/linkedlists.h"
+#include "asterisk/frame_defs.h"
 
 struct ast_codec_pref {
 	char order[32];
 	char framing[32];
+};
+
+struct ast_ecodec_pref {
+	char order[572];
+	char framing[572];
 };
 
 /*! \page Def_Frame AST Multimedia and signalling frames
@@ -169,6 +175,8 @@
 	long len;
 	/*! Sequence number */
 	int seqno;
+	/*! 576-bit bitfield for codec type */
+	struct ast_extended_codec codec;
 };
 
 /*!
@@ -281,6 +289,27 @@
 /*! Maximum text mask */
 #define AST_FORMAT_MAX_TEXT	(1 << 28))
 #define AST_FORMAT_TEXT_MASK   (((1 << 30)-1) & ~(AST_FORMAT_AUDIO_MASK) & ~(AST_FORMAT_VIDEO_MASK))
+/*! Bit to tell routines to look in the extended bit range */
+#define AST_FORMAT_EXTENDED (1 << 31)
+
+extern const struct ast_extended_codec AST_FMT_ULAW;
+extern const struct ast_extended_codec AST_FMT_ALAW;
+extern const struct ast_extended_codec AST_FMT_SLINEAR;
+extern const struct ast_extended_codec AST_FMT_SLINEAR16;
+extern const struct ast_extended_codec AST_FMT_AUDIO_MASK;
+extern const struct ast_extended_codec AST_FMT_VIDEO_MASK;
+extern const struct ast_extended_codec AST_FMT_IMAGE_MASK;
+extern const struct ast_extended_codec AST_FMT_TEXT_MASK;
+extern const struct ast_extended_codec AST_FMT_NULL_MASK;
+#define AST_FMT_ULAW_INIT	{ .audio = { AST_FORMAT_AUDIO_ULAW, }, }
+#define AST_FMT_SLINEAR_INIT	{ .audio = { AST_FORMAT_AUDIO_SLINEAR, }, }
+#define AST_FMT_SLINEAR16_INIT	{ .audio = { AST_FORMAT_AUDIO_SLINEAR16, }, }
+#define AST_FMT_AUDIO_MASK_INIT	{ .audio = { -1, -1, -1, -1, -1, -1, -1, -1 }, }
+#define AST_FMT_VIDEO_MASK_INIT	{ .video = { -1, -1, -1, -1, -1, -1, -1, -1 }, }
+#define AST_FMT_IMAGE_MASK_INIT	{ .image = { -1 }, }
+#define AST_FMT_TEXT_MASK_INIT	{ .text = { -1 }, }
+#define AST_FMT_FULL_MASK_INIT	{ .audio = { -1, -1, -1, -1, -1, -1, -1, -1 }, .video = { -1, -1, -1, -1, -1, -1, -1, -1 }, .image = { -1 }, .text = { -1 } }
+#define AST_FMT_NULL_MASK_INIT	{ { 0 } }
 
 enum ast_control_frame_type {
 	AST_CONTROL_HANGUP = 1,		/*!< Other end has hungup */
@@ -402,6 +431,21 @@
 	int cur_ms;	/*!< Current value */
 };
 
+/*! \brief Definition of supported media formats (codecs) */
+struct ast_eformat_list {
+	struct ast_extended_codec bits;	/*!< bitmask value */
+	char *name;	/*!< short name */
+	int samplespersecond; /*!< Number of samples per second (8000/16000) */
+	char *desc;	/*!< Description */
+	int fr_len;	/*!< Single frame length in bytes */
+	int min_ms;	/*!< Min value */
+	int max_ms;	/*!< Max value */
+	int inc_ms;	/*!< Increment */
+	int def_ms;	/*!< Default value */
+	unsigned int flags;	/*!< Smoother flags */
+	int cur_ms;	/*!< Current value */
+};
+
 
 /*! \brief  Requests a frame to be allocated 
  * 
@@ -458,6 +502,7 @@
  * \return A static string containing the name of the format or "unknown" if unknown.
  */
 char* ast_getformatname(int format);
+char* ast_geteformatname(struct ast_extended_codec format);
 
 /*! \brief Get the names of a set of formats
  * \param buf a buffer for the output string
@@ -468,6 +513,7 @@
  * \return The return value is buf.
  */
 char* ast_getformatname_multiple(char *buf, size_t size, int format);
+char* ast_geteformatname_multiple(char *buf, size_t size, struct ast_extended_codec format);
 
 /*!
  * \brief Gets a format from a name.
@@ -475,6 +521,7 @@
  * \return This returns the form of the format in binary on success, 0 on error.
  */
 int ast_getformatbyname(const char *name);
+struct ast_extendec_codec ast_geteformatbyname(const char *name);
 
 /*! \brief Get a name from a format 
  * Gets a name from a format
@@ -482,6 +529,7 @@
  * \return This returns a static string identifying the format on success, 0 on error.
  */
 char *ast_codec2str(int codec);
+char *ast_ecodec2str(struct ast_extended_codec codec);
 
 /*! \name AST_Smoother 
 */
@@ -521,6 +569,9 @@
 
 struct ast_format_list *ast_get_format_list_index(int index);
 struct ast_format_list *ast_get_format_list(size_t *size);
+
+struct ast_eformat_list *ast_get_eformat_list_index(int index);
+struct ast_eformat_list *ast_get_eformat_list(size_t *size);
 void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix);
 
 /*! \page AudioCodecPref Audio Codec Preferences
@@ -548,30 +599,37 @@
  * \arg \ref AudioCodecPref 
 */
 int ast_codec_pref_index(struct ast_codec_pref *pref, int index);
+struct ast_extended_codec ast_ecodec_pref_index(struct ast_codec_pref *pref, int index);
 
 /*! \brief Remove audio a codec from a preference list */
 void ast_codec_pref_remove(struct ast_codec_pref *pref, int format);
+void ast_ecodec_pref_remove(struct ast_codec_pref *pref, struct ast_extended_codec format);
 
 /*! \brief Append a audio codec to a preference list, removing it first if it was already there 
 */
 int ast_codec_pref_append(struct ast_codec_pref *pref, int format);
+int ast_ecodec_pref_append(struct ast_codec_pref *pref, struct ast_extended_codec format);
 
 /*! \brief Prepend an audio codec to a preference list, removing it first if it was already there 
 */
 void ast_codec_pref_prepend(struct ast_codec_pref *pref, int format, int only_if_existing);
+void ast_ecodec_pref_prepend(struct ast_codec_pref *pref, struct ast_extended_codec format, int only_if_existing);
 
 /*! \brief Select the best audio format according to preference list from supplied options. 
    If "find_best" is non-zero then if nothing is found, the "Best" format of 
    the format list is selected, otherwise 0 is returned. */
 int ast_codec_choose(struct ast_codec_pref *pref, int formats, int find_best);
+struct ast_extended_codec ast_ecodec_choose(struct ast_codec_pref *pref, struct ast_extended_codec formats, int find_best);
 
 /*! \brief Set packet size for codec
 */
 int ast_codec_pref_setsize(struct ast_codec_pref *pref, int format, int framems);
+int ast_ecodec_pref_setsize(struct ast_codec_pref *pref, struct ast_extended_codec format, int framems);
 
 /*! \brief Get packet size for codec
 */
 struct ast_format_list ast_codec_pref_getsize(struct ast_codec_pref *pref, int format);
+struct ast_eformat_list ast_ecodec_pref_getsize(struct ast_codec_pref *pref, struct ast_extended_codec format);
 
 /*! \brief Parse an "allow" or "deny" line in a channel or device configuration 
         and update the capabilities mask and pref if provided.
@@ -579,18 +637,23 @@
 	\return Returns number of errors encountered during parsing
  */
 int ast_parse_allow_disallow(struct ast_codec_pref *pref, int *mask, const char *list, int allowing);
+int ast_parse_allow_disallow2(struct ast_ecodec_pref *pref, struct ast_extendec_codec *mask, const char *list, int allowing);
 
 /*! \brief Dump audio codec preference list into a string */
 int ast_codec_pref_string(struct ast_codec_pref *pref, char *buf, size_t size);
+int ast_ecodec_pref_string(struct ast_ecodec_pref *pref, char *buf, size_t size);
 
 /*! \brief Shift an audio codec preference list up or down 65 bytes so that it becomes an ASCII string */
 void ast_codec_pref_convert(struct ast_codec_pref *pref, char *buf, size_t size, int right);
+void ast_ecodec_pref_convert(struct ast_ecodec_pref *pref, char *buf, size_t size, int right);
 
 /*! \brief Returns the number of samples contained in the frame */
 int ast_codec_get_samples(struct ast_frame *f);
+#define ast_ecodec_get_samples ast_codec_get_samples
 
 /*! \brief Returns the number of bytes for the number of samples of the given format */
 int ast_codec_get_len(int format, int samples);
+int ast_ecodec_get_len(struct ast_extended_codec format, int samples);
 
 /*! \brief Appends a frame to the end of a list of frames, truncating the maximum length of the list */
 struct ast_frame *ast_frame_enqueue(struct ast_frame *head, struct ast_frame *f, int maxlen, int dupe);
@@ -600,6 +663,11 @@
 static inline int ast_codec_interp_len(int format) 
 { 
 	return (format == AST_FORMAT_ILBC) ? 30 : 20;
+}
+
+static inline int ast_ecodec_interp_len(struct ast_extended_codec format) 
+{ 
+	return (format.audio[0] == AST_FORMAT_ILBC) ? 30 : 20;
 }
 
 /*!
@@ -632,6 +700,156 @@
 	return 8000;
 }
 
+static force_inline int ast_eformat_rate(struct ast_extended_codec format)
+{
+	if (format.audio[0] == AST_FORMAT_G722 || format.audio[0] == AST_FORMAT_SLINEAR16)
+		return 16000;
+
+	return 8000;
+}
+
+/*! Convert the bitfield into an array of integers, for printing */
+const char *ast_codec2bitstring(struct ast_extended_codec ecodec, struct ast_str **str);
+#define BITSTRING_SIZE	60
+
+/*! Common bitwise operations, now that codec is no longer a 32-bit integer. */
+#define FMT_AND(a,b)	ast_extended_codec_and(a,b)
+#define FMT_OR(a,b)	ast_extended_codec_or(a,b)
+#define FMT_EQ(a,b)	ast_extended_codec_equal(a,b)
+#define FMT_COMPL(a)	ast_extended_codec_compl(a)
+#define FMT_NZ(a)	ast_extended_codec_nonzero(a)
+#define FMT_NOT(a)	ast_extended_codec_not(a)
+
+AST_INLINE_API(
+int ast_extended_codec_not(struct ast_extended_codec format),
+{
+	int i;
+	int max = sizeof(format) / sizeof(int);
+	union {
+		struct ast_extended_codec c;
+		int bits[sizeof(format) / sizeof(int)];
+	} u = { format };
+	for (i = 0; i < max; i++) {
+		if (u.bits[i]) {
+			return 0;
+		}
+	}
+	return 1;
+}
+)
+
+AST_INLINE_API(
+int ast_extended_codec_nonzero(struct ast_extended_codec format),
+{
+	int i;
+	int max = sizeof(format) / sizeof(int);
+	union {
+		struct ast_extended_codec c;
+		int bits[sizeof(format) / sizeof(int)];
+	} u = { format };
+	for (i = 0; i < max; i++) {
+		if (u.bits[i]) {
+			return 1;
+		}
+	}
+	return 0;
+}
+)
+
+AST_INLINE_API(
+int ast_extended_codec_equal(struct ast_extended_codec format1, struct ast_extended_codec format2),
+{
+	return memcmp(&format1, &format2, sizeof(format1)) == 0 ? 1 : 0;
+}
+)
+
+AST_INLINE_API(
+struct ast_extended_codec ast_extended_codec_compl(struct ast_extended_codec format),
+{
+	unsigned int i;
+	union {
+		struct ast_extended_codec c;
+		int bits[sizeof(format) / sizeof(int)];
+	} u = { format };
+	for (i = 0; i < sizeof(format) / sizeof(int); i++) {
+		u.bits[i] = ~u.bits[i];
+	}
+	return u.c;
+}
+)
+
+extern struct ast_extended_codec ast_extended_codec_and(struct ast_extended_codec format1, struct ast_extended_codec format2);
+extern struct ast_extended_codec ast_extended_codec_or(struct ast_extended_codec format1, struct ast_extended_codec format2);
+
+AST_INLINE_API(
+int ast_extended_codec_isaudio(struct ast_extended_codec format),
+{
+	unsigned int i;
+	for (i = 0; i < sizeof(format.audio) / sizeof(format.audio[0]); i++) {
+		if (format.audio[i]) {
+			return 1;
+		}
+	}
+	return 0;
+}
+)
+
+AST_INLINE_API(
+int ast_extended_codec_isvideo(struct ast_extended_codec format),
+{
+	unsigned int i;
+	for (i = 0; i < sizeof(format.video) / sizeof(format.video[0]); i++) {
+		if (format.video[i]) {
+			return 1;
+		}
+	}
+	return 0;
+}
+)
+
+AST_INLINE_API(
+int ast_extended_codec_isimage(struct ast_extended_codec format),
+{
+	unsigned int i;
+	for (i = 0; i < sizeof(format.image) / sizeof(format.image[0]); i++) {
+		if (format.image[i]) {
+			return 1;
+		}
+	}
+	return 0;
+}
+)
+
+AST_INLINE_API(
+struct ast_extended_codec ast_codec2extended(int format),
+{
+	int audio = format & ((1 << 16) - 1);
+	int image = format & ((1 << 16) | (1 << 17));
+	int video = format & ((1 << 18) | (1 << 19) | (1 << 20) | (1 << 21) | (1 << 22));
+	int text = format & (1 << 25);
+	struct ast_extended_codec codec = AST_FMT_NULL_MASK_INIT;
+
+	codec.audio[0] = audio;
+	codec.video[0] = video >> 18;
+	codec.image[0] = image >> 16;
+	codec.text[0] = text >> 25;
+
+	return codec;
+}
+)
+
+AST_INLINE_API(
+int ast_extended2codec(struct ast_extended_codec codec),
+{
+	int audio = codec.audio[0] & ((1 << 16) - 1);
+	int image = codec.image[0] & 3;
+	int video = codec.image[0] & ((1 << 5) - 1);
+	int text = codec.text[0] & 1;
+
+	return (audio & (image << 16) & (video << 18) & (text < 25));
+}
+)
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif

Modified: team/tilghman/codec_bits2/include/asterisk/image.h
URL: http://svn.digium.com/view/asterisk/team/tilghman/codec_bits2/include/asterisk/image.h?view=diff&rev=136749&r1=136748&r2=136749
==============================================================================
--- team/tilghman/codec_bits2/include/asterisk/image.h (original)
+++ team/tilghman/codec_bits2/include/asterisk/image.h Thu Aug  7 21:29:48 2008
@@ -23,6 +23,8 @@
 #ifndef _ASTERISK_IMAGE_H
 #define _ASTERISK_IMAGE_H
 
+#include "asterisk/frame_defs.h"
+
 /*! \brief structure associated with registering an image format */
 struct ast_imager {
 	char *name;			/*!< Name */
@@ -33,6 +35,7 @@
 	int (*identify)(int fd);				/*!< Identify if this is that type of file */
 	int (*write_image)(int fd, struct ast_frame *frame);	/*!< Returns length written */
 	AST_LIST_ENTRY(ast_imager) list;			/*!< For linked list */
+	struct ast_extended_codec eformat;			/*!< Image format */
 };
 
 /*! 
@@ -63,6 +66,7 @@
  * \retval NULL on failure
  */
 struct ast_frame *ast_read_image(char *filename, const char *preflang, int format);
+struct ast_frame *ast_read_image2(char *filename, const char *preflang, struct ast_extended_codec format);
 
 /*! 
  * \brief Register image format

Modified: team/tilghman/codec_bits2/include/asterisk/slinfactory.h
URL: http://svn.digium.com/view/asterisk/team/tilghman/codec_bits2/include/asterisk/slinfactory.h?view=diff&rev=136749&r1=136748&r2=136749
==============================================================================
--- team/tilghman/codec_bits2/include/asterisk/slinfactory.h (original)
+++ team/tilghman/codec_bits2/include/asterisk/slinfactory.h Thu Aug  7 21:29:48 2008
@@ -24,6 +24,8 @@
 #ifndef _ASTERISK_SLINFACTORY_H
 #define _ASTERISK_SLINFACTORY_H
 
+#include "asterisk/frame_defs.h"
+
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
 #endif
@@ -38,6 +40,7 @@
 	size_t holdlen;                          /*!< Number of samples currently in the hold */
 	unsigned int size;                       /*!< Number of samples currently in the factory */
 	unsigned int format;                     /*!< Current format the translation path is converting from */
+	struct ast_extended_codec eformat;       /*!< Current format the translation path is converting from */
 };
 
 /*!

Modified: team/tilghman/codec_bits2/include/asterisk/translate.h
URL: http://svn.digium.com/view/asterisk/team/tilghman/codec_bits2/include/asterisk/translate.h?view=diff&rev=136749&r1=136748&r2=136749
==============================================================================
--- team/tilghman/codec_bits2/include/asterisk/translate.h (original)
+++ team/tilghman/codec_bits2/include/asterisk/translate.h Thu Aug  7 21:29:48 2008
@@ -35,7 +35,7 @@
 #include "asterisk/frame.h"
 #include "asterisk/plc.h"
 #include "asterisk/linkedlists.h"
-// XXX #include "asterisk/module.h"
+/* XXX #include "asterisk/module.h" */
 #endif
 
 struct ast_trans_pvt;	/* declared below */
@@ -70,25 +70,26 @@
  */
 struct ast_translator {
 	const char name[80];		/*!< Name of translator */
-	int srcfmt;			/*!< Source format (note: bit position,
-					  converted to index during registration) */
-	int dstfmt;			/*!< Destination format (note: bit position,
-					  converted to index during registration) */
-
-	int (*newpvt)(struct ast_trans_pvt *); /*!< initialize private data 
-					associated with the translator */
-
+	/*! Source format (note: bit position, converted to index during registration) */
+	int srcfmt;
+	/*! Destination format (note: bit position, converted to index during registration) */
+	int dstfmt;
+	/*! Extended source format (note: bit position, converted to index during registration) */
+	struct ast_extended_codec esrcfmt;
+	/*! Extended destination format (note: bit position, converted to index during registration) */
+	struct ast_extended_codec edstfmt;
+
+	/*! initialize private data associated with the translator */
+	int (*newpvt)(struct ast_trans_pvt *);
+
+	/*! Input frame callback. Store (and possibly convert) input frame. */
 	int (*framein)(struct ast_trans_pvt *pvt, struct ast_frame *in);
-					/*!< Input frame callback. Store 
-					     (and possibly convert) input frame. */
-
+
+	/*! Output frame callback. Generate a frame with outbuf content. */
 	struct ast_frame * (*frameout)(struct ast_trans_pvt *pvt);
-					/*!< Output frame callback. Generate a frame 
-					    with outbuf content. */
-
+
+	/*! cleanup private data, if needed (often unnecessary). */
 	void (*destroy)(struct ast_trans_pvt *pvt);
-					/*!< cleanup private data, if needed 
-						(often unnecessary). */
 
 	struct ast_frame * (*sample)(void);	/*!< Generate an example frame */
 
@@ -114,6 +115,52 @@
 	int cost;			/*!< Cost in milliseconds for encoding/decoding 1 second of sound */
 	int active;			/*!< Whether this translator should be used or not */
 	AST_LIST_ENTRY(ast_translator) list;	/*!< link field */
+};
+
+struct ast_translator2 {
+	const char name[80];		/*!< Name of translator */
+	/*! Extended source format (note: bit position, converted to index during registration) */
+	struct ast_extended_codec esrcfmt;
+	/*! Extended destination format (note: bit position, converted to index during registration) */
+	struct ast_extended_codec edstfmt;
+
+	/*! initialize private data associated with the translator */
+	int (*newpvt)(struct ast_trans_pvt *);
+
+	/*! Input frame callback. Store (and possibly convert) input frame. */
+	int (*framein)(struct ast_trans_pvt *pvt, struct ast_frame *in);
+
+	/*! Output frame callback. Generate a frame with outbuf content. */
+	struct ast_frame * (*frameout)(struct ast_trans_pvt *pvt);
+
+	/*! cleanup private data, if needed (often unnecessary). */
+	void (*destroy)(struct ast_trans_pvt *pvt);
+
+	struct ast_frame * (*sample)(void);	/*!< Generate an example frame */
+
+	/*! \brief size of outbuf, in samples. Leave it 0 if you want the framein
+	 * callback deal with the frame. Set it appropriately if you
+	 * want the code to checks if the incoming frame fits the
+	 * outbuf (this is e.g. required for plc).
+	 */
+	int buffer_samples;	/*< size of outbuf, in samples */
+
+	/*! \brief size of outbuf, in bytes. Mandatory. The wrapper code will also
+	 * allocate an AST_FRIENDLY_OFFSET space before.
+	 */
+	int buf_size;
+
+	int desc_size;			/*!< size of private descriptor in pvt->pvt, if any */
+	int plc_samples;		/*!< set to the plc block size if used, 0 otherwise */
+	int useplc;			/*!< current status of plc, changed at runtime */
+	int native_plc;			/*!< true if the translator can do native plc */
+
+	struct ast_module *module;	/* opaque reference to the parent module */
+
+	int cost;			/*!< Cost in milliseconds for encoding/decoding 1 second of sound */
+	int active;			/*!< Whether this translator should be used or not */
+	AST_LIST_ENTRY(ast_translator) list;	/*!< link field */
+	struct ast_translator *legacy_registrant;
 };
 
 /*! \brief
@@ -168,9 +215,11 @@
  * \return 0 on success, -1 on failure
  */
 int __ast_register_translator(struct ast_translator *t, struct ast_module *module);
+int __ast_register_translator2(struct ast_translator2 *t, struct ast_module *module);
 
 /*! \brief See \ref __ast_register_translator() */
 #define ast_register_translator(t) __ast_register_translator(t, ast_module_info->self)
+#define ast_register_translator2(t) __ast_register_translator2(t, ast_module_info->self)
 
 /*!
  * \brief Unregister a translator
@@ -179,6 +228,7 @@
  * \return 0 on success, -1 on failure
  */
 int ast_unregister_translator(struct ast_translator *t);
+int ast_unregister_translator2(struct ast_translator2 *t);
 
 /*!
  * \brief Activate a previously deactivated translator
@@ -188,6 +238,7 @@
  * Enables the specified translator for use.
  */
 void ast_translator_activate(struct ast_translator *t);
+void ast_translator2_activate(struct ast_translator2 *t);
 
 /*!
  * \brief Deactivate a translator
@@ -197,6 +248,7 @@
  * Disables the specified translator from being used.
  */
 void ast_translator_deactivate(struct ast_translator *t);
+void ast_translator2_deactivate(struct ast_translator2 *t);
 
 /*!
  * \brief Chooses the best translation path
@@ -207,6 +259,7 @@
  * \note Modifies dests and srcs in place 
  */
 int ast_translator_best_choice(int *dsts, int *srcs);
+int ast_translator2_best_choice(struct ast_extended_codec *dsts, struct ast_extended_codec *srcs);
 
 /*! 
  * \brief Builds a translator path
@@ -216,6 +269,7 @@
  * \return ast_trans_pvt on success, NULL on failure
  * */
 struct ast_trans_pvt *ast_translator_build_path(int dest, int source);
+struct ast_trans_pvt *ast_translator2_build_path(struct ast_extended_codec dest, struct ast_extended_codec source);
 
 /*!
  * \brief Frees a translator path
@@ -242,6 +296,7 @@
  * \return the number of translation steps required, or -1 if no path is available
  */
 unsigned int ast_translate_path_steps(unsigned int dest, unsigned int src);
+unsigned int ast_translate2_path_steps(struct ast_extended_codec dest, struct ast_extended_codec src);
 
 /*!
  * \brief Mask off unavailable formats from a format bitmask
@@ -256,6 +311,7 @@
  * present in 'src', or the function will produce unexpected results.
  */
 unsigned int ast_translate_available_formats(unsigned int dest, unsigned int src);
+struct ast_extended_codec ast_translate2_available_formats(struct ast_extended_codec dest, struct ast_extended_codec src);
 
 /*!
  * \brief Hint that a frame from a translator has been freed

Modified: team/tilghman/codec_bits2/main/frame.c
URL: http://svn.digium.com/view/asterisk/team/tilghman/codec_bits2/main/frame.c?view=diff&rev=136749&r1=136748&r2=136749
==============================================================================
--- team/tilghman/codec_bits2/main/frame.c (original)
+++ team/tilghman/codec_bits2/main/frame.c Thu Aug  7 21:29:48 2008
@@ -43,6 +43,17 @@
 static int headers;
 static AST_LIST_HEAD_STATIC(headerlist, ast_frame);
 #endif
+
+/*! Convenience structures */
+const struct ast_extended_codec AST_FMT_ULAW = { .audio = { AST_FORMAT_ULAW, }, };
+const struct ast_extended_codec AST_FMT_ALAW = { .audio = { AST_FORMAT_ALAW, }, };
+const struct ast_extended_codec AST_FMT_SLINEAR = { .audio = { AST_FORMAT_SLINEAR, }, };
+const struct ast_extended_codec AST_FMT_SLINEAR16 = { .audio = { AST_FORMAT_SLINEAR16, }, };
+const struct ast_extended_codec AST_FMT_AUDIO_MASK = AST_FMT_AUDIO_MASK_INIT;
+const struct ast_extended_codec AST_FMT_VIDEO_MASK = AST_FMT_VIDEO_MASK_INIT;
+const struct ast_extended_codec AST_FMT_IMAGE_MASK = AST_FMT_IMAGE_MASK_INIT;
+const struct ast_extended_codec AST_FMT_TEXT_MASK = AST_FMT_TEXT_MASK_INIT;
+const struct ast_extended_codec AST_FMT_NULL_MASK = AST_FMT_NULL_MASK_INIT;
 
 #if !defined(LOW_MEMORY)
 static void frame_cache_cleanup(void *data);

Modified: team/tilghman/codec_bits2/main/slinfactory.c
URL: http://svn.digium.com/view/asterisk/team/tilghman/codec_bits2/main/slinfactory.c?view=diff&rev=136749&r1=136748&r2=136749
==============================================================================
--- team/tilghman/codec_bits2/main/slinfactory.c (original)
+++ team/tilghman/codec_bits2/main/slinfactory.c Thu Aug  7 21:29:48 2008
@@ -82,18 +82,27 @@
 	struct ast_frame *begin_frame = f, *duped_frame = NULL, *frame_ptr;
 	unsigned int x;
 
-	if (f->subclass != AST_FORMAT_SLINEAR && f->subclass != AST_FORMAT_SLINEAR16) {
-		if (sf->trans && f->subclass != sf->format) {
+	if ((f->subclass != AST_FORMAT_SLINEAR && f->subclass != AST_FORMAT_SLINEAR16) ||
+		(f->subclass == AST_FORMAT_EXTENDED &&
+			f->codec.audio[0] != AST_FORMAT_SLINEAR &&
+			f->codec.audio[0] != AST_FORMAT_SLINEAR16)) {
+		if (sf->trans && (f->subclass != sf->format || (f->subclass == AST_FORMAT_EXTENDED && !FMT_EQ(f->codec, sf->eformat)))) {
 			ast_translator_free_path(sf->trans);
 			sf->trans = NULL;
 		}
 
 		if (!sf->trans) {
-			if (!(sf->trans = ast_translator_build_path((f->subclass == AST_FORMAT_G722 ? AST_FORMAT_SLINEAR16 : AST_FORMAT_SLINEAR), f->subclass))) {
+			if ((f->subclass == AST_FORMAT_EXTENDED &&
+				!(sf->trans = ast_translator2_build_path(
+					(ast_eformat_rate(f->codec) > 8000) ? AST_FMT_SLINEAR16 : AST_FMT_SLINEAR, f->codec))) ||
+			(f->subclass != AST_FORMAT_EXTENDED &&
+				!(sf->trans = ast_translator_build_path(
+					(ast_format_rate(f->subclass) > 8000 ? AST_FORMAT_SLINEAR16 : AST_FORMAT_SLINEAR), f->subclass)))) {
 				ast_log(LOG_WARNING, "Cannot build a path from %s to slin\n", ast_getformatname(f->subclass));
 				return 0;
 			}
 			sf->format = f->subclass;
+			sf->eformat = f->codec;
 		}
 
 		if (!(begin_frame = ast_translate(sf->trans, f, 0))) 

Modified: team/tilghman/codec_bits2/main/translate.c
URL: http://svn.digium.com/view/asterisk/team/tilghman/codec_bits2/main/translate.c?view=diff&rev=136749&r1=136748&r2=136749
==============================================================================
--- team/tilghman/codec_bits2/main/translate.c (original)
+++ team/tilghman/codec_bits2/main/translate.c Thu Aug  7 21:29:48 2008
@@ -42,10 +42,10 @@
 #define MAX_RECALC 1000 /* max sample recalc */
 
 /*! \brief the list of translators */
-static AST_RWLIST_HEAD_STATIC(translators, ast_translator);
+static AST_RWLIST_HEAD_STATIC(translators, ast_translator2);
 
 struct translator_path {
-	struct ast_translator *step;	/*!< Next step translator */
+	struct ast_translator2 *step;	/*!< Next step translator */
 	unsigned int cost;		/*!< Complete cost to destination */
 	unsigned int multistep;		/*!< Multiple conversions required for this translation */
 };
@@ -55,12 +55,12 @@
  * The full path can be reconstricted iterating on the matrix
  * until step->dstfmt == desired_format.
  *
- * Array indexes are 'src' and 'dest', in that order.
+ * Array indexes are 'src page', 'src bits', 'dest page', and 'dest bits', in that order.
  *
  * Note: the lock in the 'translators' list is also used to protect
  * this structure.
  */
-static struct translator_path tr_matrix[MAX_FORMAT][MAX_FORMAT];
+static struct translator_path tr_matrix[sizeof(AST_FMT_NULL_MASK) / sizeof(AST_FMT_NULL_MASK.audio[0])][sizeof(AST_FMT_NULL_MASK.audio[0]) * 8][sizeof(AST_FMT_NULL_MASK) / sizeof(AST_FMT_NULL_MASK.audio[0])][sizeof(AST_FMT_NULL_MASK.audio[0]) * 8];
 
 /*! \todo
  * TODO: sample frames for each supported input format.
@@ -89,7 +89,7 @@
  * \brief Allocate the descriptor, required outbuf space,
  * and possibly also plc and desc.
  */
-static void *newpvt(struct ast_translator *t)
+static void *newpvt(struct ast_translator2 *t)
 {
 	struct ast_trans_pvt *pvt;
 	int len;
@@ -258,32 +258,56 @@
 	}
 }
 
+static int page_and_bit_calculator(struct ast_extended_codec in, int *page, int *bits)
+{
+	union {
+		struct ast_extended_codec codec;
+		unsigned int bits[sizeof(struct ast_extended_codec) / sizeof(int)];
+	} _in = { in };
+	int ptmp, btmp;
+
+	for (ptmp = 0; ptmp < sizeof(struct ast_extended_codec) / sizeof(int); ptmp++) {
+		for (btmp = 0; btmp < sizeof(int) * 8; btmp++) {
+			if (_in.bits[ptmp] & (1 << (btmp))) {
+				*page = ptmp;
+				*bits = btmp;
+				return 0;
+			}
+		}
+	}
+
+	return -1;
+}
+
 /*! \brief Build a chain of translators based upon the given source and dest formats */
-struct ast_trans_pvt *ast_translator_build_path(int dest, int source)
+struct ast_trans_pvt *ast_translator2_build_path(struct ast_extended_codec dest, struct ast_extended_codec source)
 {
 	struct ast_trans_pvt *head = NULL, *tail = NULL;
-	
-	source = powerof(source);
-	dest = powerof(dest);
-
-	if (source == -1 || dest == -1) {
-		ast_log(LOG_WARNING, "No translator path: (%s codec is not valid)\n", source == -1 ? "starting" : "ending");
+	int dest_page, dest_bits, source_page, source_bits;
+
+	if (page_and_bit_calculator(dest, &dest_page, &dest_bits)) {
+		ast_log(LOG_ERROR, "Attempted to translate to NULL format\n");
 		return NULL;
 	}
 
+	if (page_and_bit_calculator(source, &source_page, &source_bits)) {
+		ast_log(LOG_ERROR, "Attempted to translate from NULL format\n");
+		return NULL;
+	}
+
 	AST_RWLIST_RDLOCK(&translators);
 
-	while (source != dest) {
+	while (!FMT_EQ(source, dest)) {
 		struct ast_trans_pvt *cur;
-		struct ast_translator *t = tr_matrix[source][dest].step;
+		struct ast_translator2 *t = tr_matrix[source_page][source_bits][dest_page][dest_bits].step;
 		if (!t) {
 			ast_log(LOG_WARNING, "No translator path from %s to %s\n", 
-				ast_getformatname(source), ast_getformatname(dest));
+				ast_geteformatname(source), ast_geteformatname(dest));
 			AST_RWLIST_UNLOCK(&translators);
 			return NULL;
 		}
 		if (!(cur = newpvt(t))) {
-			ast_log(LOG_WARNING, "Failed to build translator step from %d to %d\n", source, dest);
+			ast_log(LOG_WARNING, "Failed to build translator step from %s to %s\n", ast_geteformatname(source), ast_geteformatname(dest));
 			if (head)
 				ast_translator_free_path(head);	
 			AST_RWLIST_UNLOCK(&translators);
@@ -296,11 +320,16 @@
 		tail = cur;
 		cur->nextin = cur->nextout = ast_tv(0, 0);
 		/* Keep going if this isn't the final destination */
-		source = cur->t->dstfmt;
+		source = cur->t->edstfmt;
 	}
 
 	AST_RWLIST_UNLOCK(&translators);
 	return head;
+}
+
+struct ast_trans_pvt *ast_translator_build_path(int dest, int source)
+{
+	return ast_translator2_build_path(ast_codec2extended(dest), ast_codec2extended(source));
 }
 
 /*! \brief do the actual translation */
@@ -380,14 +409,14 @@
 }
 
 /*! \brief compute the cost of a single translation step */
-static void calc_cost(struct ast_translator *t, int seconds)
+static void calc_cost(struct ast_translator2 *t, int seconds)
 {
 	int num_samples = 0;
 	struct ast_trans_pvt *pvt;
 	struct rusage start;
 	struct rusage end;
 	int cost;
-	int out_rate = ast_format_rate(t->dstfmt);
+	int out_rate = ast_eformat_rate(t->edstfmt);
 
 	if (!seconds)
 		seconds = 1;
@@ -444,69 +473,101 @@
 */
 static void rebuild_matrix(int samples)
 {
-	struct ast_translator *t;
-	int x;      /* source format index */
-	int y;      /* intermediate format index */
-	int z;      /* destination format index */
+	struct ast_translator2 *t;
+	union {
+		struct ast_extended_codec codec;
+		int bits[sizeof(struct ast_extended_codec) / sizeof(int)];
+	} begin = { AST_FMT_NULL_MASK_INIT }, inter = { AST_FMT_NULL_MASK_INIT }, end = { AST_FMT_NULL_MASK_INIT };
+	int begin_page, begin_bits, inter_page, inter_bits, end_page, end_bits;
 
 	ast_debug(1, "Resetting translation matrix\n");
 
-	bzero(tr_matrix, sizeof(tr_matrix));
+	memset(tr_matrix, 0, sizeof(tr_matrix));
 
 	/* first, compute all direct costs */
 	AST_RWLIST_TRAVERSE(&translators, t, list) {
 		if (!t->active)
 			continue;
 
-		x = t->srcfmt;
-		z = t->dstfmt;
-
-		if (samples)
+		if (page_and_bit_calculator(t->esrcfmt, &begin_page, &begin_bits)) {
+			continue;
+		}
+		if (page_and_bit_calculator(t->edstfmt, &end_page, &end_bits)) {
+			continue;
+		}
+
+		if (samples) {
 			calc_cost(t, samples);
-	  
-		if (!tr_matrix[x][z].step || t->cost < tr_matrix[x][z].cost) {
-			tr_matrix[x][z].step = t;
-			tr_matrix[x][z].cost = t->cost;
+		}
+
+		if (!tr_matrix[begin_page][begin_bits][end_page][end_bits].step ||
+			t->cost < tr_matrix[begin_page][begin_bits][end_page][end_bits].cost) {
+			tr_matrix[begin_page][begin_bits][end_page][end_bits].step = t;
+			tr_matrix[begin_page][begin_bits][end_page][end_bits].cost = t->cost;
 		}
 	}
 
 	/*
-	 * For each triple x, y, z of distinct formats, check if there is
-	 * a path from x to z through y which is cheaper than what is
+	 * For each triple begin, inter, end of distinct formats, check if there is
+	 * a path from begin to end through inter which is cheaper than what is
 	 * currently known, and in case, update the matrix.
 	 * Repeat until the matrix is stable.
 	 */
 	for (;;) {
 		int changed = 0;
-		for (x = 0; x < MAX_FORMAT; x++) {      /* source format */
-			for (y = 0; y < MAX_FORMAT; y++) {    /* intermediate format */
-				if (x == y)                     /* skip ourselves */
-					continue;
-
-				for (z = 0; z<MAX_FORMAT; z++) {  /* dst format */
-					int newcost;
-
-					if (z == x || z == y)       /* skip null conversions */
-						continue;
-					if (!tr_matrix[x][y].step)  /* no path from x to y */
-						continue;
-					if (!tr_matrix[y][z].step)  /* no path from y to z */
-						continue;
-					newcost = tr_matrix[x][y].cost + tr_matrix[y][z].cost;
-					if (tr_matrix[x][z].step && newcost >= tr_matrix[x][z].cost)
-						continue;               /* x->y->z is more expensive than
-						                         * the existing path */
-					/* ok, we can get from x to z via y with a cost that
-					   is the sum of the transition from x to y and
-					   from y to z */
+		for (begin_page = 0; begin_page < sizeof(struct ast_extended_codec) / sizeof(int); begin_page++) {
+			for (begin_bits = 0; begin_bits < sizeof(int) * 8; begin_bits++) {
+				begin.bits[begin_page] = 1 << begin_bits;
+				for (inter_page = 0; inter_page < sizeof(struct ast_extended_codec) / sizeof(int); inter_page++) {
+					for (inter_bits = 0; inter_bits < sizeof(int) * 8; inter_bits++) {
+						if (begin_page == inter_page && begin_bits == inter_bits) {
+							/* Skip ourselves */
+							continue;
+						}
+						inter.bits[inter_page] = 1 << inter_bits;
+						for (end_page = 0; end_page < sizeof(struct ast_extended_codec) / sizeof(int); end_page++) {
+							for (end_bits = 0; end_bits < sizeof(int) * 8; end_bits++) {
+								int newcost;
+								if ((end_page == begin_page && end_bits == begin_bits) || (end_page == inter_page && end_bits == inter_bits)) {
+									/* Skip null conversion */
+									continue;
+								}
+
+								if (!tr_matrix[begin_page][begin_bits][inter_page][inter_bits].step) { /* no path from begin to inter */
+									continue;
+								}
+								if (!tr_matrix[inter_page][inter_bits][end_page][end_bits].step) { /* no path from inter to end */
+									continue;
+								}
+
+								newcost = tr_matrix[begin_page][begin_bits][inter_page][inter_bits].cost + tr_matrix[inter_page][inter_bits][end_page][end_bits].cost;
+
+								if (tr_matrix[begin_page][begin_bits][end_page][end_bits].step && newcost >= tr_matrix[begin_page][begin_bits][end_page][end_bits].cost) {
+									/* begin->inter->end is more expensive than the existing path */
+									continue;
+								}
+								/* ok, we can get from begin to end via inter with a cost that
+								   is the sum of the transition from begin to inter and
+								   from inter to end */
 						 
-					tr_matrix[x][z].step = tr_matrix[x][y].step;
-					tr_matrix[x][z].cost = newcost;
-					tr_matrix[x][z].multistep = 1;
-					ast_debug(3, "Discovered %d cost path from %s to %s, via %d\n", tr_matrix[x][z].cost, ast_getformatname(x), ast_getformatname(z), y);
-					changed++;
+								tr_matrix[begin_page][begin_bits][end_page][end_bits].step = tr_matrix[begin_page][begin_bits][inter_page][inter_bits].step;
+								tr_matrix[begin_page][begin_bits][end_page][end_bits].cost = newcost;
+								tr_matrix[begin_page][begin_bits][end_page][end_bits].multistep = 1;
+								end.bits[end_page] = 1 << end_bits;
+								ast_debug(3, "Discovered %d cost path from %s to %s, via %s\n",
+									tr_matrix[begin_page][begin_bits][end_page][end_bits].cost,
+									ast_geteformatname(begin.codec),
+									ast_geteformatname(end.codec),
+									ast_geteformatname(inter.codec));
+								changed++;
+							}
+							end.bits[end_page] = 0;
+						}
+					}
+					inter.bits[inter_page] = 0;
 				}
 			}
+			begin.bits[begin_page] = 0;
 		}
 		if (!changed)
 			break;
@@ -516,7 +577,9 @@
 static char *handle_cli_core_show_translation(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 #define SHOW_TRANS 16
-	int x, y, z;
+	struct ast_extended_codec source = AST_FMT_NULL_MASK_INIT, dest = AST_FMT_NULL_MASK_INIT, showme = AST_FMT_NULL_MASK_INIT;
+	int begin_page, begin_bits, end_page, end_bits;
+	struct ast_str *out = ast_str_alloca(200);
 	int curlen = 0, longest = 0;
 
 	switch (cmd) {
@@ -537,20 +600,20 @@
 		return CLI_SHOWUSAGE;
 	
 	if (a->argv[3] && !strcasecmp(a->argv[3], "recalc")) {
-		z = a->argv[4] ? atoi(a->argv[4]) : 1;
-
-		if (z <= 0) {
+		int seconds = a->argv[4] ? atoi(a->argv[4]) : 1;
+
+		if (seconds <= 0) {
 			ast_cli(a->fd, "         Recalc must be greater than 0.  Defaulting to 1.\n");
-			z = 1;
-		}
-
-		if (z > MAX_RECALC) {
-			ast_cli(a->fd, "         Maximum limit of recalc exceeded by %d, truncating value to %d\n", z - MAX_RECALC, MAX_RECALC);
-			z = MAX_RECALC;
-		}
-		ast_cli(a->fd, "         Recalculating Codec Translation (number of sample seconds: %d)\n\n", z);
+			seconds = 1;
+		}
+
+		if (seconds > MAX_RECALC) {
+			ast_cli(a->fd, "         Maximum limit of recalc exceeded by %d, truncating value to %d\n", seconds - MAX_RECALC, MAX_RECALC);
+			seconds = MAX_RECALC;
+		}
+		ast_cli(a->fd, "         Recalculating Codec Translation (number of sample seconds: %d)\n\n", seconds);
 		AST_RWLIST_WRLOCK(&translators);
-		rebuild_matrix(z);
+		rebuild_matrix(seconds);
 		AST_RWLIST_UNLOCK(&translators);
 	} else if (a->argc > 3)
 		return CLI_SHOWUSAGE;
@@ -560,45 +623,93 @@
 	ast_cli(a->fd, "         Translation times between formats (in microseconds) for one second of data\n");
 	ast_cli(a->fd, "          Source Format (Rows) Destination Format (Columns)\n\n");
 	/* Get the length of the longest (usable?) codec name, so we know how wide the left side should be */
-	for (x = 0; x < SHOW_TRANS; x++) {
-		curlen = strlen(ast_getformatname(1 << (x)));
-		if (curlen > longest)
-			longest = curlen;
-	}
-	for (x = -1; x < SHOW_TRANS; x++) {
-		struct ast_str *out = ast_str_alloca(120);
-		/*Go ahead and move to next iteration if dealing with an unknown codec*/
-		if(x >= 0 && !strcmp(ast_getformatname(1 << (x)), "unknown"))
-			continue;
-		ast_str_set(&out, -1, " ");
-		for (y = -1; y < SHOW_TRANS; y++) {
-			/*Go ahead and move to next iteration if dealing with an unknown codec*/
-			if (y >= 0 && !strcmp(ast_getformatname(1 << (y)), "unknown"))
+	for (begin_page = 0; begin_page < ARRAY_LEN(showme.audio); begin_page++) {

[... 633 lines stripped ...]



More information about the asterisk-commits mailing list