[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